Repository: launchbadge/sqlx
File: sqlx-core/src/decode.rs (Rust)

Code before:
pub trait Decode<'r, DB: Database>: Sized {
    /// Decode a new value of this type using a raw value from the database.
    fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError>;
}

// implement `Decode` for Option<T> for all SQL types
impl<'r, DB, T> Decode<'r, DB> for Option<T>
where
    DB: Database,
    T: Decode<'r, DB>,
{
    fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
        if value.is_null() {
            Ok(None)
        } else {
            Ok(Some(T::decode(value)?))
        }
    }
}

macro_rules! impl_decode_for_smartpointer {
    ($smart_pointer:ty) => {
        impl<'r, DB, T> Decode<'r, DB> for $smart_pointer
        where
            DB: Database,
            T: Decode<'r, DB>,
        {
            fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
                Ok(Self::new(T::decode(value)?))
            }
        }
    };
}

impl_decode_for_smartpointer!(Arc<T>);
impl_decode_for_smartpointer!(Box<T>);
impl_decode_for_smartpointer!(Rc<T>);

// implement `Decode` for Cow<T> for all SQL types
impl<'r, DB, T> Decode<'r, DB> for Cow<'_, T>
where
    DB: Database,
    T: Decode<'r, DB>,
    T: ToOwned<Owned = T>,
{
    fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
        Ok(Cow::Owned(T::decode(value)?))
    }
}


Review comment (suggestion):
I believe this may actually _remove_ the impls for `Box<str>` and `Box<[u8]>` because of the implicit `T: Sized` bound here.

Code after:
pub trait Decode<'r, DB: Database>: Sized {
    /// Decode a new value of this type using a raw value from the database.
    fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError>;
}

// implement `Decode` for Option<T> for all SQL types
impl<'r, DB, T> Decode<'r, DB> for Option<T>
where
    DB: Database,
    T: Decode<'r, DB>,
{
    fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
        if value.is_null() {
            Ok(None)
        } else {
            Ok(Some(T::decode(value)?))
        }
    }
}

macro_rules! impl_decode_for_smartpointer {
    ($smart_pointer:tt) => {
        impl<'r, DB, T> Decode<'r, DB> for $smart_pointer<T>
        where
            DB: Database,
            T: Decode<'r, DB>,
        {
            fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
                Ok(Self::new(T::decode(value)?))
            }
        }

        impl<'r, DB> Decode<'r, DB> for $smart_pointer<str>
        where
            DB: Database,
            &'r str: Decode<'r, DB>,
        {
            fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
                let ref_str = <&str as Decode<DB>>::decode(value)?;
                Ok(ref_str.into())
            }
        }

        impl<'r, DB> Decode<'r, DB> for $smart_pointer<[u8]>
        where
            DB: Database,
            Vec<u8>: Decode<'r, DB>,
        {
            fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
                // The `Postgres` implementation requires this to be decoded as an owned value because
                // bytes can be sent in text format.