[Solved] Repetition of "struct FooPtr" for "struct Foo"

#1
  1. I find myself often times (20+ times) doing this:
struct Foo { ... }
#[derive(Clone)]
struct FooPtr( pub Rc<Foo>);

impl Foo {
  rn ptr(self) -> FooPtr { FooPtr(Rc::new(self)) }
}
  1. Now, the obvious approach is to define a generic
pub struct Ptr<T> {
  ptr: Rc<T>
}

but the problem is impl for rules requires that atleast one of either trait or struct be in the current module, and in the generic Ptrz approach, the Ptr is defined in some utility module, not the current module

  1. So I now have this pattern repeated multiple times in multiple crates.

Anyone else run into this issue? If so, how did you get around it?

#2

I’m not sure why are you doing this. Is it to hide implementation details, or do you need to implement some traits or inherent methods on Rc-wrapped type that can’t be on the inner type?

2 Likes
#3

This is precisely it.

I have situations where:

  1. I Rc wrap a Struct because I need to refer to it from multiple places and the keeping of & lifetimes becomes way too complicated.

  2. I can’t do “impl EistingTrait for Rc<…>” because neither ExistingTrait nor Rc is defined in my crate.

  3. Thus I create this “FooPtr.” Now, unfortunately, it’s repetition everywhere.

#4

For just referring to a complex type from multiple places type FooPtr = Rc<Foo> should be fine.

But for 3rd party traits, you need wrapping indeed. For this I suggest simply using a macro to generate the boilerplate, e.g. wrap!{Foo}.

If you try to do it with generics, you’ll be adding an extra layer of indirection, which can make other generic code more complicated.

1 Like