nix_compat/wire/ser/
collections.rs1use 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}