From c0d4019d1742bc5644dd12ba6e11274b0394eed1 Mon Sep 17 00:00:00 2001 From: Grant G Date: Mon, 11 Sep 2023 19:28:18 -0700 Subject: [PATCH] Add impl for `Type`, `Decode`, and `Encode` for `Box` and `Box<[u8]>` (#2712) --- sqlx-mysql/src/types/bytes.rs | 22 ++++++++++++++++++++++ sqlx-mysql/src/types/str.rs | 22 ++++++++++++++++++++++ sqlx-postgres/src/types/bytes.rs | 21 +++++++++++++++++++++ sqlx-postgres/src/types/str.rs | 32 ++++++++++++++++++++++++++++++++ sqlx-sqlite/src/types/bytes.rs | 30 ++++++++++++++++++++++++++++++ sqlx-sqlite/src/types/str.rs | 28 ++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+) diff --git a/sqlx-mysql/src/types/bytes.rs b/sqlx-mysql/src/types/bytes.rs index fe5587b60f..69f1327566 100644 --- a/sqlx-mysql/src/types/bytes.rs +++ b/sqlx-mysql/src/types/bytes.rs @@ -40,6 +40,28 @@ impl<'r> Decode<'r, MySql> for &'r [u8] { } } +impl Type for Box<[u8]> { + fn type_info() -> MySqlTypeInfo { + <&[u8] as Type>::type_info() + } + + fn compatible(ty: &MySqlTypeInfo) -> bool { + <&[u8] as Type>::compatible(ty) + } +} + +impl Encode<'_, MySql> for Box<[u8]> { + fn encode_by_ref(&self, buf: &mut Vec) -> IsNull { + <&[u8] as Encode>::encode(self.as_ref(), buf) + } +} + +impl<'r> Decode<'r, MySql> for Box<[u8]> { + fn decode(value: MySqlValueRef<'r>) -> Result { + <&[u8] as Decode>::decode(value).map(Box::from) + } +} + impl Type for Vec { fn type_info() -> MySqlTypeInfo { <[u8] as Type>::type_info() diff --git a/sqlx-mysql/src/types/str.rs b/sqlx-mysql/src/types/str.rs index 1da303684a..7bb2f039b1 100644 --- a/sqlx-mysql/src/types/str.rs +++ b/sqlx-mysql/src/types/str.rs @@ -62,6 +62,28 @@ impl<'r> Decode<'r, MySql> for &'r str { } } +impl Type for Box { + fn type_info() -> MySqlTypeInfo { + <&str as Type>::type_info() + } + + fn compatible(ty: &MySqlTypeInfo) -> bool { + <&str as Type>::compatible(ty) + } +} + +impl Encode<'_, MySql> for Box { + fn encode_by_ref(&self, buf: &mut Vec) -> IsNull { + <&str as Encode>::encode(&**self, buf) + } +} + +impl<'r> Decode<'r, MySql> for Box { + fn decode(value: MySqlValueRef<'r>) -> Result { + <&str as Decode>::decode(value).map(Box::from) + } +} + impl Type for String { fn type_info() -> MySqlTypeInfo { >::type_info() diff --git a/sqlx-postgres/src/types/bytes.rs b/sqlx-postgres/src/types/bytes.rs index 89b11f05cd..f0e646c86e 100644 --- a/sqlx-postgres/src/types/bytes.rs +++ b/sqlx-postgres/src/types/bytes.rs @@ -22,6 +22,12 @@ impl PgHasArrayType for &'_ [u8; N] { } } +impl PgHasArrayType for Box<[u8]> { + fn array_type_info() -> PgTypeInfo { + <[&[u8]] as Type>::type_info() + } +} + impl PgHasArrayType for Vec { fn array_type_info() -> PgTypeInfo { <[&[u8]] as Type>::type_info() @@ -42,6 +48,12 @@ impl Encode<'_, Postgres> for &'_ [u8] { } } +impl Encode<'_, Postgres> for Box<[u8]> { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { + <&[u8] as Encode>::encode(self.as_ref(), buf) + } +} + impl Encode<'_, Postgres> for Vec { fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { <&[u8] as Encode>::encode(self, buf) @@ -74,6 +86,15 @@ fn text_hex_decode_input(value: PgValueRef<'_>) -> Result<&[u8], BoxDynError> { .map_err(Into::into) } +impl Decode<'_, Postgres> for Box<[u8]> { + fn decode(value: PgValueRef<'_>) -> Result { + Ok(match value.format() { + PgValueFormat::Binary => Box::from(value.as_bytes()?), + PgValueFormat::Text => Box::from(hex::decode(text_hex_decode_input(value)?)?), + }) + } +} + impl Decode<'_, Postgres> for Vec { fn decode(value: PgValueRef<'_>) -> Result { Ok(match value.format() { diff --git a/sqlx-postgres/src/types/str.rs b/sqlx-postgres/src/types/str.rs index 53dda1f446..d66532dbff 100644 --- a/sqlx-postgres/src/types/str.rs +++ b/sqlx-postgres/src/types/str.rs @@ -33,6 +33,16 @@ impl Type for Cow<'_, str> { } } +impl Type for Box { + fn type_info() -> PgTypeInfo { + <&str as Type>::type_info() + } + + fn compatible(ty: &PgTypeInfo) -> bool { + <&str as Type>::compatible(ty) + } +} + impl Type for String { fn type_info() -> PgTypeInfo { <&str as Type>::type_info() @@ -63,6 +73,16 @@ impl PgHasArrayType for Cow<'_, str> { } } +impl PgHasArrayType for Box { + fn array_type_info() -> PgTypeInfo { + <&str as PgHasArrayType>::array_type_info() + } + + fn array_compatible(ty: &PgTypeInfo) -> bool { + <&str as PgHasArrayType>::array_compatible(ty) + } +} + impl PgHasArrayType for String { fn array_type_info() -> PgTypeInfo { <&str as PgHasArrayType>::array_type_info() @@ -90,6 +110,12 @@ impl Encode<'_, Postgres> for Cow<'_, str> { } } +impl Encode<'_, Postgres> for Box { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { + <&str as Encode>::encode(&**self, buf) + } +} + impl Encode<'_, Postgres> for String { fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { <&str as Encode>::encode(&**self, buf) @@ -108,6 +134,12 @@ impl<'r> Decode<'r, Postgres> for Cow<'r, str> { } } +impl<'r> Decode<'r, Postgres> for Box { + fn decode(value: PgValueRef<'r>) -> Result { + Ok(Box::from(value.as_str()?)) + } +} + impl Decode<'_, Postgres> for String { fn decode(value: PgValueRef<'_>) -> Result { Ok(value.as_str()?.to_owned()) diff --git a/sqlx-sqlite/src/types/bytes.rs b/sqlx-sqlite/src/types/bytes.rs index 7cd06d87a0..fdb9216fce 100644 --- a/sqlx-sqlite/src/types/bytes.rs +++ b/sqlx-sqlite/src/types/bytes.rs @@ -31,6 +31,36 @@ impl<'r> Decode<'r, Sqlite> for &'r [u8] { } } +impl Type for Box<[u8]> { + fn type_info() -> SqliteTypeInfo { + <&[u8] as Type>::type_info() + } + + fn compatible(ty: &SqliteTypeInfo) -> bool { + <&[u8] as Type>::compatible(ty) + } +} + +impl Encode<'_, Sqlite> for Box<[u8]> { + fn encode(self, args: &mut Vec>) -> IsNull { + args.push(SqliteArgumentValue::Blob(Cow::Owned(self.into_vec()))); + + IsNull::No + } + + fn encode_by_ref(&self, args: &mut Vec>) -> IsNull { + args.push(SqliteArgumentValue::Blob(Cow::Owned(self.clone().into_vec()))); + + IsNull::No + } +} + +impl Decode<'_, Sqlite> for Box<[u8]> { + fn decode(value: SqliteValueRef<'_>) -> Result { + Ok(Box::from(value.blob())) + } +} + impl Type for Vec { fn type_info() -> SqliteTypeInfo { <&[u8] as Type>::type_info() diff --git a/sqlx-sqlite/src/types/str.rs b/sqlx-sqlite/src/types/str.rs index d27a09ae14..b5ef6e07e1 100644 --- a/sqlx-sqlite/src/types/str.rs +++ b/sqlx-sqlite/src/types/str.rs @@ -27,6 +27,34 @@ impl<'r> Decode<'r, Sqlite> for &'r str { } } +impl Type for Box { + fn type_info() -> SqliteTypeInfo { + <&str as Type>::type_info() + } +} + +impl Encode<'_, Sqlite> for Box { + fn encode(self, args: &mut Vec>) -> IsNull { + args.push(SqliteArgumentValue::Text(Cow::Owned(self.into_string()))); + + IsNull::No + } + + fn encode_by_ref(&self, args: &mut Vec>) -> IsNull { + args.push(SqliteArgumentValue::Text(Cow::Owned( + self.clone().into_string(), + ))); + + IsNull::No + } +} + +impl Decode<'_, Sqlite> for Box { + fn decode(value: SqliteValueRef<'_>) -> Result { + value.text().map(Box::from) + } +} + impl Type for String { fn type_info() -> SqliteTypeInfo { <&str as Type>::type_info()