darkfi_serial/types/
collections.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2026 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19//! Serialization of collections
20use std::{
21    collections::{BTreeMap, BTreeSet, HashMap, HashSet},
22    io::{Read, Result, Write},
23};
24
25#[cfg(feature = "async")]
26use crate::{AsyncDecodable, AsyncEncodable};
27#[cfg(feature = "async")]
28use async_trait::async_trait;
29#[cfg(feature = "async")]
30use futures_lite::{AsyncRead, AsyncWrite};
31
32use crate::{Decodable, Encodable, VarInt};
33
34impl<T: Encodable> Encodable for HashSet<T> {
35    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
36        let mut len = 0;
37        len += VarInt(self.len() as u64).encode(s)?;
38        for c in self.iter() {
39            len += c.encode(s)?;
40        }
41        Ok(len)
42    }
43}
44
45#[cfg(feature = "async")]
46#[async_trait]
47impl<T: AsyncEncodable + Sync> AsyncEncodable for HashSet<T> {
48    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
49        let mut len = 0;
50        len += VarInt(self.len() as u64).encode_async(s).await?;
51        for c in self.iter() {
52            len += c.encode_async(s).await?;
53        }
54        Ok(len)
55    }
56}
57
58impl<T: Decodable + std::cmp::Eq + std::hash::Hash> Decodable for HashSet<T> {
59    fn decode<D: Read>(d: &mut D) -> Result<Self> {
60        let len = VarInt::decode(d)?.0;
61        let mut ret = HashSet::new();
62        for _ in 0..len {
63            let entry: T = Decodable::decode(d)?;
64            ret.insert(entry);
65        }
66        Ok(ret)
67    }
68}
69
70#[cfg(feature = "async")]
71#[async_trait]
72impl<T: AsyncDecodable + Send + std::cmp::Eq + std::hash::Hash> AsyncDecodable for HashSet<T> {
73    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
74        let len = VarInt::decode_async(d).await?.0;
75        let mut ret = HashSet::new();
76        for _ in 0..len {
77            let entry: T = AsyncDecodable::decode_async(d).await?;
78            ret.insert(entry);
79        }
80        Ok(ret)
81    }
82}
83
84impl<T: Encodable, U: Encodable> Encodable for BTreeMap<T, U> {
85    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
86        let mut len = 0;
87        len += VarInt(self.len() as u64).encode(s)?;
88        for c in self.iter() {
89            len += c.0.encode(s)?;
90            len += c.1.encode(s)?;
91        }
92        Ok(len)
93    }
94}
95
96#[cfg(feature = "async")]
97#[async_trait]
98impl<T: AsyncEncodable + Sync, U: AsyncEncodable + Sync> AsyncEncodable for BTreeMap<T, U> {
99    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
100        let mut len = 0;
101        len += VarInt(self.len() as u64).encode_async(s).await?;
102        for c in self.iter() {
103            len += c.0.encode_async(s).await?;
104            len += c.1.encode_async(s).await?;
105        }
106        Ok(len)
107    }
108}
109
110impl<T: Decodable + std::cmp::Ord, U: Decodable> Decodable for BTreeMap<T, U> {
111    fn decode<D: Read>(d: &mut D) -> Result<Self> {
112        let len = VarInt::decode(d)?.0;
113        let mut ret = BTreeMap::new();
114        for _ in 0..len {
115            let key: T = Decodable::decode(d)?;
116            let entry: U = Decodable::decode(d)?;
117            ret.insert(key, entry);
118        }
119        Ok(ret)
120    }
121}
122
123#[cfg(feature = "async")]
124#[async_trait]
125impl<T: AsyncDecodable + Send + std::cmp::Ord, U: AsyncDecodable + Send> AsyncDecodable
126    for BTreeMap<T, U>
127{
128    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
129        let len = VarInt::decode_async(d).await?.0;
130        let mut ret = BTreeMap::new();
131        for _ in 0..len {
132            let key: T = AsyncDecodable::decode_async(d).await?;
133            let entry: U = AsyncDecodable::decode_async(d).await?;
134            ret.insert(key, entry);
135        }
136        Ok(ret)
137    }
138}
139
140impl<T: Encodable> Encodable for BTreeSet<T> {
141    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
142        let mut len = 0;
143        len += VarInt(self.len() as u64).encode(s)?;
144        for c in self.iter() {
145            len += c.encode(s)?;
146        }
147        Ok(len)
148    }
149}
150
151#[cfg(feature = "async")]
152#[async_trait]
153impl<T: AsyncEncodable + Sync> AsyncEncodable for BTreeSet<T> {
154    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
155        let mut len = 0;
156        len += VarInt(self.len() as u64).encode_async(s).await?;
157        for c in self.iter() {
158            len += c.encode_async(s).await?;
159        }
160        Ok(len)
161    }
162}
163
164impl<T: Decodable + std::cmp::Ord> Decodable for BTreeSet<T> {
165    fn decode<D: Read>(d: &mut D) -> Result<Self> {
166        let len = VarInt::decode(d)?.0;
167        let mut ret = BTreeSet::new();
168        for _ in 0..len {
169            let key: T = Decodable::decode(d)?;
170            ret.insert(key);
171        }
172        Ok(ret)
173    }
174}
175
176#[cfg(feature = "async")]
177#[async_trait]
178impl<T: AsyncDecodable + Send + std::cmp::Ord> AsyncDecodable for BTreeSet<T> {
179    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
180        let len = VarInt::decode_async(d).await?.0;
181        let mut ret = BTreeSet::new();
182        for _ in 0..len {
183            let key: T = AsyncDecodable::decode_async(d).await?;
184            ret.insert(key);
185        }
186        Ok(ret)
187    }
188}
189
190impl<T: Encodable, U: Encodable> Encodable for HashMap<T, U> {
191    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
192        let mut len = 0;
193        len += VarInt(self.len() as u64).encode(s)?;
194        for c in self.iter() {
195            len += c.0.encode(s)?;
196            len += c.1.encode(s)?;
197        }
198        Ok(len)
199    }
200}
201
202#[cfg(feature = "async")]
203#[async_trait]
204impl<T: AsyncEncodable + Sync, U: AsyncEncodable + Sync> AsyncEncodable for HashMap<T, U> {
205    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
206        let mut len = 0;
207        len += VarInt(self.len() as u64).encode_async(s).await?;
208        for c in self.iter() {
209            len += c.0.encode_async(s).await?;
210            len += c.1.encode_async(s).await?;
211        }
212        Ok(len)
213    }
214}
215
216impl<T: Decodable + std::cmp::Eq + std::hash::Hash, U: Decodable> Decodable for HashMap<T, U> {
217    fn decode<D: Read>(d: &mut D) -> Result<Self> {
218        let len = VarInt::decode(d)?.0;
219        let mut ret = HashMap::new();
220        for _ in 0..len {
221            let key: T = Decodable::decode(d)?;
222            let entry: U = Decodable::decode(d)?;
223            ret.insert(key, entry);
224        }
225        Ok(ret)
226    }
227}
228
229#[cfg(feature = "async")]
230#[async_trait]
231impl<T: AsyncDecodable + Send + std::cmp::Eq + std::hash::Hash, U: AsyncDecodable + Send>
232    AsyncDecodable for HashMap<T, U>
233{
234    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
235        let len = VarInt::decode_async(d).await?.0;
236        let mut ret = HashMap::new();
237        for _ in 0..len {
238            let key: T = AsyncDecodable::decode_async(d).await?;
239            let entry: U = AsyncDecodable::decode_async(d).await?;
240            ret.insert(key, entry);
241        }
242        Ok(ret)
243    }
244}