rshyper_core/node/
hyper_node.rs

1/*
2    Appellation: node <module>
3    Contrib: @FL03
4*/
5use crate::Weight;
6use crate::idx::{RawIndex, Udx, VertexId};
7
8/// The [`Node`] implementation generically associates a [`VertexId`] with a [`Weight`].
9#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10#[cfg_attr(
11    feature = "serde",
12    derive(serde::Deserialize, serde::Serialize),
13    serde(rename_all = "snake_case")
14)]
15#[repr(C)]
16pub struct Node<T, Ix = Udx> {
17    pub(crate) id: VertexId<Ix>,
18    pub(crate) weight: Weight<T>,
19}
20
21impl<T, Ix> Node<T, Ix>
22where
23    Ix: RawIndex,
24{
25    /// initialize a new instance with the given index and weight
26    pub const fn new(id: VertexId<Ix>, weight: T) -> Self {
27        Self {
28            id,
29            weight: Weight(weight),
30        }
31    }
32    /// returns a new weighted node using the given value and the logical default for the index
33    pub fn from_id(index: VertexId<Ix>) -> Self
34    where
35        T: Default,
36    {
37        Self::new(index, Default::default())
38    }
39    /// creates a new node with the given index using the logical default for the weight.
40    pub fn from_weight(Weight(weight): Weight<T>) -> Self
41    where
42        Ix: Default,
43    {
44        Self::new(Default::default(), weight)
45    }
46    /// consumes the current instance to create another with the given index.
47    pub fn with_id<I2: RawIndex>(self, index: VertexId<I2>) -> Node<T, I2> {
48        Node {
49            id: index,
50            weight: self.weight,
51        }
52    }
53    /// consumes the current instance to create another with the given weight.
54    pub fn with_weight<U>(self, weight: Weight<U>) -> Node<U, Ix> {
55        Node {
56            id: self.id,
57            weight,
58        }
59    }
60    /// converts the node into a 2-tuple consisting of the node index and the weight:
61    ///
62    /// - `0`: a reference to the node index
63    /// - `1`: a reference to the node weight
64    pub const fn as_tuple(&self) -> (&VertexId<Ix>, &Weight<T>) {
65        (self.id(), self.weight())
66    }
67    /// consumes the node to convert it into a 2-tuple consisting of the node index and the
68    /// weight
69    pub fn into_tuple(self) -> (VertexId<Ix>, Weight<T>) {
70        (self.id, self.weight)
71    }
72    /// returns the node as a tuple with a mutable reference to the weight such that:
73    ///
74    /// -  `0`: a reference to the node index
75    /// -  `1`: a mutable reference to the node weight
76    ///
77    /// this method is useful for converting the node into a standard item produced by mutable
78    /// key-value iterators where `Item = (&'a K, &'a mut V)`
79    pub fn as_tuple_mut(&mut self) -> (&VertexId<Ix>, &mut Weight<T>) {
80        (&self.id, &mut self.weight)
81    }
82    /// returns an immutable reference to the node index
83    pub const fn id(&self) -> &VertexId<Ix> {
84        &self.id
85    }
86    /// returns an immutable reference to the node weight
87    pub const fn weight(&self) -> &Weight<T> {
88        &self.weight
89    }
90    /// returns a mutable reference to the node weight
91    pub const fn weight_mut(&mut self) -> &mut Weight<T> {
92        &mut self.weight
93    }
94    /// update the weight and return a mutable reference to the current instance.
95    pub fn set_weight(&mut self, weight: T) -> &mut Self {
96        self.weight_mut().set(weight);
97        self
98    }
99    /// [`replace`](core::mem::replace) the weight of the current instance with the given weight,
100    /// returning the previous weight.
101    pub const fn replace_weight(&mut self, weight: T) -> Weight<T> {
102        let prev = self.weight_mut().replace(weight);
103        Weight(prev)
104    }
105    /// [`swap`](core::mem::swap) the weight of the current instance with the weight of
106    /// another instance.
107    pub fn swap_weight(&mut self, other: &mut Self) {
108        self.weight_mut().swap(other.weight_mut());
109    }
110    /// consumes the current instance and applies the given function onto the weight,
111    /// returning a new instance with the same index and the resulting weight.
112    pub fn map<U, F>(self, f: F) -> Node<U, Ix>
113    where
114        F: FnOnce(T) -> U,
115    {
116        Node {
117            id: self.id,
118            weight: self.weight.map(f),
119        }
120    }
121    /// consumes the current instance and applies the given function onto the weight,
122    pub fn map_mut<F>(&mut self, f: F) -> &mut Self
123    where
124        F: FnOnce(&mut T),
125    {
126        self.weight_mut().map_mut(f);
127        self
128    }
129}
130
131#[doc(hidden)]
132#[allow(deprecated)]
133impl<T, Idx> Node<T, Idx>
134where
135    Idx: RawIndex,
136{
137    #[deprecated(
138        note = "use `from_id` instead; the constructor will be removed in the next major release",
139        since = "0.1.2"
140    )]
141    pub fn from_index(index: VertexId<Idx>) -> Self
142    where
143        T: Default,
144    {
145        Self::new(index, Default::default())
146    }
147    #[deprecated(
148        note = "use `id` instead; the accessor will be removed in the next major release",
149        since = "0.1.2"
150    )]
151    pub const fn index(&self) -> &VertexId<Idx> {
152        self.id()
153    }
154    #[deprecated(
155        note = "use `with_id` instead; the setter will be removed in the next major release",
156        since = "0.1.2"
157    )]
158    pub fn with_index<I2: RawIndex>(self, index: VertexId<I2>) -> Node<T, I2> {
159        Node {
160            id: index,
161            weight: self.weight,
162        }
163    }
164}
165
166impl<T, Idx> Default for Node<T, Idx>
167where
168    Idx: RawIndex + Default,
169    T: Default,
170{
171    fn default() -> Self {
172        Self {
173            id: VertexId::default(),
174            weight: Weight::default(),
175        }
176    }
177}
178
179impl<T, Idx> core::fmt::Display for Node<T, Idx>
180where
181    Idx: RawIndex + core::fmt::Display,
182    T: core::fmt::Display,
183{
184    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
185        write!(f, "{{ index: {}, weight: {} }}", self.id(), self.weight())
186    }
187}