1use std::{any::TypeId, borrow::Cow, num::IntErrorKind, str::FromStr};
5
6use crate::{
7 Error, IntoFragment, Type, err,
8 error::diagnostic::number::{invalid_number_format, nan_not_allowed, number_out_of_range},
9 return_error,
10 value::is::{IsFloat, IsInt, IsUint},
11};
12
13pub fn parse_primitive_int<'a, T>(fragment: impl IntoFragment<'a>) -> Result<T, Error>
14where
15 T: IsInt + 'static,
16{
17 if TypeId::of::<T>() == TypeId::of::<i8>() {
18 Ok(cast::<T, i8>(parse_i8(fragment)?))
19 } else if TypeId::of::<T>() == TypeId::of::<i16>() {
20 Ok(cast::<T, i16>(parse_i16(fragment)?))
21 } else if TypeId::of::<T>() == TypeId::of::<i32>() {
22 Ok(cast::<T, i32>(parse_i32(fragment)?))
23 } else if TypeId::of::<T>() == TypeId::of::<i64>() {
24 Ok(cast::<T, i64>(parse_i64(fragment)?))
25 } else if TypeId::of::<T>() == TypeId::of::<i128>() {
26 Ok(cast::<T, i128>(parse_i128(fragment)?))
27 } else {
28 unreachable!();
29 }
30}
31
32pub fn parse_primitive_uint<'a, T>(fragment: impl IntoFragment<'a>) -> Result<T, Error>
33where
34 T: IsUint + 'static,
35{
36 if TypeId::of::<T>() == TypeId::of::<u8>() {
37 Ok(cast::<T, u8>(parse_u8(fragment)?))
38 } else if TypeId::of::<T>() == TypeId::of::<u16>() {
39 Ok(cast::<T, u16>(parse_u16(fragment)?))
40 } else if TypeId::of::<T>() == TypeId::of::<u32>() {
41 Ok(cast::<T, u32>(parse_u32(fragment)?))
42 } else if TypeId::of::<T>() == TypeId::of::<u64>() {
43 Ok(cast::<T, u64>(parse_u64(fragment)?))
44 } else if TypeId::of::<T>() == TypeId::of::<u128>() {
45 Ok(cast::<T, u128>(parse_u128(fragment)?))
46 } else {
47 unreachable!();
48 }
49}
50
51pub fn parse_float<'a, T>(fragment: impl IntoFragment<'a>) -> Result<T, Error>
52where
53 T: IsFloat + 'static,
54{
55 let fragment = fragment.into_fragment();
56 if fragment.text().to_lowercase().contains("nan") {
57 return_error!(nan_not_allowed());
58 }
59
60 if TypeId::of::<T>() == TypeId::of::<f32>() {
61 Ok(cast::<T, f32>(parse_f32(fragment.clone())?))
62 } else if TypeId::of::<T>() == TypeId::of::<f64>() {
63 Ok(cast::<T, f64>(parse_f64(fragment)?))
64 } else {
65 unreachable!();
66 }
67}
68
69fn cast_float_to_int<T: 'static>(f: f64) -> T {
70 if TypeId::of::<T>() == TypeId::of::<i8>() {
71 cast::<T, i8>(f as i8)
72 } else if TypeId::of::<T>() == TypeId::of::<i16>() {
73 cast::<T, i16>(f as i16)
74 } else if TypeId::of::<T>() == TypeId::of::<i32>() {
75 cast::<T, i32>(f as i32)
76 } else if TypeId::of::<T>() == TypeId::of::<i64>() {
77 cast::<T, i64>(f as i64)
78 } else if TypeId::of::<T>() == TypeId::of::<i128>() {
79 cast::<T, i128>(f as i128)
80 } else if TypeId::of::<T>() == TypeId::of::<u8>() {
81 cast::<T, u8>(f as u8)
82 } else if TypeId::of::<T>() == TypeId::of::<u16>() {
83 cast::<T, u16>(f as u16)
84 } else if TypeId::of::<T>() == TypeId::of::<u32>() {
85 cast::<T, u32>(f as u32)
86 } else if TypeId::of::<T>() == TypeId::of::<u64>() {
87 cast::<T, u64>(f as u64)
88 } else if TypeId::of::<T>() == TypeId::of::<u128>() {
89 cast::<T, u128>(f as u128)
90 } else {
91 unreachable!()
92 }
93}
94
95fn cast<T: 'static, U: 'static>(v: U) -> T {
96 assert_eq!(TypeId::of::<T>(), TypeId::of::<U>());
98 unsafe { std::mem::transmute_copy(&v) }
99}
100
101trait TypeInfo {
102 fn type_enum() -> Type;
103}
104
105impl TypeInfo for i8 {
106 fn type_enum() -> Type {
107 Type::Int1
108 }
109}
110impl TypeInfo for i16 {
111 fn type_enum() -> Type {
112 Type::Int2
113 }
114}
115impl TypeInfo for i32 {
116 fn type_enum() -> Type {
117 Type::Int4
118 }
119}
120impl TypeInfo for i64 {
121 fn type_enum() -> Type {
122 Type::Int8
123 }
124}
125impl TypeInfo for i128 {
126 fn type_enum() -> Type {
127 Type::Int16
128 }
129}
130impl TypeInfo for u8 {
131 fn type_enum() -> Type {
132 Type::Uint1
133 }
134}
135impl TypeInfo for u16 {
136 fn type_enum() -> Type {
137 Type::Uint2
138 }
139}
140impl TypeInfo for u32 {
141 fn type_enum() -> Type {
142 Type::Uint4
143 }
144}
145impl TypeInfo for u64 {
146 fn type_enum() -> Type {
147 Type::Uint8
148 }
149}
150impl TypeInfo for u128 {
151 fn type_enum() -> Type {
152 Type::Uint16
153 }
154}
155impl TypeInfo for f32 {
156 fn type_enum() -> Type {
157 Type::Float4
158 }
159}
160impl TypeInfo for f64 {
161 fn type_enum() -> Type {
162 Type::Float8
163 }
164}
165
166#[inline]
167fn parse_signed_generic<'a, T>(fragment: impl IntoFragment<'a>) -> Result<T, Error>
168where
169 T: FromStr<Err = std::num::ParseIntError> + TypeInfo + 'static,
170{
171 let fragment = fragment.into_fragment();
172 let raw_value = fragment.text();
173
174 let needs_trimming = raw_value.as_bytes().first().map_or(false, |&b| b.is_ascii_whitespace())
176 || raw_value.as_bytes().last().map_or(false, |&b| b.is_ascii_whitespace());
177 let has_underscores = raw_value.as_bytes().contains(&b'_');
178
179 let value = match (needs_trimming, has_underscores) {
180 (false, false) => Cow::Borrowed(raw_value), (true, false) => Cow::Borrowed(raw_value.trim()),
184 (false, true) => Cow::Owned(raw_value.replace('_', "")),
185 (true, true) => Cow::Owned(raw_value.trim().replace('_', "")),
186 };
187
188 if value.is_empty() {
189 return_error!(invalid_number_format(fragment, T::type_enum()));
190 }
191
192 match value.parse::<T>() {
193 Ok(v) => Ok(v),
194 Err(err) => match err.kind() {
195 IntErrorKind::Empty => {
196 err!(invalid_number_format(fragment, T::type_enum()))
197 }
198 IntErrorKind::InvalidDigit => {
199 if let Ok(f) = value.parse::<f64>() {
200 let truncated = f.trunc();
201 let type_enum = T::type_enum();
202 let in_range = match type_enum {
203 Type::Int1 => {
204 truncated >= i8::MIN as f64 && truncated <= i8::MAX as f64
205 }
206 Type::Int2 => {
207 truncated >= i16::MIN as f64 && truncated <= i16::MAX as f64
208 }
209 Type::Int4 => {
210 truncated >= i32::MIN as f64 && truncated <= i32::MAX as f64
211 }
212 Type::Int8 => {
213 truncated >= i64::MIN as f64 && truncated <= i64::MAX as f64
214 }
215 Type::Int16 => {
216 truncated >= i128::MIN as f64 && truncated <= i128::MAX as f64
217 }
218 _ => false,
219 };
220 if in_range {
221 Ok(cast_float_to_int::<T>(truncated))
222 } else {
223 err!(number_out_of_range(fragment, type_enum, None))
224 }
225 } else {
226 err!(invalid_number_format(fragment, T::type_enum()))
227 }
228 }
229 IntErrorKind::PosOverflow => {
230 err!(number_out_of_range(fragment, T::type_enum(), None))
231 }
232 IntErrorKind::NegOverflow => {
233 err!(number_out_of_range(fragment, T::type_enum(), None))
234 }
235 IntErrorKind::Zero => {
236 err!(invalid_number_format(fragment, T::type_enum()))
237 }
238 &_ => unreachable!("{}", err),
239 },
240 }
241}
242
243#[inline]
244fn parse_unsigned_generic<'a, T>(fragment: impl IntoFragment<'a>) -> Result<T, Error>
245where
246 T: FromStr<Err = std::num::ParseIntError> + TypeInfo + 'static,
247{
248 let fragment = fragment.into_fragment();
249 let raw_value = fragment.text();
250
251 let needs_trimming = raw_value.as_bytes().first().map_or(false, |&b| b.is_ascii_whitespace())
253 || raw_value.as_bytes().last().map_or(false, |&b| b.is_ascii_whitespace());
254 let has_underscores = raw_value.as_bytes().contains(&b'_');
255
256 let value = match (needs_trimming, has_underscores) {
257 (false, false) => Cow::Borrowed(raw_value), (true, false) => Cow::Borrowed(raw_value.trim()),
261 (false, true) => Cow::Owned(raw_value.replace('_', "")),
262 (true, true) => Cow::Owned(raw_value.trim().replace('_', "")),
263 };
264
265 if value.is_empty() {
266 return_error!(invalid_number_format(fragment, T::type_enum()));
267 }
268
269 match value.parse::<T>() {
270 Ok(v) => Ok(v),
271 Err(err) => {
272 match err.kind() {
273 IntErrorKind::Empty => {
274 err!(invalid_number_format(fragment, T::type_enum()))
275 }
276 IntErrorKind::InvalidDigit => {
277 if let Ok(f) = value.parse::<f64>() {
278 if f < 0.0 {
281 return_error!(number_out_of_range(
282 fragment,
283 T::type_enum(),
284 None
285 ));
286 }
287 let truncated = f.trunc();
288 let type_enum = T::type_enum();
289 let in_range = match type_enum {
290 Type::Uint1 => truncated >= 0.0 && truncated <= u8::MAX as f64,
291 Type::Uint2 => truncated >= 0.0 && truncated <= u16::MAX as f64,
292 Type::Uint4 => truncated >= 0.0 && truncated <= u32::MAX as f64,
293 Type::Uint8 => truncated >= 0.0 && truncated <= u64::MAX as f64,
294 Type::Uint16 => {
295 truncated >= 0.0 && truncated <= u128::MAX as f64
296 }
297 _ => false,
298 };
299 if in_range {
300 Ok(cast_float_to_int::<T>(truncated))
301 } else {
302 err!(number_out_of_range(fragment, type_enum, None))
303 }
304 } else {
305 if value.contains("-") {
306 err!(number_out_of_range(fragment, T::type_enum(), None))
307 } else {
308 err!(invalid_number_format(fragment, T::type_enum()))
309 }
310 }
311 }
312 IntErrorKind::PosOverflow => {
313 err!(number_out_of_range(fragment, T::type_enum(), None))
314 }
315 IntErrorKind::NegOverflow => {
316 err!(number_out_of_range(fragment, T::type_enum(), None))
317 }
318 IntErrorKind::Zero => {
319 err!(invalid_number_format(fragment, T::type_enum()))
320 }
321 &_ => unreachable!("{}", err),
322 }
323 }
324 }
325}
326
327#[inline]
328fn parse_float_generic<'a, T>(fragment: impl IntoFragment<'a>) -> Result<T, Error>
329where
330 T: FromStr<Err = std::num::ParseFloatError> + Copy + TypeInfo + PartialEq + 'static,
331{
332 let fragment = fragment.into_fragment();
333 let raw_value = fragment.text();
334
335 let needs_trimming = raw_value.as_bytes().first().map_or(false, |&b| b.is_ascii_whitespace())
337 || raw_value.as_bytes().last().map_or(false, |&b| b.is_ascii_whitespace());
338 let has_underscores = raw_value.as_bytes().contains(&b'_');
339
340 let value = match (needs_trimming, has_underscores) {
341 (false, false) => Cow::Borrowed(raw_value), (true, false) => Cow::Borrowed(raw_value.trim()),
345 (false, true) => Cow::Owned(raw_value.replace('_', "")),
346 (true, true) => Cow::Owned(raw_value.trim().replace('_', "")),
347 };
348
349 if value.is_empty() {
350 return_error!(invalid_number_format(fragment, T::type_enum()));
351 }
352
353 match value.parse::<T>() {
354 Ok(v) => {
355 if TypeId::of::<T>() == TypeId::of::<f32>() {
356 let v_f32 = cast::<f32, T>(v);
357 if v_f32 == f32::INFINITY || v_f32 == f32::NEG_INFINITY {
358 return_error!(number_out_of_range(fragment, T::type_enum(), None));
359 }
360 } else if TypeId::of::<T>() == TypeId::of::<f64>() {
361 let v_f64 = cast::<f64, T>(v);
362 if v_f64 == f64::INFINITY || v_f64 == f64::NEG_INFINITY {
363 return_error!(number_out_of_range(fragment, T::type_enum(), None));
364 }
365 }
366 Ok(v)
367 }
368 Err(_) => err!(invalid_number_format(fragment, T::type_enum())),
369 }
370}
371
372#[inline]
373fn parse_f32<'a>(fragment: impl IntoFragment<'a>) -> Result<f32, Error> {
374 parse_float_generic::<f32>(fragment)
375}
376
377#[inline]
378fn parse_f64<'a>(fragment: impl IntoFragment<'a>) -> Result<f64, Error> {
379 parse_float_generic::<f64>(fragment)
380}
381
382#[inline]
383fn parse_i8<'a>(fragment: impl IntoFragment<'a>) -> Result<i8, Error> {
384 parse_signed_generic::<i8>(fragment)
385}
386
387#[inline]
388fn parse_i16<'a>(fragment: impl IntoFragment<'a>) -> Result<i16, Error> {
389 parse_signed_generic::<i16>(fragment)
390}
391
392#[inline]
393fn parse_i32<'a>(fragment: impl IntoFragment<'a>) -> Result<i32, Error> {
394 parse_signed_generic::<i32>(fragment)
395}
396
397#[inline]
398fn parse_i64<'a>(fragment: impl IntoFragment<'a>) -> Result<i64, Error> {
399 parse_signed_generic::<i64>(fragment)
400}
401
402#[inline]
403fn parse_i128<'a>(fragment: impl IntoFragment<'a>) -> Result<i128, Error> {
404 parse_signed_generic::<i128>(fragment)
405}
406
407#[inline]
408fn parse_u8<'a>(fragment: impl IntoFragment<'a>) -> Result<u8, Error> {
409 parse_unsigned_generic::<u8>(fragment)
410}
411
412#[inline]
413fn parse_u16<'a>(fragment: impl IntoFragment<'a>) -> Result<u16, Error> {
414 parse_unsigned_generic::<u16>(fragment)
415}
416
417#[inline]
418fn parse_u32<'a>(fragment: impl IntoFragment<'a>) -> Result<u32, Error> {
419 parse_unsigned_generic::<u32>(fragment)
420}
421
422#[inline]
423fn parse_u64<'a>(fragment: impl IntoFragment<'a>) -> Result<u64, Error> {
424 parse_unsigned_generic::<u64>(fragment)
425}
426
427#[inline]
428fn parse_u128<'a>(fragment: impl IntoFragment<'a>) -> Result<u128, Error> {
429 parse_unsigned_generic::<u128>(fragment)
430}
431
432#[cfg(test)]
433#[allow(clippy::approx_constant)]
434mod tests {
435
436 mod i8 {
437 use crate::{OwnedFragment, parse_primitive_int};
438
439 #[test]
440 fn test_valid_zero() {
441 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("0")), Ok(0));
442 }
443
444 #[test]
445 fn test_valid_positive() {
446 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("42")), Ok(42));
447 }
448
449 #[test]
450 fn test_valid_negative() {
451 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("-42")), Ok(-42));
452 }
453
454 #[test]
455 fn test_valid_max() {
456 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("127")), Ok(127));
457 }
458
459 #[test]
460 fn test_valid_min() {
461 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("-128")), Ok(-128));
462 }
463
464 #[test]
465 fn test_overflow_positive() {
466 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("128")).is_err());
467 }
468
469 #[test]
470 fn test_overflow_negative() {
471 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("-129")).is_err());
472 }
473
474 #[test]
475 fn test_invalid_text() {
476 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("abc")).is_err());
477 }
478
479 #[test]
480 fn test_invalid_empty() {
481 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("")).is_err());
482 }
483
484 #[test]
485 fn test_invalid_whitespace() {
486 assert!(parse_primitive_int::<i8>(OwnedFragment::testing(" ")).is_err());
487 }
488
489 #[test]
490 fn test_float_truncation_positive() {
491 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("42.9")), Ok(42));
492 }
493
494 #[test]
495 fn test_float_truncation_negative() {
496 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("-42.9")), Ok(-42));
497 }
498
499 #[test]
500 fn test_float_truncation_zero() {
501 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("0.0")), Ok(0));
502 }
503
504 #[test]
505 fn test_float_truncation_negative_zero() {
506 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("-0.0")), Ok(0));
507 }
508
509 #[test]
510 fn test_float_truncation_max() {
511 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("127.9")), Ok(127));
512 }
513
514 #[test]
515 fn test_float_truncation_min() {
516 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("-128.9")), Ok(-128));
517 }
518
519 #[test]
520 fn test_float_scientific_notation() {
521 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("1e+2")), Ok(100));
522 }
523
524 #[test]
525 fn test_float_scientific_small() {
526 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("1.23e-1")), Ok(0));
527 }
528
529 #[test]
530 fn test_float_overflow_positive() {
531 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("128.0")).is_err());
532 }
533
534 #[test]
535 fn test_float_overflow_negative() {
536 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("-129.0")).is_err());
537 }
538
539 #[test]
540 fn test_float_overflow_scientific() {
541 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("1e3")).is_err());
542 }
543
544 #[test]
545 fn test_invalid_float_format() {
546 assert!(parse_primitive_int::<i8>(OwnedFragment::testing("1.2.3")).is_err());
547 }
548
549 #[test]
550 fn trimming_leading_space() {
551 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing(" 42")), Ok(42));
552 }
553
554 #[test]
555 fn trimming_trailing_space() {
556 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("42 ")), Ok(42));
557 }
558
559 #[test]
560 fn trimming_both_spaces() {
561 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing(" 42 ")), Ok(42));
562 }
563
564 #[test]
565 fn trimming_negative_leading_space() {
566 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing(" -42")), Ok(-42));
567 }
568
569 #[test]
570 fn trimming_negative_trailing_space() {
571 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing("-42 ")), Ok(-42));
572 }
573
574 #[test]
575 fn trimming_negative_both_spaces() {
576 assert_eq!(parse_primitive_int::<i8>(OwnedFragment::testing(" -42 ")), Ok(-42));
577 }
578 }
579
580 mod i16 {
581 use crate::{OwnedFragment, parse_primitive_int};
582
583 #[test]
584 fn test_valid_zero() {
585 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("0")), Ok(0));
586 }
587
588 #[test]
589 fn test_valid_positive() {
590 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("1000")), Ok(1000));
591 }
592
593 #[test]
594 fn test_valid_negative() {
595 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("-1000")), Ok(-1000));
596 }
597
598 #[test]
599 fn test_valid_max() {
600 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("32767")), Ok(32767));
601 }
602
603 #[test]
604 fn test_valid_min() {
605 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("-32768")), Ok(-32768));
606 }
607
608 #[test]
609 fn test_overflow_positive() {
610 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("32768")).is_err());
611 }
612
613 #[test]
614 fn test_overflow_negative() {
615 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("-32769")).is_err());
616 }
617
618 #[test]
619 fn test_invalid_text() {
620 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("hello")).is_err());
621 }
622
623 #[test]
624 fn test_invalid_empty() {
625 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("")).is_err());
626 }
627
628 #[test]
629 fn test_float_truncation_positive() {
630 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("1000.7")), Ok(1000));
631 }
632
633 #[test]
634 fn test_float_truncation_negative() {
635 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("-1000.7")), Ok(-1000));
636 }
637
638 #[test]
639 fn test_float_truncation_max() {
640 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("32767.9")), Ok(32767));
641 }
642
643 #[test]
644 fn test_float_truncation_min() {
645 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("-32768.9")), Ok(-32768));
646 }
647
648 #[test]
649 fn test_float_scientific_notation() {
650 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("1.5e3")), Ok(1500));
651 }
652
653 #[test]
654 fn test_float_overflow_positive() {
655 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("32768.0")).is_err());
656 }
657
658 #[test]
659 fn test_float_overflow_negative() {
660 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("-32769.0")).is_err());
661 }
662
663 #[test]
664 fn test_float_overflow_scientific() {
665 assert!(parse_primitive_int::<i16>(OwnedFragment::testing("1e5")).is_err());
666 }
667
668 #[test]
669 fn trimming_leading_space() {
670 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing(" 1000")), Ok(1000));
671 }
672
673 #[test]
674 fn trimming_trailing_space() {
675 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("1000 ")), Ok(1000));
676 }
677
678 #[test]
679 fn trimming_both_spaces() {
680 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing(" 1000 ")), Ok(1000));
681 }
682
683 #[test]
684 fn trimming_negative_leading_space() {
685 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing(" -1000")), Ok(-1000));
686 }
687
688 #[test]
689 fn trimming_negative_trailing_space() {
690 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing("-1000 ")), Ok(-1000));
691 }
692
693 #[test]
694 fn trimming_negative_both_spaces() {
695 assert_eq!(parse_primitive_int::<i16>(OwnedFragment::testing(" -1000 ")), Ok(-1000));
696 }
697 }
698
699 mod i32 {
700 use crate::{OwnedFragment, parse_primitive_int};
701
702 #[test]
703 fn test_valid_zero() {
704 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("0")), Ok(0));
705 }
706
707 #[test]
708 fn test_valid_positive() {
709 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("1000000")), Ok(1000000));
710 }
711
712 #[test]
713 fn test_valid_negative() {
714 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("-1000000")), Ok(-1000000));
715 }
716
717 #[test]
718 fn test_valid_max() {
719 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("2147483647")), Ok(2147483647));
720 }
721
722 #[test]
723 fn test_valid_min() {
724 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("-2147483648")), Ok(-2147483648));
725 }
726
727 #[test]
728 fn test_overflow_positive() {
729 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("2147483648")).is_err());
730 }
731
732 #[test]
733 fn test_overflow_negative() {
734 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("-2147483649")).is_err());
735 }
736
737 #[test]
738 fn test_invalid_text() {
739 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("not_a_number")).is_err());
740 }
741
742 #[test]
743 fn test_invalid_empty() {
744 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("")).is_err());
745 }
746
747 #[test]
748 fn test_float_truncation_positive() {
749 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("3.14")), Ok(3));
750 }
751
752 #[test]
753 fn test_float_truncation_negative() {
754 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("-3.14")), Ok(-3));
755 }
756
757 #[test]
758 fn test_float_truncation_zero() {
759 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("0.0")), Ok(0));
760 }
761
762 #[test]
763 fn test_float_truncation_negative_zero() {
764 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("-0.0")), Ok(0));
765 }
766
767 #[test]
768 fn test_float_truncation_large() {
769 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("42.999")), Ok(42));
770 }
771
772 #[test]
773 fn test_float_scientific_notation() {
774 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("1e+2")), Ok(100));
775 }
776
777 #[test]
778 fn test_float_scientific_decimal() {
779 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("2.5e3")), Ok(2500));
780 }
781
782 #[test]
783 fn test_float_scientific_negative() {
784 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("-1.5e2")), Ok(-150));
785 }
786
787 #[test]
788 fn test_float_scientific_small() {
789 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("1.23e-1")), Ok(0));
790 }
791
792 #[test]
793 fn test_float_scientific_very_small() {
794 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("9.9e-1")), Ok(0));
795 }
796
797 #[test]
798 fn test_float_overflow_positive() {
799 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("2147483648.0")).is_err());
800 }
801
802 #[test]
803 fn test_float_overflow_negative() {
804 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("-2147483649.0")).is_err());
805 }
806
807 #[test]
808 fn test_float_overflow_scientific() {
809 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("1e10")).is_err());
810 }
811
812 #[test]
813 fn test_invalid_float_format() {
814 assert!(parse_primitive_int::<i32>(OwnedFragment::testing("1.2.3")).is_err());
815 }
816
817 #[test]
818 fn trimming_leading_space() {
819 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing(" 123")), Ok(123));
820 }
821
822 #[test]
823 fn trimming_trailing_space() {
824 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("123 ")), Ok(123));
825 }
826
827 #[test]
828 fn trimming_both_spaces() {
829 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing(" 123 ")), Ok(123));
830 }
831
832 #[test]
833 fn trimming_negative_leading_space() {
834 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing(" -456")), Ok(-456));
835 }
836
837 #[test]
838 fn trimming_negative_trailing_space() {
839 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing("-456 ")), Ok(-456));
840 }
841
842 #[test]
843 fn trimming_negative_both_spaces() {
844 assert_eq!(parse_primitive_int::<i32>(OwnedFragment::testing(" -456 ")), Ok(-456));
845 }
846 }
847
848 mod i64 {
849 use crate::{OwnedFragment, parse_primitive_int};
850
851 #[test]
852 fn test_valid_zero() {
853 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("0")), Ok(0));
854 }
855
856 #[test]
857 fn test_valid_positive() {
858 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("1000000000")), Ok(1000000000));
859 }
860
861 #[test]
862 fn test_valid_negative() {
863 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("-1000000000")), Ok(-1000000000));
864 }
865
866 #[test]
867 fn test_valid_max() {
868 assert_eq!(
869 parse_primitive_int::<i64>(OwnedFragment::testing("9223372036854775807")),
870 Ok(i64::MAX)
871 );
872 }
873
874 #[test]
875 fn test_valid_min() {
876 assert_eq!(
877 parse_primitive_int::<i64>(OwnedFragment::testing("-9223372036854775808")),
878 Ok(i64::MIN)
879 );
880 }
881
882 #[test]
883 fn test_overflow_positive() {
884 assert!(parse_primitive_int::<i64>(OwnedFragment::testing("9223372036854775808")).is_err());
885 }
886
887 #[test]
888 fn test_overflow_negative() {
889 assert!(parse_primitive_int::<i64>(OwnedFragment::testing("-9223372036854775809")).is_err());
890 }
891
892 #[test]
893 fn test_invalid_text() {
894 assert!(parse_primitive_int::<i64>(OwnedFragment::testing("invalid")).is_err());
895 }
896
897 #[test]
898 fn test_invalid_empty() {
899 assert!(parse_primitive_int::<i64>(OwnedFragment::testing("")).is_err());
900 }
901
902 #[test]
903 fn test_float_truncation_positive() {
904 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("12345.67")), Ok(12345));
905 }
906
907 #[test]
908 fn test_float_truncation_negative() {
909 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("-12345.67")), Ok(-12345));
910 }
911
912 #[test]
913 fn test_float_scientific_notation() {
914 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("1e10")), Ok(10000000000));
915 }
916
917 #[test]
918 fn test_float_scientific_large() {
919 assert_eq!(
920 parse_primitive_int::<i64>(OwnedFragment::testing("9.223e18")),
921 Ok(9223000000000000000)
922 );
923 }
924
925 #[test]
926 fn test_float_overflow_positive() {
927 assert!(parse_primitive_int::<i64>(OwnedFragment::testing("1e19")).is_err());
928 }
929
930 #[test]
931 fn test_float_overflow_negative() {
932 assert!(parse_primitive_int::<i64>(OwnedFragment::testing("-1e19")).is_err());
933 }
934
935 #[test]
936 fn trimming_leading_space() {
937 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing(" 1000000000")), Ok(1000000000));
938 }
939
940 #[test]
941 fn trimming_trailing_space() {
942 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("1000000000 ")), Ok(1000000000));
943 }
944
945 #[test]
946 fn trimming_both_spaces() {
947 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing(" 1000000000 ")), Ok(1000000000));
948 }
949
950 #[test]
951 fn trimming_negative_leading_space() {
952 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing(" -1000000000")), Ok(-1000000000));
953 }
954
955 #[test]
956 fn trimming_negative_trailing_space() {
957 assert_eq!(parse_primitive_int::<i64>(OwnedFragment::testing("-1000000000 ")), Ok(-1000000000));
958 }
959
960 #[test]
961 fn trimming_negative_both_spaces() {
962 assert_eq!(
963 parse_primitive_int::<i64>(OwnedFragment::testing(" -1000000000 ")),
964 Ok(-1000000000)
965 );
966 }
967 }
968
969 mod i128 {
970 use crate::{OwnedFragment, parse_primitive_int};
971
972 #[test]
973 fn test_valid_zero() {
974 assert_eq!(parse_primitive_int::<i128>(OwnedFragment::testing("0")), Ok(0));
975 }
976
977 #[test]
978 fn test_valid_positive() {
979 assert_eq!(
980 parse_primitive_int::<i128>(OwnedFragment::testing("12345678901234567890")),
981 Ok(12345678901234567890)
982 );
983 }
984
985 #[test]
986 fn test_valid_negative() {
987 assert_eq!(
988 parse_primitive_int::<i128>(OwnedFragment::testing("-12345678901234567890")),
989 Ok(-12345678901234567890)
990 );
991 }
992
993 #[test]
994 fn test_valid_max() {
995 assert_eq!(
996 parse_primitive_int::<i128>(OwnedFragment::testing(&i128::MAX.to_string())),
997 Ok(i128::MAX)
998 );
999 }
1000
1001 #[test]
1002 fn test_valid_min() {
1003 assert_eq!(
1004 parse_primitive_int::<i128>(OwnedFragment::testing(&i128::MIN.to_string())),
1005 Ok(i128::MIN)
1006 );
1007 }
1008
1009 #[test]
1010 fn test_overflow_positive() {
1011 assert!(parse_primitive_int::<i128>(OwnedFragment::testing(
1012 "170141183460469231731687303715884105728"
1013 ))
1014 .is_err());
1015 }
1016
1017 #[test]
1018 fn test_overflow_negative() {
1019 assert!(parse_primitive_int::<i128>(OwnedFragment::testing(
1020 "-170141183460469231731687303715884105729"
1021 ))
1022 .is_err());
1023 }
1024
1025 #[test]
1026 fn test_invalid_text() {
1027 assert!(parse_primitive_int::<i128>(OwnedFragment::testing("abc")).is_err());
1028 }
1029
1030 #[test]
1031 fn test_invalid_empty() {
1032 assert!(parse_primitive_int::<i128>(OwnedFragment::testing("")).is_err());
1033 }
1034
1035 #[test]
1036 fn test_float_truncation_positive() {
1037 assert_eq!(parse_primitive_int::<i128>(OwnedFragment::testing("123456789.123")), Ok(123456789));
1038 }
1039
1040 #[test]
1041 fn test_float_truncation_negative() {
1042 assert_eq!(
1043 parse_primitive_int::<i128>(OwnedFragment::testing("-123456789.123")),
1044 Ok(-123456789)
1045 );
1046 }
1047
1048 #[test]
1049 fn test_float_scientific_notation() {
1050 assert_eq!(
1051 parse_primitive_int::<i128>(OwnedFragment::testing("1e20")),
1052 Ok(100000000000000000000)
1053 );
1054 }
1055
1056 #[test]
1057 fn test_float_overflow_positive() {
1058 assert!(parse_primitive_int::<i128>(OwnedFragment::testing("1e40")).is_err());
1059 }
1060
1061 #[test]
1062 fn test_float_overflow_negative() {
1063 assert!(parse_primitive_int::<i128>(OwnedFragment::testing("-1e40")).is_err());
1064 }
1065
1066 #[test]
1067 fn trimming_leading_space() {
1068 assert_eq!(
1069 parse_primitive_int::<i128>(OwnedFragment::testing(" 12345678901234567890")),
1070 Ok(12345678901234567890)
1071 );
1072 }
1073
1074 #[test]
1075 fn trimming_trailing_space() {
1076 assert_eq!(
1077 parse_primitive_int::<i128>(OwnedFragment::testing("12345678901234567890 ")),
1078 Ok(12345678901234567890)
1079 );
1080 }
1081
1082 #[test]
1083 fn trimming_both_spaces() {
1084 assert_eq!(
1085 parse_primitive_int::<i128>(OwnedFragment::testing(" 12345678901234567890 ")),
1086 Ok(12345678901234567890)
1087 );
1088 }
1089
1090 #[test]
1091 fn trimming_negative_leading_space() {
1092 assert_eq!(
1093 parse_primitive_int::<i128>(OwnedFragment::testing(" -12345678901234567890")),
1094 Ok(-12345678901234567890)
1095 );
1096 }
1097
1098 #[test]
1099 fn trimming_negative_trailing_space() {
1100 assert_eq!(
1101 parse_primitive_int::<i128>(OwnedFragment::testing("-12345678901234567890 ")),
1102 Ok(-12345678901234567890)
1103 );
1104 }
1105
1106 #[test]
1107 fn trimming_negative_both_spaces() {
1108 assert_eq!(
1109 parse_primitive_int::<i128>(OwnedFragment::testing(" -12345678901234567890 ")),
1110 Ok(-12345678901234567890)
1111 );
1112 }
1113 }
1114
1115 mod u8 {
1116 use crate::{OwnedFragment, parse_primitive_uint};
1117
1118 #[test]
1119 fn test_valid_zero() {
1120 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("0")), Ok(0));
1121 }
1122
1123 #[test]
1124 fn test_valid_positive() {
1125 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("128")), Ok(128));
1126 }
1127
1128 #[test]
1129 fn test_valid_max() {
1130 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("255")), Ok(255));
1131 }
1132
1133 #[test]
1134 fn test_overflow_positive() {
1135 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("256")).is_err());
1136 }
1137
1138 #[test]
1139 fn test_overflow_negative() {
1140 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("-1")).is_err());
1141 }
1142
1143 #[test]
1144 fn test_invalid_text() {
1145 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("abc")).is_err());
1146 }
1147
1148 #[test]
1149 fn test_invalid_empty() {
1150 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("")).is_err());
1151 }
1152
1153 #[test]
1154 fn test_float_truncation_positive() {
1155 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("128.9")), Ok(128));
1156 }
1157
1158 #[test]
1159 fn test_float_truncation_zero() {
1160 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("0.0")), Ok(0));
1161 }
1162
1163 #[test]
1164 fn test_float_truncation_max() {
1165 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("255.9")), Ok(255));
1166 }
1167
1168 #[test]
1169 fn test_float_scientific_notation() {
1170 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("2e2")), Ok(200));
1171 }
1172
1173 #[test]
1174 fn test_float_scientific_small() {
1175 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("1.23e-1")), Ok(0));
1176 }
1177
1178 #[test]
1179 fn test_float_negative() {
1180 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("-1.5")).is_err());
1181 }
1182
1183 #[test]
1184 fn test_float_negative_zero() {
1185 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("-0.1")).is_err());
1186 }
1187
1188 #[test]
1189 fn test_float_overflow_positive() {
1190 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("256.0")).is_err());
1191 }
1192
1193 #[test]
1194 fn test_float_overflow_scientific() {
1195 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("1e3")).is_err());
1196 }
1197
1198 #[test]
1199 fn test_invalid_float_format() {
1200 assert!(parse_primitive_uint::<u8>(OwnedFragment::testing("1.2.3")).is_err());
1201 }
1202
1203 #[test]
1204 fn trimming_leading_space() {
1205 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing(" 128")), Ok(128));
1206 }
1207
1208 #[test]
1209 fn trimming_trailing_space() {
1210 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing("128 ")), Ok(128));
1211 }
1212
1213 #[test]
1214 fn trimming_both_spaces() {
1215 assert_eq!(parse_primitive_uint::<u8>(OwnedFragment::testing(" 128 ")), Ok(128));
1216 }
1217 }
1218
1219 mod u16 {
1220 use crate::{OwnedFragment, parse_primitive_uint};
1221
1222 #[test]
1223 fn test_valid_zero() {
1224 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("0")), Ok(0));
1225 }
1226
1227 #[test]
1228 fn test_valid_positive() {
1229 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("32768")), Ok(32768));
1230 }
1231
1232 #[test]
1233 fn test_valid_max() {
1234 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("65535")), Ok(65535));
1235 }
1236
1237 #[test]
1238 fn test_overflow_positive() {
1239 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("65536")).is_err());
1240 }
1241
1242 #[test]
1243 fn test_overflow_negative() {
1244 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("-1")).is_err());
1245 }
1246
1247 #[test]
1248 fn test_invalid_text() {
1249 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("invalid")).is_err());
1250 }
1251
1252 #[test]
1253 fn test_invalid_empty() {
1254 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("")).is_err());
1255 }
1256
1257 #[test]
1258 fn test_float_truncation_positive() {
1259 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("32768.7")), Ok(32768));
1260 }
1261
1262 #[test]
1263 fn test_float_truncation_max() {
1264 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("65535.9")), Ok(65535));
1265 }
1266
1267 #[test]
1268 fn test_float_scientific_notation() {
1269 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("6.5e4")), Ok(65000));
1270 }
1271
1272 #[test]
1273 fn test_float_negative() {
1274 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("-100.0")).is_err());
1275 }
1276
1277 #[test]
1278 fn test_float_overflow_positive() {
1279 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("65536.0")).is_err());
1280 }
1281
1282 #[test]
1283 fn test_float_overflow_scientific() {
1284 assert!(parse_primitive_uint::<u16>(OwnedFragment::testing("1e5")).is_err());
1285 }
1286
1287 #[test]
1288 fn trimming_leading_space() {
1289 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing(" 32768")), Ok(32768));
1290 }
1291
1292 #[test]
1293 fn trimming_trailing_space() {
1294 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing("32768 ")), Ok(32768));
1295 }
1296
1297 #[test]
1298 fn trimming_both_spaces() {
1299 assert_eq!(parse_primitive_uint::<u16>(OwnedFragment::testing(" 32768 ")), Ok(32768));
1300 }
1301 }
1302
1303 mod u32 {
1304 use crate::{OwnedFragment, parse_primitive_uint};
1305
1306 #[test]
1307 fn test_valid_zero() {
1308 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("0")), Ok(0));
1309 }
1310
1311 #[test]
1312 fn test_valid_positive() {
1313 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("1000000")), Ok(1000000));
1314 }
1315
1316 #[test]
1317 fn test_valid_max() {
1318 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("4294967295")), Ok(4294967295));
1319 }
1320
1321 #[test]
1322 fn test_overflow_positive() {
1323 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("4294967296")).is_err());
1324 }
1325
1326 #[test]
1327 fn test_overflow_negative() {
1328 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("-1")).is_err());
1329 }
1330
1331 #[test]
1332 fn test_invalid_text() {
1333 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("text")).is_err());
1334 }
1335
1336 #[test]
1337 fn test_invalid_empty() {
1338 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("")).is_err());
1339 }
1340
1341 #[test]
1342 fn test_float_truncation_positive() {
1343 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("3.14")), Ok(3));
1344 }
1345
1346 #[test]
1347 fn test_float_truncation_zero() {
1348 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("0.0")), Ok(0));
1349 }
1350
1351 #[test]
1352 fn test_float_truncation_large() {
1353 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("42.999")), Ok(42));
1354 }
1355
1356 #[test]
1357 fn test_float_scientific_notation() {
1358 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("1e+2")), Ok(100));
1359 }
1360
1361 #[test]
1362 fn test_float_scientific_decimal() {
1363 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("2.5e3")), Ok(2500));
1364 }
1365
1366 #[test]
1367 fn test_float_scientific_small() {
1368 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("1.23e-1")), Ok(0));
1369 }
1370
1371 #[test]
1372 fn test_float_negative() {
1373 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("-3.14")).is_err());
1374 }
1375
1376 #[test]
1377 fn test_float_negative_small() {
1378 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("-0.1")).is_err());
1379 }
1380
1381 #[test]
1382 fn test_float_negative_scientific() {
1383 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("-1e2")).is_err());
1384 }
1385
1386 #[test]
1387 fn test_float_overflow_positive() {
1388 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("4294967296.0")).is_err());
1389 }
1390
1391 #[test]
1392 fn test_float_overflow_scientific() {
1393 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("1e10")).is_err());
1394 }
1395
1396 #[test]
1397 fn test_invalid_float_format() {
1398 assert!(parse_primitive_uint::<u32>(OwnedFragment::testing("1.2.3")).is_err());
1399 }
1400
1401 #[test]
1402 fn trimming_leading_space() {
1403 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing(" 1000000")), Ok(1000000));
1404 }
1405
1406 #[test]
1407 fn trimming_trailing_space() {
1408 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing("1000000 ")), Ok(1000000));
1409 }
1410
1411 #[test]
1412 fn trimming_both_spaces() {
1413 assert_eq!(parse_primitive_uint::<u32>(OwnedFragment::testing(" 1000000 ")), Ok(1000000));
1414 }
1415 }
1416
1417 mod u64 {
1418 use crate::{OwnedFragment, parse_primitive_uint};
1419
1420 #[test]
1421 fn test_valid_zero() {
1422 assert_eq!(parse_primitive_uint::<u64>(OwnedFragment::testing("0")), Ok(0));
1423 }
1424
1425 #[test]
1426 fn test_valid_positive() {
1427 assert_eq!(
1428 parse_primitive_uint::<u64>(OwnedFragment::testing("1000000000000")),
1429 Ok(1000000000000)
1430 );
1431 }
1432
1433 #[test]
1434 fn test_valid_max() {
1435 assert_eq!(
1436 parse_primitive_uint::<u64>(OwnedFragment::testing("18446744073709551615")),
1437 Ok(u64::MAX)
1438 );
1439 }
1440
1441 #[test]
1442 fn test_overflow_positive() {
1443 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("18446744073709551616")).is_err());
1444 }
1445
1446 #[test]
1447 fn test_overflow_negative() {
1448 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("-1")).is_err());
1449 }
1450
1451 #[test]
1452 fn test_invalid_text() {
1453 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("not_valid")).is_err());
1454 }
1455
1456 #[test]
1457 fn test_invalid_empty() {
1458 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("")).is_err());
1459 }
1460
1461 #[test]
1462 fn test_float_truncation_positive() {
1463 assert_eq!(parse_primitive_uint::<u64>(OwnedFragment::testing("123456789.123")), Ok(123456789));
1464 }
1465
1466 #[test]
1467 fn test_float_scientific_notation() {
1468 assert_eq!(parse_primitive_uint::<u64>(OwnedFragment::testing("1e12")), Ok(1000000000000));
1469 }
1470
1471 #[test]
1472 fn test_float_negative() {
1473 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("-1.0")).is_err());
1474 }
1475
1476 #[test]
1477 fn test_float_overflow_positive() {
1478 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("2e19")).is_err());
1479 }
1480
1481 #[test]
1482 fn test_float_overflow_scientific() {
1483 assert!(parse_primitive_uint::<u64>(OwnedFragment::testing("1e20")).is_err());
1484 }
1485
1486 #[test]
1487 fn trimming_leading_space() {
1488 assert_eq!(
1489 parse_primitive_uint::<u64>(OwnedFragment::testing(" 1000000000000")),
1490 Ok(1000000000000)
1491 );
1492 }
1493
1494 #[test]
1495 fn trimming_trailing_space() {
1496 assert_eq!(
1497 parse_primitive_uint::<u64>(OwnedFragment::testing("1000000000000 ")),
1498 Ok(1000000000000)
1499 );
1500 }
1501
1502 #[test]
1503 fn trimming_both_spaces() {
1504 assert_eq!(
1505 parse_primitive_uint::<u64>(OwnedFragment::testing(" 1000000000000 ")),
1506 Ok(1000000000000)
1507 );
1508 }
1509 }
1510
1511 mod u128 {
1512 use crate::{OwnedFragment, parse_primitive_uint};
1513
1514 #[test]
1515 fn test_valid_zero() {
1516 assert_eq!(parse_primitive_uint::<u128>(OwnedFragment::testing("0")), Ok(0));
1517 }
1518
1519 #[test]
1520 fn test_valid_positive() {
1521 assert_eq!(
1522 parse_primitive_uint::<u128>(OwnedFragment::testing("12345678901234567890")),
1523 Ok(12345678901234567890)
1524 );
1525 }
1526
1527 #[test]
1528 fn test_valid_max() {
1529 assert_eq!(
1530 parse_primitive_uint::<u128>(OwnedFragment::testing(&u128::MAX.to_string())),
1531 Ok(u128::MAX)
1532 );
1533 }
1534
1535 #[test]
1536 fn test_overflow_positive() {
1537 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing(
1538 "340282366920938463463374607431768211456"
1539 ))
1540 .is_err());
1541 }
1542
1543 #[test]
1544 fn test_overflow_negative() {
1545 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing("-1")).is_err());
1546 }
1547
1548 #[test]
1549 fn test_invalid_text() {
1550 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing("abc")).is_err());
1551 }
1552
1553 #[test]
1554 fn test_invalid_empty() {
1555 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing("")).is_err());
1556 }
1557
1558 #[test]
1559 fn test_float_truncation_positive() {
1560 assert_eq!(
1561 parse_primitive_uint::<u128>(OwnedFragment::testing("123456789.999")),
1562 Ok(123456789)
1563 );
1564 }
1565
1566 #[test]
1567 fn test_float_scientific_notation() {
1568 assert_eq!(
1569 parse_primitive_uint::<u128>(OwnedFragment::testing("1e20")),
1570 Ok(100000000000000000000)
1571 );
1572 }
1573
1574 #[test]
1575 fn test_float_negative() {
1576 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing("-1.0")).is_err());
1577 }
1578
1579 #[test]
1580 fn test_float_overflow_positive() {
1581 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing("1e40")).is_err());
1582 }
1583
1584 #[test]
1585 fn test_float_overflow_scientific() {
1586 assert!(parse_primitive_uint::<u128>(OwnedFragment::testing("1e50")).is_err());
1587 }
1588
1589 #[test]
1590 fn trimming_leading_space() {
1591 assert_eq!(
1592 parse_primitive_uint::<u128>(OwnedFragment::testing(" 12345678901234567890")),
1593 Ok(12345678901234567890)
1594 );
1595 }
1596
1597 #[test]
1598 fn trimming_trailing_space() {
1599 assert_eq!(
1600 parse_primitive_uint::<u128>(OwnedFragment::testing("12345678901234567890 ")),
1601 Ok(12345678901234567890)
1602 );
1603 }
1604
1605 #[test]
1606 fn trimming_both_spaces() {
1607 assert_eq!(
1608 parse_primitive_uint::<u128>(OwnedFragment::testing(" 12345678901234567890 ")),
1609 Ok(12345678901234567890)
1610 );
1611 }
1612 }
1613
1614 mod f32 {
1615 use crate::{OwnedFragment, parse_float};
1616
1617 #[test]
1618 fn test_valid_zero() {
1619 assert_eq!(parse_float::<f32>(OwnedFragment::testing("0.0")), Ok(0.0));
1620 }
1621
1622 #[test]
1623 fn test_valid_positive() {
1624 assert_eq!(parse_float::<f32>(OwnedFragment::testing("1.5")), Ok(1.5));
1625 }
1626
1627 #[test]
1628 fn test_valid_negative() {
1629 assert_eq!(parse_float::<f32>(OwnedFragment::testing("-3.14")), Ok(-3.14));
1630 }
1631
1632 #[test]
1633 fn test_valid_integer() {
1634 assert_eq!(parse_float::<f32>(OwnedFragment::testing("42")), Ok(42.0));
1635 }
1636
1637 #[test]
1638 fn test_valid_scientific() {
1639 assert_eq!(parse_float::<f32>(OwnedFragment::testing("1e2")), Ok(100.0));
1640 }
1641
1642 #[test]
1643 fn test_valid_scientific_negative() {
1644 assert_eq!(parse_float::<f32>(OwnedFragment::testing("1e-2")), Ok(0.01));
1645 }
1646
1647 #[test]
1648 fn test_overflow_positive() {
1649 assert!(parse_float::<f32>(OwnedFragment::testing("3.5e38")).is_err());
1650 }
1651
1652 #[test]
1653 fn test_overflow_negative() {
1654 assert!(parse_float::<f32>(OwnedFragment::testing("-3.5e38")).is_err());
1655 }
1656
1657 #[test]
1658 fn test_invalid_text() {
1659 assert!(parse_float::<f32>(OwnedFragment::testing("abc")).is_err());
1660 }
1661
1662 #[test]
1663 fn test_invalid_empty() {
1664 assert!(parse_float::<f32>(OwnedFragment::testing("")).is_err());
1665 }
1666
1667 #[test]
1668 fn test_invalid_whitespace() {
1669 assert!(parse_float::<f32>(OwnedFragment::testing(" ")).is_err());
1670 }
1671
1672 #[test]
1673 fn test_invalid_nan() {
1674 assert!(parse_float::<f32>(OwnedFragment::testing("NaN")).is_err());
1675 }
1676
1677 #[test]
1678 fn test_invalid_nan_lowercase() {
1679 assert!(parse_float::<f32>(OwnedFragment::testing("nan")).is_err());
1680 }
1681
1682 #[test]
1683 fn test_invalid_multiple_dots() {
1684 assert!(parse_float::<f32>(OwnedFragment::testing("1.2.3")).is_err());
1685 }
1686
1687 #[test]
1688 fn trimming_leading_space() {
1689 assert_eq!(parse_float::<f32>(OwnedFragment::testing(" 1.5")), Ok(1.5));
1690 }
1691
1692 #[test]
1693 fn trimming_trailing_space() {
1694 assert_eq!(parse_float::<f32>(OwnedFragment::testing("1.5 ")), Ok(1.5));
1695 }
1696
1697 #[test]
1698 fn trimming_both_spaces() {
1699 assert_eq!(parse_float::<f32>(OwnedFragment::testing(" 1.5 ")), Ok(1.5));
1700 }
1701
1702 #[test]
1703 fn trimming_negative_leading_space() {
1704 assert_eq!(parse_float::<f32>(OwnedFragment::testing(" -3.14")), Ok(-3.14));
1705 }
1706
1707 #[test]
1708 fn trimming_negative_trailing_space() {
1709 assert_eq!(parse_float::<f32>(OwnedFragment::testing("-3.14 ")), Ok(-3.14));
1710 }
1711
1712 #[test]
1713 fn trimming_negative_both_spaces() {
1714 assert_eq!(parse_float::<f32>(OwnedFragment::testing(" -3.14 ")), Ok(-3.14));
1715 }
1716 }
1717
1718 mod f64 {
1719 use crate::{OwnedFragment, parse_float};
1720
1721 #[test]
1722 fn test_valid_zero() {
1723 assert_eq!(parse_float::<f64>(OwnedFragment::testing("0.0")), Ok(0.0));
1724 }
1725
1726 #[test]
1727 fn test_valid_positive() {
1728 assert_eq!(parse_float::<f64>(OwnedFragment::testing("1.23")), Ok(1.23));
1729 }
1730
1731 #[test]
1732 fn test_valid_negative() {
1733 assert_eq!(parse_float::<f64>(OwnedFragment::testing("-0.001")), Ok(-0.001));
1734 }
1735
1736 #[test]
1737 fn test_valid_integer() {
1738 assert_eq!(parse_float::<f64>(OwnedFragment::testing("42")), Ok(42.0));
1739 }
1740
1741 #[test]
1742 fn test_valid_scientific() {
1743 assert_eq!(parse_float::<f64>(OwnedFragment::testing("1e10")), Ok(1e10));
1744 }
1745
1746 #[test]
1747 fn test_valid_scientific_negative() {
1748 assert_eq!(parse_float::<f64>(OwnedFragment::testing("1e-10")), Ok(1e-10));
1749 }
1750
1751 #[test]
1752 fn test_overflow_positive() {
1753 assert!(parse_float::<f64>(OwnedFragment::testing("1e400")).is_err());
1754 }
1755
1756 #[test]
1757 fn test_overflow_negative() {
1758 assert!(parse_float::<f64>(OwnedFragment::testing("-1e400")).is_err());
1759 }
1760
1761 #[test]
1762 fn test_invalid_text() {
1763 assert!(parse_float::<f64>(OwnedFragment::testing("abc")).is_err());
1764 }
1765
1766 #[test]
1767 fn test_invalid_empty() {
1768 assert!(parse_float::<f64>(OwnedFragment::testing("")).is_err());
1769 }
1770
1771 #[test]
1772 fn test_invalid_whitespace() {
1773 assert!(parse_float::<f64>(OwnedFragment::testing(" ")).is_err());
1774 }
1775
1776 #[test]
1777 fn test_invalid_nan() {
1778 assert!(parse_float::<f64>(OwnedFragment::testing("NaN")).is_err());
1779 }
1780
1781 #[test]
1782 fn test_invalid_nan_mixed_case() {
1783 assert!(parse_float::<f64>(OwnedFragment::testing("NaN")).is_err());
1784 }
1785
1786 #[test]
1787 fn test_invalid_multiple_dots() {
1788 assert!(parse_float::<f64>(OwnedFragment::testing("1.2.3")).is_err());
1789 }
1790
1791 #[test]
1792 fn trimming_leading_space() {
1793 assert_eq!(parse_float::<f64>(OwnedFragment::testing(" 1.23")), Ok(1.23));
1794 }
1795
1796 #[test]
1797 fn trimming_trailing_space() {
1798 assert_eq!(parse_float::<f64>(OwnedFragment::testing("1.23 ")), Ok(1.23));
1799 }
1800
1801 #[test]
1802 fn trimming_both_spaces() {
1803 assert_eq!(parse_float::<f64>(OwnedFragment::testing(" 1.23 ")), Ok(1.23));
1804 }
1805
1806 #[test]
1807 fn trimming_negative_leading_space() {
1808 assert_eq!(parse_float::<f64>(OwnedFragment::testing(" -0.001")), Ok(-0.001));
1809 }
1810
1811 #[test]
1812 fn trimming_negative_trailing_space() {
1813 assert_eq!(parse_float::<f64>(OwnedFragment::testing("-0.001 ")), Ok(-0.001));
1814 }
1815
1816 #[test]
1817 fn trimming_negative_both_spaces() {
1818 assert_eq!(parse_float::<f64>(OwnedFragment::testing(" -0.001 ")), Ok(-0.001));
1819 }
1820 }
1821}