I have a type that looks like this:
enum Name<'a> {
Single(&'a str),
Double(&'a str, &'a str),
}
And another, very similar type that looks like this:
enum OwnedName {
Single(String),
Double(String, String),
}
I already have a method to convert a Name to an OwnedName. However, I cannot figure out a way to implement something like Deref
or Borrow
for this type to convert an OwnedName back to a Name. This means I have to write the same methods twice, which is annoying. I’d like to have something that mimics the way PathBuf
/Path
or String
/str
work. I’ve tried something like this:
impl ops::Deref for OwnedName {
type Target = Name;
fn deref(&self) -> &Name {
match *self {
OwnedName::Single(ref s) => Name::Single(&**s),
OwnedName::Double(ref s1, ref s2) => Name::Double(&**s1, &**s2),
}
}
}
This errors with wrong number of lifetime parameters: expected 1, found 0
on type Target = Name
, which is completely understandable, as, well, it needs a lifetime. But I can’t provide one. So is there a way for me to use Deref
, or Borrow
, or ToOwned
in this way?
I agree with @DK. Just adding that if your idea is to use them interchangeably, you may not need to have an OwnedName
at all.
You can define Name to accept both &str
and String
:
enum Name<T> where T:Borrow<str> {
Single(T),
Double(T, T),
}
// these both work now
let _a1 = Name::Single("hello");
let _a2 = Name::Double(String::from("hello"), String::from("world"));
There is no way to do this.
Note that Deref::deref
's signature says it wants a pointer to a Name
with the same lifetime as the thing being deref'ed. Such a value does not exist. You cannot return a pointer to something you created in the deref
function, either, since it can't possibly outlive its own stack frame.
The fundamental problem is that Name
is basically a different kind of pointer (like *const T
is to &T
), but Deref
and other traits like it only allow you to return borrowed pointers. At present, this is just no way around this.
You can, however, do this if you just don't use Deref
and other traits like it. One possibility would be to impl<'a> From<&'a OwnedName> for Name<'a>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With