snix_serde/
error.rs

1//! When serialising Nix goes wrong ...
2
3use std::error;
4use std::fmt::Display;
5
6#[derive(Clone, Debug)]
7pub enum Error {
8    /// Attempted to deserialise an unsupported Nix value (such as a
9    /// function) that can not be represented by the
10    /// [`serde::Deserialize`] trait.
11    Unserializable { value_type: &'static str },
12
13    /// Expected to deserialize a value that is unsupported by Nix.
14    Unsupported { wanted: &'static str },
15
16    /// Expected a specific type, but got something else on the Nix side.
17    UnexpectedType {
18        expected: &'static str,
19        got: &'static str,
20    },
21
22    /// Deserialisation error returned from `serde::de`.
23    Deserialization(String),
24
25    /// Deserialized integer did not fit.
26    IntegerConversion { got: i64, need: &'static str },
27
28    /// Evaluation of the supplied Nix code failed while computing the
29    /// value for deserialisation.
30    NixErrors { errors: Vec<snix_eval::Error> },
31
32    /// Could not determine an externally tagged enum representation.
33    AmbiguousEnum,
34
35    /// Attempted to provide content to a unit enum.
36    UnitEnumContent,
37}
38
39impl Display for Error {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        match self {
42            Error::Unserializable { value_type } => write!(
43                f,
44                "can not deserialise a Nix '{}' into a Rust type",
45                value_type
46            ),
47
48            Error::Unsupported { wanted } => {
49                write!(f, "can not deserialize a '{}' from a Nix value", wanted)
50            }
51
52            Error::UnexpectedType { expected, got } => {
53                write!(f, "expected type {}, but got Nix type {}", expected, got)
54            }
55
56            Error::NixErrors { errors } => {
57                writeln!(
58                    f,
59                    "{} occured during Nix evaluation: ",
60                    if errors.len() == 1 { "error" } else { "errors" }
61                )?;
62
63                for err in errors {
64                    writeln!(f, "{}", err.fancy_format_str())?;
65                }
66
67                Ok(())
68            }
69
70            Error::Deserialization(err) => write!(f, "deserialisation error occured: {}", err),
71
72            Error::IntegerConversion { got, need } => {
73                write!(f, "i64({}) does not fit in a {}", got, need)
74            }
75
76            Error::AmbiguousEnum => write!(f, "could not determine enum variant: ambiguous keys"),
77
78            Error::UnitEnumContent => write!(f, "provided content for unit enum variant"),
79        }
80    }
81}
82
83impl error::Error for Error {
84    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
85        match self {
86            Self::NixErrors { errors, .. } => errors.first().map(|e| e as &dyn error::Error),
87            _ => None,
88        }
89    }
90}
91
92impl serde::de::Error for Error {
93    fn custom<T>(err: T) -> Self
94    where
95        T: Display,
96    {
97        Self::Deserialization(err.to_string())
98    }
99}