kodept_ast/
node_properties.rs

1use kodept_core::{ConvertibleToMut, ConvertibleToRef};
2
3use crate::graph::{Change, AnyNode, PermTkn, Identifiable, SyntaxTree, NodeId};
4
5#[repr(transparent)]
6pub struct Uninit<T>(T);
7
8impl<T> Uninit<T> {
9    pub fn new(value: T) -> Self {
10        Self(value)
11    }
12
13    #[allow(private_bounds)]
14    pub fn unwrap(self, id: NodeId<T>) -> T
15        where
16            T: crate::graph::Identifiable,
17    {
18        self.0.set_id(id);
19        self.0
20    }
21
22    #[inline]
23    pub fn map_into<U>(self) -> Uninit<U>
24        where
25            T: Into<U>,
26    {
27        Uninit(self.0.into())
28    }
29}
30
31pub trait NodeWithParent {
32    type Parent;
33}
34
35#[allow(private_bounds)]
36pub trait Node: Identifiable + Into<AnyNode> {
37    fn parent<'b>(&self, tree: &'b SyntaxTree, token: &'b PermTkn) -> &'b Self::Parent
38    where
39        Self: NodeWithParent,
40        AnyNode: ConvertibleToRef<Self::Parent>,
41    {
42        let id = self.get_id();
43        tree.parent_of(id, token)
44            .expect("NodeWithParent: contract violated")
45            .try_as_ref()
46            .expect("Node has wrong type")
47    }
48
49    fn parent_mut<'b>(
50        &self,
51        tree: &'b mut SyntaxTree,
52        token: &'b mut PermTkn,
53    ) -> &'b mut Self::Parent
54    where
55        Self: NodeWithParent,
56        AnyNode: ConvertibleToMut<Self::Parent>,
57    {
58        let id = self.get_id();
59        tree.parent_of_mut(id, token)
60    }
61
62    fn replace_with(&self, other: Uninit<Self>) -> Change {
63        Change::Replace {
64            from_id: self.get_id().widen(),
65            to: other.map_into(),
66        }
67    }
68
69    fn remove(&self) -> Change {
70        Change::DeleteSelf {
71            node_id: self.get_id().widen(),
72        }
73    }
74}