Skip to main content

prefix_trie/
serde.rs

1//! Serialization and deserialization for dense prefix collections.
2
3use ::serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5use crate::Prefix;
6
7use super::{map::PrefixMap, set::PrefixSet};
8
9impl<P: Prefix + Serialize, T: Serialize> Serialize for PrefixMap<P, T> {
10    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
11    where
12        S: Serializer,
13    {
14        let map: Vec<(P, &T)> = Vec::from_iter(self);
15        map.serialize(serializer)
16    }
17}
18
19impl<P: Prefix + Serialize> Serialize for PrefixSet<P> {
20    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21    where
22        S: Serializer,
23    {
24        let set: Vec<P> = Vec::from_iter(self);
25        set.serialize(serializer)
26    }
27}
28
29impl<'de, P: Prefix + Deserialize<'de>, T: Deserialize<'de>> Deserialize<'de> for PrefixMap<P, T> {
30    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
31    where
32        D: Deserializer<'de>,
33    {
34        let map: Vec<(P, T)> = Vec::deserialize(deserializer)?;
35        Ok(Self::from_iter(map))
36    }
37}
38
39impl<'de, P: Prefix + Deserialize<'de>> Deserialize<'de> for PrefixSet<P> {
40    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
41    where
42        D: Deserializer<'de>,
43    {
44        let set: Vec<P> = Vec::deserialize(deserializer)?;
45        Ok(Self::from_iter(set))
46    }
47}
48
49#[cfg(test)]
50#[cfg(feature = "ipnet")]
51mod test {
52    use super::*;
53    use num_traits::NumCast;
54
55    fn ip<P: Prefix>(s: &str) -> P {
56        let ip: ipnet::Ipv4Net = s.parse().unwrap();
57        let r = ip.addr().to_bits();
58        let len = ip.prefix_len();
59
60        let type_len = P::num_bits() as usize;
61        assert!(type_len >= 32);
62
63        let r: <P as Prefix>::R =
64            <<P as Prefix>::R as NumCast>::from(r).unwrap() << (type_len - 32);
65        P::from_repr_len(r, len)
66    }
67
68    #[generic_tests::define]
69    mod t {
70        use super::*;
71        use std::fmt::Debug;
72
73        #[test]
74        fn map<P: Prefix + Debug + PartialEq + Serialize + for<'de> Deserialize<'de>>() {
75            let map: PrefixMap<P, usize> = PrefixMap::from_iter([
76                (ip("10.0.0.0/8"), 1),
77                (ip("10.1.0.0/16"), 2),
78                (ip("10.2.0.0/16"), 3),
79                (ip("10.2.1.1/24"), 4),
80                (ip("10.2.2.2/24"), 5),
81            ]);
82            let s: String = serde_json::to_string(&map).unwrap();
83            let map2: PrefixMap<P, usize> = serde_json::from_str(&s).unwrap();
84            assert_eq!(map, map2);
85        }
86
87        #[test]
88        fn set<P: Prefix + Debug + PartialEq + Serialize + for<'de> Deserialize<'de>>() {
89            let set: PrefixSet<P> = PrefixSet::from_iter([
90                ip("10.0.0.0/8"),
91                ip("10.1.0.0/16"),
92                ip("10.2.0.0/16"),
93                ip("10.2.1.1/24"),
94                ip("10.2.2.2/24"),
95            ]);
96            let s: String = serde_json::to_string(&set).unwrap();
97            let set2: PrefixSet<P> = serde_json::from_str(&s).unwrap();
98            assert_eq!(set, set2);
99        }
100
101        #[instantiate_tests(<(u32, u8)>)]
102        mod raw32 {}
103
104        #[instantiate_tests(<(u64, u8)>)]
105        mod raw64 {}
106
107        #[instantiate_tests(<(u128, u8)>)]
108        mod raw128 {}
109
110        #[cfg(feature = "ipnet")]
111        #[instantiate_tests(<ipnet::Ipv4Net>)]
112        mod ipv4net {}
113
114        #[cfg(feature = "ipnet")]
115        #[instantiate_tests(<ipnet::Ipv6Net>)]
116        mod ipv6net {}
117
118        #[cfg(feature = "ipnetwork")]
119        #[instantiate_tests(<ipnetwork::Ipv4Network>)]
120        mod ipv4network {}
121
122        #[cfg(feature = "ipnetwork")]
123        #[instantiate_tests(<ipnetwork::Ipv6Network>)]
124        mod ipv6network {}
125
126        #[cfg(feature = "cidr")]
127        #[instantiate_tests(<cidr::Ipv4Cidr>)]
128        mod ipv4cidr {}
129
130        #[cfg(feature = "cidr")]
131        #[instantiate_tests(<cidr::Ipv6Cidr>)]
132        mod ipv6cidr {}
133
134        #[cfg(feature = "cidr")]
135        #[instantiate_tests(<cidr::Ipv4Inet>)]
136        mod ipv4inet {}
137
138        #[cfg(feature = "cidr")]
139        #[instantiate_tests(<cidr::Ipv6Inet>)]
140        mod ipv6inet {}
141    }
142}