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