Implement Decode, Encode and Type for Box, Arc, Cow and Rc (#3674)

* feat: implement Decode,Encode,Type for Box,Arc,Cow

* feat implement Encode,Type for Rc

* feat: implement Decode for Rc

* chore: make tests more concise

* chore: use macro's

* chore: remove conflicting impls

* chore: more macro's

* Relax Sized bound for Decode, Encode

* update unit tests

* fixes after review

* add comment in `Decode` impl

* add comment about `ToOwned` trait bound

* add comment explaining why decoding to `Cow::Owned` was chosen

* Remove unnecessary Decode impls
This commit is contained in:
Joey de Waal
2025-07-01 02:03:48 +02:00
committed by GitHub
parent 64e154abfa
commit 8602d94c4d
12 changed files with 269 additions and 136 deletions

View File

@@ -1,3 +1,5 @@
use std::borrow::Cow;
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
@@ -80,15 +82,6 @@ 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<Self, BoxDynError> {
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<u8> {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
Ok(match value.format() {
@@ -110,3 +103,9 @@ impl<const N: usize> Decode<'_, Postgres> for [u8; N] {
Ok(bytes)
}
}
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)
}
}

View File

@@ -24,26 +24,6 @@ impl Type<Postgres> for str {
}
}
impl Type<Postgres> for Cow<'_, str> {
fn type_info() -> PgTypeInfo {
<&str as Type<Postgres>>::type_info()
}
fn compatible(ty: &PgTypeInfo) -> bool {
<&str as Type<Postgres>>::compatible(ty)
}
}
impl Type<Postgres> for Box<str> {
fn type_info() -> PgTypeInfo {
<&str as Type<Postgres>>::type_info()
}
fn compatible(ty: &PgTypeInfo) -> bool {
<&str as Type<Postgres>>::compatible(ty)
}
}
impl Type<Postgres> for String {
fn type_info() -> PgTypeInfo {
<&str as Type<Postgres>>::type_info()
@@ -129,18 +109,6 @@ impl<'r> Decode<'r, Postgres> for &'r str {
}
}
impl<'r> Decode<'r, Postgres> for Cow<'r, str> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
Ok(Cow::Borrowed(value.as_str()?))
}
}
impl<'r> Decode<'r, Postgres> for Box<str> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
Ok(Box::from(value.as_str()?))
}
}
impl Decode<'_, Postgres> for String {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
Ok(value.as_str()?.to_owned())