1macro_rules! err {
3 ($($tt:tt)*) => {{
4 crate::error::Error::adhoc_from_args(format_args!($($tt)*))
5 }}
6}
7
8pub(crate) use err;
9
10#[derive(Clone, Debug)]
12pub struct Error {
13 kind: ErrorKind,
14}
15
16impl Error {
17 pub(crate) fn adhoc_from_args<'a>(
22 message: core::fmt::Arguments<'a>,
23 ) -> Error {
24 let kind = ErrorKind::Adhoc(AdhocError::from_args(message));
25 Error { kind }
26 }
27}
28
29#[derive(Clone, Debug)]
30enum ErrorKind {
31 Adhoc(AdhocError),
32 Jiff(jiff::Error),
33}
34
35impl core::fmt::Display for Error {
36 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
37 match self.kind {
38 ErrorKind::Adhoc(ref err) => {
39 core::fmt::Display::fmt(&err.message, f)
40 }
41 ErrorKind::Jiff(ref err) => err.fmt(f),
42 }
43 }
44}
45
46#[cfg(feature = "std")]
51impl core::error::Error for Error {
52 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
53 match self.kind {
54 ErrorKind::Adhoc(_) => None,
55 ErrorKind::Jiff(ref err) => Some(err),
56 }
57 }
58}
59
60impl From<jiff::Error> for Error {
61 fn from(e: jiff::Error) -> Error {
62 Error { kind: ErrorKind::Jiff(e) }
63 }
64}
65
66#[derive(Clone, Debug)]
68struct AdhocError {
69 #[cfg(feature = "alloc")]
70 message: alloc::boxed::Box<str>,
71 #[cfg(not(feature = "alloc"))]
72 message: &'static str,
73}
74
75impl AdhocError {
76 fn from_args<'a>(message: core::fmt::Arguments<'a>) -> AdhocError {
77 #[cfg(feature = "alloc")]
78 {
79 AdhocError::from_display(message)
80 }
81 #[cfg(not(feature = "alloc"))]
82 {
83 let message = message.as_str().unwrap_or(
84 "unknown `jiff-icu` error (better error messages require \
85 enabling the `alloc` feature for the `jiff-icu` crate)",
86 );
87 AdhocError::from_static_str(message)
88 }
89 }
90
91 #[cfg(feature = "alloc")]
92 fn from_display<'a>(message: impl core::fmt::Display + 'a) -> AdhocError {
93 use alloc::string::ToString;
94
95 let message = message.to_string().into_boxed_str();
96 AdhocError { message }
97 }
98
99 #[cfg(not(feature = "alloc"))]
100 fn from_static_str(message: &'static str) -> AdhocError {
101 AdhocError { message }
102 }
103}