0

We have impl<T> Trait for Vec<T>, which can implement Trait for all Vec<_>. Can we have the same thing for a newtype struct (a tuple struct with only one value)? Like:

impl<T> Trait for T(SomeType) {}

Why?

In DDD, each aggregate root/entity has a type of Id:

struct BookId(Uuid);

struct Book {
    id: BookId,
    // ...
}

struct LibraryId(Uuid);

struct Library {
    id: LibraryId,
    // ...
}

I think it is a natural way to do the modelling, but if you do that, it is hard to implement a trait for all types of ID. An example trait is the FromSql and ToSql traits in rust-postgres.

We have to do this instead:

impl ToSql for BookId {
    to_sql_checked!();

    accepts!(UUID);

    fn to_sql(&self, ty: &Type, w: &mut Vec<u8>) -> Res<IsNull> {
        self.to_id().to_sql(ty, w)
    }
}

impl<'a> FromSql<'a> for BookId {
    accepts!(UUID);

    fn from_sql(_: &Type, raw: &[u8]) -> Res<BookId> {
        let uuid = types::uuid_from_sql(raw)?;
        Ok(BookId::new(Uuid::from_bytes(uuid)))
    }
}

// same thing for LibraryId

Not that clean, eh? Is there any way to make the code cleaner?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ukonn Ra
  • 744
  • 6
  • 20
  • It looks like your question might be answered by the answers of [Implementing a trait for multiple types at once](https://stackoverflow.com/q/39150216/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Sep 25 '19 at 14:32
  • [The duplicate applied to your situation](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a1110dc1fc5112e092e9597480ca91d3), but see also [Is it considered a bad practice to implement Deref for newtypes?](https://stackoverflow.com/q/45086595/155423). – Shepmaster Sep 25 '19 at 14:39
  • Thx for your quick answer, but as you can see, if I have a bunch of Id type, say 10 or even more, it's hard to impl Trait for these newtypes one by one, so I wonder if there is any solution to impl Trait for all newtypes once and run for every newtype. – Ukonn Ra Sep 25 '19 at 23:08
  • 1
    What's wrong with the [macro-based solution](https://stackoverflow.com/a/50223259/155423)? – Shepmaster Sep 26 '19 at 00:01
  • Cool, that's exactly what I want, thx! – Ukonn Ra Sep 26 '19 at 00:52
  • Note that what's requested would defeat the whole purpose of the newtype pattern, which is to throw away the traits on the old type so they can be implemented differently. – David A Sep 26 '19 at 21:47

0 Answers0