How to impl `AsRef<Ref<'a>> for Owned`?

struct Owned {
    p: String,
}

struct Ref<'a> {
    c: &'a str,
}

impl<'a> AsRef<Ref<'a>> for Owned {
    fn as_ref(&self) -> &Ref {
        // How could I implement this?
    }
}

The String and str types here act as an example to illustrate my needs.

I have a library that returns a type P, and users can borrow &C from P:

let p = P::new();
let c: &C = P.get_sub();

And then I have:

struct Owned {
    p: P,
}

struct Ref<'a> {
    c: &'a C,
}

For some scenarios, I want a function that only accepts Ref<'a> as a parameter type:

fn foo(a: Ref<'a>) { }

Based on that, I want to impl AsRef<Ref<'a>> for my Owned.

Question:

  1. How could I implement this AsRef<T> trait?
  2. Is this fit my need?
  3. Is there any good practice for this?

The AsRef trait is intended when a reference to some object can be used to cheaply get a reference to some other object, typically because it is stored as a field.

You can think of impl AsRef<Foo> for Bar as a "function" which converts &Bar -> &Foo. However, because we return a reference, the Foo instance needs to already exist. You can't create a new instance of some object inside a function and then return a reference to it because that's a use-after-free.

In the impl AsRef<str> for String example, the String type already contains a pointer to a str that lives on the heap, so all it needs to do is return it.

In your example, you could impl<'a> AsRef<C> for Ref<'a> by returning the reference in the self.c field, but because Owned doesn't actually contain a Ref, you can't impl AsRef<Ref<'_>> for Owned.

You might need to find a different solution like giving Owned a fn ref(&self) -> Ref<'_> method.

1 Like