serde
serde copied to clipboard
Add `#[serde(ref_into = "RefIntoType")]` where `&T: Into<RefIntoType>, RefIntoType: Serialize`
I suggest adding a container-level attribute ref_into
. With this feature, the following two examples would be equivalent:
// Example one
pub struct Foo;
impl Serialize for Foo {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
let val: RefIntoType = self.into();
val.serialize(serializer)
}
}
// Example two
#[derive(Serialize)]
#[serde(ref_into = "RefIntoType")]
pub struct Foo;
This feature would be applicable whenever &Foo
implements Into<RefIntoType>
and RefIntoType
implements Serialize
.
There's already a very similar shortcut #[serde(into = "IntoType")]
but it clones the value before converting and therefore would be wasteful in cases like this where conversion only requires a reference.
As always, the exact chosen name ref_into
is subject to bikeshedding.
This should be easy to implement, need just introduce and use special RefInto
trait, and existing #[serde(into = "IntoType")]
should be enough: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4b5e87587edfb6e35952da321a1d72d9
I also have a use case for this, but I don't think restricting it to &T: Into
or such makes sense. Just having into_with = "path"
where path
is some fn(&Self) -> T
where T: Serialize
seems like a more general solution.
I think I would prefer to leave this use case to handwritten Serialize impls, instead of introducing new dedicated ref_into
or into_with
attributes.
As you showed above, these tiny Serialize impls are trivial to handwrite.