1

I have two types, call them Reusable and SingleUse, such that it is possible to construct a SingleUse from a Reusable. I'd like to enforce the invariant that the former can be reused while the latter is consumed by accepting a &Reusable or a SingleUse parameter. Something like:

let re = Reusable{};
let su = SingleUse{source:re};
do_something(&re);
do_something(&re);
do_something(su);

I can accomplish this by defining a From<&Reusable> for SingleUse and then taking a Into<SingleUse> for the do_something() parameter, but I'm not certain whether or not this is a misuse of From/Into. Most examples I've seen involving From don't mention using references. This article has an example of a From<&'a [T]> but still suggests that From/Into are intended to operate on values (and contrasts that with other traits like AsRef intended to operate on references).

So I'm hoping to sanity-check that using From on a reference type is appropriate, or if not if there's a more idiomatic way to model this Reusable/SingleUse relationship?


Full example (playground):

#[derive(Clone, Debug)]
struct Reusable { }

#[derive(Debug)]
struct SingleUse {
    #[allow(dead_code)]
    source: Reusable,
}

impl From<&Reusable> for SingleUse {
    fn from(source: &Reusable) -> Self {
        SingleUse{source: source.clone()}
    }
}

fn do_something(input: impl Into<SingleUse>) {
    println!("Saw:{:?}", input.into());
}

fn main() {
    let re = Reusable{};
    let su = SingleUse{source: re.clone()};
    do_something(&re);
    do_something(&re);
    do_something(su);
}
dimo414
  • 47,227
  • 18
  • 148
  • 244
  • Yes, [I've provided practical examples in this related answer](https://stackoverflow.com/a/76338657/), though more in the sense of providing a view using references to internal fields of an opaque type that the view is needed of. – metatoaster Jun 30 '23 at 03:28

1 Answers1

0

std implements From<&str> for {Box<str>,Rc<str>,String,Arc<str>,Vec<u8>}, From<&String> for String, From<&[T]> for {Box<[T]>,Rc<[T]>,Arc<[T]>,Vec<T>} and some more. Especially note the From<&String> for String (essentially Clone) that is pretty similar to your situation. So I'd say this is fine.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77