Skip to main content

sim_lib_mutation/managed/
edges.rs

1/// Caller-owned role evidence kept separate from managed graph identity.
2///
3/// Changing a role cannot allocate, remove, renumber, or reorder an edge. The
4/// role type is intentionally generic so guests may use open role vocabularies
5/// without introducing a global enum in the managed-graph substrate.
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct ManagedRole<R> {
8    role: R,
9}
10impl<R> ManagedRole<R> {
11    /// Wraps caller-owned role evidence.
12    pub const fn new(role: R) -> Self {
13        Self { role }
14    }
15
16    /// Borrows the current role.
17    pub const fn role(&self) -> &R {
18        &self.role
19    }
20
21    /// Replaces the role and returns the previous evidence.
22    pub fn replace_role(&mut self, role: R) -> R {
23        std::mem::replace(&mut self.role, role)
24    }
25}
26
27/// A failed checked mutation of a strong edge.
28#[derive(Clone, Copy, Debug, Eq, PartialEq)]
29pub enum StrongEdgeMutationError {
30    /// Allocating a stable identity for a new edge failed.
31    Allocation(EdgeAllocationError),
32    /// The requested identity is not a live strong edge of this node.
33    UnknownEdge(EdgeId),
34    /// The identity is live, but has different collection semantics.
35    WrongKind {
36        /// Live edge identity supplied by the caller.
37        edge: EdgeId,
38        /// Actual immutable edge kind.
39        actual: EdgeKind,
40    },
41    /// The edge exists, but no longer names the caller's expected target.
42    TargetChanged {
43        /// Target supplied by the caller as the mutation precondition.
44        expected: ManagedId,
45        /// Current target, which was left unchanged.
46        actual: ManagedId,
47    },
48}
49
50/// A failed checked mutation of a weak edge.
51#[derive(Clone, Copy, Debug, Eq, PartialEq)]
52pub enum WeakEdgeMutationError {
53    /// Allocating a stable identity for a new edge failed.
54    Allocation(EdgeAllocationError),
55    /// The requested identity is not a live weak edge of this node.
56    UnknownEdge(EdgeId),
57    /// The identity is live, but has different collection semantics.
58    WrongKind {
59        /// Live edge identity supplied by the caller.
60        edge: EdgeId,
61        /// Actual immutable edge kind.
62        actual: EdgeKind,
63    },
64    /// The edge exists, but no longer names the caller's expected target.
65    TargetChanged {
66        /// Target supplied by the caller as the mutation precondition.
67        expected: ManagedId,
68        /// Current target, which was left unchanged.
69        actual: ManagedId,
70    },
71}
72
73/// A failed checked mutation of an ephemeron entry.
74#[derive(Clone, Copy, Debug, Eq, PartialEq)]
75pub enum EphemeronMutationError {
76    /// Allocating a stable identity for a new entry failed.
77    Allocation(EdgeAllocationError),
78    /// The requested identity is not a live ephemeron entry of this node.
79    UnknownEdge(EdgeId),
80    /// The identity is live, but has different collection semantics.
81    WrongKind {
82        /// Live edge identity supplied by the caller.
83        edge: EdgeId,
84        /// Actual immutable edge kind.
85        actual: EdgeKind,
86    },
87    /// The entry exists, but no longer contains the caller's expected pair.
88    EntryChanged {
89        /// Key supplied by the caller as the mutation precondition.
90        expected_key: ManagedId,
91        /// Value supplied by the caller as the mutation precondition.
92        expected_value: ManagedId,
93        /// Current key, which was left unchanged.
94        actual_key: ManagedId,
95        /// Current value, which was left unchanged.
96        actual_value: ManagedId,
97    },
98}
99
100impl fmt::Display for EphemeronMutationError {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        match self {
103            Self::Allocation(error) => error.fmt(f),
104            Self::UnknownEdge(edge) => write!(f, "unknown ephemeron edge {}", edge.0),
105            Self::WrongKind { edge, actual } => {
106                write!(f, "edge {} is {actual:?}, not Ephemeron", edge.0)
107            }
108            Self::EntryChanged {
109                expected_key,
110                expected_value,
111                actual_key,
112                actual_value,
113            } => write!(
114                f,
115                "ephemeron entry changed from ({}, {}) to ({}, {})",
116                expected_key.allocation_ordinal(),
117                expected_value.allocation_ordinal(),
118                actual_key.allocation_ordinal(),
119                actual_value.allocation_ordinal()
120            ),
121        }
122    }
123}
124
125impl Error for EphemeronMutationError {}
126
127impl From<EdgeAllocationError> for EphemeronMutationError {
128    fn from(error: EdgeAllocationError) -> Self {
129        Self::Allocation(error)
130    }
131}
132
133impl fmt::Display for WeakEdgeMutationError {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        match self {
136            Self::Allocation(error) => error.fmt(f),
137            Self::UnknownEdge(edge) => write!(f, "unknown weak edge {}", edge.0),
138            Self::WrongKind { edge, actual } => {
139                write!(f, "edge {} is {actual:?}, not Weak", edge.0)
140            }
141            Self::TargetChanged { expected, actual } => write!(
142                f,
143                "weak edge target changed from allocation {} to allocation {}",
144                expected.allocation_ordinal(),
145                actual.allocation_ordinal()
146            ),
147        }
148    }
149}
150
151impl Error for WeakEdgeMutationError {}
152
153impl From<EdgeAllocationError> for WeakEdgeMutationError {
154    fn from(error: EdgeAllocationError) -> Self {
155        Self::Allocation(error)
156    }
157}
158
159impl fmt::Display for StrongEdgeMutationError {
160    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161        match self {
162            Self::Allocation(error) => error.fmt(f),
163            Self::UnknownEdge(edge) => write!(f, "unknown strong edge {}", edge.0),
164            Self::WrongKind { edge, actual } => {
165                write!(f, "edge {} is {actual:?}, not Strong", edge.0)
166            }
167            Self::TargetChanged { expected, actual } => write!(
168                f,
169                "strong edge target changed from allocation {} to allocation {}",
170                expected.allocation_ordinal(),
171                actual.allocation_ordinal()
172            ),
173        }
174    }
175}
176
177impl Error for StrongEdgeMutationError {}
178
179impl From<EdgeAllocationError> for StrongEdgeMutationError {
180    fn from(error: EdgeAllocationError) -> Self {
181        Self::Allocation(error)
182    }
183}