I've hit this when splitting crates into two seperate parts, so I use wrapper types
Pattern 1. Borrow wrappers give you instant access, but they require frequent rewrapping, which always requires some explicit code.
pub struct APKToo<'a,'p,C: CurveGroup>(pub &'a AggregatedPublicKeys<'p,C>);
impl<'a,'p,C: CurveGroup> From<&'a AggregatedPublicKeys<'p,C>> for APKToo<'a,'p,C> { .. }
Pattern 2. Owned wrappers, unsafe { mem::transmute(..) }, and Derefs winds up much more ergonomic, especially if you can use the wrapper in your own types. I suppose the safe transmute work should removes the unsafe eventually.
#[derive(Clone,Debug)]
#[repr(transparent)]
pub struct APKToo<'p,C: CurveGroup>(pub AggregatedPublicKeys<'p,C>);
fn apk_local<'a,'p,C: CurveGroup>(apk: &'a AggregatedPublicKeys<'p,C>) -> &'a APKToo<'p,C> {
unsafe { core::mem::transmute(apk) }
}
impl<'p,C: CurveGroup> core::ops::Deref for APKToo<'p,C> {
type Target = AggregatedPublicKeys<'p,C>;
fn deref(&self) -> &AggregatedPublicKeys<'p,C> { &self.0 }
}
impl<'p,C: CurveGroup> core::ops::DerefMut for APKToo<'p,C> {
fn deref_mut(&mut self) -> &mut AggregatedPublicKeys<'p,C> { &mut self.0 }
}
We've many discussions around the orphan rules here, but yes I wonder if some fancier wrapper type declaration could improve this, but really not so sure.