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