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