Skip to main content

nix_compat/wire/ser/
collections.rs

1use std::collections::{BTreeMap, BTreeSet};
2use std::future::Future;
3
4use super::{NixSerialize, NixWrite};
5
6impl<T> NixSerialize for Vec<T>
7where
8    T: NixSerialize + Send + Sync,
9{
10    #[allow(clippy::manual_async_fn)]
11    fn serialize<W>(&self, writer: &mut W) -> impl Future<Output = Result<(), W::Error>> + Send
12    where
13        W: NixWrite,
14    {
15        async move {
16            writer.write_value(&self.len()).await?;
17            for value in self.iter() {
18                writer.write_value(value).await?;
19            }
20            Ok(())
21        }
22    }
23}
24
25impl<K, V> NixSerialize for BTreeMap<K, V>
26where
27    K: NixSerialize + Ord + Send + Sync,
28    V: NixSerialize + Send + Sync,
29{
30    #[allow(clippy::manual_async_fn)]
31    fn serialize<W>(&self, writer: &mut W) -> impl Future<Output = Result<(), W::Error>> + Send
32    where
33        W: NixWrite,
34    {
35        async move {
36            writer.write_value(&self.len()).await?;
37            for (key, value) in self.iter() {
38                writer.write_value(key).await?;
39                writer.write_value(value).await?;
40            }
41            Ok(())
42        }
43    }
44}
45
46impl<T> NixSerialize for BTreeSet<T>
47where
48    T: NixSerialize + Send + Sync,
49{
50    #[allow(clippy::manual_async_fn)]
51    fn serialize<W>(&self, writer: &mut W) -> impl Future<Output = Result<(), W::Error>> + Send
52    where
53        W: NixWrite,
54    {
55        async move {
56            writer.write_value(&self.len()).await?;
57            for value in self.iter() {
58                writer.write_value(value).await?;
59            }
60            Ok(())
61        }
62    }
63}
64
65#[cfg(test)]
66mod test {
67    use std::collections::BTreeMap;
68    use std::fmt;
69
70    use hex_literal::hex;
71    use rstest::rstest;
72    use tokio::io::AsyncWriteExt as _;
73    use tokio_test::io::Builder;
74
75    use crate::wire::ser::{NixSerialize, NixWrite, NixWriter};
76
77    #[rstest]
78    #[case::empty(vec![], &hex!("0000 0000 0000 0000"))]
79    #[case::one(vec![0x29], &hex!("0100 0000 0000 0000 2900 0000 0000 0000"))]
80    #[case::two(vec![0x7469, 10], &hex!("0200 0000 0000 0000 6974 0000 0000 0000 0A00 0000 0000 0000"))]
81    #[tokio::test]
82    async fn test_write_small_vec(#[case] value: Vec<usize>, #[case] data: &[u8]) {
83        let mock = Builder::new().write(data).build();
84        let mut writer = NixWriter::new(mock);
85        writer.write_value(&value).await.unwrap();
86        writer.flush().await.unwrap();
87    }
88
89    fn empty_map() -> BTreeMap<usize, u64> {
90        BTreeMap::new()
91    }
92    macro_rules! map {
93        ($($key:expr => $value:expr),*) => {{
94            let mut ret = BTreeMap::new();
95            $(ret.insert($key, $value);)*
96            ret
97        }};
98    }
99
100    #[rstest]
101    #[case::empty(empty_map(), &hex!("0000 0000 0000 0000"))]
102    #[case::one(map![0x7469usize => 10u64], &hex!("0100 0000 0000 0000 6974 0000 0000 0000 0A00 0000 0000 0000"))]
103    #[tokio::test]
104    async fn test_write_small_btree_map<E>(#[case] value: E, #[case] data: &[u8])
105    where
106        E: NixSerialize + Send + PartialEq + fmt::Debug,
107    {
108        let mock = Builder::new().write(data).build();
109        let mut writer = NixWriter::new(mock);
110        writer.write_value(&value).await.unwrap();
111        writer.flush().await.unwrap();
112    }
113}