1use super::cesr_code::CesrCode;
2use super::matter_code::MatterCode;
3use super::sealed::Sealed;
4use crate::core::matter::error::ValidationError;
5#[cfg(feature = "alloc")]
6#[allow(
7 unused_imports,
8 reason = "alloc prelude items; subset used per cfg/feature combination"
9)]
10use alloc::string::ToString;
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
14#[allow(
15 non_camel_case_types,
16 reason = "variable-size code names use underscores by convention"
17)]
18pub enum LabelerCode {
19 Empty,
21 Tag1,
23 Tag2,
25 Tag3,
27 Tag4,
29 Tag5,
31 Tag6,
33 Tag7,
35 Tag8,
37 Tag9,
39 Tag10,
41 Tag11,
43 Label1,
45 Label2,
47 StrB64_L0,
49 StrB64_L1,
51 StrB64_L2,
53 StrB64Big_L0,
55 StrB64Big_L1,
57 StrB64Big_L2,
59 Bytes_L0,
61 Bytes_L1,
63 Bytes_L2,
65 BytesBig_L0,
67 BytesBig_L1,
69 BytesBig_L2,
71}
72
73impl Sealed for LabelerCode {}
74
75impl CesrCode for LabelerCode {
76 fn to_matter_code(&self) -> MatterCode {
77 match self {
78 Self::Empty => MatterCode::Empty,
79 Self::Tag1 => MatterCode::Tag1,
80 Self::Tag2 => MatterCode::Tag2,
81 Self::Tag3 => MatterCode::Tag3,
82 Self::Tag4 => MatterCode::Tag4,
83 Self::Tag5 => MatterCode::Tag5,
84 Self::Tag6 => MatterCode::Tag6,
85 Self::Tag7 => MatterCode::Tag7,
86 Self::Tag8 => MatterCode::Tag8,
87 Self::Tag9 => MatterCode::Tag9,
88 Self::Tag10 => MatterCode::Tag10,
89 Self::Tag11 => MatterCode::Tag11,
90 Self::Label1 => MatterCode::Label1,
91 Self::Label2 => MatterCode::Label2,
92 Self::StrB64_L0 => MatterCode::StrB64_L0,
93 Self::StrB64_L1 => MatterCode::StrB64_L1,
94 Self::StrB64_L2 => MatterCode::StrB64_L2,
95 Self::StrB64Big_L0 => MatterCode::StrB64Big_L0,
96 Self::StrB64Big_L1 => MatterCode::StrB64Big_L1,
97 Self::StrB64Big_L2 => MatterCode::StrB64Big_L2,
98 Self::Bytes_L0 => MatterCode::Bytes_L0,
99 Self::Bytes_L1 => MatterCode::Bytes_L1,
100 Self::Bytes_L2 => MatterCode::Bytes_L2,
101 Self::BytesBig_L0 => MatterCode::BytesBig_L0,
102 Self::BytesBig_L1 => MatterCode::BytesBig_L1,
103 Self::BytesBig_L2 => MatterCode::BytesBig_L2,
104 }
105 }
106
107 fn as_str(&self) -> &'static str {
108 match self {
109 Self::Empty => "1AAP",
110 Self::Tag1 => "0J",
111 Self::Tag2 => "0K",
112 Self::Tag3 => "X",
113 Self::Tag4 => "1AAF",
114 Self::Tag5 => "0L",
115 Self::Tag6 => "0M",
116 Self::Tag7 => "Y",
117 Self::Tag8 => "1AAN",
118 Self::Tag9 => "0N",
119 Self::Tag10 => "0O",
120 Self::Tag11 => "Z",
121 Self::Label1 => "V",
122 Self::Label2 => "W",
123 Self::StrB64_L0 => "4A",
124 Self::StrB64_L1 => "5A",
125 Self::StrB64_L2 => "6A",
126 Self::StrB64Big_L0 => "7AAA",
127 Self::StrB64Big_L1 => "8AAA",
128 Self::StrB64Big_L2 => "9AAA",
129 Self::Bytes_L0 => "4B",
130 Self::Bytes_L1 => "5B",
131 Self::Bytes_L2 => "6B",
132 Self::BytesBig_L0 => "7AAB",
133 Self::BytesBig_L1 => "8AAB",
134 Self::BytesBig_L2 => "9AAB",
135 }
136 }
137}
138
139impl TryFrom<MatterCode> for LabelerCode {
140 type Error = ValidationError;
141
142 fn try_from(code: MatterCode) -> Result<Self, Self::Error> {
143 match code {
144 MatterCode::Empty => Ok(Self::Empty),
145 MatterCode::Tag1 => Ok(Self::Tag1),
146 MatterCode::Tag2 => Ok(Self::Tag2),
147 MatterCode::Tag3 => Ok(Self::Tag3),
148 MatterCode::Tag4 => Ok(Self::Tag4),
149 MatterCode::Tag5 => Ok(Self::Tag5),
150 MatterCode::Tag6 => Ok(Self::Tag6),
151 MatterCode::Tag7 => Ok(Self::Tag7),
152 MatterCode::Tag8 => Ok(Self::Tag8),
153 MatterCode::Tag9 => Ok(Self::Tag9),
154 MatterCode::Tag10 => Ok(Self::Tag10),
155 MatterCode::Tag11 => Ok(Self::Tag11),
156 MatterCode::Label1 => Ok(Self::Label1),
157 MatterCode::Label2 => Ok(Self::Label2),
158 MatterCode::StrB64_L0 => Ok(Self::StrB64_L0),
159 MatterCode::StrB64_L1 => Ok(Self::StrB64_L1),
160 MatterCode::StrB64_L2 => Ok(Self::StrB64_L2),
161 MatterCode::StrB64Big_L0 => Ok(Self::StrB64Big_L0),
162 MatterCode::StrB64Big_L1 => Ok(Self::StrB64Big_L1),
163 MatterCode::StrB64Big_L2 => Ok(Self::StrB64Big_L2),
164 MatterCode::Bytes_L0 => Ok(Self::Bytes_L0),
165 MatterCode::Bytes_L1 => Ok(Self::Bytes_L1),
166 MatterCode::Bytes_L2 => Ok(Self::Bytes_L2),
167 MatterCode::BytesBig_L0 => Ok(Self::BytesBig_L0),
168 MatterCode::BytesBig_L1 => Ok(Self::BytesBig_L1),
169 MatterCode::BytesBig_L2 => Ok(Self::BytesBig_L2),
170 _ => Err(ValidationError::UnknownMatterCode(code.to_string())),
171 }
172 }
173}
174
175impl From<LabelerCode> for MatterCode {
176 fn from(code: LabelerCode) -> Self {
177 code.to_matter_code()
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184 use crate::core::matter::code::MatterCode;
185
186 #[test]
187 fn labeler_code_to_matter_code_roundtrip() {
188 let codes = [
189 (LabelerCode::Empty, MatterCode::Empty),
190 (LabelerCode::Tag1, MatterCode::Tag1),
191 (LabelerCode::Tag2, MatterCode::Tag2),
192 (LabelerCode::Tag3, MatterCode::Tag3),
193 (LabelerCode::Tag4, MatterCode::Tag4),
194 (LabelerCode::Tag5, MatterCode::Tag5),
195 (LabelerCode::Tag6, MatterCode::Tag6),
196 (LabelerCode::Tag7, MatterCode::Tag7),
197 (LabelerCode::Tag8, MatterCode::Tag8),
198 (LabelerCode::Tag9, MatterCode::Tag9),
199 (LabelerCode::Tag10, MatterCode::Tag10),
200 (LabelerCode::Tag11, MatterCode::Tag11),
201 (LabelerCode::Label1, MatterCode::Label1),
202 (LabelerCode::Label2, MatterCode::Label2),
203 (LabelerCode::StrB64_L0, MatterCode::StrB64_L0),
204 (LabelerCode::StrB64_L1, MatterCode::StrB64_L1),
205 (LabelerCode::StrB64_L2, MatterCode::StrB64_L2),
206 (LabelerCode::StrB64Big_L0, MatterCode::StrB64Big_L0),
207 (LabelerCode::StrB64Big_L1, MatterCode::StrB64Big_L1),
208 (LabelerCode::StrB64Big_L2, MatterCode::StrB64Big_L2),
209 (LabelerCode::Bytes_L0, MatterCode::Bytes_L0),
210 (LabelerCode::Bytes_L1, MatterCode::Bytes_L1),
211 (LabelerCode::Bytes_L2, MatterCode::Bytes_L2),
212 (LabelerCode::BytesBig_L0, MatterCode::BytesBig_L0),
213 (LabelerCode::BytesBig_L1, MatterCode::BytesBig_L1),
214 (LabelerCode::BytesBig_L2, MatterCode::BytesBig_L2),
215 ];
216 for (lc, mc) in codes {
217 assert_eq!(lc.to_matter_code(), mc);
218 assert_eq!(LabelerCode::try_from(mc).unwrap(), lc);
219 assert_eq!(MatterCode::from(lc), mc);
220 }
221 }
222
223 #[test]
224 fn labeler_code_rejects_non_labeler() {
225 assert!(LabelerCode::try_from(MatterCode::Ed25519).is_err());
226 assert!(LabelerCode::try_from(MatterCode::Ed25519Seed).is_err());
227 assert!(LabelerCode::try_from(MatterCode::Short).is_err());
228 }
229
230 #[test]
231 fn labeler_code_as_str() {
232 assert_eq!(LabelerCode::Empty.as_str(), "1AAP");
233 assert_eq!(LabelerCode::Tag3.as_str(), "X");
234 assert_eq!(LabelerCode::Tag7.as_str(), "Y");
235 assert_eq!(LabelerCode::Label1.as_str(), "V");
236 assert_eq!(LabelerCode::StrB64_L0.as_str(), "4A");
237 assert_eq!(LabelerCode::Bytes_L0.as_str(), "4B");
238 assert_eq!(LabelerCode::BytesBig_L2.as_str(), "9AAB");
239 }
240}