1use core::{
2 fmt::{self, Debug, Display, Formatter},
3 ops::{BitAnd, BitOr},
4};
5
6use serde::{
7 de::{Deserialize, Deserializer, SeqAccess, Visitor},
8 ser::{Serialize, SerializeSeq, Serializer},
9};
10
11#[cfg(feature = "arbitrary")]
12use arbitrary::Arbitrary;
13
14static OPS: &[KeyOps] = &[
15 KeyOps::Encrypt,
16 KeyOps::Decrypt,
17 KeyOps::Sign,
18 KeyOps::Verify,
19 KeyOps::WrapKey,
20 KeyOps::UnwrapKey,
21 KeyOps::DeriveKey,
22 KeyOps::DeriveBits,
23];
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
27#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
28#[repr(usize)]
29pub enum KeyOps {
30 Encrypt = 1 << 0,
32 Decrypt = 1 << 1,
34 Sign = 1 << 2,
36 Verify = 1 << 3,
38 WrapKey = 1 << 4,
40 UnwrapKey = 1 << 5,
42 DeriveKey = 1 << 6,
44 DeriveBits = 1 << 7,
46}
47
48impl Display for KeyOps {
49 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
50 f.write_str(self.as_str())
51 }
52}
53
54impl KeyOps {
55 pub fn as_str(&self) -> &'static str {
57 match self {
58 Self::Encrypt => "encrypt",
59 Self::Decrypt => "decrypt",
60 Self::Sign => "sign",
61 Self::Verify => "verify",
62 Self::WrapKey => "wrapKey",
63 Self::UnwrapKey => "unwrapKey",
64 Self::DeriveKey => "deriveKey",
65 Self::DeriveBits => "deriveBits",
66 }
67 }
68
69 pub fn try_from_str(key: &str) -> Option<Self> {
71 match key {
72 "sign" => Some(Self::Sign),
73 "verify" => Some(Self::Verify),
74 "encrypt" => Some(Self::Encrypt),
75 "decrypt" => Some(Self::Decrypt),
76 "wrapKey" => Some(Self::WrapKey),
77 "unwrapKey" => Some(Self::UnwrapKey),
78 "deriveKey" => Some(Self::DeriveKey),
79 "deriveBits" => Some(Self::DeriveBits),
80 _ => None,
81 }
82 }
83}
84
85impl BitOr<Self> for KeyOps {
86 type Output = KeyOpsSet;
87
88 fn bitor(self, rhs: Self) -> Self::Output {
89 KeyOpsSet {
90 value: self as usize | rhs as usize,
91 }
92 }
93}
94
95#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
97#[repr(transparent)]
98#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
99pub struct KeyOpsSet {
100 value: usize,
101}
102
103impl KeyOpsSet {
104 pub const fn new() -> Self {
106 Self { value: 0 }
107 }
108
109 pub fn is_empty(&self) -> bool {
111 self.value == 0
112 }
113}
114
115impl Default for KeyOpsSet {
116 fn default() -> Self {
117 Self::new()
118 }
119}
120
121impl BitOr<Self> for KeyOpsSet {
122 type Output = Self;
123
124 fn bitor(self, rhs: Self) -> Self::Output {
125 KeyOpsSet {
126 value: self.value | rhs.value,
127 }
128 }
129}
130
131impl BitOr<KeyOps> for KeyOpsSet {
132 type Output = KeyOpsSet;
133
134 fn bitor(self, rhs: KeyOps) -> Self::Output {
135 KeyOpsSet {
136 value: self.value | rhs as usize,
137 }
138 }
139}
140
141impl BitAnd<KeyOps> for KeyOpsSet {
142 type Output = bool;
143
144 fn bitand(self, rhs: KeyOps) -> Self::Output {
145 self.value & rhs as usize != 0
146 }
147}
148
149impl BitAnd<Self> for KeyOpsSet {
150 type Output = bool;
151
152 fn bitand(self, rhs: Self) -> Self::Output {
153 self.value & rhs.value != 0
154 }
155}
156
157impl Debug for KeyOpsSet {
158 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
159 let mut vals = &mut f.debug_set();
160 for op in self {
161 vals = vals.entry(&op.as_str());
162 }
163 vals.finish()
164 }
165}
166
167impl From<KeyOps> for KeyOpsSet {
168 fn from(op: KeyOps) -> Self {
169 Self { value: op as usize }
170 }
171}
172
173impl IntoIterator for &KeyOpsSet {
174 type IntoIter = KeyOpsIter;
175 type Item = KeyOps;
176
177 fn into_iter(self) -> Self::IntoIter {
178 KeyOpsIter {
179 index: 0,
180 value: *self,
181 }
182 }
183}
184
185#[derive(Debug)]
186pub struct KeyOpsIter {
187 index: usize,
188 value: KeyOpsSet,
189}
190
191impl Iterator for KeyOpsIter {
192 type Item = KeyOps;
193
194 fn next(&mut self) -> Option<Self::Item> {
195 while self.index < OPS.len() {
196 let op = OPS[self.index];
197 self.index += 1;
198 if self.value & op {
199 return Some(op);
200 }
201 }
202 None
203 }
204}
205
206struct KeyOpsVisitor;
207
208impl<'de> Visitor<'de> for KeyOpsVisitor {
209 type Value = KeyOpsSet;
210
211 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
212 formatter.write_str("an array of key operations")
213 }
214
215 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
216 where
217 A: SeqAccess<'de>,
218 {
219 let mut ops = KeyOpsSet::new();
220 while let Some(op) = seq.next_element()? {
221 if let Some(op) = KeyOps::try_from_str(op) {
222 if ops & op {
223 return Err(serde::de::Error::duplicate_field(op.as_str()));
224 } else {
225 ops = ops | op;
226 }
227 }
228 }
229 Ok(ops)
230 }
231}
232
233impl<'de> Deserialize<'de> for KeyOpsSet {
234 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
235 where
236 D: Deserializer<'de>,
237 {
238 deserializer.deserialize_seq(KeyOpsVisitor)
239 }
240}
241
242impl Serialize for KeyOpsSet {
243 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
244 where
245 S: Serializer,
246 {
247 let mut seq = serializer.serialize_seq(None)?;
248 for op in self {
249 seq.serialize_element(op.as_str())?;
250 }
251 seq.end()
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use super::*;
258
259 #[test]
260 fn invariants() {
261 assert!(KeyOpsSet::new().is_empty());
262 assert!(!KeyOpsSet::from(KeyOps::Decrypt).is_empty());
263 assert_eq!(KeyOpsSet::new(), KeyOpsSet::new());
264 assert_ne!(KeyOpsSet::from(KeyOps::Decrypt), KeyOpsSet::new());
265 assert_ne!(KeyOps::Decrypt, KeyOps::Encrypt);
266 assert_ne!(
267 KeyOpsSet::from(KeyOps::Decrypt),
268 KeyOpsSet::from(KeyOps::Encrypt)
269 );
270 assert_eq!(
271 KeyOps::Decrypt | KeyOps::Encrypt,
272 KeyOps::Encrypt | KeyOps::Decrypt
273 );
274 }
275
276 #[test]
277 fn debug_format() {
278 assert_eq!(
279 format!("{:?}", KeyOps::Decrypt | KeyOps::Encrypt),
280 "{\"encrypt\", \"decrypt\"}"
281 );
282 }
283}