1use bstr::ByteSlice;
4use serde::de::value::{MapDeserializer, SeqDeserializer};
5use serde::de::{self, EnumAccess, VariantAccess};
6use snix_eval::{EvalIO, EvalMode, EvaluationBuilder, Value};
7
8use crate::error::Error;
9
10struct NixDeserializer {
11 value: snix_eval::Value,
12}
13
14impl NixDeserializer {
15 fn new(value: Value) -> Self {
16 if let Value::Thunk(thunk) = value {
17 Self::new(thunk.value().clone())
18 } else {
19 Self { value }
20 }
21 }
22}
23
24impl de::IntoDeserializer<'_, Error> for NixDeserializer {
25 type Deserializer = Self;
26
27 fn into_deserializer(self) -> Self::Deserializer {
28 self
29 }
30}
31
32pub fn from_value<T>(value: snix_eval::Value) -> Result<T, Error>
35where
36 T: serde::de::DeserializeOwned,
37{
38 T::deserialize(NixDeserializer::new(value))
39}
40
41pub fn from_str<'code, T>(src: &'code str) -> Result<T, Error>
44where
45 T: serde::Deserialize<'code>,
46{
47 from_str_with_config(src, |b| b)
48}
49
50pub fn from_str_with_config<'code, T, F>(src: &'code str, config: F) -> Result<T, Error>
53where
54 T: serde::Deserialize<'code>,
55 F: for<'co, 'ro, 'env> FnOnce(
56 EvaluationBuilder<'co, 'ro, 'env, Box<dyn EvalIO>>,
57 ) -> EvaluationBuilder<'co, 'ro, 'env, Box<dyn EvalIO>>,
58{
59 let eval = config(EvaluationBuilder::new_pure().mode(EvalMode::Strict)).build();
61 let result = eval.evaluate(src, None);
62
63 if !result.errors.is_empty() {
64 return Err(Error::NixErrors {
65 errors: result.errors,
66 });
67 }
68
69 let de = NixDeserializer::new(result.value.expect("value should be present on success"));
70
71 T::deserialize(de)
72}
73
74fn unexpected(expected: &'static str, got: &Value) -> Error {
75 Error::UnexpectedType {
76 expected,
77 got: got.type_of(),
78 }
79}
80
81fn visit_integer<I: TryFrom<i64>>(v: &Value) -> Result<I, Error> {
82 match v {
83 Value::Integer(i) => I::try_from(*i).map_err(|_| Error::IntegerConversion {
84 got: *i,
85 need: std::any::type_name::<I>(),
86 }),
87
88 _ => Err(unexpected("integer", v)),
89 }
90}
91
92impl<'de> de::Deserializer<'de> for NixDeserializer {
93 type Error = Error;
94
95 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
96 where
97 V: de::Visitor<'de>,
98 {
99 match self.value {
100 Value::Null => visitor.visit_unit(),
101 Value::Bool(b) => visitor.visit_bool(b),
102 Value::Integer(i) => visitor.visit_i64(i),
103 Value::Float(f) => visitor.visit_f64(f),
104 Value::String(s) => visitor.visit_string(s.to_string()),
105 Value::Path(p) => visitor.visit_string(p.to_string_lossy().into()), Value::Attrs(_) => self.deserialize_map(visitor),
107 Value::List(_) => self.deserialize_seq(visitor),
108
109 Value::Closure(_)
111 | Value::Builtin(_)
112 | Value::Thunk(_)
113 | Value::AttrNotFound
114 | Value::Blueprint(_)
115 | Value::DeferredUpvalue(_)
116 | Value::UnresolvedPath(_)
117 | Value::Catchable(_)
118 | Value::FinaliseRequest(_) => Err(Error::Unserializable {
119 value_type: self.value.type_of(),
120 }),
121 }
122 }
123
124 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
125 where
126 V: de::Visitor<'de>,
127 {
128 match self.value {
129 Value::Bool(b) => visitor.visit_bool(b),
130 _ => Err(unexpected("bool", &self.value)),
131 }
132 }
133
134 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
135 where
136 V: de::Visitor<'de>,
137 {
138 visitor.visit_i8(visit_integer(&self.value)?)
139 }
140
141 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
142 where
143 V: de::Visitor<'de>,
144 {
145 visitor.visit_i16(visit_integer(&self.value)?)
146 }
147
148 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
149 where
150 V: de::Visitor<'de>,
151 {
152 visitor.visit_i32(visit_integer(&self.value)?)
153 }
154
155 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
156 where
157 V: de::Visitor<'de>,
158 {
159 visitor.visit_i64(visit_integer(&self.value)?)
160 }
161
162 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
163 where
164 V: de::Visitor<'de>,
165 {
166 visitor.visit_u8(visit_integer(&self.value)?)
167 }
168
169 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
170 where
171 V: de::Visitor<'de>,
172 {
173 visitor.visit_u16(visit_integer(&self.value)?)
174 }
175
176 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
177 where
178 V: de::Visitor<'de>,
179 {
180 visitor.visit_u32(visit_integer(&self.value)?)
181 }
182
183 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
184 where
185 V: de::Visitor<'de>,
186 {
187 visitor.visit_u64(visit_integer(&self.value)?)
188 }
189
190 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
191 where
192 V: de::Visitor<'de>,
193 {
194 if let Value::Float(f) = self.value {
195 return visitor.visit_f32(f as f32);
196 }
197
198 Err(unexpected("float", &self.value))
199 }
200
201 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
202 where
203 V: de::Visitor<'de>,
204 {
205 if let Value::Float(f) = self.value {
206 return visitor.visit_f64(f);
207 }
208
209 Err(unexpected("float", &self.value))
210 }
211
212 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
213 where
214 V: de::Visitor<'de>,
215 {
216 if let Value::String(s) = &self.value {
217 let chars = s.chars().collect::<Vec<_>>();
218 if chars.len() == 1 {
219 return visitor.visit_char(chars[0]);
220 }
221 }
222
223 Err(unexpected("char", &self.value))
224 }
225
226 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
227 where
228 V: de::Visitor<'de>,
229 {
230 if let Value::String(s) = &self.value
231 && let Ok(s) = s.to_str()
232 {
233 return visitor.visit_str(s);
234 }
235
236 Err(unexpected("string", &self.value))
237 }
238
239 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
240 where
241 V: de::Visitor<'de>,
242 {
243 if let Value::String(s) = &self.value
244 && let Ok(s) = s.to_str()
245 {
246 return visitor.visit_str(s);
247 }
248
249 Err(unexpected("string", &self.value))
250 }
251
252 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
253 where
254 V: de::Visitor<'de>,
255 {
256 Err(Error::Unsupported { wanted: "bytes" })
257 }
258
259 fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
260 where
261 V: de::Visitor<'de>,
262 {
263 Err(Error::Unsupported { wanted: "byte_buf" })
264 }
265
266 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
269 where
270 V: de::Visitor<'de>,
271 {
272 if let Value::Null = self.value {
273 visitor.visit_none()
274 } else {
275 visitor.visit_some(self)
276 }
277 }
278
279 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
280 where
281 V: de::Visitor<'de>,
282 {
283 if let Value::Null = self.value {
284 return visitor.visit_unit();
285 }
286
287 Err(unexpected("null", &self.value))
288 }
289
290 fn deserialize_unit_struct<V>(
291 self,
292 _name: &'static str,
293 visitor: V,
294 ) -> Result<V::Value, Self::Error>
295 where
296 V: de::Visitor<'de>,
297 {
298 self.deserialize_unit(visitor)
299 }
300
301 fn deserialize_newtype_struct<V>(
302 self,
303 _name: &'static str,
304 visitor: V,
305 ) -> Result<V::Value, Self::Error>
306 where
307 V: de::Visitor<'de>,
308 {
309 visitor.visit_newtype_struct(self)
310 }
311
312 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
313 where
314 V: de::Visitor<'de>,
315 {
316 if let Value::List(list) = self.value {
317 let mut seq = SeqDeserializer::new(list.into_iter().map(NixDeserializer::new));
318 let result = visitor.visit_seq(&mut seq)?;
319 seq.end()?;
320 return Ok(result);
321 }
322
323 Err(unexpected("list", &self.value))
324 }
325
326 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
327 where
328 V: de::Visitor<'de>,
329 {
330 self.deserialize_seq(visitor)
332 }
333
334 fn deserialize_tuple_struct<V>(
335 self,
336 _name: &'static str,
337 _len: usize,
338 visitor: V,
339 ) -> Result<V::Value, Self::Error>
340 where
341 V: de::Visitor<'de>,
342 {
343 self.deserialize_seq(visitor)
345 }
346
347 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
348 where
349 V: de::Visitor<'de>,
350 {
351 if let Value::Attrs(attrs) = self.value {
352 let mut map = MapDeserializer::new(attrs.into_iter().map(|(k, v)| {
353 (
354 NixDeserializer::new(Value::from(k)),
355 NixDeserializer::new(v),
356 )
357 }));
358 let result = visitor.visit_map(&mut map)?;
359 map.end()?;
360 return Ok(result);
361 }
362
363 Err(unexpected("map", &self.value))
364 }
365
366 fn deserialize_struct<V>(
367 self,
368 _name: &'static str,
369 _fields: &'static [&'static str],
370 visitor: V,
371 ) -> Result<V::Value, Self::Error>
372 where
373 V: de::Visitor<'de>,
374 {
375 self.deserialize_map(visitor)
376 }
377
378 fn deserialize_enum<V>(
381 self,
382 name: &'static str,
383 _variants: &'static [&'static str],
384 visitor: V,
385 ) -> Result<V::Value, Self::Error>
386 where
387 V: de::Visitor<'de>,
388 {
389 match self.value {
390 Value::String(ref s) => {
392 if let Ok(s) = s.to_str() {
393 visitor.visit_enum(de::value::StrDeserializer::new(s))
394 } else {
395 Err(unexpected(name, &self.value))
396 }
397 }
398
399 Value::Attrs(attrs) => visitor.visit_enum(Enum(attrs)),
402
403 _ => Err(unexpected(name, &self.value)),
404 }
405 }
406
407 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
408 where
409 V: de::Visitor<'de>,
410 {
411 self.deserialize_str(visitor)
412 }
413
414 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
415 where
416 V: de::Visitor<'de>,
417 {
418 visitor.visit_unit()
419 }
420}
421
422struct Enum(snix_eval::NixAttrs);
423
424impl<'de> EnumAccess<'de> for Enum {
425 type Error = Error;
426 type Variant = NixDeserializer;
427
428 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
430 where
431 V: de::DeserializeSeed<'de>,
432 {
433 if self.0.len() != 1 {
434 return Err(Error::AmbiguousEnum);
435 }
436
437 let (key, value) = self.0.into_iter().next().expect("length asserted above");
438 if let Ok(k) = key.to_str() {
439 let val = seed.deserialize(de::value::StrDeserializer::<Error>::new(k))?;
440 Ok((val, NixDeserializer::new(value)))
441 } else {
442 Err(unexpected("string", &key.clone().into()))
443 }
444 }
445}
446
447impl<'de> VariantAccess<'de> for NixDeserializer {
448 type Error = Error;
449
450 fn unit_variant(self) -> Result<(), Self::Error> {
451 Err(Error::UnitEnumContent)
455 }
456
457 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
458 where
459 T: de::DeserializeSeed<'de>,
460 {
461 seed.deserialize(self)
462 }
463
464 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
465 where
466 V: de::Visitor<'de>,
467 {
468 de::Deserializer::deserialize_seq(self, visitor)
469 }
470
471 fn struct_variant<V>(
472 self,
473 _fields: &'static [&'static str],
474 visitor: V,
475 ) -> Result<V::Value, Self::Error>
476 where
477 V: de::Visitor<'de>,
478 {
479 de::Deserializer::deserialize_map(self, visitor)
480 }
481}