Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions sqlx-core/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,17 @@ where
<&T as Encode<DB>>::size_hint(&self.as_ref())
}
}

#[macro_export]
macro_rules! forward_encode_impl {
($for_type:ty, $forward_to:ty, $db:ident) => {
impl<'q> Encode<'q, $db> for $for_type {
fn encode_by_ref(
&self,
buf: &mut <$db as sqlx_core::database::Database>::ArgumentBuffer<'q>,
) -> Result<IsNull, BoxDynError> {
<$forward_to as Encode<$db>>::encode(self.as_ref(), buf)
}
}
};
}
17 changes: 6 additions & 11 deletions sqlx-mysql/src/types/bytes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;

use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
Expand Down Expand Up @@ -42,12 +44,6 @@ impl<'r> Decode<'r, MySql> for &'r [u8] {
}
}

impl Encode<'_, MySql> for Box<[u8]> {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
<&[u8] as Encode<MySql>>::encode(self.as_ref(), buf)
}
}

impl Type<MySql> for Vec<u8> {
fn type_info() -> MySqlTypeInfo {
<[u8] as Type<MySql>>::type_info()
Expand All @@ -70,8 +66,7 @@ impl Decode<'_, MySql> for Vec<u8> {
}
}

impl Encode<'_, MySql> for Cow<'_, [u8]> {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
<&[u8] as Encode<MySql>>::encode(self.as_ref(), buf)
}
}
forward_encode_impl!(Arc<[u8]>, &[u8], MySql);
forward_encode_impl!(Rc<[u8]>, &[u8], MySql);
forward_encode_impl!(Box<[u8]>, &[u8], MySql);
forward_encode_impl!(Cow<'_, [u8]>, &[u8], MySql);
27 changes: 7 additions & 20 deletions sqlx-mysql/src/types/str.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;

use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
Expand Down Expand Up @@ -47,12 +49,6 @@ impl<'r> Decode<'r, MySql> for &'r str {
}
}

impl Encode<'_, MySql> for Box<str> {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
<&str as Encode<MySql>>::encode(&**self, buf)
}
}

impl Type<MySql> for String {
fn type_info() -> MySqlTypeInfo {
<str as Type<MySql>>::type_info()
Expand All @@ -63,23 +59,14 @@ impl Type<MySql> for String {
}
}

impl Encode<'_, MySql> for String {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
<&str as Encode<MySql>>::encode(&**self, buf)
}
}

impl Decode<'_, MySql> for String {
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
<&str as Decode<MySql>>::decode(value).map(ToOwned::to_owned)
}
}

impl Encode<'_, MySql> for Cow<'_, str> {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
match self {
Cow::Borrowed(str) => <&str as Encode<MySql>>::encode(*str, buf),
Cow::Owned(str) => <&str as Encode<MySql>>::encode(&**str, buf),
}
}
}
forward_encode_impl!(Arc<str>, &str, MySql);
forward_encode_impl!(Rc<str>, &str, MySql);
forward_encode_impl!(Cow<'_, str>, &str, MySql);
forward_encode_impl!(Box<str>, &str, MySql);
forward_encode_impl!(String, &str, MySql);
17 changes: 6 additions & 11 deletions sqlx-postgres/src/types/bytes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;

use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
Expand Down Expand Up @@ -44,12 +46,6 @@ impl Encode<'_, Postgres> for &'_ [u8] {
}
}

impl Encode<'_, Postgres> for Box<[u8]> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
<&[u8] as Encode<Postgres>>::encode(self.as_ref(), buf)
}
}

impl Encode<'_, Postgres> for Vec<u8> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
<&[u8] as Encode<Postgres>>::encode(self, buf)
Expand Down Expand Up @@ -104,8 +100,7 @@ impl<const N: usize> Decode<'_, Postgres> for [u8; N] {
}
}

