Skip to main content

selene_core/
change_kind.rs

1//! Compact stable discriminants for [`Change`] variants.
2
3use crate::Change;
4
5/// Stable discriminant for one [`Change`] variant.
6#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7#[repr(u8)]
8pub enum ChangeKind {
9    /// [`Change::NodeCreated`].
10    NodeCreated = 0,
11    /// [`Change::NodeUpdated`].
12    NodeUpdated = 1,
13    /// [`Change::NodeDeleted`].
14    NodeDeleted = 2,
15    /// [`Change::EdgeCreated`].
16    EdgeCreated = 3,
17    /// [`Change::EdgeUpdated`].
18    EdgeUpdated = 4,
19    /// [`Change::EdgeDeleted`].
20    EdgeDeleted = 5,
21    /// [`Change::SchemaChanged`].
22    SchemaChanged = 6,
23    /// [`Change::NodePropertyRemoved`].
24    NodePropertyRemoved = 7,
25    /// [`Change::EdgePropertyRemoved`].
26    EdgePropertyRemoved = 8,
27    /// [`Change::NodeLabelRemoved`].
28    NodeLabelRemoved = 9,
29    /// [`Change::NodesOfTypeTruncated`].
30    NodesOfTypeTruncated = 10,
31    /// [`Change::EdgesOfTypeTruncated`].
32    EdgesOfTypeTruncated = 11,
33    /// [`Change::GraphReset`].
34    GraphReset = 12,
35}
36
37impl Change {
38    /// Return the compact kind discriminant for this change.
39    #[must_use]
40    pub const fn kind(&self) -> ChangeKind {
41        match self {
42            Self::NodeCreated { .. } => ChangeKind::NodeCreated,
43            Self::NodeUpdated { .. } => ChangeKind::NodeUpdated,
44            Self::NodeDeleted { .. } => ChangeKind::NodeDeleted,
45            Self::EdgeCreated { .. } => ChangeKind::EdgeCreated,
46            Self::EdgeUpdated { .. } => ChangeKind::EdgeUpdated,
47            Self::EdgeDeleted { .. } => ChangeKind::EdgeDeleted,
48            Self::SchemaChanged { .. } => ChangeKind::SchemaChanged,
49            Self::NodePropertyRemoved { .. } => ChangeKind::NodePropertyRemoved,
50            Self::EdgePropertyRemoved { .. } => ChangeKind::EdgePropertyRemoved,
51            Self::NodeLabelRemoved { .. } => ChangeKind::NodeLabelRemoved,
52            Self::NodesOfTypeTruncated { .. } => ChangeKind::NodesOfTypeTruncated,
53            Self::EdgesOfTypeTruncated { .. } => ChangeKind::EdgesOfTypeTruncated,
54            Self::GraphReset {} => ChangeKind::GraphReset,
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::ChangeKind;
62    use crate::Change;
63
64    #[test]
65    fn change_kind_maps_every_change_variant() {
66        let expected = [
67            ChangeKind::NodeCreated,
68            ChangeKind::NodeUpdated,
69            ChangeKind::NodeDeleted,
70            ChangeKind::EdgeCreated,
71            ChangeKind::EdgeUpdated,
72            ChangeKind::EdgeDeleted,
73            ChangeKind::SchemaChanged,
74            ChangeKind::NodePropertyRemoved,
75            ChangeKind::EdgePropertyRemoved,
76            ChangeKind::NodeLabelRemoved,
77            ChangeKind::NodesOfTypeTruncated,
78            ChangeKind::EdgesOfTypeTruncated,
79            ChangeKind::GraphReset,
80        ];
81        assert_eq!(Change::VARIANT_COUNT, expected.len());
82
83        for (factory, kind) in Change::ALL.iter().zip(expected) {
84            assert_eq!(factory().kind(), kind);
85        }
86    }
87
88    #[test]
89    fn change_kind_discriminants_are_contiguous_and_stable() {
90        // The discriminant values are a stable telemetry/ABI surface; pin them
91        // so a reordering of the `ChangeKind` enum is caught at test time.
92        assert_eq!(ChangeKind::NodeCreated as u8, 0);
93        assert_eq!(ChangeKind::NodePropertyRemoved as u8, 7);
94        assert_eq!(ChangeKind::GraphReset as u8, 12);
95    }
96}