1use crate::wire::de::Error;
2use crate::{
3 narinfo::Signature,
4 nixhash::CAHash,
5 store_path::StorePath,
6 wire::{
7 de::{NixDeserialize, NixRead},
8 ser::{NixSerialize, NixWrite},
9 },
10};
11use nix_compat_derive::{NixDeserialize, NixSerialize};
12use std::future::Future;
13
14#[derive(Clone, Debug, NixDeserialize, NixSerialize)]
16#[nix(from = "u64", into = "u64")]
17pub struct IgnoredZero;
18impl From<u64> for IgnoredZero {
19 fn from(_: u64) -> Self {
20 IgnoredZero
21 }
22}
23
24impl From<IgnoredZero> for u64 {
25 fn from(_: IgnoredZero) -> Self {
26 0
27 }
28}
29
30#[derive(Debug, NixSerialize)]
31pub struct TraceLine {
32 have_pos: IgnoredZero,
33 hint: String,
34}
35
36#[derive(NixSerialize)]
40pub struct NixError {
41 #[nix(version = "26..")]
42 type_: &'static str,
43
44 #[nix(version = "26..")]
45 level: u64,
46
47 #[nix(version = "26..")]
48 name: &'static str,
49
50 msg: String,
51 #[nix(version = "26..")]
52 have_pos: IgnoredZero,
53
54 #[nix(version = "26..")]
55 traces: Vec<TraceLine>,
56
57 #[nix(version = "..=25")]
58 exit_status: u64,
59}
60
61impl NixError {
62 pub fn new(msg: String) -> Self {
63 Self {
64 type_: "Error",
65 level: 0, name: "Error",
67 msg,
68 have_pos: IgnoredZero {},
69 traces: vec![],
70 exit_status: 1,
71 }
72 }
73}
74
75nix_compat_derive::nix_serialize_remote!(#[nix(display)] Signature<String>);
76
77impl NixDeserialize for Signature<String> {
78 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
79 where
80 R: ?Sized + NixRead + Send,
81 {
82 let value: Option<String> = reader.try_read_value().await?;
83 match value {
84 Some(value) => Ok(Some(
85 Signature::<String>::parse(&value).map_err(R::Error::invalid_data)?,
86 )),
87 None => Ok(None),
88 }
89 }
90}
91
92impl NixSerialize for CAHash {
93 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
94 where
95 W: NixWrite,
96 {
97 writer.write_value(&self.to_nix_nixbase32_string()).await
98 }
99}
100
101impl NixSerialize for Option<CAHash> {
102 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
103 where
104 W: NixWrite,
105 {
106 match self {
107 Some(value) => writer.write_value(value).await,
108 None => writer.write_value("").await,
109 }
110 }
111}
112
113impl NixDeserialize for CAHash {
114 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
115 where
116 R: ?Sized + NixRead + Send,
117 {
118 let value: Option<String> = reader.try_read_value().await?;
119 match value {
120 Some(value) => Ok(Some(CAHash::from_nix_hex_str(&value).ok_or_else(|| {
121 R::Error::invalid_data(format!("Invalid cahash {}", value))
122 })?)),
123 None => Ok(None),
124 }
125 }
126}
127
128impl NixDeserialize for Option<CAHash> {
129 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
130 where
131 R: ?Sized + NixRead + Send,
132 {
133 let value: Option<String> = reader.try_read_value().await?;
134 match value {
135 Some(value) => {
136 if value.is_empty() {
137 Ok(None)
138 } else {
139 Ok(Some(Some(CAHash::from_nix_hex_str(&value).ok_or_else(
140 || R::Error::invalid_data(format!("Invalid cahash {}", value)),
141 )?)))
142 }
143 }
144 None => Ok(None),
145 }
146 }
147}
148
149impl NixSerialize for Option<UnkeyedValidPathInfo> {
150 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
151 where
152 W: NixWrite,
153 {
154 match self {
155 Some(value) => {
156 writer.write_value(&true).await?;
157 writer.write_value(value).await
158 }
159 None => writer.write_value(&false).await,
160 }
161 }
162}
163
164impl NixDeserialize for StorePath<String> {
166 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
167 where
168 R: ?Sized + NixRead + Send,
169 {
170 use crate::wire::de::Error;
171 if let Some(buf) = reader.try_read_bytes().await? {
172 let result = StorePath::<String>::from_absolute_path(&buf);
173 result.map(Some).map_err(R::Error::invalid_data)
174 } else {
175 Ok(None)
176 }
177 }
178}
179
180impl NixDeserialize for Option<StorePath<String>> {
181 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
182 where
183 R: ?Sized + NixRead + Send,
184 {
185 use crate::wire::de::Error;
186 if let Some(buf) = reader.try_read_bytes().await? {
187 if buf.is_empty() {
188 Ok(Some(None))
189 } else {
190 let result = StorePath::<String>::from_absolute_path(&buf);
191 result
192 .map(|r| Some(Some(r)))
193 .map_err(R::Error::invalid_data)
194 }
195 } else {
196 Ok(Some(None))
197 }
198 }
199}
200
201impl<S> NixSerialize for StorePath<S>
203where
204 S: AsRef<str>,
205{
206 fn serialize<W>(&self, writer: &mut W) -> impl Future<Output = Result<(), W::Error>> + Send
207 where
208 W: NixWrite,
209 {
210 let sp = self.to_absolute_path();
211 async move { writer.write_value(&sp).await }
212 }
213}
214
215impl NixSerialize for Option<StorePath<String>> {
217 async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
218 where
219 W: NixWrite,
220 {
221 match self {
222 Some(value) => writer.write_value(value).await,
223 None => writer.write_value("").await,
224 }
225 }
226}
227
228#[derive(NixSerialize, Debug, Clone, Default, PartialEq)]
229pub struct UnkeyedValidPathInfo {
230 pub deriver: Option<StorePath<String>>,
231 pub nar_hash: String,
232 pub references: Vec<StorePath<String>>,
233 pub registration_time: u64,
234 pub nar_size: u64,
235 pub ultimate: bool,
236 pub signatures: Vec<Signature<String>>,
237 pub ca: Option<CAHash>,
238}
239
240#[derive(NixDeserialize)]
242pub struct QueryValidPaths {
243 pub paths: Vec<StorePath<String>>,
245
246 #[nix(version = "27..")]
248 pub substitute: bool,
249}
250
251#[derive(Debug)]
253pub struct NarHash([u8; 32]);
254
255impl std::ops::Deref for NarHash {
256 type Target = [u8; 32];
257
258 fn deref(&self) -> &Self::Target {
259 &self.0
260 }
261}
262
263impl NixDeserialize for NarHash {
264 async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
265 where
266 R: ?Sized + NixRead + Send,
267 {
268 if let Some(bytes) = reader.try_read_bytes().await? {
269 let result = data_encoding::HEXLOWER
270 .decode(bytes.as_ref())
271 .map_err(R::Error::invalid_data)?;
272 Ok(Some(NarHash(result.try_into().map_err(|_| {
273 R::Error::invalid_data("incorrect length")
274 })?)))
275 } else {
276 Ok(None)
277 }
278 }
279}
280
281#[derive(NixDeserialize, Debug)]
283pub struct AddToStoreNarRequest {
284 pub path: StorePath<String>,
286 pub deriver: Option<StorePath<String>>,
288 pub nar_hash: NarHash,
290 pub references: Vec<StorePath<String>>,
292 pub registration_time: u64,
294 pub nar_size: u64,
296 pub ultimate: bool,
298 pub signatures: Vec<Signature<String>>,
300 pub ca: Option<CAHash>,
302 pub repair: bool,
304 pub dont_check_sigs: bool,
306}