Skip to main content

aranya_runtime/
prior.rs

1/// Refer to immediately prior commands in a graph, usually via `Prior<CmdId>` or `Prior<Location>`.
2#[derive(
3    Copy,
4    Clone,
5    Debug,
6    PartialEq,
7    Eq,
8    PartialOrd,
9    Ord,
10    serde::Serialize,
11    serde::Deserialize,
12    rkyv::Archive,
13    rkyv::Serialize,
14    rkyv::Deserialize,
15    rkyv::Portable,
16    rkyv::bytecheck::CheckBytes,
17)]
18#[rkyv(as = Prior<T::Archived>)]
19#[bytecheck(crate = rkyv::bytecheck)]
20#[repr(u8)]
21pub enum Prior<T> {
22    /// No parents (init command)
23    None,
24    /// One parent (basic command)
25    Single(T),
26    /// Two parents (merge command)
27    Merge(T, T),
28}
29
30impl<T> Prior<T> {
31    /// Converts from `&Prior<T>` to `Prior<&T>`.
32    pub fn as_ref(&self) -> Prior<&T> {
33        match self {
34            Self::None => Prior::None,
35            Self::Single(x) => Prior::Single(x),
36            Self::Merge(x, y) => Prior::Merge(x, y),
37        }
38    }
39}
40
41impl<T: Clone> Prior<&T> {
42    /// Maps an `Prior<&T>` to an `Prior<T>` by cloning the contents.
43    pub fn cloned(self) -> Prior<T> {
44        match self {
45            Prior::None => Prior::None,
46            Prior::Single(x) => Prior::Single(x.clone()),
47            Prior::Merge(x, y) => Prior::Merge(x.clone(), y.clone()),
48        }
49    }
50}
51
52impl<T: Copy> Prior<&T> {
53    /// Maps an `Prior<&T>` to an `Prior<T>` by copying the contents.
54    pub fn copied(self) -> Prior<T> {
55        match self {
56            Prior::None => Prior::None,
57            Prior::Single(x) => Prior::Single(*x),
58            Prior::Merge(x, y) => Prior::Merge(*x, *y),
59        }
60    }
61}
62
63/// An iterator over the values in `Prior`.
64///
65/// Yields 0, 1, or 2 values.
66pub struct IntoIter<T>(Prior<T>);
67
68impl<T> IntoIterator for Prior<T> {
69    type IntoIter = IntoIter<T>;
70    type Item = T;
71    fn into_iter(self) -> Self::IntoIter {
72        IntoIter(self)
73    }
74}
75
76impl<T> Iterator for IntoIter<T> {
77    type Item = T;
78    fn next(&mut self) -> Option<Self::Item> {
79        match core::mem::replace(&mut self.0, Prior::None) {
80            Prior::None => None,
81            Prior::Single(x) => Some(x),
82            Prior::Merge(x, y) => {
83                self.0 = Prior::Single(y);
84                Some(x)
85            }
86        }
87    }
88}