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 '{value_type}' into a Rust type"
45            ),
46
47            Error::Unsupported { wanted } => {
48                write!(f, "can not deserialize a '{wanted}' from a Nix value")
49            }
50
51            Error::UnexpectedType { expected, got } => {
52                write!(f, "expected type {expected}, but got Nix type {got}")
53            }
54
55            Error::NixErrors { errors } => {
56                writeln!(
57                    f,
58                    "{} occured during Nix evaluation: ",
59                    if errors.len() == 1 { "error" } else { "errors" }
60                )?;
61
62                for err in errors {
63                    writeln!(f, "{}", err.fancy_format_str())?;
64                }
65
66                Ok(())
67            }
68
69            Error::Deserialization(err) => write!(f, "deserialisation error occured: {err}"),
70
71            Error::IntegerConversion { got, need } => {
72                write!(f, "i64({got}) does not fit in a {need}")
73            }
74
75            Error::AmbiguousEnum => write!(f, "could not determine enum variant: ambiguous keys"),
76
77            Error::UnitEnumContent => write!(f, "provided content for unit enum variant"),
78        }
79    }
80}
81
82impl error::Error for Error {
83    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
84        match self {
85            Self::NixErrors { errors, .. } => errors.first().map(|e| e as &dyn error::Error),
86            _ => None,
87        }
88    }
89}
90
91impl serde::de::Error for Error {
92    fn custom<T>(err: T) -> Self
93    where
94        T: Display,
95    {
96        Self::Deserialization(err.to_string())
97    }
98}