impl Encode<'_, Postgres> for Cow<'_, [u8]> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
<&[u8] as Encode<Postgres>>::encode(self.as_ref(), buf)
}
}
forward_encode_impl!(Arc<[u8]>, &[u8], Postgres);
forward_encode_impl!(Rc<[u8]>, &[u8], Postgres);
forward_encode_impl!(Box<[u8]>, &[u8], Postgres);
forward_encode_impl!(Cow<'_, [u8]>, &[u8], Postgres);
29 changes: 8 additions & 21 deletions sqlx-postgres/src/types/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::types::array_compatible;
use crate::types::Type;
use crate::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef, Postgres};
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;

impl Type<Postgres> for str {
fn type_info() -> PgTypeInfo {
Expand Down Expand Up @@ -82,27 +84,6 @@ impl Encode<'_, Postgres> for &'_ str {
}
}

impl Encode<'_, Postgres> for Cow<'_, str> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
match self {
Cow::Borrowed(str) => <&str as Encode<Postgres>>::encode(*str, buf),
Cow::Owned(str) => <&str as Encode<Postgres>>::encode(&**str, buf),
}
}
}

impl Encode<'_, Postgres> for Box<str> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
<&str as Encode<Postgres>>::encode(&**self, buf)
}
}

impl Encode<'_, Postgres> for String {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
<&str as Encode<Postgres>>::encode(&**self, buf)
}
}

impl<'r> Decode<'r, Postgres> for &'r str {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
value.as_str()
Expand All @@ -114,3 +95,9 @@ impl Decode<'_, Postgres> for String {
Ok(value.as_str()?.to_owned())
}
}

forward_encode_impl!(Arc<str>, &str, Postgres);
forward_encode_impl!(Rc<str>, &str, Postgres);
forward_encode_impl!(Cow<'_, str>, &str, Postgres);
forward_encode_impl!(Box<str>, &str, Postgres);
forward_encode_impl!(String, &str, Postgres);
20 changes: 20 additions & 0 deletions sqlx-sqlite/src/types/bytes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;

use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
Expand Down Expand Up @@ -102,3 +104,21 @@ impl<'q> Encode<'q, Sqlite> for Cow<'q, [u8]> {
Ok(IsNull::No)
}
}

impl<'q> Encode<'q, Sqlite> for Arc<[u8]> {
fn encode_by_ref(
&self,
args: &mut Vec<SqliteArgumentValue<'q>>,
) -> Result<IsNull, BoxDynError> {
<Vec<u8> as Encode<'_, Sqlite>>::encode(self.to_vec(), args)
}
}

impl<'q> Encode<'q, Sqlite> for Rc<[u8]> {
fn encode_by_ref(
&self,
args: &mut Vec<SqliteArgumentValue<'q>>,
) -> Result<IsNull, BoxDynError> {
<Vec<u8> as Encode<'_, Sqlite>>::encode(self.to_vec(), args)
}
}
20 changes: 20 additions & 0 deletions sqlx-sqlite/src/types/str.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;

use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
Expand Down Expand Up @@ -94,3 +96,21 @@ impl<'q> Encode<'q, Sqlite> for Cow<'q, str> {
Ok(IsNull::No)
}
}

impl<'q> Encode<'q, Sqlite> for Arc<str> {
fn encode_by_ref(
&self,
args: &mut Vec<SqliteArgumentValue<'q>>,
) -> Result<IsNull, BoxDynError> {
<String as Encode<'_, Sqlite>>::encode(self.to_string(), args)
}
}

impl<'q> Encode<'q, Sqlite> for Rc<str> {
fn encode_by_ref(
&self,
args: &mut Vec<SqliteArgumentValue<'q>>,
) -> Result<IsNull, BoxDynError> {
<String as Encode<'_, Sqlite>>::encode(self.to_string(), args)
}
}
4 changes: 4 additions & 0 deletions tests/mysql/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,13 @@ test_type!(test_rc<Rc<i32>>(MySql, "1" == Rc::new(1i32)));

