1mod derivation {
2 use crate::derivation::OutputName;
3 use nix_compat_derive::nix_serde_remote;
4
5 nix_serde_remote!(
6 #[nix(from_str, display)]
7 OutputName
8 );
9}
10
11mod derived_path {
12 use crate::derived_path::{DerivedPath, LegacyDerivedPath};
13 use nix_compat_derive::nix_serde_remote;
14
15 nix_serde_remote!(
16 #[nix(into = "LegacyDerivedPath", from = "LegacyDerivedPath")]
17 DerivedPath
18 );
19 nix_serde_remote!(
20 #[nix(from_str, display)]
21 LegacyDerivedPath
22 );
23}
24
25mod int {
26 use nix_compat_derive::{nix_deserialize_remote, nix_serde_remote};
27
28 nix_deserialize_remote!(
29 #[nix(try_from = "u64")]
30 u8
31 );
32 nix_serde_remote!(
33 #[nix(try_from = "u64", into = "u64")]
34 u16
35 );
36 nix_serde_remote!(
37 #[nix(try_from = "u64", into = "u64")]
38 u32
39 );
40 nix_serde_remote!(
41 #[nix(try_from = "u64", try_into = "u64")]
42 i64
43 );
44}
45
46mod log {
47 nix_compat_derive::nix_serde_remote!(
48 #[nix(try_from = "u64", into = "u64")]
49 crate::log::VerbosityLevel
50 );
51}
52
53mod narinfo {
54 use crate::narinfo::Signature;
55 use crate::wire::de::{NixDeserialize, NixRead};
56
57 nix_compat_derive::nix_serialize_remote!(#[nix(display)] Signature<String>);
58
59 impl NixDeserialize for Signature<String> {
60 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
61 where
62 R: ?Sized + NixRead + Send,
63 {
64 use crate::wire::de::Error;
65 let value: Option<String> = reader.try_read_value().await?;
66 match value {
67 Some(value) => Ok(Some(
68 Signature::<String>::parse(&value).map_err(R::Error::invalid_data)?,
69 )),
70 None => Ok(None),
71 }
72 }
73 }
74}
75
76mod nixhash {
77 use nix_compat_derive::nix_serde_remote;
78
79 use crate::nixhash::{CAHash, HashAlgo};
80 use crate::wire::de::{NixDeserialize, NixRead};
81 use crate::wire::ser::{NixSerialize, NixWrite};
82
83 nix_serde_remote!(
84 #[nix(display, from_str)]
85 HashAlgo
86 );
87
88 impl NixSerialize for CAHash {
89 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
90 where
91 W: NixWrite,
92 {
93 writer.write_value(&self.to_string()).await
94 }
95 }
96
97 impl NixDeserialize for CAHash {
98 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
99 where
100 R: ?Sized + NixRead + Send,
101 {
102 use crate::wire::de::Error;
103 let value: Option<String> = reader.try_read_value().await?;
104 match value {
105 Some(value) => Ok(Some(CAHash::from_nix_hex_str(&value).ok_or_else(|| {
106 R::Error::invalid_data(format!("Invalid cahash {value}"))
107 })?)),
108 None => Ok(None),
109 }
110 }
111 }
112
113 impl NixSerialize for Option<CAHash> {
114 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
115 where
116 W: NixWrite,
117 {
118 match self {
119 Some(value) => writer.write_value(value).await,
120 None => writer.write_value("").await,
121 }
122 }
123 }
124
125 impl NixDeserialize for Option<CAHash> {
126 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
127 where
128 R: ?Sized + NixRead + Send,
129 {
130 use crate::wire::de::Error;
131 let value: Option<String> = reader.try_read_value().await?;
132 match value {
133 Some(value) => {
134 if value.is_empty() {
135 Ok(None)
136 } else {
137 Ok(Some(Some(CAHash::from_nix_hex_str(&value).ok_or_else(
138 || R::Error::invalid_data(format!("Invalid cahash {value}")),
139 )?)))
140 }
141 }
142 None => Ok(None),
143 }
144 }
145 }
146}
147
148mod realisation {
149 use nix_compat_derive::nix_serde_remote;
150
151 use crate::realisation::{DrvOutput, Realisation};
152 use crate::wire::de::NixDeserialize;
153 use crate::wire::ser::NixSerialize;
154
155 nix_serde_remote!(
156 #[nix(from_str, display)]
157 DrvOutput
158 );
159
160 impl NixSerialize for Realisation {
161 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
162 where
163 W: crate::wire::ser::NixWrite,
164 {
165 use crate::wire::ser::Error;
166 let s = serde_json::to_string(&self).map_err(W::Error::custom)?;
167 writer.write_slice(s.as_bytes()).await
168 }
169 }
170
171 impl NixDeserialize for Realisation {
172 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
173 where
174 R: ?Sized + crate::wire::de::NixRead + Send,
175 {
176 use crate::wire::de::Error;
177 if let Some(buf) = reader.try_read_bytes().await? {
178 Ok(Some(
179 serde_json::from_slice(&buf).map_err(R::Error::custom)?,
180 ))
181 } else {
182 Ok(None)
183 }
184 }
185 }
186
187 #[cfg(test)]
188 mod tests {
189 use rstest::rstest;
190
191 use crate::{btree_map, hash_set, realisation::Realisation};
192
193 #[tokio::test]
194 #[rstest]
195 #[case(
196 Realisation {
197 id: "sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!out".parse().unwrap(),
198 out_path: "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3".parse().unwrap(),
199 signatures: hash_set!["cache.nixos.org-1:0CpHca+06TwFp9VkMyz5OaphT3E8mnS+1SWymYlvFaghKSYPCMQ66TS1XPAr1+y9rfQZPLaHrBjjnIRktE/nAA=="],
200 dependent_realisations: btree_map![
201 "sha256:ba7816bf8f01cfea414140de5dae2223b00361a496177a9cf410ff61f20015ad!dev" => "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-dev",
202 "sha256:ba7816bf8f01cfea414140de5dae2223b00361a696177a9cf410ff61f20015ad!bin" => "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-bin",
203
204 ],
205 },
206 "{\"id\":\"sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!out\",\"outPath\":\"7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3\",\"signatures\":[\"cache.nixos.org-1:0CpHca+06TwFp9VkMyz5OaphT3E8mnS+1SWymYlvFaghKSYPCMQ66TS1XPAr1+y9rfQZPLaHrBjjnIRktE/nAA==\"],\"dependentRealisations\":{\"sha256:ba7816bf8f01cfea414140de5dae2223b00361a496177a9cf410ff61f20015ad!dev\":\"7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-dev\",\"sha256:ba7816bf8f01cfea414140de5dae2223b00361a696177a9cf410ff61f20015ad!bin\":\"7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-bin\"}}",
207 )]
208 async fn nix_write_realisation(#[case] value: Realisation, #[case] expected: &str) {
209 use crate::wire::ser::NixWrite as _;
210
211 let mut mock = crate::test::wire::ser::Builder::new()
212 .write_slice(expected.as_bytes())
213 .build();
214 mock.write_value(&value).await.unwrap();
215 }
216
217 #[tokio::test]
218 #[rstest]
219 #[case(
220 Realisation {
221 id: "sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!out".parse().unwrap(),
222 out_path: "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3".parse().unwrap(),
223 signatures: hash_set!["cache.nixos.org-1:0CpHca+06TwFp9VkMyz5OaphT3E8mnS+1SWymYlvFaghKSYPCMQ66TS1XPAr1+y9rfQZPLaHrBjjnIRktE/nAA=="],
224 dependent_realisations: btree_map![
225 "sha256:ba7816bf8f01cfea414140de5dae2223b00361a496177a9cf410ff61f20015ad!dev" => "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-dev",
226 "sha256:ba7816bf8f01cfea414140de5dae2223b00361a696177a9cf410ff61f20015ad!bin" => "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-bin",
227
228 ],
229 },
230 "{\"id\":\"sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!out\",\"outPath\":\"7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3\",\"signatures\":[\"cache.nixos.org-1:0CpHca+06TwFp9VkMyz5OaphT3E8mnS+1SWymYlvFaghKSYPCMQ66TS1XPAr1+y9rfQZPLaHrBjjnIRktE/nAA==\"],\"dependentRealisations\":{\"sha256:ba7816bf8f01cfea414140de5dae2223b00361a496177a9cf410ff61f20015ad!dev\":\"7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-dev\",\"sha256:ba7816bf8f01cfea414140de5dae2223b00361a696177a9cf410ff61f20015ad!bin\":\"7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3-bin\"}}",
231 )]
232 async fn nix_read_realisation(#[case] expected: Realisation, #[case] value: &str) {
233 use crate::wire::de::NixRead as _;
234
235 let mut mock = crate::test::wire::de::Builder::new()
236 .read_slice(value.as_bytes())
237 .build();
238 let actual: Realisation = mock.read_value().await.unwrap();
239 pretty_assertions::assert_eq!(actual, expected);
240 }
241 }
242}
243
244mod store_path {
245 use crate::store_path::StorePath;
246 use crate::wire::de::{NixDeserialize, NixRead};
247 use crate::wire::ser::{NixSerialize, NixWrite};
248
249 impl NixDeserialize for StorePath {
251 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
252 where
253 R: ?Sized + NixRead + Send,
254 {
255 use crate::wire::de::Error;
256 if let Some(buf) = reader.try_read_bytes().await? {
257 let result = StorePath::from_absolute_path(&buf);
258 result.map(Some).map_err(R::Error::invalid_data)
259 } else {
260 Ok(None)
261 }
262 }
263 }
264
265 impl NixSerialize for StorePath {
267 fn serialize<W>(&self, writer: &mut W) -> impl Future<Output = Result<(), W::Error>> + Send
268 where
269 W: NixWrite,
270 {
271 let sp = self.as_absolute_path_fmt();
272 async move { writer.write_display(&sp).await }
273 }
274 }
275
276 impl NixDeserialize for Option<StorePath> {
277 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
278 where
279 R: ?Sized + NixRead + Send,
280 {
281 use crate::wire::de::Error;
282 if let Some(buf) = reader.try_read_bytes().await? {
283 if buf.is_empty() {
284 Ok(Some(None))
285 } else {
286 let result = StorePath::from_absolute_path(&buf);
287 result
288 .map(|r| Some(Some(r)))
289 .map_err(R::Error::invalid_data)
290 }
291 } else {
292 Ok(Some(None))
293 }
294 }
295 }
296
297 impl NixSerialize for Option<StorePath> {
299 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
300 where
301 W: NixWrite,
302 {
303 match self {
304 Some(value) => writer.write_value(value).await,
305 None => writer.write_value("").await,
306 }
307 }
308 }
309}