trait Handle {
fn handle(&self, event: &Event) -> Vec<Effect>;
}
trait Add {
type Inner: Handle;
fn add<'a>(&mut self, path: &'a Path, inner: Self::Inner) -> Option<Self::Inner>;
}
enum Extracted<T, T2> { This(T), Deeper(T2) }
trait Extract {
type Inner;
fn extract<'a>(self, path: &'a Path) -> Option<Extracted<Self, Self::Inner>> where Self: Sized;
}
struct Node<H, H2>(H, Vec<H2>);
The idea is to impl Handle
for specific root types of Node
impl<H2> Handle for Node<N1, H2> { ... }
impl<H2> Handle for Node<N2, H2> { ... }
impl<H2> Handle for Node<N3, H2> { ... }
...
I want to organize the nodes into a graph data structures where they can decorate each other as implementers of Handle
. A Node wrapped in a Node wrapped in a Node wrapped in a Node, etc. Passing events into the root of this graph will bubble up the events based on the structure of the graph and the returned Vec<Effect>
will get treated by each Node
it visits on the way back down as if applying middleware.
So I need the Node(s) to have the ability to dynamically modify their own structure. I do not want to treat each node as an explicit type with a vec that I know I can modify. At most I want to only give basic list like abilities to the nodes. Add and Extract (remove and return). I also need a Wrap. But Wrap can be achieved as a Add + Extract.
n1 -> n2 -> n5 -> n6
-> n4
Let's say n5 wants to wrap itself in a nk. First we extract n5 from n2 by returning Effect::ExtractHandle(Path)
from n5 in response to some event.
Path is a data structure that is used to traverse the graph. And n5 will construct a Path that will lead back to itself: enum Path { Here(HandleMatcher), Next(Box<Path>), AStar(HandleMatcher) }
we end up with this
(returned n5 -> n6) <- n1 -> n2
-> n4
then outside the graph some calling code (with system resources and permissions that can be shared with nodes it constructs) will wrap n5 with nk
nk -> n5 -> n6
and add it back to the graph using the same path it used to Extract
n1 -> n2 -> nk -> n5 -> n6
-> n4