If I want to implement From for a struct as well as for a &struct, is there a way to do that without needing to repeat things (not a macro - though I guess if there's no other choice...)?
The problem is that Rust sees Struct and &Struct as two different types. Accordingly, you need two different impl's. In addition, the example you provide is a special one as it does not use the argument. If we do it another way you see that two different implementations are mandatory:
#[derive(Clone)]
struct Foo {}
struct Bar(Foo);
impl From<Foo> for Bar {
fn from(foo: Foo) -> Self {
Bar(foo)
}
}
impl From<&Foo> for Bar {
fn from(foo: &Foo) -> Self {
Bar(foo.clone()) // requires the clone
}
}
I don't think they are always mandatory to be different... e.g. if I just want to use the same as_slice() method on the struct in both cases (and let's say that method isn't from a Trait, it's on the struct itself)
They are definitely different types, however Rust has convince features that sometimes let you call reference methods on owned types. E.g. you can call as_bytes on a String even though it was defined on &str. You can look up the Deref trait which is what let's you do this.
Note that this does not make String the same type as &str, and you can only go one way: from owned to reference unless the type is copy.