1use arrow_array::ArrowNativeTypeOp;
22use arrow_array::timezone::Tz;
23use arrow_array::types::*;
24use arrow_buffer::ArrowNativeType;
25use arrow_schema::ArrowError;
26use chrono::prelude::*;
27use half::f16;
28use std::str::FromStr;
29
30#[inline]
32fn parse_nanos<const N: usize, const O: u8>(digits: &[u8]) -> u32 {
33 digits[..N]
34 .iter()
35 .fold(0_u32, |acc, v| acc * 10 + v.wrapping_sub(O) as u32)
36 * 10_u32.pow((9 - N) as _)
37}
38
39struct TimestampParser {
41 digits: [u8; 32],
45 mask: u32,
47}
48
49impl TimestampParser {
50 fn new(bytes: &[u8]) -> Self {
51 let mut digits = [0; 32];
52 let mut mask = 0;
53
54 for (idx, (o, i)) in digits.iter_mut().zip(bytes).enumerate() {
56 *o = i.wrapping_sub(b'0');
57 mask |= ((*o < 10) as u32) << idx
58 }
59
60 Self { digits, mask }
61 }
62
63 fn test(&self, idx: usize, b: u8) -> bool {
65 self.digits[idx] == b.wrapping_sub(b'0')
66 }
67
68 fn date(&self) -> Option<NaiveDate> {
70 if self.mask & 0b1111111111 != 0b1101101111 || !self.test(4, b'-') || !self.test(7, b'-') {
71 return None;
72 }
73
74 let year = self.digits[0] as u16 * 1000
75 + self.digits[1] as u16 * 100
76 + self.digits[2] as u16 * 10
77 + self.digits[3] as u16;
78
79 let month = self.digits[5] * 10 + self.digits[6];
80 let day = self.digits[8] * 10 + self.digits[9];
81
82 NaiveDate::from_ymd_opt(year as _, month as _, day as _)
83 }
84
85 fn time(&self) -> Option<(NaiveTime, usize)> {
94 let time = |hour, min, sec, nano| match sec {
96 60 => {
97 let nano = 1_000_000_000 + nano;
98 NaiveTime::from_hms_nano_opt(hour as _, min as _, 59, nano)
99 }
100 _ => NaiveTime::from_hms_nano_opt(hour as _, min as _, sec as _, nano),
101 };
102
103 match (self.mask >> 11) & 0b11111111 {
104 0b11011011 if self.test(13, b':') && self.test(16, b':') => {
106 let hour = self.digits[11] * 10 + self.digits[12];
107 let minute = self.digits[14] * 10 + self.digits[15];
108 let second = self.digits[17] * 10 + self.digits[18];
109
110 match self.test(19, b'.') {
111 true => {
112 let digits = (self.mask >> 20).trailing_ones();
113 let nanos = match digits {
114 0 => return None,
115 1 => parse_nanos::<1, 0>(&self.digits[20..21]),
116 2 => parse_nanos::<2, 0>(&self.digits[20..22]),
117 3 => parse_nanos::<3, 0>(&self.digits[20..23]),
118 4 => parse_nanos::<4, 0>(&self.digits[20..24]),
119 5 => parse_nanos::<5, 0>(&self.digits[20..25]),
120 6 => parse_nanos::<6, 0>(&self.digits[20..26]),
121 7 => parse_nanos::<7, 0>(&self.digits[20..27]),
122 8 => parse_nanos::<8, 0>(&self.digits[20..28]),
123 _ => parse_nanos::<9, 0>(&self.digits[20..29]),
124 };
125 Some((time(hour, minute, second, nanos)?, 20 + digits as usize))
126 }
127 false => Some((time(hour, minute, second, 0)?, 19)),
128 }
129 }
130 0b111111 => {
132 let hour = self.digits[11] * 10 + self.digits[12];
133 let minute = self.digits[13] * 10 + self.digits[14];
134 let second = self.digits[15] * 10 + self.digits[16];
135 let time = time(hour, minute, second, 0)?;
136 Some((time, 17))
137 }
138 _ => None,
139 }
140 }
141}
142
143pub fn string_to_datetime<T: TimeZone>(timezone: &T, s: &str) -> Result<DateTime<T>, ArrowError> {
177 let err =
178 |ctx: &str| ArrowError::ParseError(format!("Error parsing timestamp from '{s}': {ctx}"));
179
180 let bytes = s.as_bytes();
181 if bytes.len() < 10 {
182 return Err(err("timestamp must contain at least 10 characters"));
183 }
184
185 let parser = TimestampParser::new(bytes);
186 let date = parser.date().ok_or_else(|| err("error parsing date"))?;
187 if bytes.len() == 10 {
188 let datetime = date.and_time(NaiveTime::from_hms_opt(0, 0, 0).unwrap());
189 return timezone
190 .from_local_datetime(&datetime)
191 .single()
192 .ok_or_else(|| err("error computing timezone offset"));
193 }
194
195 if !parser.test(10, b'T') && !parser.test(10, b't') && !parser.test(10, b' ') {
196 return Err(err("invalid timestamp separator"));
197 }
198
199 let (time, mut tz_offset) = parser.time().ok_or_else(|| err("error parsing time"))?;
200 let datetime = date.and_time(time);
201
202 if tz_offset == 32 {
203 while tz_offset < bytes.len() && bytes[tz_offset].is_ascii_digit() {
205 tz_offset += 1;
206 }
207 }
208
209 if bytes.len() <= tz_offset {
210 return timezone
211 .from_local_datetime(&datetime)
212 .single()
213 .ok_or_else(|| err("error computing timezone offset"));
214 }
215
216 if (bytes[tz_offset] == b'z' || bytes[tz_offset] == b'Z') && tz_offset == bytes.len() - 1 {
217 return Ok(timezone.from_utc_datetime(&datetime));
218 }
219
220 let parsed_tz: Tz = s[tz_offset..].trim_start().parse()?;
222 let parsed = parsed_tz
223 .from_local_datetime(&datetime)
224 .single()
225 .ok_or_else(|| err("error computing timezone offset"))?;
226
227 Ok(parsed.with_timezone(timezone))
228}
229
230#[inline]
272pub fn string_to_timestamp_nanos(s: &str) -> Result<i64, ArrowError> {
273 to_timestamp_nanos(string_to_datetime(&Utc, s)?.naive_utc())
274}
275
276#[inline]
278fn to_timestamp_nanos(dt: NaiveDateTime) -> Result<i64, ArrowError> {
279 dt.and_utc()
280 .timestamp_nanos_opt()
281 .ok_or_else(|| ArrowError::ParseError(ERR_NANOSECONDS_NOT_SUPPORTED.to_string()))
282}
283
284pub fn string_to_time_nanoseconds(s: &str) -> Result<i64, ArrowError> {
300 let nt = string_to_time(s)
301 .ok_or_else(|| ArrowError::ParseError(format!("Failed to parse \'{s}\' as time")))?;
302 Ok(nt.num_seconds_from_midnight() as i64 * 1_000_000_000 + nt.nanosecond() as i64)
303}
304
305fn string_to_time(s: &str) -> Option<NaiveTime> {
306 let bytes = s.as_bytes();
307 if bytes.len() < 4 {
308 return None;
309 }
310
311 let (am, bytes) = match bytes.get(bytes.len() - 3..) {
312 Some(b" AM" | b" am" | b" Am" | b" aM") => (Some(true), &bytes[..bytes.len() - 3]),
313 Some(b" PM" | b" pm" | b" pM" | b" Pm") => (Some(false), &bytes[..bytes.len() - 3]),
314 _ => (None, bytes),
315 };
316
317 if bytes.len() < 4 {
318 return None;
319 }
320
321 let mut digits = [b'0'; 6];
322
323 let bytes = match (bytes[1], bytes[2]) {
325 (b':', _) => {
326 digits[1] = bytes[0];
327 &bytes[2..]
328 }
329 (_, b':') => {
330 digits[0] = bytes[0];
331 digits[1] = bytes[1];
332 &bytes[3..]
333 }
334 _ => return None,
335 };
336
337 if bytes.len() < 2 {
338 return None; }
340
341 digits[2] = bytes[0];
343 digits[3] = bytes[1];
344
345 let nanoseconds = match bytes.get(2) {
346 Some(b':') => {
347 if bytes.len() < 5 {
348 return None;
349 }
350
351 digits[4] = bytes[3];
353 digits[5] = bytes[4];
354
355 match bytes.get(5) {
357 Some(b'.') => {
358 let decimal = &bytes[6..];
359 if decimal.iter().any(|x| !x.is_ascii_digit()) {
360 return None;
361 }
362 match decimal.len() {
363 0 => return None,
364 1 => parse_nanos::<1, b'0'>(decimal),
365 2 => parse_nanos::<2, b'0'>(decimal),
366 3 => parse_nanos::<3, b'0'>(decimal),
367 4 => parse_nanos::<4, b'0'>(decimal),
368 5 => parse_nanos::<5, b'0'>(decimal),
369 6 => parse_nanos::<6, b'0'>(decimal),
370 7 => parse_nanos::<7, b'0'>(decimal),
371 8 => parse_nanos::<8, b'0'>(decimal),
372 _ => parse_nanos::<9, b'0'>(decimal),
373 }
374 }
375 Some(_) => return None,
376 None => 0,
377 }
378 }
379 Some(_) => return None,
380 None => 0,
381 };
382
383 digits.iter_mut().for_each(|x| *x = x.wrapping_sub(b'0'));
384 if digits.iter().any(|x| *x > 9) {
385 return None;
386 }
387
388 let hour = match (digits[0] * 10 + digits[1], am) {
389 (12, Some(true)) => 0, (h @ 1..=11, Some(true)) => h, (12, Some(false)) => 12, (h @ 1..=11, Some(false)) => h + 12, (_, Some(_)) => return None,
394 (h, None) => h,
395 };
396
397 let (second, nanoseconds) = match digits[4] * 10 + digits[5] {
399 60 => (59, nanoseconds + 1_000_000_000),
400 s => (s, nanoseconds),
401 };
402
403 NaiveTime::from_hms_nano_opt(
404 hour as _,
405 (digits[2] * 10 + digits[3]) as _,
406 second as _,
407 nanoseconds,
408 )
409}
410
411pub trait Parser: ArrowPrimitiveType {
435 fn parse(string: &str) -> Option<Self::Native>;
437
438 fn parse_formatted(string: &str, _format: &str) -> Option<Self::Native> {
442 Self::parse(string)
443 }
444}
445
446impl Parser for Float16Type {
447 fn parse(string: &str) -> Option<f16> {
448 if let Ok(raw_float) = lexical_core::parse(string.as_bytes()) {
449 return Some(f16::from_f32(raw_float));
450 }
451 let string = trim_pre_and_post_whitespace(string);
452 lexical_core::parse(string.as_bytes())
453 .ok()
454 .map(f16::from_f32)
455 }
456}
457
458impl Parser for Float32Type {
459 fn parse(string: &str) -> Option<f32> {
460 if let Ok(raw_float) = lexical_core::parse(string.as_bytes()) {
461 return Some(raw_float);
462 }
463 let string = trim_pre_and_post_whitespace(string);
464 lexical_core::parse(string.as_bytes()).ok()
465 }
466}
467
468impl Parser for Float64Type {
469 fn parse(string: &str) -> Option<f64> {
470 if let Ok(raw_float) = lexical_core::parse(string.as_bytes()) {
471 return Some(raw_float);
472 }
473 let string = trim_pre_and_post_whitespace(string);
474 lexical_core::parse(string.as_bytes()).ok()
475 }
476}
477
478#[inline]
480fn trim_pre_and_post_whitespace(string: &str) -> &str {
481 let bytes = string.as_bytes();
482 let prefix = bytes.first().is_some_and(|b| !b.is_ascii_digit());
483 let suffix = bytes.last().is_some_and(|b| !b.is_ascii_digit());
484 match (prefix, suffix) {
485 (false, false) => string,
486 (true, false) => string.trim_ascii_start(),
487 (false, true) => string.trim_ascii_end(),
488 (true, true) => string.trim_ascii(),
489 }
490}
491
492macro_rules! parser_primitive {
493 ($t:ty) => {
494 impl Parser for $t {
495 fn parse(string: &str) -> Option<Self::Native> {
496 let mut raw_bytes = string.as_bytes();
497 if !raw_bytes.last().is_some_and(|x| x.is_ascii_digit()) {
498 raw_bytes = raw_bytes.trim_ascii_end();
499 if !raw_bytes.last().is_some_and(|x| x.is_ascii_digit()) {
500 return None;
501 }
502 }
503 match atoi::FromRadix10SignedChecked::from_radix_10_signed_checked(raw_bytes) {
504 (Some(n), x) if x == raw_bytes.len() => Some(n),
505 _ => {
506 let trimmed = raw_bytes.trim_ascii_start();
507 match atoi::FromRadix10SignedChecked::from_radix_10_signed_checked(trimmed)
508 {
509 (Some(n), x) if x == trimmed.len() => Some(n),
510 _ => None,
511 }
512 }
513 }
514 }
515 }
516 };
517}
518parser_primitive!(UInt64Type);
519parser_primitive!(UInt32Type);
520parser_primitive!(UInt16Type);
521parser_primitive!(UInt8Type);
522parser_primitive!(Int64Type);
523parser_primitive!(Int32Type);
524parser_primitive!(Int16Type);
525parser_primitive!(Int8Type);
526parser_primitive!(DurationNanosecondType);
527parser_primitive!(DurationMicrosecondType);
528parser_primitive!(DurationMillisecondType);
529parser_primitive!(DurationSecondType);
530
531impl Parser for TimestampNanosecondType {
532 fn parse(string: &str) -> Option<i64> {
533 string_to_timestamp_nanos(string).ok()
534 }
535}
536
537impl Parser for TimestampMicrosecondType {
538 fn parse(string: &str) -> Option<i64> {
539 let nanos = string_to_timestamp_nanos(string).ok();
540 nanos.map(|x| x / 1000)
541 }
542}
543
544impl Parser for TimestampMillisecondType {
545 fn parse(string: &str) -> Option<i64> {
546 let nanos = string_to_timestamp_nanos(string).ok();
547 nanos.map(|x| x / 1_000_000)
548 }
549}
550
551impl Parser for TimestampSecondType {
552 fn parse(string: &str) -> Option<i64> {
553 let nanos = string_to_timestamp_nanos(string).ok();
554 nanos.map(|x| x / 1_000_000_000)
555 }
556}
557
558impl Parser for Time64NanosecondType {
559 fn parse(string: &str) -> Option<Self::Native> {
561 string_to_time_nanoseconds(string)
562 .ok()
563 .or_else(|| string.parse::<Self::Native>().ok())
564 }
565
566 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
567 let nt = NaiveTime::parse_from_str(string, format).ok()?;
568 Some(nt.num_seconds_from_midnight() as i64 * 1_000_000_000 + nt.nanosecond() as i64)
569 }
570}
571
572impl Parser for Time64MicrosecondType {
573 fn parse(string: &str) -> Option<Self::Native> {
575 string_to_time_nanoseconds(string)
576 .ok()
577 .map(|nanos| nanos / 1_000)
578 .or_else(|| string.parse::<Self::Native>().ok())
579 }
580
581 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
582 let nt = NaiveTime::parse_from_str(string, format).ok()?;
583 Some(nt.num_seconds_from_midnight() as i64 * 1_000_000 + nt.nanosecond() as i64 / 1_000)
584 }
585}
586
587impl Parser for Time32MillisecondType {
588 fn parse(string: &str) -> Option<Self::Native> {
590 string_to_time_nanoseconds(string)
591 .ok()
592 .map(|nanos| (nanos / 1_000_000) as i32)
593 .or_else(|| string.parse::<Self::Native>().ok())
594 }
595
596 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
597 let nt = NaiveTime::parse_from_str(string, format).ok()?;
598 Some(nt.num_seconds_from_midnight() as i32 * 1_000 + nt.nanosecond() as i32 / 1_000_000)
599 }
600}
601
602impl Parser for Time32SecondType {
603 fn parse(string: &str) -> Option<Self::Native> {
605 string_to_time_nanoseconds(string)
606 .ok()
607 .map(|nanos| (nanos / 1_000_000_000) as i32)
608 .or_else(|| string.parse::<Self::Native>().ok())
609 }
610
611 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
612 let nt = NaiveTime::parse_from_str(string, format).ok()?;
613 Some(nt.num_seconds_from_midnight() as i32 + nt.nanosecond() as i32 / 1_000_000_000)
614 }
615}
616
617const EPOCH_DAYS_FROM_CE: i32 = 719_163;
619
620const ERR_NANOSECONDS_NOT_SUPPORTED: &str = "The dates that can be represented as nanoseconds have to be between 1677-09-21T00:12:44.0 and 2262-04-11T23:47:16.854775804";
622
623fn parse_extended_ymd(string: &str) -> Option<(i32, u32, u32)> {
630 debug_assert!(string.starts_with('+') || string.starts_with('-'));
631 let rest = &string[1..];
634 let hyphen = rest.find('-')?;
635 if hyphen < 4 {
636 return None;
637 }
638 let year: i32 = string[..hyphen + 1].parse().ok()?;
641 let remainder = string[hyphen + 1..].strip_prefix('-')?;
643 let mut parts = remainder.splitn(2, '-');
644 let month: u32 = parts.next()?.parse().ok()?;
645 let day: u32 = parts.next()?.parse().ok()?;
646 Some((year, month, day))
647}
648
649fn parse_date(string: &str) -> Option<NaiveDate> {
650 if string.starts_with('+') || string.starts_with('-') {
658 let (year, month, day) = parse_extended_ymd(string)?;
659 return NaiveDate::from_ymd_opt(year, month, day);
660 }
661
662 if string.len() > 10 {
663 return string_to_datetime(&Utc, string)
665 .map(|dt| dt.date_naive())
666 .ok();
667 };
668 let mut digits = [0; 10];
669 let mut mask = 0;
670
671 for (idx, (o, i)) in digits.iter_mut().zip(string.bytes()).enumerate() {
673 *o = i.wrapping_sub(b'0');
674 mask |= ((*o < 10) as u16) << idx
675 }
676
677 const HYPHEN: u8 = b'-'.wrapping_sub(b'0');
678
679 if digits[4] != HYPHEN {
681 let (year, month, day) = match (mask, string.len()) {
682 (0b11111111, 8) => (
683 digits[0] as u16 * 1000
684 + digits[1] as u16 * 100
685 + digits[2] as u16 * 10
686 + digits[3] as u16,
687 digits[4] * 10 + digits[5],
688 digits[6] * 10 + digits[7],
689 ),
690 _ => return None,
691 };
692 return NaiveDate::from_ymd_opt(year as _, month as _, day as _);
693 }
694
695 let (month, day) = match mask {
696 0b1101101111 => {
697 if digits[7] != HYPHEN {
698 return None;
699 }
700 (digits[5] * 10 + digits[6], digits[8] * 10 + digits[9])
701 }
702 0b101101111 => {
703 if digits[7] != HYPHEN {
704 return None;
705 }
706 (digits[5] * 10 + digits[6], digits[8])
707 }
708 0b110101111 => {
709 if digits[6] != HYPHEN {
710 return None;
711 }
712 (digits[5], digits[7] * 10 + digits[8])
713 }
714 0b10101111 => {
715 if digits[6] != HYPHEN {
716 return None;
717 }
718 (digits[5], digits[7])
719 }
720 _ => return None,
721 };
722
723 let year =
724 digits[0] as u16 * 1000 + digits[1] as u16 * 100 + digits[2] as u16 * 10 + digits[3] as u16;
725
726 NaiveDate::from_ymd_opt(year as _, month as _, day as _)
727}
728
729fn parse_date_to_days(string: &str) -> Option<i32> {
738 if string.starts_with('+') || string.starts_with('-') {
739 let (year, month, day) = parse_extended_ymd(string)?;
740 let y = year as i64;
741 let era = y.div_euclid(400);
742 let yoe = y.rem_euclid(400) as i32;
743 let nd = NaiveDate::from_ymd_opt(yoe, month, day)?;
744 let in_era = (nd.num_days_from_ce() - EPOCH_DAYS_FROM_CE) as i64;
745 return i32::try_from(era * 146_097 + in_era).ok();
746 }
747 parse_date(string).map(|nd| nd.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
748}
749
750impl Parser for Date32Type {
751 fn parse(string: &str) -> Option<i32> {
752 parse_date_to_days(string)
753 }
754
755 fn parse_formatted(string: &str, format: &str) -> Option<i32> {
756 let date = NaiveDate::parse_from_str(string, format).ok()?;
757 Some(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
758 }
759}
760
761impl Parser for Date64Type {
762 fn parse(string: &str) -> Option<i64> {
763 if string.len() <= 10 {
764 let datetime = NaiveDateTime::new(parse_date(string)?, NaiveTime::default());
765 Some(datetime.and_utc().timestamp_millis())
766 } else {
767 let date_time = string_to_datetime(&Utc, string).ok()?;
768 Some(date_time.timestamp_millis())
769 }
770 }
771
772 fn parse_formatted(string: &str, format: &str) -> Option<i64> {
773 use chrono::format::Fixed;
774 use chrono::format::StrftimeItems;
775 let fmt = StrftimeItems::new(format);
776 let has_zone = fmt.into_iter().any(|item| match item {
777 chrono::format::Item::Fixed(fixed_item) => matches!(
778 fixed_item,
779 Fixed::RFC2822
780 | Fixed::RFC3339
781 | Fixed::TimezoneName
782 | Fixed::TimezoneOffsetColon
783 | Fixed::TimezoneOffsetColonZ
784 | Fixed::TimezoneOffset
785 | Fixed::TimezoneOffsetZ
786 ),
787 _ => false,
788 });
789 if has_zone {
790 let date_time = chrono::DateTime::parse_from_str(string, format).ok()?;
791 Some(date_time.timestamp_millis())
792 } else {
793 let date_time = NaiveDateTime::parse_from_str(string, format).ok()?;
794 Some(date_time.and_utc().timestamp_millis())
795 }
796 }
797}
798
799fn parse_e_notation<T: DecimalType>(
800 s: &str,
801 mut digits: u16,
802 mut fractionals: i16,
803 mut result: T::Native,
804 index: usize,
805 precision: u16,
806 scale: i16,
807) -> Result<T::Native, ArrowError> {
808 let mut exp: i16 = 0;
809 let base = T::Native::usize_as(10);
810
811 let mut pos_shift_direction: bool = true;
813
814 let mut bs = s.as_bytes().iter().skip(index + fractionals as usize);
816
817 for b in bs.by_ref() {
823 match b {
824 b'0'..=b'9' => {
825 result = result.mul_wrapping(base);
826 result = result.add_wrapping(T::Native::usize_as((b - b'0') as usize));
827 fractionals += 1;
828 digits += 1;
829 }
830 b'e' | b'E' => {
831 break;
832 }
833 _ => {
834 return Err(ArrowError::ParseError(format!(
835 "can't parse the string value {s} to decimal"
836 )));
837 }
838 };
839 }
840
841 let mut signed = false;
843 for b in bs {
844 match b {
845 b'-' if !signed => {
846 pos_shift_direction = false;
847 signed = true;
848 }
849 b'+' if !signed => {
850 pos_shift_direction = true;
851 signed = true;
852 }
853 b if b.is_ascii_digit() => {
854 exp *= 10;
855 exp += (b - b'0') as i16;
856 }
857 _ => {
858 return Err(ArrowError::ParseError(format!(
859 "can't parse the string value {s} to decimal"
860 )));
861 }
862 }
863 }
864
865 if digits == 0 && fractionals == 0 && exp == 0 {
866 return Err(ArrowError::ParseError(format!(
867 "can't parse the string value {s} to decimal"
868 )));
869 }
870
871 if !pos_shift_direction {
872 if exp - (digits as i16 + scale) > 0 {
875 return Ok(T::Native::usize_as(0));
876 }
877 exp *= -1;
878 }
879
880 exp = fractionals - exp;
882 if !pos_shift_direction && exp > digits as i16 {
884 digits = exp as u16;
885 }
886 exp = scale - exp;
888
889 if (digits as i16 + exp) as u16 > precision {
890 return Err(ArrowError::ParseError(format!(
891 "parse decimal overflow ({s})"
892 )));
893 }
894
895 if exp < 0 {
896 result = result.div_wrapping(base.pow_wrapping(-exp as _));
897 } else {
898 result = result.mul_wrapping(base.pow_wrapping(exp as _));
899 }
900
901 Ok(result)
902}
903
904pub fn parse_decimal<T: DecimalType>(
911 s: &str,
912 precision: u8,
913 scale: i8,
914) -> Result<T::Native, ArrowError> {
915 let mut result = T::Native::usize_as(0);
916 let mut fractionals: i8 = 0;
917 let mut digits: u8 = 0;
918 let base = T::Native::usize_as(10);
919
920 let bs = s.as_bytes();
921
922 if !bs
923 .last()
924 .is_some_and(|b| b.is_ascii_digit() || (b == &b'.' && s.len() > 1))
925 {
926 return Err(ArrowError::ParseError(format!(
929 "can't parse the string value {s} to decimal"
930 )));
931 }
932
933 let (signed, negative) = match bs.first() {
934 Some(b'-') => (true, true),
935 Some(b'+') => (true, false),
936 _ => (false, false),
937 };
938
939 let mut bs = bs.iter().enumerate().skip(signed as usize);
941
942 let mut is_e_notation = false;
943
944 while let Some((index, b)) = bs.next() {
947 match b {
948 b'0'..=b'9' => {
949 if digits == 0 && *b == b'0' {
950 continue;
952 }
953 digits += 1;
954 result = result.mul_wrapping(base);
955 result = result.add_wrapping(T::Native::usize_as((b - b'0') as usize));
956 }
957 b'.' => {
958 let point_index = index;
959
960 for (_, b) in bs.by_ref() {
961 if !b.is_ascii_digit() {
962 if *b == b'e' || *b == b'E' {
963 result = parse_e_notation::<T>(
964 s,
965 digits as u16,
966 fractionals as i16,
967 result,
968 point_index + 1,
969 precision as u16,
970 scale as i16,
971 )?;
972
973 is_e_notation = true;
974
975 break;
976 }
977 return Err(ArrowError::ParseError(format!(
978 "can't parse the string value {s} to decimal"
979 )));
980 }
981 if fractionals == scale {
982 continue;
986 }
987 fractionals += 1;
988 digits += 1;
989 result = result.mul_wrapping(base);
990 result = result.add_wrapping(T::Native::usize_as((b - b'0') as usize));
991 }
992
993 if is_e_notation {
994 break;
995 }
996 }
997 b'e' | b'E' => {
998 result = parse_e_notation::<T>(
999 s,
1000 digits as u16,
1001 fractionals as i16,
1002 result,
1003 index,
1004 precision as u16,
1005 scale as i16,
1006 )?;
1007
1008 is_e_notation = true;
1009
1010 break;
1011 }
1012 _ => {
1013 return Err(ArrowError::ParseError(format!(
1014 "can't parse the string value {s} to decimal"
1015 )));
1016 }
1017 }
1018 }
1019
1020 if !is_e_notation {
1021 if fractionals < scale {
1022 let exp = scale - fractionals;
1023 if exp as u8 + digits > precision {
1024 return Err(ArrowError::ParseError(format!(
1025 "parse decimal overflow ({s})"
1026 )));
1027 }
1028 let mul = base.pow_wrapping(exp as _);
1029 result = result.mul_wrapping(mul);
1030 } else if digits > precision {
1031 return Err(ArrowError::ParseError(format!(
1032 "parse decimal overflow ({s})"
1033 )));
1034 }
1035 }
1036
1037 Ok(if negative {
1038 result.neg_wrapping()
1039 } else {
1040 result
1041 })
1042}
1043
1044pub fn parse_interval_year_month(
1046 value: &str,
1047) -> Result<<IntervalYearMonthType as ArrowPrimitiveType>::Native, ArrowError> {
1048 let config = IntervalParseConfig::new(IntervalUnit::Year);
1049 let interval = Interval::parse(value, &config)?;
1050
1051 let months = interval.to_year_months().map_err(|_| {
1052 ArrowError::CastError(format!(
1053 "Cannot cast {value} to IntervalYearMonth. Only year and month fields are allowed."
1054 ))
1055 })?;
1056
1057 Ok(IntervalYearMonthType::make_value(0, months))
1058}
1059
1060pub fn parse_interval_day_time(
1062 value: &str,
1063) -> Result<<IntervalDayTimeType as ArrowPrimitiveType>::Native, ArrowError> {
1064 let config = IntervalParseConfig::new(IntervalUnit::Day);
1065 let interval = Interval::parse(value, &config)?;
1066
1067 let (days, millis) = interval.to_day_time().map_err(|_| ArrowError::CastError(format!(
1068 "Cannot cast {value} to IntervalDayTime because the nanos part isn't multiple of milliseconds"
1069 )))?;
1070
1071 Ok(IntervalDayTimeType::make_value(days, millis))
1072}
1073
1074pub fn parse_interval_month_day_nano_config(
1076 value: &str,
1077 config: IntervalParseConfig,
1078) -> Result<<IntervalMonthDayNanoType as ArrowPrimitiveType>::Native, ArrowError> {
1079 let interval = Interval::parse(value, &config)?;
1080
1081 let (months, days, nanos) = interval.to_month_day_nanos();
1082
1083 Ok(IntervalMonthDayNanoType::make_value(months, days, nanos))
1084}
1085
1086pub fn parse_interval_month_day_nano(
1088 value: &str,
1089) -> Result<<IntervalMonthDayNanoType as ArrowPrimitiveType>::Native, ArrowError> {
1090 parse_interval_month_day_nano_config(value, IntervalParseConfig::new(IntervalUnit::Month))
1091}
1092
1093const NANOS_PER_MILLIS: i64 = 1_000_000;
1094const NANOS_PER_SECOND: i64 = 1_000 * NANOS_PER_MILLIS;
1095const NANOS_PER_MINUTE: i64 = 60 * NANOS_PER_SECOND;
1096const NANOS_PER_HOUR: i64 = 60 * NANOS_PER_MINUTE;
1097#[cfg(test)]
1098const NANOS_PER_DAY: i64 = 24 * NANOS_PER_HOUR;
1099
1100#[derive(Debug, Clone)]
1104pub struct IntervalParseConfig {
1105 default_unit: IntervalUnit,
1108}
1109
1110impl IntervalParseConfig {
1111 pub fn new(default_unit: IntervalUnit) -> Self {
1113 Self { default_unit }
1114 }
1115}
1116
1117#[rustfmt::skip]
1118#[derive(Debug, Clone, Copy)]
1119#[repr(u16)]
1120pub enum IntervalUnit {
1123 Century = 0b_0000_0000_0001,
1125 Decade = 0b_0000_0000_0010,
1127 Year = 0b_0000_0000_0100,
1129 Month = 0b_0000_0000_1000,
1131 Week = 0b_0000_0001_0000,
1133 Day = 0b_0000_0010_0000,
1135 Hour = 0b_0000_0100_0000,
1137 Minute = 0b_0000_1000_0000,
1139 Second = 0b_0001_0000_0000,
1141 Millisecond = 0b_0010_0000_0000,
1143 Microsecond = 0b_0100_0000_0000,
1145 Nanosecond = 0b_1000_0000_0000,
1147}
1148
1149impl FromStr for IntervalUnit {
1154 type Err = ArrowError;
1155
1156 fn from_str(s: &str) -> Result<Self, ArrowError> {
1157 match s.to_lowercase().as_str() {
1158 "c" | "cent" | "cents" | "century" | "centuries" => Ok(Self::Century),
1159 "dec" | "decs" | "decade" | "decades" => Ok(Self::Decade),
1160 "y" | "yr" | "yrs" | "year" | "years" => Ok(Self::Year),
1161 "mon" | "mons" | "month" | "months" => Ok(Self::Month),
1162 "w" | "week" | "weeks" => Ok(Self::Week),
1163 "d" | "day" | "days" => Ok(Self::Day),
1164 "h" | "hr" | "hrs" | "hour" | "hours" => Ok(Self::Hour),
1165 "m" | "min" | "mins" | "minute" | "minutes" => Ok(Self::Minute),
1166 "s" | "sec" | "secs" | "second" | "seconds" => Ok(Self::Second),
1167 "ms" | "msec" | "msecs" | "msecond" | "mseconds" | "millisecond" | "milliseconds" => {
1168 Ok(Self::Millisecond)
1169 }
1170 "us" | "usec" | "usecs" | "usecond" | "useconds" | "microsecond" | "microseconds" => {
1171 Ok(Self::Microsecond)
1172 }
1173 "nanosecond" | "nanoseconds" => Ok(Self::Nanosecond),
1174 _ => Err(ArrowError::InvalidArgumentError(format!(
1175 "Unknown interval type: {s}"
1176 ))),
1177 }
1178 }
1179}
1180
1181impl IntervalUnit {
1182 fn from_str_or_config(
1183 s: Option<&str>,
1184 config: &IntervalParseConfig,
1185 ) -> Result<Self, ArrowError> {
1186 match s {
1187 Some(s) => s.parse(),
1188 None => Ok(config.default_unit),
1189 }
1190 }
1191}
1192
1193pub type MonthDayNano = (i32, i32, i64);
1195
1196const INTERVAL_PRECISION: u32 = 15;
1198
1199#[derive(Clone, Copy, Debug, PartialEq)]
1200struct IntervalAmount {
1201 integer: i64,
1203 frac: i64,
1205}
1206
1207#[cfg(test)]
1208impl IntervalAmount {
1209 fn new(integer: i64, frac: i64) -> Self {
1210 Self { integer, frac }
1211 }
1212}
1213
1214impl FromStr for IntervalAmount {
1215 type Err = ArrowError;
1216
1217 fn from_str(s: &str) -> Result<Self, Self::Err> {
1218 match s.split_once('.') {
1219 Some((integer, frac))
1220 if frac.len() <= INTERVAL_PRECISION as usize
1221 && !frac.is_empty()
1222 && !frac.starts_with('-') =>
1223 {
1224 let explicit_neg = integer.starts_with('-');
1227 let integer = if integer.is_empty() || integer == "-" {
1228 Ok(0)
1229 } else {
1230 integer.parse::<i64>().map_err(|_| {
1231 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1232 })
1233 }?;
1234
1235 let frac_unscaled = frac.parse::<i64>().map_err(|_| {
1236 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1237 })?;
1238
1239 let frac = frac_unscaled * 10_i64.pow(INTERVAL_PRECISION - frac.len() as u32);
1241
1242 let frac = if integer < 0 || explicit_neg {
1244 -frac
1245 } else {
1246 frac
1247 };
1248
1249 let result = Self { integer, frac };
1250
1251 Ok(result)
1252 }
1253 Some((_, frac)) if frac.starts_with('-') => Err(ArrowError::ParseError(format!(
1254 "Failed to parse {s} as interval amount"
1255 ))),
1256 Some((_, frac)) if frac.len() > INTERVAL_PRECISION as usize => {
1257 Err(ArrowError::ParseError(format!(
1258 "{s} exceeds the precision available for interval amount"
1259 )))
1260 }
1261 Some(_) | None => {
1262 let integer = s.parse::<i64>().map_err(|_| {
1263 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1264 })?;
1265
1266 let result = Self { integer, frac: 0 };
1267 Ok(result)
1268 }
1269 }
1270 }
1271}
1272
1273#[derive(Debug, Default, PartialEq)]
1274struct Interval {
1275 months: i32,
1276 days: i32,
1277 nanos: i64,
1278}
1279
1280impl Interval {
1281 fn new(months: i32, days: i32, nanos: i64) -> Self {
1282 Self {
1283 months,
1284 days,
1285 nanos,
1286 }
1287 }
1288
1289 fn to_year_months(&self) -> Result<i32, ArrowError> {
1290 match (self.months, self.days, self.nanos) {
1291 (months, days, nanos) if days == 0 && nanos == 0 => Ok(months),
1292 _ => Err(ArrowError::InvalidArgumentError(format!(
1293 "Unable to represent interval with days and nanos as year-months: {self:?}"
1294 ))),
1295 }
1296 }
1297
1298 fn to_day_time(&self) -> Result<(i32, i32), ArrowError> {
1299 let days = self.months.mul_checked(30)?.add_checked(self.days)?;
1300
1301 match self.nanos {
1302 nanos if nanos % NANOS_PER_MILLIS == 0 => {
1303 let millis = (self.nanos / 1_000_000).try_into().map_err(|_| {
1304 ArrowError::InvalidArgumentError(format!(
1305 "Unable to represent {} nanos as milliseconds in a signed 32-bit integer",
1306 self.nanos
1307 ))
1308 })?;
1309
1310 Ok((days, millis))
1311 }
1312 nanos => Err(ArrowError::InvalidArgumentError(format!(
1313 "Unable to represent {nanos} as milliseconds"
1314 ))),
1315 }
1316 }
1317
1318 fn to_month_day_nanos(&self) -> (i32, i32, i64) {
1319 (self.months, self.days, self.nanos)
1320 }
1321
1322 fn parse(value: &str, config: &IntervalParseConfig) -> Result<Self, ArrowError> {
1325 let components = parse_interval_components(value, config)?;
1326
1327 components
1328 .into_iter()
1329 .try_fold(Self::default(), |result, (amount, unit)| {
1330 result.add(amount, unit)
1331 })
1332 }
1333
1334 fn add(&self, amount: IntervalAmount, unit: IntervalUnit) -> Result<Self, ArrowError> {
1341 let result = match unit {
1342 IntervalUnit::Century => {
1343 let months_int = amount.integer.mul_checked(100)?.mul_checked(12)?;
1344 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION - 2);
1345 let months = months_int
1346 .add_checked(month_frac)?
1347 .try_into()
1348 .map_err(|_| {
1349 ArrowError::ParseError(format!(
1350 "Unable to represent {} centuries as months in a signed 32-bit integer",
1351 amount.integer
1352 ))
1353 })?;
1354
1355 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1356 }
1357 IntervalUnit::Decade => {
1358 let months_int = amount.integer.mul_checked(10)?.mul_checked(12)?;
1359
1360 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION - 1);
1361 let months = months_int
1362 .add_checked(month_frac)?
1363 .try_into()
1364 .map_err(|_| {
1365 ArrowError::ParseError(format!(
1366 "Unable to represent {} decades as months in a signed 32-bit integer",
1367 amount.integer
1368 ))
1369 })?;
1370
1371 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1372 }
1373 IntervalUnit::Year => {
1374 let months_int = amount.integer.mul_checked(12)?;
1375 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION);
1376 let months = months_int
1377 .add_checked(month_frac)?
1378 .try_into()
1379 .map_err(|_| {
1380 ArrowError::ParseError(format!(
1381 "Unable to represent {} years as months in a signed 32-bit integer",
1382 amount.integer
1383 ))
1384 })?;
1385
1386 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1387 }
1388 IntervalUnit::Month => {
1389 let months = amount.integer.try_into().map_err(|_| {
1390 ArrowError::ParseError(format!(
1391 "Unable to represent {} months in a signed 32-bit integer",
1392 amount.integer
1393 ))
1394 })?;
1395
1396 let days = amount.frac * 3 / 10_i64.pow(INTERVAL_PRECISION - 1);
1397 let days = days.try_into().map_err(|_| {
1398 ArrowError::ParseError(format!(
1399 "Unable to represent {} months as days in a signed 32-bit integer",
1400 amount.frac / 10_i64.pow(INTERVAL_PRECISION)
1401 ))
1402 })?;
1403
1404 Self::new(
1405 self.months.add_checked(months)?,
1406 self.days.add_checked(days)?,
1407 self.nanos,
1408 )
1409 }
1410 IntervalUnit::Week => {
1411 let days = amount.integer.mul_checked(7)?.try_into().map_err(|_| {
1412 ArrowError::ParseError(format!(
1413 "Unable to represent {} weeks as days in a signed 32-bit integer",
1414 amount.integer
1415 ))
1416 })?;
1417
1418 let nanos = amount.frac * 7 * 24 * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1419
1420 Self::new(
1421 self.months,
1422 self.days.add_checked(days)?,
1423 self.nanos.add_checked(nanos)?,
1424 )
1425 }
1426 IntervalUnit::Day => {
1427 let days = amount.integer.try_into().map_err(|_| {
1428 ArrowError::InvalidArgumentError(format!(
1429 "Unable to represent {} days in a signed 32-bit integer",
1430 amount.integer
1431 ))
1432 })?;
1433
1434 let nanos = amount.frac * 24 * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1435
1436 Self::new(
1437 self.months,
1438 self.days.add_checked(days)?,
1439 self.nanos.add_checked(nanos)?,
1440 )
1441 }
1442 IntervalUnit::Hour => {
1443 let nanos_int = amount.integer.mul_checked(NANOS_PER_HOUR)?;
1444 let nanos_frac = amount.frac * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1445 let nanos = nanos_int.add_checked(nanos_frac)?;
1446
1447 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1448 }
1449 IntervalUnit::Minute => {
1450 let nanos_int = amount.integer.mul_checked(NANOS_PER_MINUTE)?;
1451 let nanos_frac = amount.frac * 6 / 10_i64.pow(INTERVAL_PRECISION - 10);
1452
1453 let nanos = nanos_int.add_checked(nanos_frac)?;
1454
1455 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1456 }
1457 IntervalUnit::Second => {
1458 let nanos_int = amount.integer.mul_checked(NANOS_PER_SECOND)?;
1459 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 9);
1460 let nanos = nanos_int.add_checked(nanos_frac)?;
1461
1462 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1463 }
1464 IntervalUnit::Millisecond => {
1465 let nanos_int = amount.integer.mul_checked(NANOS_PER_MILLIS)?;
1466 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 6);
1467 let nanos = nanos_int.add_checked(nanos_frac)?;
1468
1469 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1470 }
1471 IntervalUnit::Microsecond => {
1472 let nanos_int = amount.integer.mul_checked(1_000)?;
1473 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 3);
1474 let nanos = nanos_int.add_checked(nanos_frac)?;
1475
1476 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1477 }
1478 IntervalUnit::Nanosecond => {
1479 let nanos_int = amount.integer;
1480 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION);
1481 let nanos = nanos_int.add_checked(nanos_frac)?;
1482
1483 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1484 }
1485 };
1486
1487 Ok(result)
1488 }
1489}
1490
1491fn parse_interval_components(
1493 value: &str,
1494 config: &IntervalParseConfig,
1495) -> Result<Vec<(IntervalAmount, IntervalUnit)>, ArrowError> {
1496 let raw_pairs = split_interval_components(value);
1497
1498 let Ok(pairs): Result<Vec<(IntervalAmount, IntervalUnit)>, ArrowError> = raw_pairs
1500 .iter()
1501 .map(|(a, u)| Ok((a.parse()?, IntervalUnit::from_str_or_config(*u, config)?)))
1502 .collect()
1503 else {
1504 return Err(ArrowError::ParseError(format!(
1505 "Invalid input syntax for type interval: {value:?}"
1506 )));
1507 };
1508
1509 let (amounts, units): (Vec<_>, Vec<_>) = pairs.into_iter().unzip();
1511
1512 let mut observed_interval_types = 0;
1514 for (unit, (_, raw_unit)) in units.iter().zip(raw_pairs) {
1515 if observed_interval_types & (*unit as u16) != 0 {
1516 return Err(ArrowError::ParseError(format!(
1517 "Invalid input syntax for type interval: {:?}. Repeated type '{}'",
1518 value,
1519 raw_unit.unwrap_or_default(),
1520 )));
1521 }
1522
1523 observed_interval_types |= *unit as u16;
1524 }
1525
1526 let result = amounts.iter().copied().zip(units.iter().copied());
1527
1528 Ok(result.collect::<Vec<_>>())
1529}
1530
1531fn split_interval_components(value: &str) -> Vec<(&str, Option<&str>)> {
1537 let mut result = vec![];
1538 let mut words = value.split(char::is_whitespace);
1539 while let Some(word) = words.next() {
1540 if let Some(split_word_at) = word.find(not_interval_amount) {
1541 let (amount, unit) = word.split_at(split_word_at);
1542 result.push((amount, Some(unit)));
1543 } else if let Some(unit) = words.next() {
1544 result.push((word, Some(unit)));
1545 } else {
1546 result.push((word, None));
1547 break;
1548 }
1549 }
1550 result
1551}
1552
1553fn not_interval_amount(c: char) -> bool {
1555 !c.is_ascii_digit() && c != '.' && c != '-'
1556}
1557
1558#[cfg(test)]
1559mod tests {
1560 use super::*;
1561 use arrow_array::temporal_conversions::date32_to_datetime;
1562 use arrow_buffer::i256;
1563
1564 #[test]
1565 fn test_parse_nanos() {
1566 assert_eq!(parse_nanos::<3, 0>(&[1, 2, 3]), 123_000_000);
1567 assert_eq!(parse_nanos::<5, 0>(&[1, 2, 3, 4, 5]), 123_450_000);
1568 assert_eq!(parse_nanos::<6, b'0'>(b"123456"), 123_456_000);
1569 }
1570
1571 #[test]
1572 fn string_to_timestamp_timezone() {
1573 assert_eq!(
1575 1599572549190855000,
1576 parse_timestamp("2020-09-08T13:42:29.190855+00:00").unwrap()
1577 );
1578 assert_eq!(
1579 1599572549190855000,
1580 parse_timestamp("2020-09-08T13:42:29.190855Z").unwrap()
1581 );
1582 assert_eq!(
1583 1599572549000000000,
1584 parse_timestamp("2020-09-08T13:42:29Z").unwrap()
1585 ); assert_eq!(
1587 1599590549190855000,
1588 parse_timestamp("2020-09-08T13:42:29.190855-05:00").unwrap()
1589 );
1590 }
1591
1592 #[test]
1593 fn string_to_timestamp_timezone_space() {
1594 assert_eq!(
1596 1599572549190855000,
1597 parse_timestamp("2020-09-08 13:42:29.190855+00:00").unwrap()
1598 );
1599 assert_eq!(
1600 1599572549190855000,
1601 parse_timestamp("2020-09-08 13:42:29.190855Z").unwrap()
1602 );
1603 assert_eq!(
1604 1599572549000000000,
1605 parse_timestamp("2020-09-08 13:42:29Z").unwrap()
1606 ); assert_eq!(
1608 1599590549190855000,
1609 parse_timestamp("2020-09-08 13:42:29.190855-05:00").unwrap()
1610 );
1611 }
1612
1613 #[test]
1614 #[cfg_attr(miri, ignore)] fn string_to_timestamp_no_timezone() {
1616 let naive_datetime = NaiveDateTime::new(
1620 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1621 NaiveTime::from_hms_nano_opt(13, 42, 29, 190855000).unwrap(),
1622 );
1623
1624 assert_eq!(
1626 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1627 parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
1628 );
1629
1630 assert_eq!(
1631 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1632 parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
1633 );
1634
1635 let datetime_whole_secs = NaiveDateTime::new(
1638 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1639 NaiveTime::from_hms_opt(13, 42, 29).unwrap(),
1640 )
1641 .and_utc();
1642
1643 assert_eq!(
1645 datetime_whole_secs.timestamp_nanos_opt().unwrap(),
1646 parse_timestamp("2020-09-08T13:42:29").unwrap()
1647 );
1648
1649 assert_eq!(
1650 datetime_whole_secs.timestamp_nanos_opt().unwrap(),
1651 parse_timestamp("2020-09-08 13:42:29").unwrap()
1652 );
1653
1654 let datetime_no_time = NaiveDateTime::new(
1658 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1659 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
1660 )
1661 .and_utc();
1662
1663 assert_eq!(
1664 datetime_no_time.timestamp_nanos_opt().unwrap(),
1665 parse_timestamp("2020-09-08").unwrap()
1666 )
1667 }
1668
1669 #[test]
1670 fn string_to_timestamp_chrono() {
1671 let cases = [
1672 "2020-09-08T13:42:29Z",
1673 "1969-01-01T00:00:00.1Z",
1674 "2020-09-08T12:00:12.12345678+00:00",
1675 "2020-09-08T12:00:12+00:00",
1676 "2020-09-08T12:00:12.1+00:00",
1677 "2020-09-08T12:00:12.12+00:00",
1678 "2020-09-08T12:00:12.123+00:00",
1679 "2020-09-08T12:00:12.1234+00:00",
1680 "2020-09-08T12:00:12.12345+00:00",
1681 "2020-09-08T12:00:12.123456+00:00",
1682 "2020-09-08T12:00:12.1234567+00:00",
1683 "2020-09-08T12:00:12.12345678+00:00",
1684 "2020-09-08T12:00:12.123456789+00:00",
1685 "2020-09-08T12:00:12.12345678912z",
1686 "2020-09-08T12:00:12.123456789123Z",
1687 "2020-09-08T12:00:12.123456789123+02:00",
1688 "2020-09-08T12:00:12.12345678912345Z",
1689 "2020-09-08T12:00:12.1234567891234567+02:00",
1690 "2020-09-08T12:00:60Z",
1691 "2020-09-08T12:00:60.123Z",
1692 "2020-09-08T12:00:60.123456+02:00",
1693 "2020-09-08T12:00:60.1234567891234567+02:00",
1694 "2020-09-08T12:00:60.999999999+02:00",
1695 "2020-09-08t12:00:12.12345678+00:00",
1696 "2020-09-08t12:00:12+00:00",
1697 "2020-09-08t12:00:12Z",
1698 ];
1699
1700 for case in cases {
1701 let chrono = DateTime::parse_from_rfc3339(case).unwrap();
1702 let chrono_utc = chrono.with_timezone(&Utc);
1703
1704 let custom = string_to_datetime(&Utc, case).unwrap();
1705 assert_eq!(chrono_utc, custom)
1706 }
1707 }
1708
1709 #[test]
1710 fn string_to_timestamp_naive() {
1711 let cases = [
1712 "2018-11-13T17:11:10.011375885995",
1713 "2030-12-04T17:11:10.123",
1714 "2030-12-04T17:11:10.1234",
1715 "2030-12-04T17:11:10.123456",
1716 ];
1717 for case in cases {
1718 let chrono = NaiveDateTime::parse_from_str(case, "%Y-%m-%dT%H:%M:%S%.f").unwrap();
1719 let custom = string_to_datetime(&Utc, case).unwrap();
1720 assert_eq!(chrono, custom.naive_utc())
1721 }
1722 }
1723
1724 #[test]
1725 fn string_to_timestamp_invalid() {
1726 let cases = [
1728 ("", "timestamp must contain at least 10 characters"),
1729 ("SS", "timestamp must contain at least 10 characters"),
1730 ("Wed, 18 Feb 2015 23:16:09 GMT", "error parsing date"),
1731 ("1997-01-31H09:26:56.123Z", "invalid timestamp separator"),
1732 ("1997-01-31 09:26:56.123Z", "error parsing time"),
1733 ("1997:01:31T09:26:56.123Z", "error parsing date"),
1734 ("1997:1:31T09:26:56.123Z", "error parsing date"),
1735 ("1997-01-32T09:26:56.123Z", "error parsing date"),
1736 ("1997-13-32T09:26:56.123Z", "error parsing date"),
1737 ("1997-02-29T09:26:56.123Z", "error parsing date"),
1738 ("2015-02-30T17:35:20-08:00", "error parsing date"),
1739 ("1997-01-10T9:26:56.123Z", "error parsing time"),
1740 ("2015-01-20T25:35:20-08:00", "error parsing time"),
1741 ("1997-01-10T09:61:56.123Z", "error parsing time"),
1742 ("1997-01-10T09:61:90.123Z", "error parsing time"),
1743 ("1997-01-10T12:00:6.123Z", "error parsing time"),
1744 ("1997-01-31T092656.123Z", "error parsing time"),
1745 ("1997-01-10T12:00:06.", "error parsing time"),
1746 ("1997-01-10T12:00:06. ", "error parsing time"),
1747 ];
1748
1749 for (s, ctx) in cases {
1750 let expected = format!("Parser error: Error parsing timestamp from '{s}': {ctx}");
1751 let actual = string_to_datetime(&Utc, s).unwrap_err().to_string();
1752 assert_eq!(actual, expected)
1753 }
1754 }
1755
1756 fn parse_timestamp(s: &str) -> Result<i64, ArrowError> {
1758 let result = string_to_timestamp_nanos(s);
1759 if let Err(e) = &result {
1760 eprintln!("Error parsing timestamp '{s}': {e:?}");
1761 }
1762 result
1763 }
1764
1765 #[test]
1766 fn string_without_timezone_to_timestamp() {
1767 let naive_datetime = NaiveDateTime::new(
1770 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1771 NaiveTime::from_hms_nano_opt(13, 42, 29, 190855000).unwrap(),
1772 );
1773
1774 assert_eq!(
1776 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1777 parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
1778 );
1779
1780 assert_eq!(
1781 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1782 parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
1783 );
1784
1785 let naive_datetime = NaiveDateTime::new(
1786 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1787 NaiveTime::from_hms_nano_opt(13, 42, 29, 0).unwrap(),
1788 );
1789
1790 assert_eq!(
1792 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1793 parse_timestamp("2020-09-08T13:42:29").unwrap()
1794 );
1795
1796 assert_eq!(
1797 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1798 parse_timestamp("2020-09-08 13:42:29").unwrap()
1799 );
1800
1801 let tz: Tz = "+02:00".parse().unwrap();
1802 let date = string_to_datetime(&tz, "2020-09-08 13:42:29").unwrap();
1803 let utc = date.naive_utc().to_string();
1804 assert_eq!(utc, "2020-09-08 11:42:29");
1805 let local = date.naive_local().to_string();
1806 assert_eq!(local, "2020-09-08 13:42:29");
1807
1808 let date = string_to_datetime(&tz, "2020-09-08 13:42:29Z").unwrap();
1809 let utc = date.naive_utc().to_string();
1810 assert_eq!(utc, "2020-09-08 13:42:29");
1811 let local = date.naive_local().to_string();
1812 assert_eq!(local, "2020-09-08 15:42:29");
1813
1814 let dt =
1815 NaiveDateTime::parse_from_str("2020-09-08T13:42:29Z", "%Y-%m-%dT%H:%M:%SZ").unwrap();
1816 let local: Tz = "+08:00".parse().unwrap();
1817
1818 let date = string_to_datetime(&local, "2020-09-08T13:42:29Z").unwrap();
1820 assert_eq!(dt, date.naive_utc());
1821 assert_ne!(dt, date.naive_local());
1822
1823 let date = string_to_datetime(&local, "2020-09-08 13:42:29").unwrap();
1825 assert_eq!(dt, date.naive_local());
1826 assert_ne!(dt, date.naive_utc());
1827 }
1828
1829 #[test]
1830 fn parse_date32() {
1831 let cases = [
1832 "2020-09-08",
1833 "2020-9-8",
1834 "2020-09-8",
1835 "2020-9-08",
1836 "2020-12-1",
1837 "1690-2-5",
1838 "2020-09-08 01:02:03",
1839 ];
1840 for case in cases {
1841 let v = date32_to_datetime(Date32Type::parse(case).unwrap()).unwrap();
1842 let expected = NaiveDate::parse_from_str(case, "%Y-%m-%d")
1843 .or(NaiveDate::parse_from_str(case, "%Y-%m-%d %H:%M:%S"))
1844 .unwrap();
1845 assert_eq!(v.date(), expected);
1846 }
1847
1848 let err_cases = [
1849 "",
1850 "80-01-01",
1851 "342",
1852 "Foo",
1853 "2020-09-08-03",
1854 "2020--04-03",
1855 "2020--",
1856 "2020-09-08 01",
1857 "2020-09-08 01:02",
1858 "2020-09-08 01-02-03",
1859 "2020-9-8 01:02:03",
1860 "2020-09-08 1:2:3",
1861 ];
1862 for case in err_cases {
1863 assert_eq!(Date32Type::parse(case), None);
1864 }
1865 }
1866
1867 #[test]
1868 fn parse_date32_extended_year() {
1869 let cases: &[(&str, i32)] = &[
1871 ("+1970-01-01", 0),
1872 ("+2024-01-01", 19_723),
1873 ("-0001-01-01", -719_893),
1874 ("+29349-01-26", 10_000_000),
1875 ("+2739877-01-03", 1_000_000_000),
1876 ("+5881580-07-11", i32::MAX),
1878 ("-5877641-06-23", i32::MIN),
1879 ];
1880 for (input, expected) in cases {
1881 assert_eq!(Date32Type::parse(input), Some(*expected), "input: {input}");
1882 }
1883
1884 assert_eq!(Date32Type::parse("+5881580-07-12"), None);
1886 assert_eq!(Date32Type::parse("-5877641-06-22"), None);
1887 assert_eq!(Date32Type::parse("+2739877-02-30"), None);
1889 assert_eq!(Date32Type::parse("+2739877-13-01"), None);
1890 assert_eq!(Date32Type::parse("-2739877-02-30"), None);
1891 }
1892
1893 #[test]
1894 fn parse_time64_nanos() {
1895 assert_eq!(
1896 Time64NanosecondType::parse("02:10:01.1234567899999999"),
1897 Some(7_801_123_456_789)
1898 );
1899 assert_eq!(
1900 Time64NanosecondType::parse("02:10:01.1234567"),
1901 Some(7_801_123_456_700)
1902 );
1903 assert_eq!(
1904 Time64NanosecondType::parse("2:10:01.1234567"),
1905 Some(7_801_123_456_700)
1906 );
1907 assert_eq!(
1908 Time64NanosecondType::parse("12:10:01.123456789 AM"),
1909 Some(601_123_456_789)
1910 );
1911 assert_eq!(
1912 Time64NanosecondType::parse("12:10:01.123456789 am"),
1913 Some(601_123_456_789)
1914 );
1915 assert_eq!(
1916 Time64NanosecondType::parse("2:10:01.12345678 PM"),
1917 Some(51_001_123_456_780)
1918 );
1919 assert_eq!(
1920 Time64NanosecondType::parse("2:10:01.12345678 pm"),
1921 Some(51_001_123_456_780)
1922 );
1923 assert_eq!(
1924 Time64NanosecondType::parse("02:10:01"),
1925 Some(7_801_000_000_000)
1926 );
1927 assert_eq!(
1928 Time64NanosecondType::parse("2:10:01"),
1929 Some(7_801_000_000_000)
1930 );
1931 assert_eq!(
1932 Time64NanosecondType::parse("12:10:01 AM"),
1933 Some(601_000_000_000)
1934 );
1935 assert_eq!(
1936 Time64NanosecondType::parse("12:10:01 am"),
1937 Some(601_000_000_000)
1938 );
1939 assert_eq!(
1940 Time64NanosecondType::parse("2:10:01 PM"),
1941 Some(51_001_000_000_000)
1942 );
1943 assert_eq!(
1944 Time64NanosecondType::parse("2:10:01 pm"),
1945 Some(51_001_000_000_000)
1946 );
1947 assert_eq!(
1948 Time64NanosecondType::parse("02:10"),
1949 Some(7_800_000_000_000)
1950 );
1951 assert_eq!(Time64NanosecondType::parse("2:10"), Some(7_800_000_000_000));
1952 assert_eq!(
1953 Time64NanosecondType::parse("12:10 AM"),
1954 Some(600_000_000_000)
1955 );
1956 assert_eq!(
1957 Time64NanosecondType::parse("12:10 am"),
1958 Some(600_000_000_000)
1959 );
1960 assert_eq!(
1961 Time64NanosecondType::parse("2:10 PM"),
1962 Some(51_000_000_000_000)
1963 );
1964 assert_eq!(
1965 Time64NanosecondType::parse("2:10 pm"),
1966 Some(51_000_000_000_000)
1967 );
1968
1969 assert_eq!(Time64NanosecondType::parse("1"), Some(1));
1971
1972 assert_eq!(
1974 Time64NanosecondType::parse("23:59:60"),
1975 Some(86_400_000_000_000)
1976 );
1977
1978 assert_eq!(
1980 Time64NanosecondType::parse_formatted("02 - 10 - 01 - .1234567", "%H - %M - %S - %.f"),
1981 Some(7_801_123_456_700)
1982 );
1983 }
1984
1985 #[test]
1986 fn parse_time64_micros() {
1987 assert_eq!(
1989 Time64MicrosecondType::parse("02:10:01.1234"),
1990 Some(7_801_123_400)
1991 );
1992 assert_eq!(
1993 Time64MicrosecondType::parse("2:10:01.1234"),
1994 Some(7_801_123_400)
1995 );
1996 assert_eq!(
1997 Time64MicrosecondType::parse("12:10:01.123456 AM"),
1998 Some(601_123_456)
1999 );
2000 assert_eq!(
2001 Time64MicrosecondType::parse("12:10:01.123456 am"),
2002 Some(601_123_456)
2003 );
2004 assert_eq!(
2005 Time64MicrosecondType::parse("2:10:01.12345 PM"),
2006 Some(51_001_123_450)
2007 );
2008 assert_eq!(
2009 Time64MicrosecondType::parse("2:10:01.12345 pm"),
2010 Some(51_001_123_450)
2011 );
2012 assert_eq!(
2013 Time64MicrosecondType::parse("02:10:01"),
2014 Some(7_801_000_000)
2015 );
2016 assert_eq!(Time64MicrosecondType::parse("2:10:01"), Some(7_801_000_000));
2017 assert_eq!(
2018 Time64MicrosecondType::parse("12:10:01 AM"),
2019 Some(601_000_000)
2020 );
2021 assert_eq!(
2022 Time64MicrosecondType::parse("12:10:01 am"),
2023 Some(601_000_000)
2024 );
2025 assert_eq!(
2026 Time64MicrosecondType::parse("2:10:01 PM"),
2027 Some(51_001_000_000)
2028 );
2029 assert_eq!(
2030 Time64MicrosecondType::parse("2:10:01 pm"),
2031 Some(51_001_000_000)
2032 );
2033 assert_eq!(Time64MicrosecondType::parse("02:10"), Some(7_800_000_000));
2034 assert_eq!(Time64MicrosecondType::parse("2:10"), Some(7_800_000_000));
2035 assert_eq!(Time64MicrosecondType::parse("12:10 AM"), Some(600_000_000));
2036 assert_eq!(Time64MicrosecondType::parse("12:10 am"), Some(600_000_000));
2037 assert_eq!(
2038 Time64MicrosecondType::parse("2:10 PM"),
2039 Some(51_000_000_000)
2040 );
2041 assert_eq!(
2042 Time64MicrosecondType::parse("2:10 pm"),
2043 Some(51_000_000_000)
2044 );
2045
2046 assert_eq!(Time64MicrosecondType::parse("1"), Some(1));
2048
2049 assert_eq!(
2051 Time64MicrosecondType::parse("23:59:60"),
2052 Some(86_400_000_000)
2053 );
2054
2055 assert_eq!(
2057 Time64MicrosecondType::parse_formatted("02 - 10 - 01 - .1234", "%H - %M - %S - %.f"),
2058 Some(7_801_123_400)
2059 );
2060 }
2061
2062 #[test]
2063 fn parse_time32_millis() {
2064 assert_eq!(Time32MillisecondType::parse("02:10:01.1"), Some(7_801_100));
2066 assert_eq!(Time32MillisecondType::parse("2:10:01.1"), Some(7_801_100));
2067 assert_eq!(
2068 Time32MillisecondType::parse("12:10:01.123 AM"),
2069 Some(601_123)
2070 );
2071 assert_eq!(
2072 Time32MillisecondType::parse("12:10:01.123 am"),
2073 Some(601_123)
2074 );
2075 assert_eq!(
2076 Time32MillisecondType::parse("2:10:01.12 PM"),
2077 Some(51_001_120)
2078 );
2079 assert_eq!(
2080 Time32MillisecondType::parse("2:10:01.12 pm"),
2081 Some(51_001_120)
2082 );
2083 assert_eq!(Time32MillisecondType::parse("02:10:01"), Some(7_801_000));
2084 assert_eq!(Time32MillisecondType::parse("2:10:01"), Some(7_801_000));
2085 assert_eq!(Time32MillisecondType::parse("12:10:01 AM"), Some(601_000));
2086 assert_eq!(Time32MillisecondType::parse("12:10:01 am"), Some(601_000));
2087 assert_eq!(Time32MillisecondType::parse("2:10:01 PM"), Some(51_001_000));
2088 assert_eq!(Time32MillisecondType::parse("2:10:01 pm"), Some(51_001_000));
2089 assert_eq!(Time32MillisecondType::parse("02:10"), Some(7_800_000));
2090 assert_eq!(Time32MillisecondType::parse("2:10"), Some(7_800_000));
2091 assert_eq!(Time32MillisecondType::parse("12:10 AM"), Some(600_000));
2092 assert_eq!(Time32MillisecondType::parse("12:10 am"), Some(600_000));
2093 assert_eq!(Time32MillisecondType::parse("2:10 PM"), Some(51_000_000));
2094 assert_eq!(Time32MillisecondType::parse("2:10 pm"), Some(51_000_000));
2095
2096 assert_eq!(Time32MillisecondType::parse("1"), Some(1));
2098
2099 assert_eq!(Time32MillisecondType::parse("23:59:60"), Some(86_400_000));
2101
2102 assert_eq!(
2104 Time32MillisecondType::parse_formatted("02 - 10 - 01 - .1", "%H - %M - %S - %.f"),
2105 Some(7_801_100)
2106 );
2107 }
2108
2109 #[test]
2110 fn parse_time32_secs() {
2111 assert_eq!(Time32SecondType::parse("02:10:01.1"), Some(7_801));
2113 assert_eq!(Time32SecondType::parse("02:10:01"), Some(7_801));
2114 assert_eq!(Time32SecondType::parse("2:10:01"), Some(7_801));
2115 assert_eq!(Time32SecondType::parse("12:10:01 AM"), Some(601));
2116 assert_eq!(Time32SecondType::parse("12:10:01 am"), Some(601));
2117 assert_eq!(Time32SecondType::parse("2:10:01 PM"), Some(51_001));
2118 assert_eq!(Time32SecondType::parse("2:10:01 pm"), Some(51_001));
2119 assert_eq!(Time32SecondType::parse("02:10"), Some(7_800));
2120 assert_eq!(Time32SecondType::parse("2:10"), Some(7_800));
2121 assert_eq!(Time32SecondType::parse("12:10 AM"), Some(600));
2122 assert_eq!(Time32SecondType::parse("12:10 am"), Some(600));
2123 assert_eq!(Time32SecondType::parse("2:10 PM"), Some(51_000));
2124 assert_eq!(Time32SecondType::parse("2:10 pm"), Some(51_000));
2125
2126 assert_eq!(Time32SecondType::parse("1"), Some(1));
2128
2129 assert_eq!(Time32SecondType::parse("23:59:60"), Some(86400));
2131
2132 assert_eq!(
2134 Time32SecondType::parse_formatted("02 - 10 - 01", "%H - %M - %S"),
2135 Some(7_801)
2136 );
2137 }
2138
2139 #[test]
2140 fn test_string_to_time_invalid() {
2141 let cases = [
2142 "25:00",
2143 "9:00:",
2144 "009:00",
2145 "09:0:00",
2146 "25:00:00",
2147 "13:00 AM",
2148 "13:00 PM",
2149 "12:00. AM",
2150 "09:0:00",
2151 "09:01:0",
2152 "09:01:1",
2153 "9:1:0",
2154 "09:01:0",
2155 "1:00.123",
2156 "1:00:00.123f",
2157 " 9:00:00",
2158 ":09:00",
2159 "T9:00:00",
2160 "AM",
2161 ];
2162 for case in cases {
2163 assert!(string_to_time(case).is_none(), "{case}");
2164 }
2165 }
2166
2167 #[test]
2168 fn test_string_to_time_chrono() {
2169 let cases = [
2170 ("1:00", "%H:%M"),
2171 ("12:00", "%H:%M"),
2172 ("13:00", "%H:%M"),
2173 ("24:00", "%H:%M"),
2174 ("1:00:00", "%H:%M:%S"),
2175 ("12:00:30", "%H:%M:%S"),
2176 ("13:00:59", "%H:%M:%S"),
2177 ("24:00:60", "%H:%M:%S"),
2178 ("09:00:00", "%H:%M:%S%.f"),
2179 ("0:00:30.123456", "%H:%M:%S%.f"),
2180 ("0:00 AM", "%I:%M %P"),
2181 ("1:00 AM", "%I:%M %P"),
2182 ("12:00 AM", "%I:%M %P"),
2183 ("13:00 AM", "%I:%M %P"),
2184 ("0:00 PM", "%I:%M %P"),
2185 ("1:00 PM", "%I:%M %P"),
2186 ("12:00 PM", "%I:%M %P"),
2187 ("13:00 PM", "%I:%M %P"),
2188 ("1:00 pM", "%I:%M %P"),
2189 ("1:00 Pm", "%I:%M %P"),
2190 ("1:00 aM", "%I:%M %P"),
2191 ("1:00 Am", "%I:%M %P"),
2192 ("1:00:30.123456 PM", "%I:%M:%S%.f %P"),
2193 ("1:00:30.123456789 PM", "%I:%M:%S%.f %P"),
2194 ("1:00:30.123456789123 PM", "%I:%M:%S%.f %P"),
2195 ("1:00:30.1234 PM", "%I:%M:%S%.f %P"),
2196 ("1:00:30.123456 PM", "%I:%M:%S%.f %P"),
2197 ("1:00:30.123456789123456789 PM", "%I:%M:%S%.f %P"),
2198 ("1:00:30.12F456 PM", "%I:%M:%S%.f %P"),
2199 ];
2200 for (s, format) in cases {
2201 let chrono = NaiveTime::parse_from_str(s, format).ok();
2202 let custom = string_to_time(s);
2203 assert_eq!(chrono, custom, "{s}");
2204 }
2205 }
2206
2207 #[test]
2208 fn test_parse_interval() {
2209 let config = IntervalParseConfig::new(IntervalUnit::Month);
2210
2211 assert_eq!(
2212 Interval::new(1i32, 0i32, 0i64),
2213 Interval::parse("1 month", &config).unwrap(),
2214 );
2215
2216 assert_eq!(
2217 Interval::new(2i32, 0i32, 0i64),
2218 Interval::parse("2 month", &config).unwrap(),
2219 );
2220
2221 assert_eq!(
2222 Interval::new(-1i32, -18i32, -(NANOS_PER_DAY / 5)),
2223 Interval::parse("-1.5 months -3.2 days", &config).unwrap(),
2224 );
2225
2226 assert_eq!(
2227 Interval::new(0i32, 15i32, 0),
2228 Interval::parse("0.5 months", &config).unwrap(),
2229 );
2230
2231 assert_eq!(
2232 Interval::new(0i32, 15i32, 0),
2233 Interval::parse(".5 months", &config).unwrap(),
2234 );
2235
2236 assert_eq!(
2237 Interval::new(0i32, -15i32, 0),
2238 Interval::parse("-0.5 months", &config).unwrap(),
2239 );
2240
2241 assert_eq!(
2242 Interval::new(0i32, -15i32, 0),
2243 Interval::parse("-.5 months", &config).unwrap(),
2244 );
2245
2246 assert_eq!(
2247 Interval::new(2i32, 10i32, 9 * NANOS_PER_HOUR),
2248 Interval::parse("2.1 months 7.25 days 3 hours", &config).unwrap(),
2249 );
2250
2251 assert_eq!(
2252 Interval::parse("1 centurys 1 month", &config)
2253 .unwrap_err()
2254 .to_string(),
2255 r#"Parser error: Invalid input syntax for type interval: "1 centurys 1 month""#
2256 );
2257
2258 assert_eq!(
2259 Interval::new(37i32, 0i32, 0i64),
2260 Interval::parse("3 year 1 month", &config).unwrap(),
2261 );
2262
2263 assert_eq!(
2264 Interval::new(35i32, 0i32, 0i64),
2265 Interval::parse("3 year -1 month", &config).unwrap(),
2266 );
2267
2268 assert_eq!(
2269 Interval::new(-37i32, 0i32, 0i64),
2270 Interval::parse("-3 year -1 month", &config).unwrap(),
2271 );
2272
2273 assert_eq!(
2274 Interval::new(-35i32, 0i32, 0i64),
2275 Interval::parse("-3 year 1 month", &config).unwrap(),
2276 );
2277
2278 assert_eq!(
2279 Interval::new(0i32, 5i32, 0i64),
2280 Interval::parse("5 days", &config).unwrap(),
2281 );
2282
2283 assert_eq!(
2284 Interval::new(0i32, 7i32, 3 * NANOS_PER_HOUR),
2285 Interval::parse("7 days 3 hours", &config).unwrap(),
2286 );
2287
2288 assert_eq!(
2289 Interval::new(0i32, 7i32, 5 * NANOS_PER_MINUTE),
2290 Interval::parse("7 days 5 minutes", &config).unwrap(),
2291 );
2292
2293 assert_eq!(
2294 Interval::new(0i32, 7i32, -5 * NANOS_PER_MINUTE),
2295 Interval::parse("7 days -5 minutes", &config).unwrap(),
2296 );
2297
2298 assert_eq!(
2299 Interval::new(0i32, -7i32, 5 * NANOS_PER_HOUR),
2300 Interval::parse("-7 days 5 hours", &config).unwrap(),
2301 );
2302
2303 assert_eq!(
2304 Interval::new(
2305 0i32,
2306 -7i32,
2307 -5 * NANOS_PER_HOUR - 5 * NANOS_PER_MINUTE - 5 * NANOS_PER_SECOND
2308 ),
2309 Interval::parse("-7 days -5 hours -5 minutes -5 seconds", &config).unwrap(),
2310 );
2311
2312 assert_eq!(
2313 Interval::new(12i32, 0i32, 25 * NANOS_PER_MILLIS),
2314 Interval::parse("1 year 25 millisecond", &config).unwrap(),
2315 );
2316
2317 assert_eq!(
2318 Interval::new(
2319 12i32,
2320 1i32,
2321 (NANOS_PER_SECOND as f64 * 0.000000001_f64) as i64
2322 ),
2323 Interval::parse("1 year 1 day 0.000000001 seconds", &config).unwrap(),
2324 );
2325
2326 assert_eq!(
2327 Interval::new(12i32, 1i32, NANOS_PER_MILLIS / 10),
2328 Interval::parse("1 year 1 day 0.1 milliseconds", &config).unwrap(),
2329 );
2330
2331 assert_eq!(
2332 Interval::new(12i32, 1i32, 1000i64),
2333 Interval::parse("1 year 1 day 1 microsecond", &config).unwrap(),
2334 );
2335
2336 assert_eq!(
2337 Interval::new(12i32, 1i32, 1i64),
2338 Interval::parse("1 year 1 day 1 nanoseconds", &config).unwrap(),
2339 );
2340
2341 assert_eq!(
2342 Interval::new(1i32, 0i32, -NANOS_PER_SECOND),
2343 Interval::parse("1 month -1 second", &config).unwrap(),
2344 );
2345
2346 assert_eq!(
2347 Interval::new(
2348 -13i32,
2349 -8i32,
2350 -NANOS_PER_HOUR
2351 - NANOS_PER_MINUTE
2352 - NANOS_PER_SECOND
2353 - (1.11_f64 * NANOS_PER_MILLIS as f64) as i64
2354 ),
2355 Interval::parse(
2356 "-1 year -1 month -1 week -1 day -1 hour -1 minute -1 second -1.11 millisecond",
2357 &config
2358 )
2359 .unwrap(),
2360 );
2361
2362 assert_eq!(
2364 Interval::new(1, 0, 0),
2365 Interval::parse("1", &config).unwrap()
2366 );
2367 assert_eq!(
2368 Interval::new(42, 0, 0),
2369 Interval::parse("42", &config).unwrap()
2370 );
2371 assert_eq!(
2372 Interval::new(0, 0, 42_000_000_000),
2373 Interval::parse("42", &IntervalParseConfig::new(IntervalUnit::Second)).unwrap()
2374 );
2375
2376 assert_eq!(
2378 Interval::new(1, 0, 0),
2379 Interval::parse("1 mon", &config).unwrap()
2380 );
2381 assert_eq!(
2382 Interval::new(1, 0, 0),
2383 Interval::parse("1 mons", &config).unwrap()
2384 );
2385 assert_eq!(
2386 Interval::new(0, 0, 1_000_000),
2387 Interval::parse("1 ms", &config).unwrap()
2388 );
2389 assert_eq!(
2390 Interval::new(0, 0, 1_000),
2391 Interval::parse("1 us", &config).unwrap()
2392 );
2393
2394 assert_eq!(
2396 Interval::new(0, 0, 1_000),
2397 Interval::parse("1us", &config).unwrap()
2398 );
2399 assert_eq!(
2400 Interval::new(0, 0, NANOS_PER_SECOND),
2401 Interval::parse("1s", &config).unwrap()
2402 );
2403 assert_eq!(
2404 Interval::new(1, 2, 10_864_000_000_000),
2405 Interval::parse("1mon 2days 3hr 1min 4sec", &config).unwrap()
2406 );
2407
2408 assert_eq!(
2409 Interval::new(
2410 -13i32,
2411 -8i32,
2412 -NANOS_PER_HOUR
2413 - NANOS_PER_MINUTE
2414 - NANOS_PER_SECOND
2415 - (1.11_f64 * NANOS_PER_MILLIS as f64) as i64
2416 ),
2417 Interval::parse(
2418 "-1year -1month -1week -1day -1 hour -1 minute -1 second -1.11millisecond",
2419 &config
2420 )
2421 .unwrap(),
2422 );
2423
2424 assert_eq!(
2425 Interval::parse("1h s", &config).unwrap_err().to_string(),
2426 r#"Parser error: Invalid input syntax for type interval: "1h s""#
2427 );
2428
2429 assert_eq!(
2430 Interval::parse("1XX", &config).unwrap_err().to_string(),
2431 r#"Parser error: Invalid input syntax for type interval: "1XX""#
2432 );
2433 }
2434
2435 #[test]
2436 fn test_duplicate_interval_type() {
2437 let config = IntervalParseConfig::new(IntervalUnit::Month);
2438
2439 let err = Interval::parse("1 month 1 second 1 second", &config)
2440 .expect_err("parsing interval should have failed");
2441 assert_eq!(
2442 r#"ParseError("Invalid input syntax for type interval: \"1 month 1 second 1 second\". Repeated type 'second'")"#,
2443 format!("{err:?}")
2444 );
2445
2446 let err = Interval::parse("1 century 2 centuries", &config)
2448 .expect_err("parsing interval should have failed");
2449 assert_eq!(
2450 r#"ParseError("Invalid input syntax for type interval: \"1 century 2 centuries\". Repeated type 'centuries'")"#,
2451 format!("{err:?}")
2452 );
2453 }
2454
2455 #[test]
2456 fn test_interval_amount_parsing() {
2457 let result = IntervalAmount::from_str("123").unwrap();
2459 let expected = IntervalAmount::new(123, 0);
2460
2461 assert_eq!(result, expected);
2462
2463 let result = IntervalAmount::from_str("0.3").unwrap();
2465 let expected = IntervalAmount::new(0, 3 * 10_i64.pow(INTERVAL_PRECISION - 1));
2466
2467 assert_eq!(result, expected);
2468
2469 let result = IntervalAmount::from_str("-3.5").unwrap();
2471 let expected = IntervalAmount::new(-3, -5 * 10_i64.pow(INTERVAL_PRECISION - 1));
2472
2473 assert_eq!(result, expected);
2474
2475 let result = IntervalAmount::from_str("3.");
2477 assert!(result.is_err());
2478
2479 let result = IntervalAmount::from_str("3.-5");
2481 assert!(result.is_err());
2482 }
2483
2484 #[test]
2485 fn test_interval_precision() {
2486 let config = IntervalParseConfig::new(IntervalUnit::Month);
2487
2488 let result = Interval::parse("100000.1 days", &config).unwrap();
2489 let expected = Interval::new(0_i32, 100_000_i32, NANOS_PER_DAY / 10);
2490
2491 assert_eq!(result, expected);
2492 }
2493
2494 #[test]
2495 fn test_interval_addition() {
2496 let start = Interval::new(1, 2, 3);
2498 let expected = Interval::new(4921, 2, 3);
2499
2500 let result = start
2501 .add(
2502 IntervalAmount::new(4, 10_i64.pow(INTERVAL_PRECISION - 1)),
2503 IntervalUnit::Century,
2504 )
2505 .unwrap();
2506
2507 assert_eq!(result, expected);
2508
2509 let start = Interval::new(1, 2, 3);
2511 let expected = Interval::new(1231, 2, 3);
2512
2513 let result = start
2514 .add(
2515 IntervalAmount::new(10, 25 * 10_i64.pow(INTERVAL_PRECISION - 2)),
2516 IntervalUnit::Decade,
2517 )
2518 .unwrap();
2519
2520 assert_eq!(result, expected);
2521
2522 let start = Interval::new(1, 2, 3);
2524 let expected = Interval::new(364, 2, 3);
2525
2526 let result = start
2527 .add(
2528 IntervalAmount::new(30, 3 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2529 IntervalUnit::Year,
2530 )
2531 .unwrap();
2532
2533 assert_eq!(result, expected);
2534
2535 let start = Interval::new(1, 2, 3);
2537 let expected = Interval::new(2, 17, 3);
2538
2539 let result = start
2540 .add(
2541 IntervalAmount::new(1, 5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2542 IntervalUnit::Month,
2543 )
2544 .unwrap();
2545
2546 assert_eq!(result, expected);
2547
2548 let start = Interval::new(1, 25, 3);
2550 let expected = Interval::new(1, 11, 3);
2551
2552 let result = start
2553 .add(IntervalAmount::new(-2, 0), IntervalUnit::Week)
2554 .unwrap();
2555
2556 assert_eq!(result, expected);
2557
2558 let start = Interval::new(12, 15, 3);
2560 let expected = Interval::new(12, 17, 3 + 17_280 * NANOS_PER_SECOND);
2561
2562 let result = start
2563 .add(
2564 IntervalAmount::new(2, 2 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2565 IntervalUnit::Day,
2566 )
2567 .unwrap();
2568
2569 assert_eq!(result, expected);
2570
2571 let start = Interval::new(1, 2, 3);
2573 let expected = Interval::new(1, 2, 3 + 45_000 * NANOS_PER_SECOND);
2574
2575 let result = start
2576 .add(
2577 IntervalAmount::new(12, 5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2578 IntervalUnit::Hour,
2579 )
2580 .unwrap();
2581
2582 assert_eq!(result, expected);
2583
2584 let start = Interval::new(0, 0, -3);
2586 let expected = Interval::new(0, 0, -90_000_000_000 - 3);
2587
2588 let result = start
2589 .add(
2590 IntervalAmount::new(-1, -5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2591 IntervalUnit::Minute,
2592 )
2593 .unwrap();
2594
2595 assert_eq!(result, expected);
2596 }
2597
2598 #[test]
2599 fn string_to_timestamp_old() {
2600 parse_timestamp("1677-06-14T07:29:01.256")
2601 .map_err(|e| assert!(e.to_string().ends_with(ERR_NANOSECONDS_NOT_SUPPORTED)))
2602 .unwrap_err();
2603 }
2604
2605 #[test]
2606 fn test_parse_decimal_with_parameter() {
2607 let tests = [
2608 ("0", 0i128),
2609 ("123.123", 123123i128),
2610 ("123.1234", 123123i128),
2611 ("123.1", 123100i128),
2612 ("123", 123000i128),
2613 ("-123.123", -123123i128),
2614 ("-123.1234", -123123i128),
2615 ("-123.1", -123100i128),
2616 ("-123", -123000i128),
2617 ("0.0000123", 0i128),
2618 ("12.", 12000i128),
2619 ("-12.", -12000i128),
2620 ("00.1", 100i128),
2621 ("-00.1", -100i128),
2622 ("12345678912345678.1234", 12345678912345678123i128),
2623 ("-12345678912345678.1234", -12345678912345678123i128),
2624 ("99999999999999999.999", 99999999999999999999i128),
2625 ("-99999999999999999.999", -99999999999999999999i128),
2626 (".123", 123i128),
2627 ("-.123", -123i128),
2628 ("123.", 123000i128),
2629 ("-123.", -123000i128),
2630 ];
2631 for (s, i) in tests {
2632 let result_128 = parse_decimal::<Decimal128Type>(s, 20, 3);
2633 assert_eq!(i, result_128.unwrap());
2634 let result_256 = parse_decimal::<Decimal256Type>(s, 20, 3);
2635 assert_eq!(i256::from_i128(i), result_256.unwrap());
2636 }
2637
2638 let e_notation_tests = [
2639 ("1.23e3", "1230.0", 2),
2640 ("5.6714e+2", "567.14", 4),
2641 ("5.6714e-2", "0.056714", 4),
2642 ("5.6714e-2", "0.056714", 3),
2643 ("5.6741214125e2", "567.41214125", 4),
2644 ("8.91E4", "89100.0", 2),
2645 ("3.14E+5", "314000.0", 2),
2646 ("2.718e0", "2.718", 2),
2647 ("9.999999e-1", "0.9999999", 4),
2648 ("1.23e+3", "1230", 2),
2649 ("1.234559e+3", "1234.559", 2),
2650 ("1.00E-10", "0.0000000001", 11),
2651 ("1.23e-4", "0.000123", 2),
2652 ("9.876e7", "98760000.0", 2),
2653 ("5.432E+8", "543200000.0", 10),
2654 ("1.234567e9", "1234567000.0", 2),
2655 ("1.234567e2", "123.45670000", 2),
2656 ("4749.3e-5", "0.047493", 10),
2657 ("4749.3e+5", "474930000", 10),
2658 ("4749.3e-5", "0.047493", 1),
2659 ("4749.3e+5", "474930000", 1),
2660 ("0E-8", "0", 10),
2661 ("0E+6", "0", 10),
2662 ("1E-8", "0.00000001", 10),
2663 ("12E+6", "12000000", 10),
2664 ("12E-6", "0.000012", 10),
2665 ("0.1e-6", "0.0000001", 10),
2666 ("0.1e+6", "100000", 10),
2667 ("0.12e-6", "0.00000012", 10),
2668 ("0.12e+6", "120000", 10),
2669 ("000000000001e0", "000000000001", 3),
2670 ("000001.1034567002e0", "000001.1034567002", 3),
2671 ("1.234e16", "12340000000000000", 0),
2672 ("123.4e16", "1234000000000000000", 0),
2673 ];
2674 for (e, d, scale) in e_notation_tests {
2675 let result_128_e = parse_decimal::<Decimal128Type>(e, 20, scale);
2676 let result_128_d = parse_decimal::<Decimal128Type>(d, 20, scale);
2677 assert_eq!(result_128_e.unwrap(), result_128_d.unwrap());
2678 let result_256_e = parse_decimal::<Decimal256Type>(e, 20, scale);
2679 let result_256_d = parse_decimal::<Decimal256Type>(d, 20, scale);
2680 assert_eq!(result_256_e.unwrap(), result_256_d.unwrap());
2681 }
2682 let can_not_parse_tests = [
2683 "123,123",
2684 ".",
2685 "123.123.123",
2686 "",
2687 "+",
2688 "-",
2689 "e",
2690 "1.3e+e3",
2691 "5.6714ee-2",
2692 "4.11ee-+4",
2693 "4.11e++4",
2694 "1.1e.12",
2695 "1.23e+3.",
2696 "1.23e+3.1",
2697 "1e",
2698 "1e+",
2699 "1e-",
2700 ];
2701 for s in can_not_parse_tests {
2702 let result_128 = parse_decimal::<Decimal128Type>(s, 20, 3);
2703 assert_eq!(
2704 format!("Parser error: can't parse the string value {s} to decimal"),
2705 result_128.unwrap_err().to_string()
2706 );
2707 let result_256 = parse_decimal::<Decimal256Type>(s, 20, 3);
2708 assert_eq!(
2709 format!("Parser error: can't parse the string value {s} to decimal"),
2710 result_256.unwrap_err().to_string()
2711 );
2712 }
2713 let overflow_parse_tests = [
2714 ("12345678", 3),
2715 ("1.2345678e7", 3),
2716 ("12345678.9", 3),
2717 ("1.23456789e+7", 3),
2718 ("99999999.99", 3),
2719 ("9.999999999e7", 3),
2720 ("12345678908765.123456", 3),
2721 ("123456789087651234.56e-4", 3),
2722 ("1234560000000", 0),
2723 ("12345678900.0", 0),
2724 ("1.23456e12", 0),
2725 ];
2726 for (s, scale) in overflow_parse_tests {
2727 let result_128 = parse_decimal::<Decimal128Type>(s, 10, scale);
2728 let expected_128 = "Parser error: parse decimal overflow";
2729 let actual_128 = result_128.unwrap_err().to_string();
2730
2731 assert!(
2732 actual_128.contains(expected_128),
2733 "actual: '{actual_128}', expected: '{expected_128}'"
2734 );
2735
2736 let result_256 = parse_decimal::<Decimal256Type>(s, 10, scale);
2737 let expected_256 = "Parser error: parse decimal overflow";
2738 let actual_256 = result_256.unwrap_err().to_string();
2739
2740 assert!(
2741 actual_256.contains(expected_256),
2742 "actual: '{actual_256}', expected: '{expected_256}'"
2743 );
2744 }
2745
2746 let edge_tests_128 = [
2747 (
2748 "99999999999999999999999999999999999999",
2749 99999999999999999999999999999999999999i128,
2750 0,
2751 ),
2752 (
2753 "999999999999999999999999999999999999.99",
2754 99999999999999999999999999999999999999i128,
2755 2,
2756 ),
2757 (
2758 "9999999999999999999999999.9999999999999",
2759 99999999999999999999999999999999999999i128,
2760 13,
2761 ),
2762 (
2763 "9999999999999999999999999",
2764 99999999999999999999999990000000000000i128,
2765 13,
2766 ),
2767 (
2768 "0.99999999999999999999999999999999999999",
2769 99999999999999999999999999999999999999i128,
2770 38,
2771 ),
2772 (
2773 "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001016744",
2774 0i128,
2775 15,
2776 ),
2777 ("1.016744e-320", 0i128, 15),
2778 ("-1e3", -1000000000i128, 6),
2779 ("+1e3", 1000000000i128, 6),
2780 ("-1e31", -10000000000000000000000000000000000000i128, 6),
2781 ];
2782 for (s, i, scale) in edge_tests_128 {
2783 let result_128 = parse_decimal::<Decimal128Type>(s, 38, scale);
2784 assert_eq!(i, result_128.unwrap());
2785 }
2786 let edge_tests_256 = [
2787 (
2788 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2789 i256::from_string(
2790 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2791 )
2792 .unwrap(),
2793 0,
2794 ),
2795 (
2796 "999999999999999999999999999999999999999999999999999999999999999999999999.9999",
2797 i256::from_string(
2798 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2799 )
2800 .unwrap(),
2801 4,
2802 ),
2803 (
2804 "99999999999999999999999999999999999999999999999999.99999999999999999999999999",
2805 i256::from_string(
2806 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2807 )
2808 .unwrap(),
2809 26,
2810 ),
2811 (
2812 "9.999999999999999999999999999999999999999999999999999999999999999999999999999e49",
2813 i256::from_string(
2814 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2815 )
2816 .unwrap(),
2817 26,
2818 ),
2819 (
2820 "99999999999999999999999999999999999999999999999999",
2821 i256::from_string(
2822 "9999999999999999999999999999999999999999999999999900000000000000000000000000",
2823 )
2824 .unwrap(),
2825 26,
2826 ),
2827 (
2828 "9.9999999999999999999999999999999999999999999999999e+49",
2829 i256::from_string(
2830 "9999999999999999999999999999999999999999999999999900000000000000000000000000",
2831 )
2832 .unwrap(),
2833 26,
2834 ),
2835 ];
2836 for (s, i, scale) in edge_tests_256 {
2837 let result = parse_decimal::<Decimal256Type>(s, 76, scale);
2838 assert_eq!(i, result.unwrap());
2839 }
2840
2841 let zero_scale_tests = [
2842 (".123", 0, 3),
2843 ("0.123", 0, 3),
2844 ("1.0", 1, 3),
2845 ("1.2", 1, 3),
2846 ("1.00", 1, 3),
2847 ("1.23", 1, 3),
2848 ("1.000", 1, 3),
2849 ("1.123", 1, 3),
2850 ("123.0", 123, 3),
2851 ("123.4", 123, 3),
2852 ("123.00", 123, 3),
2853 ("123.45", 123, 3),
2854 ("123.000000000000000000004", 123, 3),
2855 ("0.123e2", 12, 3),
2856 ("0.123e4", 1230, 10),
2857 ("1.23e4", 12300, 10),
2858 ("12.3e4", 123000, 10),
2859 ("123e4", 1230000, 10),
2860 (
2861 "20000000000000000000000000000000000002.0",
2862 20000000000000000000000000000000000002,
2863 38,
2864 ),
2865 ];
2866 for (s, i, precision) in zero_scale_tests {
2867 let result_128 = parse_decimal::<Decimal128Type>(s, precision, 0).unwrap();
2868 assert_eq!(i, result_128);
2869 }
2870
2871 let can_not_parse_zero_scale = [".", "blag", "", "+", "-", "e"];
2872 for s in can_not_parse_zero_scale {
2873 let result_128 = parse_decimal::<Decimal128Type>(s, 5, 0);
2874 assert_eq!(
2875 format!("Parser error: can't parse the string value {s} to decimal"),
2876 result_128.unwrap_err().to_string(),
2877 );
2878 }
2879 }
2880
2881 #[test]
2882 fn test_parse_empty() {
2883 assert_eq!(Int32Type::parse(""), None);
2884 assert_eq!(Int64Type::parse(""), None);
2885 assert_eq!(UInt32Type::parse(""), None);
2886 assert_eq!(UInt64Type::parse(""), None);
2887 assert_eq!(Float32Type::parse(""), None);
2888 assert_eq!(Float64Type::parse(""), None);
2889 assert_eq!(Int32Type::parse("+"), None);
2890 assert_eq!(Int64Type::parse("+"), None);
2891 assert_eq!(UInt32Type::parse("+"), None);
2892 assert_eq!(UInt64Type::parse("+"), None);
2893 assert_eq!(Float32Type::parse("+"), None);
2894 assert_eq!(Float64Type::parse("+"), None);
2895 assert_eq!(TimestampNanosecondType::parse(""), None);
2896 assert_eq!(Date32Type::parse(""), None);
2897 }
2898
2899 #[test]
2900 fn test_parse_interval_month_day_nano_config() {
2901 let interval = parse_interval_month_day_nano_config(
2902 "1",
2903 IntervalParseConfig::new(IntervalUnit::Second),
2904 )
2905 .unwrap();
2906 assert_eq!(interval.months, 0);
2907 assert_eq!(interval.days, 0);
2908 assert_eq!(interval.nanoseconds, NANOS_PER_SECOND);
2909 }
2910 #[test]
2911 fn test_parse_prefix_white_space() {
2912 assert_eq!(Float64Type::parse(" 1.5"), Some(1.5));
2913 assert_eq!(Float64Type::parse("\t\n 20.54"), Some(20.54));
2914 assert_eq!(Float64Type::parse("\n2.5"), Some(2.5));
2915 assert_eq!(Float64Type::parse("\n-942.5423"), Some(-942.5423));
2916 assert_eq!(Float64Type::parse("\n\t\n\t\n40.5123"), Some(40.5123));
2917 assert_eq!(Float64Type::parse(" 1.5"), Some(1.5));
2918 assert_eq!(Float64Type::parse("\n\t\n\t\n-40.5123"), Some(-40.5123));
2919 assert_eq!(Float64Type::parse(" -1.5"), Some(-1.5));
2920 assert_eq!(Int32Type::parse(" 3"), Some(3));
2921 assert_eq!(Int32Type::parse(" 30"), Some(30));
2922 assert_eq!(Int32Type::parse("\n \n 100"), Some(100));
2923 assert_eq!(Int32Type::parse(" \n25"), Some(25));
2924 assert_eq!(Int32Type::parse("\t800"), Some(800));
2925 assert_eq!(Int32Type::parse("\t \n \t 851"), Some(851));
2926 assert_eq!(Int32Type::parse("\t\n\t\n\n\n\t1"), Some(1));
2927 assert_eq!(Int32Type::parse(" \n-25"), Some(-25));
2928 assert_eq!(Int32Type::parse("\t-800"), Some(-800));
2929
2930 assert_eq!(Float64Type::parse("1.5 "), Some(1.5));
2932 assert_eq!(Float64Type::parse("40.5123\n"), Some(40.5123));
2933 assert_eq!(Float64Type::parse("40.5123\n\t\n\t\n"), Some(40.5123));
2934 assert_eq!(Float64Type::parse("-942.5423\t"), Some(-942.5423));
2935 assert_eq!(Int32Type::parse("3 "), Some(3));
2936 assert_eq!(Int32Type::parse("30 "), Some(30));
2937 assert_eq!(Int32Type::parse("-25 \n"), Some(-25));
2938 assert_eq!(Int32Type::parse("800\t"), Some(800));
2939 assert_eq!(Float64Type::parse(" 1.5 "), Some(1.5));
2941 assert_eq!(Float64Type::parse("\t\n 20.54 \t"), Some(20.54));
2942 assert_eq!(Float64Type::parse("\n-942.5423\n"), Some(-942.5423));
2943 assert_eq!(Int32Type::parse(" 3 "), Some(3));
2944 assert_eq!(Int32Type::parse("\n \n 100 \n"), Some(100));
2945 assert_eq!(Int32Type::parse("\t-800\t\n"), Some(-800));
2946
2947 assert_eq!(Float64Type::parse("1.5abc"), None);
2949 assert_eq!(Float64Type::parse("40.5123x"), None);
2950 assert_eq!(Int32Type::parse("30x"), None);
2951 assert_eq!(Int32Type::parse("100px"), None);
2952 assert_eq!(Int32Type::parse("-25!"), None);
2953 assert_eq!(Int32Type::parse("3j"), None);
2954 assert_eq!(Int32Type::parse("3"), Some(3));
2955 }
2956}