I want a recursive function that is called do()
to be common to a family of types. I also need each type to have a function that returns a type with the same implementation as itself.
struct A;
struct B;
struct C;
impl A { fn do(&mut self, path: Path) -> Option<Path> { ... } fn next(&mut self) -> _? { ... } }
impl B { fn do(&mut self, path: Path) -> Option<Path> { ... } fn next(&mut self) -> _? { ... } }
impl C { fn do(&mut self, path: Path) -> Option<Path> { ... } fn next(&mut self) -> _? { ... } }
But I don't want to rewrite the same function in a separate impl for each type. A trait wont help here because it just makes sure that I do write the same implementation for each type.
So I made a wrapper type and put the next fn in a trait.
trait Next {
type Inner;
fn next(&mut self) -> Option<Self::Inner>;
}
struct Node<T>(T);
impl Next for Node<A> {
type Inner = Node<B>;
fn next(&mut self) -> Option<Self::Inner> { ... }
}
impl Next for Node<B> {
type Inner = Node<C>;
fn next(&mut self) -> Option<Self::Inner> { ... }
}
impl Next for Node<C> {
type Inner = Node<A>;
fn next(&mut self) -> Option<Self::Inner> { ... }
}
impl<T, T2> Node<T>
where
Self: Next<Inner = Node<T2>>
{
fn do(&mut self, path: Path) -> Option<Path> {
match path {
Path::Here => {
let next_node = self.next();
// stuff
},
Path::Next(path) => {
let next_node = self.next().unwrap();
next_node.do(path); // Error
}
};
todo!()
}
}
This doesn't work. The next_node.do(path)
is the problem. I need self.next()
to return the next node based on a specific impl Node<A> | Node<B> | Node<C>
. And I also need the thing that returns to be a Node<_> that I can call do(&mut self, path: Path)
on. I thought Self: Next<Inner = Node<T2>>
constraint would do it. As in I assumed Node<T> == Node<T2>
such that a Node<T2>
would recursively use the impl impl<T, T2> Node<T2>
in which it is constrained in. So now I am stuck.