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
63impl<C: Command> Command for &C {
64 fn priority(&self) -> Priority {
65 (*self).priority()
66 }
67
68 fn id(&self) -> CmdId {
69 (*self).id()
70 }
71
72 fn parent(&self) -> Prior<Address> {
73 (*self).parent()
74 }
75
76 fn policy(&self) -> Option<&[u8]> {
77 (*self).policy()
78 }
79
80 fn bytes(&self) -> &[u8] {
81 (*self).bytes()
82 }
83}
84
85pub trait CommandExt: Command {
86 fn max_cut(&self) -> Result<MaxCut, Bug>;
90
91 fn address(&self) -> Result<Address, Bug>;
93}
94
95impl<C: Command> CommandExt for C {
96 fn max_cut(&self) -> Result<MaxCut, Bug> {
97 match self.parent() {
98 Prior::None => Ok(MaxCut::new(0)),
99 Prior::Single(l) => Ok(l.max_cut.checked_add(1).assume("must not overflow")?),
100 Prior::Merge(l, r) => Ok(l
101 .max_cut
102 .max(r.max_cut)
103 .checked_add(1)
104 .assume("must not overflow")?),
105 }
106 }
107
108 fn address(&self) -> Result<Address, Bug> {
109 Ok(Address {
110 id: self.id(),
111 max_cut: self.max_cut()?,
112 })
113 }
114}
115
116#[derive(
122 Copy,
123 Clone,
124 Debug,
125 PartialEq,
126 Eq,
127 PartialOrd,
128 Ord,
129 serde::Serialize,
130 serde::Deserialize,
131 rkyv::Archive,
132 rkyv::Serialize,
133 rkyv::Deserialize,
134 rkyv::Portable,
135 rkyv::bytecheck::CheckBytes,
136)]
137#[rkyv(as = Self)]
138#[bytecheck(crate = rkyv::bytecheck)]
139#[repr(C)]
140pub struct Address {
141 pub id: CmdId,
142 pub max_cut: MaxCut,
143}
144
145#[cfg(test)]
146mod test {
147 use super::*;
148
149 #[test]
150 fn priority_ordering() {
151 assert!(Priority::Merge < Priority::Basic(0));
152 assert!(Priority::Basic(0) < Priority::Basic(1));
153 assert!(Priority::Basic(1) < Priority::Basic(u32::MAX));
154 assert!(Priority::Basic(u32::MAX) < Priority::Finalize);
155 assert!(Priority::Finalize < Priority::Init);
156 }
157}