#Deriving trait for associated type defined by derive

9 messages · Page 1 of 1 (latest)

fresh spindle
#

Hi! I am using two libraries for my project: serde and diff-struct

diff-struct allows me to generate a diff between two structs of the same type. It comes with a trait Diff that lets me write code like this:

use diff::Diff;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Diff, PartialEq, Debug)]
struct Entity {
    x: i32,
    y: i32
}

fn main() {
    let mut entity = Entity { x: 1, y: 1 };

    let entity2 = Entity { x: 1, y: 2 };

    let diff: EntityDiff = entity.diff(&entity2);

    entity.apply(&diff);

    assert_eq!(entity, entity2);
}

entity_diff in this code is of type EntityDiff, which is an associated type for the trait Diff.

Now here comes the problem: since I derive Diff I am not defining this associated type. This is an issue because I want to derive Serialize and Deserialize on this associated type.

Is there a way to do this?

Sorry if my explanation isn't quite clear. I'm still a bit new to rust and especially associated types and derives.

marsh shadow
#

there's no way to do this in general — it can only happen if the Diff derive macro provides some way to ask for additional attributes on the generated struct

fresh spindle
#

So I would need to implement Diff myself?

marsh shadow
#

or implement Serialize and Deserialize yourself

#

in particular, serde's "remote derive" is meant for situations like this, though usually in the context of defining serialization for another crate's type
https://serde.rs/remote-derive.html

#

basically you have to declare a version of the struct that's close enough to the real thing that the serialization code serde generates can work for it

#

but it doesn't have to be actually usable for anything else

fresh spindle
#

Deriving trait for associated type defined by derive

little wagon
#

diff-struct has this exact thing in the first example:

#[derive(Debug, Default, PartialEq, Diff)]
// this will apply the specified derives on the generated 'ProjectMetaDiff' struct
#[diff(attr(
    #[derive(Debug, PartialEq)]
))]
pub struct ProjectMeta {
    contributors: Vec<String>,
    combined_work_hours: usize,
}