orx_selfref_col/
node.rs

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use crate::{Refs, Variant};
use core::fmt::Debug;

/// Node of the self referential collection.
pub struct Node<V>
where
    V: Variant,
{
    data: Option<V::Item>,
    prev: V::Prev,
    next: V::Next,
}

impl<V> Node<V>
where
    V: Variant,
{
    /// Creates a new active node with the given `data`, and `prev` and `next` references.
    pub fn new_active(data: V::Item, prev: V::Prev, next: V::Next) -> Self {
        Self {
            data: Some(data),
            prev,
            next,
        }
    }

    /// Creates a new active node with the given `data` but with no connections.
    pub fn new_free_node(data: V::Item) -> Self {
        Self {
            data: Some(data),
            prev: Refs::empty(),
            next: Refs::empty(),
        }
    }

    // consuming

    /// Takes and returns the data of the node, transitions the node into the closed state.
    pub fn into_data(self) -> Option<V::Item> {
        self.data
    }

    // ref

    /// Returns a reference to the data of the node; None if the node is already closed.
    pub fn data(&self) -> Option<&V::Item> {
        self.data.as_ref()
    }

    /// Returns a reference to the previous references.
    pub fn prev(&self) -> &V::Prev {
        &self.prev
    }

    /// Returns a reference to the next references.
    pub fn next(&self) -> &V::Next {
        &self.next
    }

    /// Returns true if the node is active, false if it is closed.
    #[inline(always)]
    pub fn is_active(&self) -> bool {
        self.data.is_some()
    }

    /// Returns true if the node is closed, false if it is active.
    #[inline(always)]
    pub fn is_closed(&self) -> bool {
        self.data.is_none()
    }

    // mut

    /// Returns a mutable reference to the underlying data.
    pub fn data_mut(&mut self) -> Option<&mut V::Item> {
        self.data.as_mut()
    }

    /// Returns a mutable reference to the previous references.
    pub fn prev_mut(&mut self) -> &mut V::Prev {
        &mut self.prev
    }

    /// Returns a mutable reference to the next references.
    pub fn next_mut(&mut self) -> &mut V::Next {
        &mut self.next
    }

    /// Closes the node and returns its data, and clears its connections.
    ///
    /// # Panics
    ///
    /// Panics if the node was already closed.
    pub fn close(&mut self) -> V::Item {
        self.prev.clear();
        self.next.clear();
        self.data.take().expect("must be an open node")
    }

    /// Swaps the data of the node with the `new_value` and returns the old value.
    ///
    /// # Panics
    ///
    /// Panics if the node was already closed.
    pub fn swap_data(&mut self, new_value: V::Item) -> V::Item {
        debug_assert!(self.is_active());
        self.data.replace(new_value).expect("must be active")
    }

    /// Closes the node and returns its data.
    ///
    /// # Panics
    ///
    /// Panics if the node was already closed.
    pub fn take_data(&mut self) -> Option<V::Item> {
        self.data.take()
    }
}

impl<V: Variant> Debug for Node<V>
where
    V::Item: Debug,
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_struct("Node")
            .field("data", &self.data)
            .field("prev", &self.prev)
            .field("next", &self.next)
            .finish()
    }
}