1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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<dyn Topology<'a, Ctx>>
    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<Arc<dyn SingularResolution<'a, Ctx>>>;

impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for TopoVec<'a, Ctx> {
    fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) {
        self.push(Arc::new(point.clone()));
    }
}

pub trait Topology<'a, Ctx: Context<'a>>: 'a + Send + Sync {
    fn points_count(&self) -> usize;

    fn point_at(&self, index: usize) -> Option<Arc<dyn SingularResolution<'a, Ctx>>>;
}

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<Arc<dyn SingularResolution<'a, Ctx>>> {
        self.get(index).cloned()
    }
}