aranya_runtime/
command.rs1pub use aranya_crypto::policy::CmdId;
2use buggy::{Bug, BugExt as _};
3
4use crate::{MaxCut, Prior};
5
6#[derive(
9 Debug,
10 Clone,
11 PartialEq,
12 Eq,
13 PartialOrd,
14 Ord,
15 serde::Serialize,
16 serde::Deserialize,
17 rkyv::Archive,
18 rkyv::Serialize,
19 rkyv::Deserialize,
20)]
21pub enum Priority {
22 Merge,
26 Basic(u32),
29 Finalize,
31 Init,
35}
36
37pub trait Command {
45 fn priority(&self) -> Priority;
48
49 fn id(&self) -> CmdId;
51
52 fn parent(&self) -> Prior<Address>;
55
56 fn policy(&self) -> Option<&[u8]>;
58
59 fn bytes(&self) -> &[u8];
61
62 fn max_cut(&self) -> Result<MaxCut, Bug> {
64 match self.parent() {
65 Prior::None => Ok(MaxCut::new(0)),
66 Prior::Single(l) => Ok(l.max_cut.checked_add(1).assume("must not overflow")?),
67 Prior::Merge(l, r) => Ok(l
68 .max_cut
69 .max(r.max_cut)
70 .checked_add(1)
71 .assume("must not overflow")?),
72 }
73 }
74
75 fn address(&self) -> Result<Address, Bug> {
77 Ok(Address {
78 id: self.id(),
79 max_cut: self.max_cut()?,
80 })
81 }
82}
83
84impl<C: Command> Command for &C {
85 fn priority(&self) -> Priority {
86 (*self).priority()
87 }
88
89 fn id(&self) -> CmdId {
90 (*self).id()
91 }
92
93 fn parent(&self) -> Prior<Address> {
94 (*self).parent()
95 }
96
97 fn policy(&self) -> Option<&[u8]> {
98 (*self).policy()
99 }
100
101 fn bytes(&self) -> &[u8] {
102 (*self).bytes()
103 }
104
105 fn max_cut(&self) -> Result<MaxCut, Bug> {
106 (*self).max_cut()
107 }
108
109 fn address(&self) -> Result<Address, Bug> {
110 (*self).address()
111 }
112}
113
114#[derive(
120 Copy,
121 Clone,
122 Debug,
123 PartialEq,
124 Eq,
125 PartialOrd,
126 Ord,
127 serde::Serialize,
128 serde::Deserialize,
129 rkyv::Archive,
130 rkyv::Serialize,
131 rkyv::Deserialize,
132 rkyv::Portable,
133 rkyv::bytecheck::CheckBytes,
134)]
135#[rkyv(as = Self)]
136#[bytecheck(crate = rkyv::bytecheck)]
137#[repr(C)]
138pub struct Address {
139 pub id: CmdId,
140 pub max_cut: MaxCut,
141}
142
143impl Prior<Address> {
144 pub fn next_max_cut(&self) -> Result<MaxCut, Bug> {
146 Ok(match self {
147 Self::None => MaxCut::new(1),
148 Self::Single(l) => l.max_cut.checked_add(1).assume("must not overflow")?,
149 Self::Merge(l, r) => l
150 .max_cut
151 .max(r.max_cut)
152 .checked_add(1)
153 .assume("must not overflow")?,
154 })
155 }
156}
157
158#[cfg(test)]
159mod test {
160 use super::*;
161
162 #[test]
163 fn priority_ordering() {
164 assert!(Priority::Merge < Priority::Basic(0));
165 assert!(Priority::Basic(0) < Priority::Basic(1));
166 assert!(Priority::Basic(1) < Priority::Basic(u32::MAX));
167 assert!(Priority::Basic(u32::MAX) < Priority::Finalize);
168 assert!(Priority::Finalize < Priority::Init);
169 }
170}