1use std::{
2 fmt,
3 io,
4 path::{Path, PathBuf},
5};
6
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub struct Error {
11 path: Option<PathBuf>,
12 #[source]
13 kind: ErrorKind,
14}
15
16impl Error {
17 pub(crate) fn new(kind: impl Into<ErrorKind>) -> Self {
18 Self { path: None, kind: kind.into() }
19 }
20
21 pub(crate) fn new_with_path<E>(
22 path: impl Into<PathBuf>,
23 ) -> impl FnOnce(E) -> Self
24 where
25 E: Into<ErrorKind>,
26 {
27 |kind| Self::with_path(path)(Self::new(kind))
28 }
29
30 pub(crate) fn with_path(
31 path: impl Into<PathBuf>,
32 ) -> impl FnOnce(Self) -> Self {
33 |this| Self { path: Some(path.into()), ..this }
34 }
35
36 pub fn path(&self) -> Option<&Path> {
37 self.path.as_deref()
38 }
39
40 pub fn kind(&self) -> &ErrorKind {
41 &self.kind
42 }
43}
44
45impl fmt::Display for Error {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 write!(f, "{}", self.kind)?;
48 if let Some(path) = &self.path {
49 write!(f, ", path: {}", path.display())?;
50 }
51 Ok(())
52 }
53}
54
55#[derive(Debug, Error)]
56pub enum ErrorKind {
57 #[error("Failed reading development scripts file")]
58 Read(
59 #[source]
60 #[from]
61 io::Error,
62 ),
63 #[error("Failed decoding script")]
64 Decode(
65 #[from]
66 #[source]
67 serde_json::Error,
68 ),
69 #[error("Unknown key {:?}", .0)]
70 UnknownKey(char),
71}