Description
Currently this code doesn't work since Decode isn't implemented for Cow<T>
but for Cow<str>
.
This leads to the problem that I have to implement two different structs for the types if I don't want to clone the fields for every query (one using owned types to retrieve data and one using references to bind in query).
Cow<T>
can be used in this case to allow treating a field like a pointer or like a owned value as needed.
The same is true for other smart pointer types like Arc
and Rc
.
#[derive(sqlx::FromRow, Clone)]
pub(super) struct A<'a> {
pub(super) content: Cow<'a, MaybeBig>,
...
}
Describe the solution you'd like
impl<DB, T> Type<DB> for Cow<'_, T>
where
T: Type<DB>,
DB: Database,
{
fn type_info() -> DB::TypeInfo {
T::type_info()
}
fn compatible(ty: &DB::TypeInfo) -> bool {
T::compatible(ty)
}
}
// Maybe this is unnecessary since smart pointers implement Deref for T
impl<'q, DB, T> Encode<'q, DB> for Cow<'q, T>
where
T: Encode<'q, DB>,
DB: Database,
{
// encode() omitted since it requires an additional ToOwned<Owned=T> bound on T
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
T::encode_by_ref(self, buf)
}
fn produces(&self) -> Option<DB::TypeInfo> {
T::produces(self)
}
fn size_hint(&self) -> usize {
T::size_hint(self)
}
}
impl<'r, DB, T> Decode<'r, DB> for Cow<'static, T>
where
T: Decode<'r, DB> + ToOwned<Owned = T>,
DB: Database,
{
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
T::decode(value).map(|t| t.to_owned()).map(Cow::Owned)
}
}
Describe alternatives you've considered
I've considered using a extension trait for a short time, but couldn't get it done, because of dyn object safety.
And i believe this should be part of the library.
Another alternative is to have two different structs. One for querying (uses references) and one for retrieving (uses owned Types)
Create a wrapper around Cow from standard library that delegates to the inner and implement the trait on this wrapper.
If this seems useful to you I would like to start working on a PR for this.
This is related to #1904