1use serde::{
2 de::{self, Deserialize, Deserializer},
3 ser::{Serialize, SerializeSeq, Serializer},
4};
5
6macro_rules! impl_key_ops {
7 ($(($key_op:ident, $const_name:ident, $i:literal)),+,) => {
8 bitflags::bitflags! {
9 #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
10 pub struct KeyOps: u16 {
11 $(const $const_name = $i;)*
12 }
13 }
14
15 impl Serialize for KeyOps {
16 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
17 let mut seq = s.serialize_seq(Some(self.bits().count_ones() as usize))?;
18 $(
19 if self.contains(KeyOps::$const_name) {
20 seq.serialize_element(stringify!($key_op))?;
21 }
22 )+
23 seq.end()
24 }
25 }
26
27 impl<'de> Deserialize<'de> for KeyOps {
28 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<KeyOps, D::Error> {
29 let op_strs: Vec<String> = Deserialize::deserialize(d)?;
30 let mut ops = KeyOps::default();
31 for op_str in op_strs {
32 $(
33 if op_str == stringify!($key_op) {
34 ops |= KeyOps::$const_name;
35 continue;
36 }
37 )+
38 return Err(de::Error::custom(&format!("invalid key op: `{}`", op_str)));
39 }
40 Ok(ops)
41 }
42 }
43 };
44}
45
46#[rustfmt::skip]
47impl_key_ops!(
48 (sign, SIGN, 0b00000001),
49 (verify, VERIFY, 0b00000010),
50 (encrypt, ENCRYPT, 0b00000100),
51 (decrypt, DECRYPT, 0b00001000),
52 (wrapKey, WRAP_KEY, 0b00010000),
53 (unwrapKey, UNWRAP_KEY, 0b00100000),
54 (deriveKey, DERIVE_KEY, 0b01000000),
55 (deriveBits, DERIVE_BITS, 0b10000000),
56);
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn deserialize_invalid() {
64 let result: Result<KeyOps, _> = serde_json::from_str(r#"["unknown"]"#);
65 assert!(result.is_err());
66 }
67
68 #[test]
69 fn serialize() {
70 let ops = KeyOps::SIGN | KeyOps::DERIVE_BITS;
71 let json = serde_json::to_string(&ops).unwrap();
72 assert_eq!(json, r#"["sign","deriveBits"]"#)
73 }
74}