1use serde::{Deserialize, Serialize};
15
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
25pub enum KeyRepr {
26 Surrogate(u32),
28 KvKey(Box<[u8]>),
30 Edge {
32 src: Box<str>,
33 label: Box<str>,
34 dst: Box<str>,
35 },
36}
37
38const KEY_REPR_TAG_SURROGATE: u32 = 0;
45const KEY_REPR_TAG_KV: u32 = 1;
46const KEY_REPR_TAG_EDGE: u32 = 2;
47
48impl zerompk::ToMessagePack for KeyRepr {
49 fn write<W: zerompk::Write>(&self, writer: &mut W) -> zerompk::Result<()> {
50 writer.write_array_len(2)?;
51 match self {
52 KeyRepr::Surrogate(v) => {
53 writer.write_u32(KEY_REPR_TAG_SURROGATE)?;
54 writer.write_u32(*v)?;
55 }
56 KeyRepr::KvKey(bytes) => {
57 writer.write_u32(KEY_REPR_TAG_KV)?;
58 writer.write_binary(bytes)?;
59 }
60 KeyRepr::Edge { src, label, dst } => {
61 writer.write_u32(KEY_REPR_TAG_EDGE)?;
62 writer.write_array_len(3)?;
63 writer.write_string(src)?;
64 writer.write_string(label)?;
65 writer.write_string(dst)?;
66 }
67 }
68 Ok(())
69 }
70}
71
72impl<'de> zerompk::FromMessagePack<'de> for KeyRepr {
73 fn read<R: zerompk::Read<'de>>(reader: &mut R) -> zerompk::Result<Self> {
74 let outer = reader.read_array_len()?;
75 if outer != 2 {
76 return Err(zerompk::Error::InvalidMarker(0));
77 }
78 let tag = reader.read_u32()?;
79 match tag {
80 KEY_REPR_TAG_SURROGATE => Ok(KeyRepr::Surrogate(reader.read_u32()?)),
81 KEY_REPR_TAG_KV => {
82 let bytes = reader.read_binary()?;
83 Ok(KeyRepr::KvKey(Box::from(bytes.as_ref())))
84 }
85 KEY_REPR_TAG_EDGE => {
86 let inner = reader.read_array_len()?;
87 if inner != 3 {
88 return Err(zerompk::Error::InvalidMarker(0));
89 }
90 let src = reader.read_string()?;
91 let label = reader.read_string()?;
92 let dst = reader.read_string()?;
93 Ok(KeyRepr::Edge {
94 src: Box::from(src.as_ref()),
95 label: Box::from(label.as_ref()),
96 dst: Box::from(dst.as_ref()),
97 })
98 }
99 _ => Err(zerompk::Error::InvalidMarker(0)),
100 }
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 fn roundtrip(k: &KeyRepr) -> KeyRepr {
109 let bytes = zerompk::to_msgpack_vec(k).expect("encode KeyRepr");
110 zerompk::from_msgpack(&bytes).expect("decode KeyRepr")
111 }
112
113 #[test]
114 fn surrogate_roundtrips() {
115 let k = KeyRepr::Surrogate(0xDEAD_BEEF);
116 assert_eq!(roundtrip(&k), k);
117 }
118
119 #[test]
120 fn kv_key_roundtrips() {
121 let k = KeyRepr::KvKey(Box::from(&b"\x00\x01\xffhello"[..]));
122 assert_eq!(roundtrip(&k), k);
123 }
124
125 #[test]
126 fn edge_roundtrips() {
127 let k = KeyRepr::Edge {
128 src: Box::from("alice"),
129 label: Box::from("FOLLOWS"),
130 dst: Box::from("bob"),
131 };
132 assert_eq!(roundtrip(&k), k);
133 }
134}