test_type!(test_box_str<Box<str>>(MySql, "'John'" == Box::<str>::from("John")));
test_type!(test_cow_str<Cow<'_, str>>(MySql, "'Phil'" == Cow::<'static, str>::from("Phil")));
test_type!(test_arc_str<Arc<str>>(MySql, "'1234'" == Arc::<str>::from("1234")));
test_type!(test_rc_str<Rc<str>>(MySql, "'5678'" == Rc::<str>::from("5678")));

test_prepared_type!(test_box_slice<Box<[u8]>>(MySql, "X'01020304'" == Box::<[u8]>::from([1,2,3,4])));
test_prepared_type!(test_cow_slice<Cow<'_, [u8]>>(MySql, "X'01020304'" == Cow::<'static, [u8]>::from(&[1,2,3,4])));
test_prepared_type!(test_arc_slice<Arc<[u8]>>(MySql, "X'01020304'" == Arc::<[u8]>::from([1,2,3,4])));
test_prepared_type!(test_rc_slice<Rc<[u8]>>(MySql, "X'01020304'" == Rc::<[u8]>::from([1,2,3,4])));

#[sqlx_macros::test]
async fn test_bits() -> anyhow::Result<()> {
Expand Down
4 changes: 4 additions & 0 deletions tests/postgres/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,13 @@ test_type!(test_rc<Rc<i32>>(Postgres, "1::INT4" == Rc::new(1i32)));

test_type!(test_box_str<Box<str>>(Postgres, "'John'::TEXT" == Box::<str>::from("John")));
test_type!(test_cow_str<Cow<'_, str>>(Postgres, "'Phil'::TEXT" == Cow::<'static, str>::from("Phil")));
test_type!(test_arc_str<Arc<str>>(Postgres, "'1234'::TEXT" == Arc::<str>::from("1234")));
test_type!(test_rc_str<Rc<str>>(Postgres, "'5678'::TEXT" == Rc::<str>::from("5678")));

test_prepared_type!(test_box_slice<Box<[u8]>>(Postgres, "'\\x01020304'::BYTEA" == Box::<[u8]>::from([1,2,3,4])));
test_prepared_type!(test_cow_slice<Cow<'_, [u8]>>(Postgres, "'\\x01020304'::BYTEA" == Cow::<'static, [u8]>::from(&[1,2,3,4])));
test_prepared_type!(test_arc_slice<Arc<[u8]>>(Postgres, "'\\x01020304'::BYTEA" == Arc::<[u8]>::from([1,2,3,4])));
test_prepared_type!(test_rc_slice<Rc<[u8]>>(Postgres, "'\\x01020304'::BYTEA" == Rc::<[u8]>::from([1,2,3,4])));

#[sqlx_macros::test]
async fn test_text_adapter() -> anyhow::Result<()> {
Expand Down
4 changes: 4 additions & 0 deletions tests/sqlite/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,13 @@ test_type!(test_rc<Rc<i32>>(Sqlite, "1" == Rc::new(1i32)));

test_type!(test_box_str<Box<str>>(Sqlite, "'John'" == Box::<str>::from("John")));
test_type!(test_cow_str<Cow<'_, str>>(Sqlite, "'Phil'" == Cow::<'static, str>::from("Phil")));
test_type!(test_arc_str<Arc<str>>(Sqlite, "'1234'" == Arc::<str>::from("1234")));
test_type!(test_rc_str<Rc<str>>(Sqlite, "'5678'" == Rc::<str>::from("5678")));

test_type!(test_box_slice<Box<[u8]>>(Sqlite, "X'01020304'" == Box::<[u8]>::from([1,2,3,4])));
test_type!(test_cow_slice<Cow<'_, [u8]>>(Sqlite, "X'01020304'" == Cow::<'static, [u8]>::from(&[1,2,3,4])));
test_type!(test_arc_slice<Arc<[u8]>>(Sqlite, "X'01020304'" == Arc::<[u8]>::from([1,2,3,4])));
test_type!(test_rc_slice<Rc<[u8]>>(Sqlite, "X'01020304'" == Rc::<[u8]>::from([1,2,3,4])));

#[sqlx_macros::test]
async fn test_text_adapter() -> anyhow::Result<()> {
Expand Down
Loading