Skip to main content

jiff/error/
util.rs

1use crate::{error, util::escape::Byte};
2
3#[derive(Clone, Debug)]
4#[cfg_attr(feature = "defmt", derive(defmt::Format))]
5pub(crate) enum RoundingIncrementError {
6    ForDateTime,
7    ForOffset,
8    ForSignedDuration,
9    ForSpan,
10    ForTime,
11    ForTimestamp,
12}
13
14impl From<RoundingIncrementError> for error::Error {
15    #[cold]
16    #[inline(never)]
17    fn from(err: RoundingIncrementError) -> error::Error {
18        error::ErrorKind::RoundingIncrement(err).into()
19    }
20}
21
22impl error::IntoError for RoundingIncrementError {
23    fn into_error(self) -> error::Error {
24        self.into()
25    }
26}
27
28impl core::fmt::Display for RoundingIncrementError {
29    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
30        use self::RoundingIncrementError::*;
31
32        match *self {
33            ForDateTime => f.write_str("failed rounding datetime"),
34            ForOffset => f.write_str("failed rounding time zone offset"),
35            ForSignedDuration => {
36                f.write_str("failed rounding signed duration")
37            }
38            ForSpan => f.write_str("failed rounding span"),
39            ForTime => f.write_str("failed rounding time"),
40            ForTimestamp => f.write_str("failed rounding timestamp"),
41        }
42    }
43}
44
45#[derive(Clone, Debug)]
46#[cfg_attr(feature = "defmt", derive(defmt::Format))]
47pub(crate) enum ParseIntError {
48    NoDigitsFound,
49    InvalidDigit(u8),
50    TooBig,
51}
52
53impl From<ParseIntError> for error::Error {
54    #[cold]
55    #[inline(never)]
56    fn from(err: ParseIntError) -> error::Error {
57        error::ErrorKind::ParseInt(err).into()
58    }
59}
60
61impl error::IntoError for ParseIntError {
62    fn into_error(self) -> error::Error {
63        self.into()
64    }
65}
66
67impl core::fmt::Display for ParseIntError {
68    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
69        use self::ParseIntError::*;
70
71        match *self {
72            NoDigitsFound => write!(f, "invalid number, no digits found"),
73            InvalidDigit(got) => {
74                write!(f, "invalid digit, expected 0-9 but got {}", Byte(got))
75            }
76            TooBig => {
77                write!(f, "number too big to parse into 64-bit integer")
78            }
79        }
80    }
81}
82
83#[derive(Clone, Debug)]
84#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85pub(crate) enum ParseFractionError {
86    NoDigitsFound,
87    TooManyDigits,
88    InvalidDigit(u8),
89    TooBig,
90}
91
92impl ParseFractionError {
93    pub(crate) const MAX_PRECISION: usize = 9;
94}
95
96impl From<ParseFractionError> for error::Error {
97    #[cold]
98    #[inline(never)]
99    fn from(err: ParseFractionError) -> error::Error {
100        error::ErrorKind::ParseFraction(err).into()
101    }
102}
103
104impl error::IntoError for ParseFractionError {
105    fn into_error(self) -> error::Error {
106        self.into()
107    }
108}
109
110impl core::fmt::Display for ParseFractionError {
111    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
112        use self::ParseFractionError::*;
113
114        match *self {
115            NoDigitsFound => write!(f, "invalid fraction, no digits found"),
116            TooManyDigits => write!(
117                f,
118                "invalid fraction, too many digits \
119                 (at most {max} are allowed)",
120                max = ParseFractionError::MAX_PRECISION,
121            ),
122            InvalidDigit(got) => {
123                write!(
124                    f,
125                    "invalid fractional digit, expected 0-9 but got {}",
126                    Byte(got)
127                )
128            }
129            TooBig => {
130                write!(
131                    f,
132                    "fractional number too big to parse into 64-bit integer"
133                )
134            }
135        }
136    }
137}
138
139#[derive(Clone, Debug)]
140pub(crate) struct OsStrUtf8Error {
141    #[cfg(feature = "std")]
142    value: alloc::boxed::Box<std::ffi::OsStr>,
143}
144
145#[cfg(feature = "std")]
146impl From<&std::ffi::OsStr> for OsStrUtf8Error {
147    #[cold]
148    #[inline(never)]
149    fn from(value: &std::ffi::OsStr) -> OsStrUtf8Error {
150        OsStrUtf8Error { value: value.into() }
151    }
152}
153
154impl From<OsStrUtf8Error> for error::Error {
155    #[cold]
156    #[inline(never)]
157    fn from(err: OsStrUtf8Error) -> error::Error {
158        error::ErrorKind::OsStrUtf8(err).into()
159    }
160}
161
162impl error::IntoError for OsStrUtf8Error {
163    fn into_error(self) -> error::Error {
164        self.into()
165    }
166}
167
168impl core::fmt::Display for OsStrUtf8Error {
169    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
170        #[cfg(feature = "std")]
171        {
172            write!(
173                f,
174                "environment value `{value:?}` is not valid UTF-8",
175                value = self.value
176            )
177        }
178        #[cfg(not(feature = "std"))]
179        {
180            write!(f, "<BUG: SHOULD NOT EXIST>")
181        }
182    }
183}
184
185#[cfg(feature = "defmt")]
186impl defmt::Format for OsStrUtf8Error {
187    fn format(&self, f: defmt::Formatter) {
188        // `OsStr` does not implement `defmt::Format`. Since this error is std-only
189        // and defmt is mainly used in embedded contexts, omitting the value is fine.
190        defmt::write!(f, "OsStrUtf8Error(unavailable)");
191    }
192}