map_suffix on types without type parameter
Closed this issue · 4 comments
ubolonton commented
I have an API like the following
pub struct Tree;
pub struct Node<'t> {
pub tree: &'t Tree,
}
impl<'t> Node<'t> {
fn child(&self) -> Node<'t> {
unimplemented!()
}
}
To use child()
with a rental wrapper, I'm having to use PhantomData
with map_suffix
, like below
#[macro_use]
extern crate rental;
use std::{rc::Rc, marker::PhantomData};
pub struct PhantomNode<'t, T>(Node<'t>, PhantomData<T>);
impl<'t> PhantomNode<'t, ()> {
fn child(&self) -> Self {
PhantomNode(self.0.child(), PhantomData)
}
}
rental! {
pub mod inner {
use std::rc::Rc;
#[rental(map_suffix = "T")]
pub struct RentingNode<T: 'static> {
tree: Rc<super::Tree>,
node: super::PhantomNode<'tree, T>
}
}
}
type RentingNode = inner::RentingNode<()>;
fn child(node: RentingNode) -> RentingNode {
node.map(|n| n.child())
}
Is there a better way to do this? Can we make map_suffix
support types without type parameter?
jpernst commented
The purpose of map_suffix
is to map from one type parameter to another, so it wouldn't be able to really do anything if there are no type parameters.
ubolonton commented
Is there a cleaner approach for this use case of mapping the suffix to another value of the same type?
jpernst commented
Unfortunately I overlooked this usecase. Wrapping it with a dummy type param like you're doing is probably the best workaround.
frondeus commented
Hi, I found solution:
#[derive(Debug, Clone)]
pub struct T<'a> {
i: &'a str
} // This struct implements child()
#[rental(debug, clone)
pub struct OwnedT {
source: Arc<Box<str>>,
item: T<'source>
}
let parent: OwnedT = OwnedT::new(...); // Create parent.
let mut child = parent.clone();
child.rent_mut(|c| *c = c.child());
It works because:
- You have Rc - so cloning source works as well as mine Arc example
- You don't have to use
map_suffix
at all.