use super::*; /// Topological [Mentionable]. Allows iterating over [Point]s it references, if any; pub trait MentionableTop<'a, Ctx: Context<'a>>: 'a { /// See implementation for the definition. /// Hash of all the references' points concatenated, ordered, non-unique. /// Used for walking over object trees to ensure two objects with different references don't collide. fn topology_hash(&self) -> Hash where Self: Mentionable<'a, Ctx>, { let mut vec = Vec::new(); self.points_typed(&mut vec); Ctx::hash(&vec) } /// References ([Point]s) to other objects. Typed. fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) where Self: Mentionable<'a, Ctx>; fn topology(&self) -> Arc> where Self: Mentionable<'a, Ctx>, { let mut vec: TopoVec<'a, Ctx> = Vec::new(); self.points_typed(&mut vec); Arc::new(vec) } } pub type TopoVec<'a, Ctx> = Vec>>; impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for TopoVec<'a, Ctx> { fn visit>(&mut self, point: &Point<'a, Ctx, A>) { self.push(Arc::new(point.clone())); } } pub trait Topology<'a, Ctx: Context<'a>>: 'a { fn points_count(&self) -> usize; fn point_at(&self, index: usize) -> Option>>; } impl<'a, Ctx: Context<'a>> Topology<'a, Ctx> for TopoVec<'a, Ctx> { fn points_count(&self) -> usize { self.len() } fn point_at(&self, index: usize) -> Option>> { self.get(index).cloned() } }