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