Skip to main content

wowlab_engine_domain/rotation/
error.rs

1/// Shorthand for [`std::result::Result`] parameterised with this module's [`struct@Error`].
2pub type Result<T> = std::result::Result<T, Error>;
3
4wowlab_engine_macros::define_error! {
5    /// Errors produced while parsing, validating, or compiling a rotation definition.
6    #[derive(Debug)]
7    #[non_exhaustive]
8    pub struct Error {
9        #[source]
10        kind: ErrorKind,
11    }
12
13    #[derive(Debug, thiserror::Error)]
14    enum ErrorKind {
15        #[error("JSON parse error: {0}")]
16        Json(#[from] serde_json::Error),
17
18        #[error("unknown {entity}: {name}")]
19        Unknown { entity: &'static str, name: String },
20
21        #[cfg(feature = "jit")]
22        #[error("compilation error: {0}")]
23        Compilation(String),
24
25        #[error("unknown field: {domain}.{name}")]
26        UnknownField { domain: String, name: String },
27
28        #[error("keyed field {domain}.{name} requires a key")]
29        MissingKey { domain: String, name: String },
30
31        #[error("singleton field {domain}.{name} does not accept a key")]
32        UnexpectedKey { domain: String, name: String },
33
34        #[error("unknown domain: {0}")]
35        UnknownDomain(String),
36
37        #[error("validation failed: {0}")]
38        Validation(String),
39    }
40}
41
42impl Error {
43    fn new(kind: ErrorKind) -> Self {
44        Self { kind }
45    }
46
47    pub fn unknown_spell(name: impl Into<String>) -> Self {
48        Self::unknown("spell", name)
49    }
50
51    fn unknown(entity: &'static str, name: impl Into<String>) -> Self {
52        Self::new(ErrorKind::Unknown {
53            entity,
54            name: name.into(),
55        })
56    }
57
58    pub fn unknown_aura(name: impl Into<String>) -> Self {
59        Self::unknown("aura", name)
60    }
61
62    pub fn unknown_talent(name: impl Into<String>) -> Self {
63        Self::unknown("talent", name)
64    }
65
66    pub fn unknown_resource(name: impl Into<String>) -> Self {
67        Self::unknown("resource", name)
68    }
69
70    pub(crate) fn validation(message: impl Into<String>) -> Self {
71        Self::new(ErrorKind::Validation(message.into()))
72    }
73
74    #[cfg(feature = "jit")]
75    pub(crate) fn compilation(message: impl Into<String>) -> Self {
76        Self::new(ErrorKind::Compilation(message.into()))
77    }
78
79    pub(crate) fn unknown_field(domain: impl Into<String>, name: impl Into<String>) -> Self {
80        Self::new(ErrorKind::UnknownField {
81            domain: domain.into(),
82            name: name.into(),
83        })
84    }
85
86    pub(crate) fn missing_key(domain: impl Into<String>, name: impl Into<String>) -> Self {
87        Self::new(ErrorKind::MissingKey {
88            domain: domain.into(),
89            name: name.into(),
90        })
91    }
92
93    pub(crate) fn unexpected_key(domain: impl Into<String>, name: impl Into<String>) -> Self {
94        Self::new(ErrorKind::UnexpectedKey {
95            domain: domain.into(),
96            name: name.into(),
97        })
98    }
99
100    pub(crate) fn unknown_domain(domain: impl Into<String>) -> Self {
101        Self::new(ErrorKind::UnknownDomain(domain.into()))
102    }
103
104    pub(crate) fn is_unknown(&self) -> bool {
105        matches!(self.kind, ErrorKind::Unknown { .. })
106    }
107
108    #[cfg(test)]
109    pub(crate) fn is_unknown_entity(&self, expected: &str) -> bool {
110        matches!(self.kind, ErrorKind::Unknown { entity, .. } if entity == expected)
111    }
112
113    #[cfg(test)]
114    pub(crate) fn is_unknown_field(&self) -> bool {
115        matches!(self.kind, ErrorKind::UnknownField { .. })
116    }
117
118    #[cfg(test)]
119    pub(crate) fn is_missing_key(&self) -> bool {
120        matches!(self.kind, ErrorKind::MissingKey { .. })
121    }
122
123    #[cfg(test)]
124    pub(crate) fn is_unexpected_key(&self) -> bool {
125        matches!(self.kind, ErrorKind::UnexpectedKey { .. })
126    }
127}
128
129impl From<serde_json::Error> for Error {
130    fn from(source: serde_json::Error) -> Self {
131        Self::new(ErrorKind::Json(source))
132    }
133}