remote attribute should implement a trait instead of an associated function.
I'm using the remote attribute in my derive proc macro within serde_many, and I've encountered an issue with constraining the implementation bounds added by the Serialize derive macro.
This is how my derive proc macro works:
/// Marker.
struct Many1;
/// Marker.
struct Many2;
#[derive(SerializeMany)]
#[serde_many(many1 = "Many1", many2 = "Many2")] // Declaring the implementation markers.
struct Point<X, Y> {
#[serde(many2(rename = "x_value"))]
x: X,
#[serde(many2(rename = "y_value"), many1(rename = "y2"))]
y: Y,
}
expands to:
const _: () = {
type __Derived<X, Y> = Point<X, Y>;
const _: () = {
#[derive(::serde_many::__private::serde::Serialize)]
#[serde(remote = "__Derived")]
#[serde(crate = "::serde_many::__private::serde")]
struct Point<X, Y> {
#[serde(serialize_with = ":: serde_many :: SerializeMany :: < Many1 > :: serialize")]
x: X,
#[serde(rename = "y2")]
#[serde(
serialize_with = ":: serde_many :: SerializeMany :: < Many1 > :: serialize"
)] y: Y,
}
impl<X, Y> ::serde_many::SerializeMany<Many1> for __Derived<X, Y> {
fn serialize<S: ::serde_many::__private::serde::Serializer>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error> { Point::serialize(self, serializer) }
}
};
const _: () = {
#[derive(::serde_many::__private::serde::Serialize)]
#[serde(remote = "__Derived")]
#[serde(crate = "::serde_many::__private::serde")]
struct Point<X, Y> {
#[serde(rename = "x_value")]
#[serde(
serialize_with = ":: serde_many :: SerializeMany :: < Many2 > :: serialize"
)] x: X,
#[serde(rename = "y_value")]
#[serde(
serialize_with = ":: serde_many :: SerializeMany :: < Many2 > :: serialize"
)] y: Y,
}
impl<X, Y> ::serde_many::SerializeMany<Many2> for __Derived<X, Y> {
fn serialize<S: ::serde_many::__private::serde::Serializer>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error> { Point::serialize(self, serializer) }
}
};
};
The core issue is that I cannot call Point::serialize because it is subject to bounds generated by the Serialize derive macro. Normally, one would rely on the Point: Serialize constraint, but the use of the remote attribute prevents this.
I suggest introducing a new trait, RemoteSerialize, which would be defined as:
trait RemoteSerialize<Origin> {
fn serialize<S: Serializer>(origin: Origin, serializer: S) -> Result<S::Ok, S::Error>;
}
With this approach, the remote attribute will implement the RemoteSerialize trait, and one could use constrain his implementation with the bounds of the trait implmentation (Point: RemoteSerialize<__Derived>). Of course a similar change would be made for RemoteDeserialize.
What do you think about this change? Would you accept a PR for this?
Thanks!
Just bumping this @dtolnay