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