1use std::{collections::VecDeque, str};
2
3use crate::{
4 combined::{
5 LocalDate, LocalDateTime, LocalTime, PreciseLocalDateTime, PreciseLocalTime,
6 PreciseShiftedDateTime, ShiftedDateTime,
7 },
8 components::{
9 Day, ExtendedYear, Hour, Minute, Month, Nanosecond, Second, SimpleYear, Timeshift, Year,
10 YearDigits,
11 },
12 parse_utils::{any_of, is_digit, parse_n_digits, tag, take_while, ParseError},
13};
14
15pub struct Builder {
16 context: ParseContext,
17}
18
19impl Builder {
20 pub fn new_iso8601() -> Self {
21 Self {
22 context: ParseContext::new_iso8601(),
23 }
24 }
25 pub fn new_rfc3339() -> Self {
26 Self {
27 context: ParseContext::new_rfc3339(),
28 }
29 }
30 pub fn new_strict_rfc3339() -> Self {
31 Self {
32 context: ParseContext::new_strict_rfc3339(),
33 }
34 }
35 pub fn space_allowed(&mut self, allowed: bool) -> &mut Self {
36 self.context.space_as_date_time_separator = allowed;
37 self
38 }
39 pub fn empty_date_separator_allowed(&mut self, allowed: bool) -> &mut Self {
40 self.context.empty_date_separator = allowed;
41 self
42 }
43 pub fn empty_time_separator_allowed(&mut self, allowed: bool) -> &mut Self {
44 self.context.empty_time_separator = allowed;
45 self
46 }
47 pub fn year_digits(&mut self, digits: usize) -> &mut Self {
48 self.context.year_digits = digits;
49 self
50 }
51 pub fn into_parser(self) -> Parser<Year> {
52 self.context.into_parser()
53 }
54}
55
56impl Default for Builder {
57 fn default() -> Self {
58 Self::new_iso8601()
59 }
60}
61
62#[derive(Debug)]
63pub enum Element<Y = SimpleYear> {
64 Year(Year<Y>),
65 Month(Month),
66 Day(Day),
67 Hour(Hour),
68 Minute(Minute),
69 Second(Second),
70 Nanosecond(Nanosecond),
71 Timeshift(Timeshift),
72}
73
74#[derive(Debug)]
75pub enum ElementTag {
76 Year,
77 Month,
78 Day,
79 Hour,
80 Minute,
81 Second,
82 Nanosecond,
83 Timeshift,
84}
85
86pub struct Parser<Y = SimpleYear> {
87 elements: VecDeque<Element<Y>>,
88 context: ParseContext,
89}
90
91#[derive(Debug)]
92pub enum BuildError<Y> {
93 NotEnoughElements,
94 Unexpected {
95 got: Element<Y>,
96 expected: ElementTag,
97 },
98}
99
100pub struct ParseContext {
101 space_as_date_time_separator: bool,
102 empty_date_separator: bool,
103 empty_time_separator: bool,
104 negative_zero: bool,
105 lower_case_t_z: bool,
106 year_digits: usize,
107}
108
109impl ParseContext {
110 pub fn new_rfc3339() -> Self {
111 Self {
112 space_as_date_time_separator: true,
113 empty_date_separator: false,
114 empty_time_separator: false,
115 negative_zero: true,
116 lower_case_t_z: true,
117 year_digits: 4,
118 }
119 }
120
121 pub fn new_strict_rfc3339() -> Self {
122 Self {
123 space_as_date_time_separator: false,
124 empty_date_separator: false,
125 empty_time_separator: false,
126 negative_zero: true,
127 lower_case_t_z: false,
128 year_digits: 4,
129 }
130 }
131
132 pub fn new_iso8601() -> Self {
133 Self {
134 space_as_date_time_separator: false,
135 empty_date_separator: true,
136 empty_time_separator: true,
137 negative_zero: false,
138 lower_case_t_z: false,
139 year_digits: 4,
140 }
141 }
142
143 pub fn into_parser<Y>(self) -> Parser<Y> {
144 Parser::<Y> {
145 elements: VecDeque::new(),
146 context: self,
147 }
148 }
149
150 fn allows_empty_date_separators(&self) -> bool {
151 self.empty_date_separator
152 }
153
154 fn allows_empty_time_separators(&self) -> bool {
155 self.empty_time_separator
156 }
157
158 fn allows_space_as_date_time_separator(&self) -> bool {
159 self.space_as_date_time_separator
160 }
161
162 fn allows_negative_zero(&self) -> bool {
163 self.negative_zero
164 }
165
166 fn t_seperator_set(&self) -> &'static [&'static [u8]] {
167 if self.lower_case_t_z {
168 &[b"T", b"t"]
169 } else {
170 &[b"T"]
171 }
172 }
173
174 fn z_seperator_set(&self) -> &'static [&'static [u8]] {
175 if self.lower_case_t_z {
176 &[b"Z", b"z"]
177 } else {
178 &[b"Z"]
179 }
180 }
181}
182
183impl Default for ParseContext {
184 fn default() -> Self {
185 Self::new_iso8601()
186 }
187}
188
189impl Parser<SimpleYear> {
190 pub fn new() -> Parser<SimpleYear> {
191 Parser {
192 elements: VecDeque::new(),
193 context: ParseContext::default(),
194 }
195 }
196}
197
198impl<const N: usize> Parser<ExtendedYear<N>> {
199 pub fn new_extended() -> Parser<ExtendedYear<N>> {
200 Parser {
201 elements: VecDeque::new(),
202 context: ParseContext::default(),
203 }
204 }
205}
206
207impl Default for Parser<SimpleYear> {
208 fn default() -> Self {
209 Self::new()
210 }
211}
212
213impl<Y> Parser<Y>
214where
215 Y: YearDigits,
216{
217 pub fn parse_year<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
218 let (year, rest) = parse_n_digits(Y::digits(), data)?;
219 let year = year.try_into().map_err(|_| ParseError::RangeError)?;
220 self.elements
221 .push_back(Element::Year(Y::from_digits(year)?));
222 Ok(rest)
223 }
224
225 pub fn parse_month<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
226 let (month, rest) = parse_n_digits(2, data)?;
227 self.elements.push_back(Element::Month(Month::new(month)?));
228 Ok(rest)
229 }
230
231 pub fn parse_day<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
232 let (day, rest) = parse_n_digits(2, data)?;
233 self.elements.push_back(Element::Day(Day::new(day)?));
234 Ok(rest)
235 }
236
237 pub fn parse_date_separator<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
238 let rest = match tag(b"-")(data) {
239 Ok((_, rest)) => rest,
240 Err(ParseError::Fail(x)) => {
241 if self.context.allows_empty_date_separators() {
242 data
243 } else {
244 return Err(ParseError::Fail(x));
245 }
246 }
247 Err(e) => return Err(e),
248 };
249 Ok(rest)
250 }
251
252 pub fn parse_date<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
253 let rest = self.parse_year(data)?;
254 let rest = self.parse_date_separator(rest)?;
255 let rest = self.parse_month(rest)?;
256 let rest = self.parse_date_separator(rest)?;
257 let rest = self.parse_day(rest)?;
258 Ok(rest)
259 }
260
261 pub fn parse_hour<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
262 let (hour, rest) = parse_n_digits(2, data)?;
263 self.elements.push_back(Element::Hour(Hour::new(hour)?));
264 Ok(rest)
265 }
266
267 pub fn parse_minute<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
268 let (minute, rest) = parse_n_digits(2, data)?;
269 self.elements
270 .push_back(Element::Minute(Minute::new(minute)?));
271 Ok(rest)
272 }
273
274 pub fn parse_second<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
275 let (second, rest) = parse_n_digits(2, data)?;
276 self.elements
277 .push_back(Element::Second(Second::new(second)?));
278 Ok(rest)
279 }
280
281 pub fn parse_time_separator<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
282 let rest = match tag(b":")(data) {
283 Ok((_, rest)) => rest,
284 Err(ParseError::Fail(x)) => {
285 if self.context.allows_empty_time_separators() {
286 data
287 } else {
288 return Err(ParseError::Fail(x));
289 }
290 }
291 Err(e) => return Err(e),
292 };
293 Ok(rest)
294 }
295
296 pub fn parse_time<'a>(&mut self, data: &'a [u8]) -> Result<&'a [u8], ParseError<'a>> {
297 let rest = self.parse_hour(data)?;
298 let rest = self.parse_time_separator(rest)?;
299 let rest = self.parse_minute(rest)?;
300 let rest = self.parse_time_separator(rest)?;
301 let rest = self.parse_second(rest)?;
302 Ok(rest)
303 }
304
305 pub fn parse_date_time_separator<'a>(
306 &mut self,
307 data: &'a [u8],
308 ) -> Result<&'a [u8], ParseError<'a>> {
309 let rest = match any_of(self.context.t_seperator_set())(data) {
310 Ok((_, rest)) => rest,
311 Err(ParseError::Fail(x)) => {
312 if self.context.allows_space_as_date_time_separator() {
313 let (_, rest) = tag(b" ")(data)?;
314 rest
315 } else {
316 return Err(ParseError::Fail(x));
317 }
318 }
319 Err(e) => return Err(e),
320 };
321 Ok(rest)
322 }
323
324 pub fn parse_fractional_separator<'a>(
325 &mut self,
326 data: &'a [u8],
327 ) -> Result<&'a [u8], ParseError<'a>> {
328 let (_, rest) = tag(b".")(data)?;
329 Ok(rest)
330 }
331
332 pub fn parse_fractional_seconds<'a>(
333 &mut self,
334 data: &'a [u8],
335 ) -> Result<&'a [u8], ParseError<'a>> {
336 let (digits, rest) = take_while(is_digit)(data)?;
337 if digits.len() > 9 {
338 return Err(ParseError::RangeError);
339 }
340 let number: u64 = str::from_utf8(digits)?.parse()?;
341 let factor = 10u64.pow((9 - digits.len()) as u32);
342 self.elements
343 .push_back(Element::Nanosecond(Nanosecond::new(number * factor)?));
344 Ok(rest)
345 }
346
347 pub fn parse_timezone_offset<'a>(
348 &mut self,
349 data: &'a [u8],
350 ) -> Result<&'a [u8], ParseError<'a>> {
351 let res = any_of(self.context.z_seperator_set())(data);
352 if let Ok((_, rest)) = res {
353 self.elements
354 .push_back(Element::Timeshift(Timeshift::utc()));
355 return Ok(rest);
356 }
357 if data.is_empty() {
358 return Err(ParseError::UnexpectedEof { needed: 1 });
359 }
360 let (non_negative, rest) = match data[0] {
361 b'-' => (false, &data[1..]),
362 b'+' => (true, &data[1..]),
363 _ => return Err(ParseError::Fail(data)),
364 };
365 let (hours, rest) = parse_n_digits(2, rest)?;
366 let rest = self.parse_time_separator(rest)?;
367 let (minutes, rest) = parse_n_digits(2, rest)?;
368 if !non_negative && hours == 0 && minutes == 0 && !self.context.allows_negative_zero() {
369 return Err(ParseError::NegativeZero);
370 }
371 let hours = Hour::new(hours)?;
372 let minutes = Minute::new(minutes)?;
373
374 self.elements
375 .push_back(Element::Timeshift(Timeshift::offset(
376 non_negative,
377 hours,
378 minutes,
379 )));
380
381 Ok(rest)
382 }
383
384 pub fn parse_local_date_time<'a>(
385 &mut self,
386 data: &'a [u8],
387 ) -> Result<&'a [u8], ParseError<'a>> {
388 let rest = self.parse_date(data)?;
389 let rest = self.parse_date_time_separator(rest)?;
390 let rest = self.parse_time(rest)?;
391 Ok(rest)
392 }
393
394 pub fn parse_precise_local_date_time<'a>(
395 &mut self,
396 data: &'a [u8],
397 ) -> Result<&'a [u8], ParseError<'a>> {
398 let rest = self.parse_local_date_time(data)?;
399 let rest = match self.parse_fractional_separator(rest) {
400 Ok(rest) => self.parse_fractional_seconds(rest)?,
401 Err(ParseError::Fail(_)) => {
402 self.elements
403 .push_back(Element::Nanosecond(Nanosecond::new(0)?));
404 return Ok(rest);
405 }
406 Err(e) => return Err(e),
407 };
408 Ok(rest)
409 }
410
411 pub fn parse_shifted_date_time<'a>(
412 &mut self,
413 data: &'a [u8],
414 ) -> Result<&'a [u8], ParseError<'a>> {
415 let rest = self.parse_local_date_time(data)?;
416 let rest = self.parse_timezone_offset(rest)?;
417 Ok(rest)
418 }
419
420 pub fn parse_precise_shifted_date_time<'a>(
421 &mut self,
422 data: &'a [u8],
423 ) -> Result<&'a [u8], ParseError<'a>> {
424 let rest = self.parse_precise_local_date_time(data)?;
425 let rest = self.parse_timezone_offset(rest)?;
426 Ok(rest)
427 }
428
429 pub fn parse_precise_local_time<'a>(
430 &mut self,
431 data: &'a [u8],
432 ) -> Result<&'a [u8], ParseError<'a>> {
433 let rest = self.parse_time(data)?;
434 let rest = match self.parse_fractional_separator(rest) {
435 Ok(rest) => self.parse_fractional_seconds(rest)?,
436 Err(ParseError::Fail(_)) => {
437 self.elements
438 .push_back(Element::Nanosecond(Nanosecond::new(0)?));
439 return Ok(rest);
440 }
441 Err(e) => return Err(e),
442 };
443 Ok(rest)
444 }
445
446 pub fn build_date(mut self) -> Result<LocalDate<Y>, BuildError<Y>> {
447 let year = match self.elements.pop_front() {
448 Some(Element::Year(year)) => year,
449 Some(e) => {
450 return Err(BuildError::Unexpected {
451 got: e,
452 expected: ElementTag::Year,
453 })
454 }
455 None => return Err(BuildError::NotEnoughElements),
456 };
457 let month = match self.elements.pop_front() {
458 Some(Element::Month(month)) => month,
459 Some(e) => {
460 return Err(BuildError::Unexpected {
461 got: e,
462 expected: ElementTag::Month,
463 })
464 }
465 None => return Err(BuildError::NotEnoughElements),
466 };
467 let day = match self.elements.pop_front() {
468 Some(Element::Day(day)) => day,
469 Some(e) => {
470 return Err(BuildError::Unexpected {
471 got: e,
472 expected: ElementTag::Day,
473 })
474 }
475 None => return Err(BuildError::NotEnoughElements),
476 };
477 Ok(LocalDate { year, month, day })
478 }
479
480 pub fn build_time(mut self) -> Result<LocalTime, BuildError<Y>> {
481 let hour = match self.elements.pop_front() {
482 Some(Element::Hour(hour)) => hour,
483 Some(e) => {
484 return Err(BuildError::Unexpected {
485 got: e,
486 expected: ElementTag::Hour,
487 })
488 }
489 None => return Err(BuildError::NotEnoughElements),
490 };
491 let minute = match self.elements.pop_front() {
492 Some(Element::Minute(minute)) => minute,
493 Some(e) => {
494 return Err(BuildError::Unexpected {
495 got: e,
496 expected: ElementTag::Minute,
497 })
498 }
499 None => return Err(BuildError::NotEnoughElements),
500 };
501 let second = match self.elements.pop_front() {
502 Some(Element::Second(second)) => second,
503 Some(e) => {
504 return Err(BuildError::Unexpected {
505 got: e,
506 expected: ElementTag::Second,
507 })
508 }
509 None => return Err(BuildError::NotEnoughElements),
510 };
511
512 Ok(LocalTime {
513 hour,
514 minute,
515 second,
516 })
517 }
518
519 pub fn build_precise_local_time(
520 mut self,
521 ) -> Result<PreciseLocalTime, BuildError<Y>> {
522 let hour = match self.elements.pop_front() {
523 Some(Element::Hour(hour)) => hour,
524 Some(e) => {
525 return Err(BuildError::Unexpected {
526 got: e,
527 expected: ElementTag::Hour,
528 })
529 }
530 None => return Err(BuildError::NotEnoughElements),
531 };
532 let minute = match self.elements.pop_front() {
533 Some(Element::Minute(minute)) => minute,
534 Some(e) => {
535 return Err(BuildError::Unexpected {
536 got: e,
537 expected: ElementTag::Minute,
538 })
539 }
540 None => return Err(BuildError::NotEnoughElements),
541 };
542 let second = match self.elements.pop_front() {
543 Some(Element::Second(second)) => second,
544 Some(e) => {
545 return Err(BuildError::Unexpected {
546 got: e,
547 expected: ElementTag::Second,
548 })
549 }
550 None => return Err(BuildError::NotEnoughElements),
551 };
552 let nanosecond = match self.elements.pop_front() {
553 Some(Element::Nanosecond(nanosecond)) => nanosecond,
554 Some(e) => {
555 return Err(BuildError::Unexpected {
556 got: e,
557 expected: ElementTag::Nanosecond,
558 })
559 }
560 None => return Err(BuildError::NotEnoughElements),
561 };
562
563 Ok(PreciseLocalTime {
564 hour,
565 minute,
566 second,
567 nanosecond,
568 })
569 }
570
571 pub fn build_local_date_time(
572 mut self,
573 ) -> Result<LocalDateTime<Y>, BuildError<Y>> {
574 let year = match self.elements.pop_front() {
575 Some(Element::Year(year)) => year,
576 Some(e) => {
577 return Err(BuildError::Unexpected {
578 got: e,
579 expected: ElementTag::Year,
580 })
581 }
582 None => return Err(BuildError::NotEnoughElements),
583 };
584 let month = match self.elements.pop_front() {
585 Some(Element::Month(month)) => month,
586 Some(e) => {
587 return Err(BuildError::Unexpected {
588 got: e,
589 expected: ElementTag::Month,
590 })
591 }
592 None => return Err(BuildError::NotEnoughElements),
593 };
594 let day = match self.elements.pop_front() {
595 Some(Element::Day(day)) => day,
596 Some(e) => {
597 return Err(BuildError::Unexpected {
598 got: e,
599 expected: ElementTag::Day,
600 })
601 }
602 None => return Err(BuildError::NotEnoughElements),
603 };
604 let hour = match self.elements.pop_front() {
605 Some(Element::Hour(hour)) => hour,
606 Some(e) => {
607 return Err(BuildError::Unexpected {
608 got: e,
609 expected: ElementTag::Hour,
610 })
611 }
612 None => return Err(BuildError::NotEnoughElements),
613 };
614 let minute = match self.elements.pop_front() {
615 Some(Element::Minute(minute)) => minute,
616 Some(e) => {
617 return Err(BuildError::Unexpected {
618 got: e,
619 expected: ElementTag::Minute,
620 })
621 }
622 None => return Err(BuildError::NotEnoughElements),
623 };
624 let second = match self.elements.pop_front() {
625 Some(Element::Second(second)) => second,
626 Some(e) => {
627 return Err(BuildError::Unexpected {
628 got: e,
629 expected: ElementTag::Second,
630 })
631 }
632 None => return Err(BuildError::NotEnoughElements),
633 };
634 Ok(LocalDateTime {
635 year,
636 month,
637 day,
638 hour,
639 minute,
640 second,
641 })
642 }
643
644 pub fn build_shifted_date_time(
645 mut self,
646 ) -> Result<ShiftedDateTime<Y>, BuildError<Y>> {
647 let year = match self.elements.pop_front() {
648 Some(Element::Year(year)) => year,
649 Some(e) => {
650 return Err(BuildError::Unexpected {
651 got: e,
652 expected: ElementTag::Year,
653 })
654 }
655 None => return Err(BuildError::NotEnoughElements),
656 };
657 let month = match self.elements.pop_front() {
658 Some(Element::Month(month)) => month,
659 Some(e) => {
660 return Err(BuildError::Unexpected {
661 got: e,
662 expected: ElementTag::Month,
663 })
664 }
665 None => return Err(BuildError::NotEnoughElements),
666 };
667 let day = match self.elements.pop_front() {
668 Some(Element::Day(day)) => day,
669 Some(e) => {
670 return Err(BuildError::Unexpected {
671 got: e,
672 expected: ElementTag::Day,
673 })
674 }
675 None => return Err(BuildError::NotEnoughElements),
676 };
677 let hour = match self.elements.pop_front() {
678 Some(Element::Hour(hour)) => hour,
679 Some(e) => {
680 return Err(BuildError::Unexpected {
681 got: e,
682 expected: ElementTag::Hour,
683 })
684 }
685 None => return Err(BuildError::NotEnoughElements),
686 };
687 let minute = match self.elements.pop_front() {
688 Some(Element::Minute(minute)) => minute,
689 Some(e) => {
690 return Err(BuildError::Unexpected {
691 got: e,
692 expected: ElementTag::Minute,
693 })
694 }
695 None => return Err(BuildError::NotEnoughElements),
696 };
697 let second = match self.elements.pop_front() {
698 Some(Element::Second(second)) => second,
699 Some(e) => {
700 return Err(BuildError::Unexpected {
701 got: e,
702 expected: ElementTag::Second,
703 })
704 }
705 None => return Err(BuildError::NotEnoughElements),
706 };
707 let timeshift = match self.elements.pop_front() {
708 Some(Element::Timeshift(timeshift)) => timeshift,
709 Some(e) => {
710 return Err(BuildError::Unexpected {
711 got: e,
712 expected: ElementTag::Timeshift,
713 })
714 }
715 None => return Err(BuildError::NotEnoughElements),
716 };
717 Ok(ShiftedDateTime {
718 year,
719 month,
720 day,
721 hour,
722 minute,
723 second,
724 timeshift,
725 })
726 }
727
728 pub fn build_precise_local_date_time(
729 mut self,
730 ) -> Result<PreciseLocalDateTime<Y>, BuildError<Y>> {
731 let year = match self.elements.pop_front() {
732 Some(Element::Year(year)) => year,
733 Some(e) => {
734 return Err(BuildError::Unexpected {
735 got: e,
736 expected: ElementTag::Year,
737 })
738 }
739 None => return Err(BuildError::NotEnoughElements),
740 };
741 let month = match self.elements.pop_front() {
742 Some(Element::Month(month)) => month,
743 Some(e) => {
744 return Err(BuildError::Unexpected {
745 got: e,
746 expected: ElementTag::Month,
747 })
748 }
749 None => return Err(BuildError::NotEnoughElements),
750 };
751 let day = match self.elements.pop_front() {
752 Some(Element::Day(day)) => day,
753 Some(e) => {
754 return Err(BuildError::Unexpected {
755 got: e,
756 expected: ElementTag::Day,
757 })
758 }
759 None => return Err(BuildError::NotEnoughElements),
760 };
761 let hour = match self.elements.pop_front() {
762 Some(Element::Hour(hour)) => hour,
763 Some(e) => {
764 return Err(BuildError::Unexpected {
765 got: e,
766 expected: ElementTag::Hour,
767 })
768 }
769 None => return Err(BuildError::NotEnoughElements),
770 };
771 let minute = match self.elements.pop_front() {
772 Some(Element::Minute(minute)) => minute,
773 Some(e) => {
774 return Err(BuildError::Unexpected {
775 got: e,
776 expected: ElementTag::Minute,
777 })
778 }
779 None => return Err(BuildError::NotEnoughElements),
780 };
781 let second = match self.elements.pop_front() {
782 Some(Element::Second(second)) => second,
783 Some(e) => {
784 return Err(BuildError::Unexpected {
785 got: e,
786 expected: ElementTag::Second,
787 })
788 }
789 None => return Err(BuildError::NotEnoughElements),
790 };
791 let nanosecond = match self.elements.pop_front() {
792 Some(Element::Nanosecond(nanosecond)) => nanosecond,
793 Some(e) => {
794 return Err(BuildError::Unexpected {
795 got: e,
796 expected: ElementTag::Nanosecond,
797 })
798 }
799 None => return Err(BuildError::NotEnoughElements),
800 };
801 Ok(PreciseLocalDateTime {
802 year,
803 month,
804 day,
805 hour,
806 minute,
807 second,
808 nanosecond,
809 })
810 }
811
812 pub fn build_precise_shifted_date_time(
813 mut self,
814 ) -> Result<PreciseShiftedDateTime<Y>, BuildError<Y>> {
815 let year = match self.elements.pop_front() {
816 Some(Element::Year(year)) => year,
817 Some(e) => {
818 return Err(BuildError::Unexpected {
819 got: e,
820 expected: ElementTag::Year,
821 })
822 }
823 None => return Err(BuildError::NotEnoughElements),
824 };
825 let month = match self.elements.pop_front() {
826 Some(Element::Month(month)) => month,
827 Some(e) => {
828 return Err(BuildError::Unexpected {
829 got: e,
830 expected: ElementTag::Month,
831 })
832 }
833 None => return Err(BuildError::NotEnoughElements),
834 };
835 let day = match self.elements.pop_front() {
836 Some(Element::Day(day)) => day,
837 Some(e) => {
838 return Err(BuildError::Unexpected {
839 got: e,
840 expected: ElementTag::Day,
841 })
842 }
843 None => return Err(BuildError::NotEnoughElements),
844 };
845 let hour = match self.elements.pop_front() {
846 Some(Element::Hour(hour)) => hour,
847 Some(e) => {
848 return Err(BuildError::Unexpected {
849 got: e,
850 expected: ElementTag::Hour,
851 })
852 }
853 None => return Err(BuildError::NotEnoughElements),
854 };
855 let minute = match self.elements.pop_front() {
856 Some(Element::Minute(minute)) => minute,
857 Some(e) => {
858 return Err(BuildError::Unexpected {
859 got: e,
860 expected: ElementTag::Minute,
861 })
862 }
863 None => return Err(BuildError::NotEnoughElements),
864 };
865 let second = match self.elements.pop_front() {
866 Some(Element::Second(second)) => second,
867 Some(e) => {
868 return Err(BuildError::Unexpected {
869 got: e,
870 expected: ElementTag::Second,
871 })
872 }
873 None => return Err(BuildError::NotEnoughElements),
874 };
875 let nanosecond = match self.elements.pop_front() {
876 Some(Element::Nanosecond(nanosecond)) => nanosecond,
877 Some(e) => {
878 return Err(BuildError::Unexpected {
879 got: e,
880 expected: ElementTag::Nanosecond,
881 })
882 }
883 None => return Err(BuildError::NotEnoughElements),
884 };
885 let timeshift = match self.elements.pop_front() {
886 Some(Element::Timeshift(timeshift)) => timeshift,
887 Some(e) => {
888 return Err(BuildError::Unexpected {
889 got: e,
890 expected: ElementTag::Timeshift,
891 })
892 }
893 None => return Err(BuildError::NotEnoughElements),
894 };
895 Ok(PreciseShiftedDateTime {
896 year,
897 month,
898 day,
899 hour,
900 minute,
901 second,
902 nanosecond,
903 timeshift,
904 })
905 }
906}
907
908#[cfg(test)]
909mod tests {
910 use super::Parser;
911
912 #[test]
913 pub fn test_parse_time() {
914 let mut parser = Parser::new();
915 let rest = b"20:10:21";
916 let rest = parser.parse_time(rest).unwrap();
917 assert_eq!(rest, b"");
918 let time = parser.build_time().unwrap();
919 assert_eq!(time, (20, 10, 21).try_into().unwrap())
920 }
921}