wnfs_hamt/
serializable.rs1use crate::constants::HAMT_BITMASK_BYTE_SIZE;
2use ipld_core::cid::serde::{BytesToCidVisitor, CID_SERDE_PRIVATE_IDENTIFIER};
3use semver::Version;
4use serde::{
5 Deserialize, Deserializer, Serialize, Serializer,
6 de::{SeqAccess, Visitor},
7};
8use serde_byte_array::ByteArray;
9use serde_bytes::ByteBuf;
10use std::marker::PhantomData;
11use wnfs_common::Cid;
12
13#[derive(Serialize, Deserialize, Debug, Clone)]
18pub struct HamtSerializable<K, V> {
19 pub(crate) root: NodeSerializable<K, V>,
20 pub(crate) version: Version,
21 pub(crate) structure: String,
22}
23
24#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
25pub struct NodeSerializable<K, V>(
26 pub(crate) ByteArray<HAMT_BITMASK_BYTE_SIZE>,
27 pub(crate) Vec<PointerSerializable<K, V>>,
28);
29
30#[derive(Debug, Clone, PartialEq)]
31pub(crate) enum PointerSerializable<K, V> {
32 Values(Vec<(K, V)>),
33 Link(Cid),
34}
35
36impl<K: Serialize, V: Serialize> Serialize for PointerSerializable<K, V> {
41 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
42 match *self {
43 Self::Values(ref vec) => vec.serialize(serializer),
44 Self::Link(ref cid) => {
45 let value = ByteBuf::from(cid.to_bytes());
46 serializer.serialize_newtype_struct(CID_SERDE_PRIVATE_IDENTIFIER, &value)
47 }
48 }
49 }
50}
51
52impl<'de, K: Deserialize<'de>, V: Deserialize<'de>> Deserialize<'de> for PointerSerializable<K, V> {
53 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
54 struct PointerVisitor<K, V>(PhantomData<(K, V)>);
55
56 impl<'de, K: Deserialize<'de>, V: Deserialize<'de>> Visitor<'de> for PointerVisitor<K, V> {
57 type Value = PointerSerializable<K, V>;
58
59 fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
60 write!(
61 fmt,
62 "a valid PointerSerializable represented as CID bytes or as a sequence of tuples of keys and values"
63 )
64 }
65
66 fn visit_newtype_struct<D: Deserializer<'de>>(
67 self,
68 deserializer: D,
69 ) -> Result<Self::Value, D::Error> {
70 let cid = deserializer.deserialize_bytes(BytesToCidVisitor)?;
71 Ok(PointerSerializable::Link(cid))
72 }
73
74 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
75 let mut values = Vec::new();
76 while let Some(elem) = seq.next_element::<(K, V)>()? {
77 values.push(elem);
78 }
79 Ok(PointerSerializable::Values(values))
80 }
81 }
82
83 let visitor = PointerVisitor(PhantomData);
84 deserializer.deserialize_any(visitor)
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use testresult::TestResult;
92
93 #[test]
94 fn test_pointer_link_roundtrip() -> TestResult {
95 let pointers = PointerSerializable::<String, String>::Link(Cid::default());
96 let bytes = serde_ipld_dagcbor::to_vec(&pointers)?;
97
98 let pointers_back: PointerSerializable<String, String> =
99 serde_ipld_dagcbor::from_slice(&bytes)?;
100
101 assert_eq!(pointers, pointers_back);
102
103 Ok(())
104 }
105
106 #[test]
107 fn test_pointer_values_roundtrip() -> TestResult {
108 let pointers = PointerSerializable::Values(vec![(1, 10), (2, 20), (3, 30)]);
109 let bytes = serde_ipld_dagcbor::to_vec(&pointers)?;
110
111 let pointers_back: PointerSerializable<u32, u32> = serde_ipld_dagcbor::from_slice(&bytes)?;
112
113 assert_eq!(pointers, pointers_back);
114
115 Ok(())
116 }
117}