wnfs_hamt/
serializable.rs

1use 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//--------------------------------------------------------------------------------------------------
14// Type Definitions
15//--------------------------------------------------------------------------------------------------
16
17#[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
36//--------------------------------------------------------------------------------------------------
37// Implementations
38//--------------------------------------------------------------------------------------------------
39
40impl<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}