target_spec_json/
error.rs1use core::fmt;
4use std::io;
5
6pub(crate) type Result<T, E = Error> = core::result::Result<T, E>;
7
8#[derive(Debug)]
9pub struct Error(ErrorKind);
10
11#[derive(Debug)]
16pub(crate) enum ErrorKind {
17 Io(io::Error),
18
19 Json(serde_json::Error),
20
21 Other(Box<str>),
22 WithContext(Box<str>, Option<Box<dyn std::error::Error + Send + Sync>>),
23}
24
25impl Error {
26 pub(crate) fn new(e: impl Into<ErrorKind>) -> Self {
27 Self(e.into())
28 }
29}
30
31impl fmt::Display for Error {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 match &self.0 {
34 ErrorKind::Io(e) => fmt::Display::fmt(e, f),
35 ErrorKind::Json(e) => fmt::Display::fmt(e, f),
36 ErrorKind::Other(e) | ErrorKind::WithContext(e, ..) => fmt::Display::fmt(e, f),
37 }
38 }
39}
40
41impl std::error::Error for Error {
42 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
43 match &self.0 {
44 ErrorKind::Io(e) => e.source(),
45 ErrorKind::Json(e) => e.source(),
46 ErrorKind::Other(_) => None,
47 ErrorKind::WithContext(_, e) => Some(&**e.as_ref()?),
48 }
49 }
50}
51
52impl From<io::Error> for ErrorKind {
53 fn from(e: io::Error) -> Self {
54 Self::Io(e)
55 }
56}
57impl From<String> for ErrorKind {
58 fn from(e: String) -> Self {
59 Self::Other(e.into_boxed_str())
60 }
61}
62impl From<serde_json::Error> for ErrorKind {
63 fn from(e: serde_json::Error) -> Self {
64 Self::Json(e)
65 }
66}
67
68pub(crate) trait Context<T, E> {
76 fn with_context<C, F>(self, context: F) -> Result<T, Error>
80 where
81 C: fmt::Display,
82 F: FnOnce() -> C;
83}
84impl<T, E> Context<T, E> for Result<T, E>
85where
86 E: std::error::Error + Send + Sync + 'static,
87{
88 fn with_context<C, F>(self, context: F) -> Result<T, Error>
101 where
102 C: fmt::Display,
103 F: FnOnce() -> C,
104 {
105 match self {
106 Ok(ok) => Ok(ok),
107 Err(e) => Err(Error(ErrorKind::WithContext(
108 context().to_string().into_boxed_str(),
109 Some(Box::new(e)),
110 ))),
111 }
112 }
113}
114impl<T> Context<T, core::convert::Infallible> for Option<T> {
115 fn with_context<C, F>(self, context: F) -> Result<T, Error>
125 where
126 C: fmt::Display,
127 F: FnOnce() -> C,
128 {
129 match self {
130 Some(ok) => Ok(ok),
131 None => {
132 Err(Error(ErrorKind::WithContext(context().to_string().into_boxed_str(), None)))
133 }
134 }
135 }
136}