1use crate::num::{JsonInt, JsonUInt};
5use std::{
6 fmt::{self, Display},
7 num::IntErrorKind,
8};
9use thiserror::Error;
10
11#[derive(Debug, PartialEq, Error, Clone)]
15pub struct JsonIntOverflowError {
16 kind: JsonIntOverflowKind,
17}
18
19#[derive(Debug, PartialEq, Eq, Error, Clone)]
21pub struct JsonIntParseError {
22 kind: JsonIntParseErrorKind,
23}
24
25#[derive(Debug, PartialEq, Error, Clone)]
28pub struct JsonFloatConvertError {
29 kind: JsonFloatConvertErrorKind,
30}
31
32#[derive(Debug, PartialEq, Eq, Error, Clone)]
34pub struct JsonFloatParseError {
35 kind: JsonFloatParseErrorKind,
36}
37
38impl JsonIntOverflowError {
39 pub(crate) fn int_pos_overflow(src: i64) -> Self {
40 Self {
41 kind: JsonIntOverflowKind::IntPos(src),
42 }
43 }
44
45 pub(crate) fn int_pos_overflow_u(src: u64) -> Self {
46 Self {
47 kind: JsonIntOverflowKind::IntPosU(src),
48 }
49 }
50
51 pub(crate) fn int_neg_overflow(src: i64) -> Self {
52 Self {
53 kind: JsonIntOverflowKind::IntNeg(src),
54 }
55 }
56
57 pub(crate) fn uint_pos_overflow(src: u64) -> Self {
58 Self {
59 kind: JsonIntOverflowKind::UIntPos(src),
60 }
61 }
62
63 pub(crate) fn negative_uint(src: i64) -> Self {
64 Self {
65 kind: JsonIntOverflowKind::UIntNeg(src),
66 }
67 }
68
69 pub(crate) fn zero_non_zero_uint() -> Self {
70 Self {
71 kind: JsonIntOverflowKind::NonZeroUIntZero,
72 }
73 }
74
75 pub(crate) fn fractional(src: f64) -> Self {
76 Self {
77 kind: JsonIntOverflowKind::Fractional(src),
78 }
79 }
80
81 pub(crate) fn int_float_pos_overflow(src: f64) -> Self {
82 Self {
83 kind: JsonIntOverflowKind::FloatPos(src),
84 }
85 }
86
87 pub(crate) fn int_float_neg_overflow(src: f64) -> Self {
88 Self {
89 kind: JsonIntOverflowKind::FloatNeg(src),
90 }
91 }
92}
93
94impl JsonIntParseError {
95 pub(crate) fn int_parse_error(src: &str, err: &IntErrorKind) -> Self {
96 Self {
97 kind: match err {
98 IntErrorKind::PosOverflow => JsonIntParseErrorKind::IntPosOverflow(src.to_string()),
99 IntErrorKind::NegOverflow => JsonIntParseErrorKind::IntNegOverflow(src.to_string()),
100 IntErrorKind::Zero => unreachable!(), _ => JsonIntParseErrorKind::InvalidFormat(src.to_string()),
102 },
103 }
104 }
105
106 pub(crate) fn parse_conversion_err(src: &str, err: &JsonIntOverflowError) -> Self {
107 Self {
108 kind: match err.kind {
109 JsonIntOverflowKind::IntPosU(_) | JsonIntOverflowKind::IntPos(_) => {
110 JsonIntParseErrorKind::IntPosOverflow(src.to_string())
111 }
112 JsonIntOverflowKind::IntNeg(_) => JsonIntParseErrorKind::IntNegOverflow(src.to_string()),
113 JsonIntOverflowKind::UIntPos(_) => JsonIntParseErrorKind::UIntPosOverflow(src.to_string()),
114 JsonIntOverflowKind::UIntNeg(_) => JsonIntParseErrorKind::UIntNegOverflow(src.to_string()),
115 JsonIntOverflowKind::NonZeroUIntZero => JsonIntParseErrorKind::NonZeroUIntZero(src.to_string()),
116 JsonIntOverflowKind::Fractional(_)
117 | JsonIntOverflowKind::FloatPos(_)
118 | JsonIntOverflowKind::FloatNeg(_) => JsonIntParseErrorKind::InvalidFormat(src.to_string()),
119 },
120 }
121 }
122
123 pub(crate) fn uint_parse_error(src: &str, err: &IntErrorKind) -> Self {
124 Self {
125 kind: match err {
126 IntErrorKind::PosOverflow => JsonIntParseErrorKind::UIntPosOverflow(src.to_string()),
127 IntErrorKind::NegOverflow => JsonIntParseErrorKind::UIntNegOverflow(src.to_string()),
128 IntErrorKind::Zero => unreachable!(), _ => JsonIntParseErrorKind::InvalidFormat(src.to_string()),
130 },
131 }
132 }
133
134 pub(crate) fn non_zero_uint_parse_error(src: &str, err: &IntErrorKind) -> Self {
135 Self {
136 kind: match err {
137 IntErrorKind::PosOverflow => JsonIntParseErrorKind::UIntPosOverflow(src.to_string()),
138 IntErrorKind::NegOverflow => JsonIntParseErrorKind::UIntNegOverflow(src.to_string()),
139 IntErrorKind::Zero => JsonIntParseErrorKind::NonZeroUIntZero(src.to_string()),
140 _ => JsonIntParseErrorKind::InvalidFormat(src.to_string()),
141 },
142 }
143 }
144}
145
146impl JsonFloatConvertError {
147 pub(crate) fn infinite_or_nan(src: f64) -> Self {
148 Self {
149 kind: JsonFloatConvertErrorKind::InfinityOrNaN(src),
150 }
151 }
152}
153
154impl JsonFloatParseError {
155 pub(crate) fn infinite_or_nan(src: &str) -> Self {
156 Self {
157 kind: JsonFloatParseErrorKind::InfinityOrNaN(src.to_string()),
158 }
159 }
160
161 pub(crate) fn leading_plus_sign(src: &str) -> Self {
162 Self {
163 kind: JsonFloatParseErrorKind::LeadingPlusSign(src.to_string()),
164 }
165 }
166
167 pub(crate) fn leading_zeros(src: &str) -> Self {
168 Self {
169 kind: JsonFloatParseErrorKind::LeadingZeros(src.to_string()),
170 }
171 }
172
173 pub(crate) fn nothing_after_decimal_point(src: &str) -> Self {
174 Self {
175 kind: JsonFloatParseErrorKind::NothingAfterDecimalPoint(src.to_string()),
176 }
177 }
178
179 pub(crate) fn nothing_before_decimal_point(src: &str) -> Self {
180 Self {
181 kind: JsonFloatParseErrorKind::NothingBeforeDecimalPoint(src.to_string()),
182 }
183 }
184
185 pub(crate) fn f64_parse_error(src: &str) -> Self {
186 Self {
187 kind: JsonFloatParseErrorKind::InvalidFormat(src.to_string()),
188 }
189 }
190}
191
192#[derive(Debug, PartialEq, Clone)]
193enum JsonIntOverflowKind {
194 IntPos(i64),
195 IntPosU(u64),
196 IntNeg(i64),
197 UIntPos(u64),
198 UIntNeg(i64),
199 NonZeroUIntZero,
200 Fractional(f64),
201 FloatPos(f64),
202 FloatNeg(f64),
203}
204
205#[derive(Debug, PartialEq, Eq, Clone)]
206enum JsonIntParseErrorKind {
207 IntPosOverflow(String),
208 IntNegOverflow(String),
209 UIntPosOverflow(String),
210 UIntNegOverflow(String),
211 NonZeroUIntZero(String),
212 InvalidFormat(String),
213}
214
215#[derive(Debug, PartialEq, Clone)]
216enum JsonFloatConvertErrorKind {
217 InfinityOrNaN(f64),
218}
219
220#[derive(Debug, PartialEq, Eq, Clone)]
221enum JsonFloatParseErrorKind {
222 InfinityOrNaN(String),
223 NothingBeforeDecimalPoint(String),
224 NothingAfterDecimalPoint(String),
225 LeadingPlusSign(String),
226 LeadingZeros(String),
227 InvalidFormat(String),
228}
229
230impl Display for JsonIntOverflowError {
231 #[inline(always)]
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 self.kind.fmt(f)
234 }
235}
236
237impl Display for JsonIntParseError {
238 #[inline(always)]
239 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240 self.kind.fmt(f)
241 }
242}
243
244impl Display for JsonFloatConvertError {
245 #[inline(always)]
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 self.kind.fmt(f)
248 }
249}
250
251impl Display for JsonFloatParseError {
252 #[inline(always)]
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 self.kind.fmt(f)
255 }
256}
257
258impl Display for JsonIntOverflowKind {
259 #[inline]
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 match self {
262 Self::IntPos(src) => write!(
263 f,
264 "value {src} is above the range of JsonInt values [{}..{}]",
265 JsonInt::MIN,
266 JsonInt::MAX
267 ),
268 Self::IntPosU(src) => write!(
269 f,
270 "value {src} is above the range of JsonInt values [{}..{}]",
271 JsonInt::MIN,
272 JsonInt::MAX
273 ),
274 Self::IntNeg(src) => write!(
275 f,
276 "value {src} is below the range of JsonInt values [{}..{}]",
277 JsonInt::MIN,
278 JsonInt::MAX
279 ),
280 Self::UIntPos(src) => write!(
281 f,
282 "value {src} is above the range of JsonUInt values [0..{}]",
283 JsonUInt::MAX
284 ),
285 Self::UIntNeg(src) => {
286 write!(f, "attempt to convert a negative value {src} into a JsonUInt",)
287 }
288 Self::NonZeroUIntZero => {
289 write!(f, "attempt to convert a zero value into a JsonNonZeroUInt",)
290 }
291 Self::Fractional(src) => write!(f, "attempt to convert a fractional value {src} into a JsonInt"),
292 Self::FloatPos(src) => write!(
293 f,
294 "floating-point value {src} is above the range of JsonInt values [{}..{}]",
295 JsonInt::MIN,
296 JsonInt::MAX
297 ),
298 Self::FloatNeg(src) => write!(
299 f,
300 "floating-point value {src} is below the range of JsonInt values [{}..{}]",
301 JsonInt::MIN,
302 JsonInt::MAX
303 ),
304 }
305 }
306}
307
308impl Display for JsonIntParseErrorKind {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 match self {
311 Self::IntPosOverflow(src) => write!(
312 f,
313 "string '{src}' represents a value above the range of JsonInt values [{}..{}]",
314 JsonInt::MIN,
315 JsonInt::MAX
316 ),
317 Self::IntNegOverflow(src) => write!(
318 f,
319 "string '{src}' represents a value below the range of JsonInt values [{}..{}]",
320 JsonInt::MIN,
321 JsonInt::MAX
322 ),
323 Self::UIntPosOverflow(src) => write!(
324 f,
325 "string '{src}' represents a value above the range of JsonUInt values [0..{}]",
326 JsonUInt::MAX
327 ),
328 Self::UIntNegOverflow(src) => {
329 write!(
330 f,
331 "string '{src}' represents a value below the range of JsonUInt values [0..{}]",
332 JsonUInt::MAX
333 )
334 }
335 Self::NonZeroUIntZero(src) => write!(
336 f,
337 "string '{src}' represents a zero value, which is not a valid JsonNonZeroUInt"
338 ),
339 Self::InvalidFormat(src) => write!(f, "string '{src}' is not a valid representation of a JSON integer"),
340 }
341 }
342}
343
344impl Display for JsonFloatConvertErrorKind {
345 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346 match self {
347 Self::InfinityOrNaN(src) => write!(f, "cannot convert from a non-finite float {src}"),
348 }
349 }
350}
351
352impl Display for JsonFloatParseErrorKind {
353 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354 match self {
355 Self::InfinityOrNaN(src) => {
356 write!(
357 f,
358 "string '{src}' is not a valid JsonFloat as it is not a finite number"
359 )
360 }
361 Self::NothingBeforeDecimalPoint(src) => write!(f, "missing digits before the decimal point in '{src}'"),
362 Self::NothingAfterDecimalPoint(src) => write!(f, "missing digits after the decimal point in '{src}'"),
363 Self::LeadingPlusSign(src) => write!(f, "string '{src}' includes a leading plus sign"),
364 Self::LeadingZeros(src) => write!(f, "string '{src}' includes leading zeros"),
365 Self::InvalidFormat(src) => write!(f, "string '{src}' is not a valid representation of a float"),
366 }
367 }
368}