ssh_agent/proto/
key_type.rs

1pub trait KeyTypeEnum {
2    fn key_type(&self) -> String;
3}
4
5pub trait KeyType {
6    const KEY_TYPE: &'static str;
7    fn key_type(&self) -> String {
8        Self::KEY_TYPE.to_string()
9    }
10}
11
12macro_rules! impl_key_type_enum_ser_de {
13    ($class_name:path, $(($variant_name:path, $variant_class:ty)),* ) => {
14        impl KeyTypeEnum for $class_name {
15            fn key_type(&self) -> String {
16                match self {
17                    $($variant_name(key) => key.key_type()),*
18                }
19            }
20        }
21        
22        impl Serialize for $class_name {
23            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
24                let mut serialize_tuple = serializer.serialize_tuple(2)?;
25                
26                match self {
27                    $(
28                        $variant_name(key) => {
29                            serialize_tuple.serialize_element(&key.key_type())?;
30                            serialize_tuple.serialize_element(key)?;
31                        }
32                    ),*
33                };
34                serialize_tuple.end()
35            }
36        }
37        
38        impl<'de> Deserialize<'de> for $class_name {
39            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<$class_name, D::Error> {
40                struct KeyVisitor;
41                
42                impl<'de> serde::de::Visitor<'de> for KeyVisitor {
43                    type Value = $class_name;
44
45                    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
46                        formatter.write_str("Key with format (type, key)")
47                    }
48
49                    fn visit_seq<V: serde::de::SeqAccess<'de>>(
50                        self,
51                        mut seq: V
52                    ) -> Result<Self::Value, V::Error> {
53                        let key_type: String = seq.next_element()?
54                            .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
55                        let key_type_str = key_type.as_str();
56                        
57                        $(
58                            if key_type_str.starts_with(<$variant_class>::KEY_TYPE) {
59                                let key: $variant_class = seq.next_element()?
60                                    .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
61                                return Ok($variant_name(key))
62                            }
63                        )*
64                        
65                        return Err(Error::custom(ProtoError::UnexpectedVariant));
66                    }
67                }
68                
69                deserializer.deserialize_tuple(2, KeyVisitor)
70            }
71        }
72    };
73}