Skip to main content

nix_compat/wire/
serde.rs

1mod derived_path {
2    use crate::derived_path::{DerivedPath, LegacyDerivedPath};
3    use nix_compat_derive::nix_serde_remote;
4
5    nix_serde_remote!(
6        #[nix(into = "LegacyDerivedPath", from = "LegacyDerivedPath")]
7        DerivedPath
8    );
9    nix_serde_remote!(
10        #[nix(from_str, display)]
11        LegacyDerivedPath
12    );
13}
14
15mod int {
16    use nix_compat_derive::{nix_deserialize_remote, nix_serde_remote};
17
18    nix_deserialize_remote!(
19        #[nix(try_from = "u64")]
20        u8
21    );
22    nix_serde_remote!(
23        #[nix(try_from = "u64", into = "u64")]
24        u16
25    );
26    nix_serde_remote!(
27        #[nix(try_from = "u64", into = "u64")]
28        u32
29    );
30    nix_serde_remote!(
31        #[nix(try_from = "u64", try_into = "u64")]
32        i64
33    );
34}
35
36mod log {
37    nix_compat_derive::nix_serde_remote!(
38        #[nix(try_from = "u64", into = "u64")]
39        crate::log::VerbosityLevel
40    );
41}
42
43mod narinfo {
44    use crate::narinfo::Signature;
45    use crate::wire::de::{NixDeserialize, NixRead};
46
47    nix_compat_derive::nix_serialize_remote!(#[nix(display)] Signature<String>);
48
49    impl NixDeserialize for Signature<String> {
50        async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
51        where
52            R: ?Sized + NixRead + Send,
53        {
54            use crate::wire::de::Error;
55            let value: Option<String> = reader.try_read_value().await?;
56            match value {
57                Some(value) => Ok(Some(
58                    Signature::<String>::parse(&value).map_err(R::Error::invalid_data)?,
59                )),
60                None => Ok(None),
61            }
62        }
63    }
64}
65
66mod nixhash {
67    use nix_compat_derive::nix_serde_remote;
68
69    use crate::nixhash::{CAHash, HashAlgo};
70    use crate::wire::de::{NixDeserialize, NixRead};
71    use crate::wire::ser::{NixSerialize, NixWrite};
72
73    nix_serde_remote!(
74        #[nix(display, from_str)]
75        HashAlgo
76    );
77
78    impl NixSerialize for CAHash {
79        async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
80        where
81            W: NixWrite,
82        {
83            writer.write_value(&self.to_string()).await
84        }
85    }
86
87    impl NixDeserialize for CAHash {
88        async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
89        where
90            R: ?Sized + NixRead + Send,
91        {
92            use crate::wire::de::Error;
93            let value: Option<String> = reader.try_read_value().await?;
94            match value {
95                Some(value) => Ok(Some(CAHash::from_nix_hex_str(&value).ok_or_else(|| {
96                    R::Error::invalid_data(format!("Invalid cahash {value}"))
97                })?)),
98                None => Ok(None),
99            }
100        }
101    }
102
103    impl NixSerialize for Option<CAHash> {
104        async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
105        where
106            W: NixWrite,
107        {
108            match self {
109                Some(value) => writer.write_value(value).await,
110                None => writer.write_value("").await,
111            }
112        }
113    }
114
115    impl NixDeserialize for Option<CAHash> {
116        async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
117        where
118            R: ?Sized + NixRead + Send,
119        {
120            use crate::wire::de::Error;
121            let value: Option<String> = reader.try_read_value().await?;
122            match value {
123                Some(value) => {
124                    if value.is_empty() {
125                        Ok(None)
126                    } else {
127                        Ok(Some(Some(CAHash::from_nix_hex_str(&value).ok_or_else(
128                            || R::Error::invalid_data(format!("Invalid cahash {value}")),
129                        )?)))
130                    }
131                }
132                None => Ok(None),
133            }
134        }
135    }
136}
137
138mod store_path {
139    use crate::store_path::StorePath;
140    use crate::wire::de::{NixDeserialize, NixRead};
141    use crate::wire::ser::{NixSerialize, NixWrite};
142
143    // Custom implementation since FromStr does not use from_absolute_path
144    impl NixDeserialize for StorePath {
145        async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
146        where
147            R: ?Sized + NixRead + Send,
148        {
149            use crate::wire::de::Error;
150            if let Some(buf) = reader.try_read_bytes().await? {
151                let result = StorePath::from_absolute_path(&buf);
152                result.map(Some).map_err(R::Error::invalid_data)
153            } else {
154                Ok(None)
155            }
156        }
157    }
158
159    // Custom implementation since Display does not use absolute paths.
160    impl NixSerialize for StorePath {
161        fn serialize<W>(&self, writer: &mut W) -> impl Future<Output = Result<(), W::Error>> + Send
162        where
163            W: NixWrite,
164        {
165            let sp = self.as_absolute_path_fmt();
166            async move { writer.write_display(&sp).await }
167        }
168    }
169
170    impl NixDeserialize for Option<StorePath> {
171        async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
172        where
173            R: ?Sized + NixRead + Send,
174        {
175            use crate::wire::de::Error;
176            if let Some(buf) = reader.try_read_bytes().await? {
177                if buf.is_empty() {
178                    Ok(Some(None))
179                } else {
180                    let result = StorePath::from_absolute_path(&buf);
181                    result
182                        .map(|r| Some(Some(r)))
183                        .map_err(R::Error::invalid_data)
184                }
185            } else {
186                Ok(Some(None))
187            }
188        }
189    }
190
191    // Writes StorePath or an empty string.
192    impl NixSerialize for Option<StorePath> {
193        async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
194        where
195            W: NixWrite,
196        {
197            match self {
198                Some(value) => writer.write_value(value).await,
199                None => writer.write_value("").await,
200            }
201        }
202    }
203}