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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Creates and changes relationships between nodes

use crate::{error::Error, id::NodeId, tree::Tree};

impl<T> Tree<T> {
    /// Makes three nodes related to each other
    fn relate(
        &mut self,
        node_index: usize,
        parent_index: Option<usize>,
        prev_sibling_index: Option<usize>,
        next_sibling_index: Option<usize>,
    ) {
        let node = &mut self.nodes[node_index];
        node.parent = parent_index;
        node.prev_sibling = prev_sibling_index;
        node.next_sibling = next_sibling_index;

        // If the parent doesn't have children set the node as first and last
        if let Some(parent_index) = parent_index {
            let parent = &mut self.nodes[parent_index];

            if prev_sibling_index.is_none() {
                parent.first_child = Some(node_index);
            }

            if next_sibling_index.is_none() {
                parent.last_child = Some(node_index);
            }
        }

        if let Some(prev_sibling_index) = prev_sibling_index {
            let prev_sibling = &mut self.nodes[prev_sibling_index];

            debug_assert!(prev_sibling.next_sibling.is_none());
            debug_assert_eq!(prev_sibling.parent, parent_index);

            prev_sibling.next_sibling = Some(node_index);
        }

        if let Some(next_sibling_index) = next_sibling_index {
            let next_sibling = &mut self.nodes[next_sibling_index];

            debug_assert!(next_sibling.prev_sibling.is_none());
            debug_assert_eq!(next_sibling.parent, parent_index);

            next_sibling.prev_sibling = Some(node_index);
        }
    }

    /// Make the `child` nodes as the last child of the `parent` node.
    ///
    /// # Errors
    ///
    /// - Fails of the same `NodeId` is passed
    /// - TODO: Fail if the child node is parent of the parent node.
    pub fn make_child(&mut self, child: &NodeId, parent: &NodeId) -> Result<(), Error> {
        let child_index = self.index(child).ok_or(Error::Invalid("for child"))?;
        let parent_index = self.index(parent).ok_or(Error::Invalid("for parent"))?;

        if child_index == parent_index {
            return Err(Error::SameNode);
        }

        // TODO: search if the child has the parent as child

        let parent_node = &self.nodes[parent_index];
        let last_child = parent_node.last_child;

        self.relate(child_index, Some(parent.index), last_child, None);

        Ok(())
    }
}