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);
}