1use std::time::Duration;
36
37pub fn duration(input: &str) -> Result<Duration, crate::error::Error> {
76 crate::parser::duration(input)
77 .map(|(_, duration)| Ok(duration.to_std()))
78 .map_err(|_| crate::error::Error::ParseError)?
79}
80
81pub fn years(input: &str) -> Result<u64, crate::error::Error> {
94 crate::parser::duration(input)
95 .map(|(_, duration)| Ok(duration.to_std().as_secs() / crate::time::SECONDS_PER_YEAR))
96 .map_err(|_| crate::error::Error::ParseError)?
97}
98
99pub fn months(input: &str) -> Result<u64, crate::error::Error> {
113 crate::parser::duration(input)
114 .map(|(_, duration)| Ok(duration.to_std().as_secs() / crate::time::SECONDS_PER_MONTH))
115 .map_err(|_| crate::error::Error::ParseError)?
116}
117
118pub fn weeks(input: &str) -> Result<u64, crate::error::Error> {
133 crate::parser::duration(input)
134 .map(|(_, duration)| Ok(duration.to_std().as_secs() / crate::time::SECONDS_PER_WEEK))
135 .map_err(|_| crate::error::Error::ParseError)?
136}
137
138pub fn days(input: &str) -> Result<u64, crate::error::Error> {
154 crate::parser::duration(input)
155 .map(|(_, duration)| Ok(duration.to_std().as_secs() / crate::time::SECONDS_PER_DAY))
156 .map_err(|_| crate::error::Error::ParseError)?
157}
158
159pub fn hours(input: &str) -> Result<u64, crate::error::Error> {
175 crate::parser::duration(input)
176 .map(|(_, duration)| Ok(duration.to_std().as_secs() / crate::time::SECONDS_PER_HOUR))
177 .map_err(|_| crate::error::Error::ParseError)?
178}
179
180pub fn minutes(input: &str) -> Result<u64, crate::error::Error> {
197 crate::parser::duration(input)
198 .map(|(_, duration)| Ok(duration.to_std().as_secs() / crate::time::SECONDS_PER_MINUTE))
199 .map_err(|_| crate::error::Error::ParseError)?
200}
201
202pub fn seconds(input: &str) -> Result<u64, crate::error::Error> {
219 crate::parser::duration(input)
220 .map(|(_, duration)| Ok(duration.to_std().as_secs()))
221 .map_err(|_| crate::error::Error::ParseError)?
222}
223
224pub fn milliseconds(input: &str) -> Result<u128, crate::error::Error> {
242 crate::parser::duration(input)
243 .map(|(_, duration)| Ok(duration.to_std().as_millis()))
244 .map_err(|_| crate::error::Error::ParseError)?
245}
246
247pub fn nanoseconds(input: &str) -> Result<u128, crate::error::Error> {
264 crate::parser::duration(input)
265 .map(|(_, duration)| Ok(duration.to_std().as_nanos()))
266 .map_err(|_| crate::error::Error::ParseError)?
267}
268
269pub mod error {
270 use std::fmt;
272
273 #[derive(Debug, PartialEq)]
275 pub enum Error {
276 ParseError,
277 }
278
279 impl std::error::Error for Error {}
280
281 impl fmt::Display for Error {
282 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
283 match self {
284 Error::ParseError => write!(f, "parsing the expression failed"),
285 }
286 }
287 }
288}
289
290#[cfg(test)]
291mod tests {
292 use super::{
293 days, duration, hours, milliseconds, minutes, months, nanoseconds, seconds, weeks, years,
294 };
295 use std::time::Duration;
296
297 #[test]
298 fn test_duration() {
299 assert_eq!(
300 duration("1 year"),
301 Ok(Duration::new(crate::time::SECONDS_PER_YEAR, 0))
302 );
303 assert_eq!(
304 duration("1 month"),
305 Ok(Duration::new(crate::time::SECONDS_PER_MONTH, 0))
306 );
307 assert_eq!(
308 duration("1 week"),
309 Ok(Duration::new(crate::time::SECONDS_PER_WEEK, 0))
310 );
311 assert_eq!(
312 duration("1 day"),
313 Ok(Duration::new(crate::time::SECONDS_PER_DAY, 0))
314 );
315 assert_eq!(
316 duration("1 hour"),
317 Ok(Duration::new(crate::time::SECONDS_PER_HOUR, 0))
318 );
319 assert_eq!(
320 duration("1 minute"),
321 Ok(Duration::new(crate::time::SECONDS_PER_MINUTE, 0))
322 );
323 assert_eq!(duration("1 second"), Ok(Duration::new(1, 0)));
324 assert_eq!(duration("1 millisecond"), Ok(Duration::new(0, 1_000_000)));
325 assert_eq!(duration("1 nanosecond"), Ok(Duration::new(0, 1)));
326 assert_eq!(
327 duration("1 year 2 months"),
328 Ok(Duration::new(36_720_000, 0))
329 );
330 assert_eq!(
331 duration("1 year, 2 months"),
332 Ok(Duration::new(36_720_000, 0))
333 );
334 assert_eq!(
335 duration("1 year and 2 months"),
336 Ok(Duration::new(36_720_000, 0))
337 );
338 assert_eq!(
339 duration("1 year, 2 months and 3 weeks"),
340 Ok(Duration::new(38_534_400, 0))
341 );
342 assert_eq!(
343 duration("1 year, 2 months, 3 weeks and 4 days"),
344 Ok(Duration::new(38_880_000, 0))
345 );
346 assert_eq!(
347 duration("1 year, 2 months, 3 weeks, 4 days and 5 hours"),
348 Ok(Duration::new(38_898_000, 0))
349 );
350 assert_eq!(
351 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours and 6 minutes"),
352 Ok(Duration::new(38_898_360, 0))
353 );
354 assert_eq!(
355 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes and 7 seconds"),
356 Ok(Duration::new(38_898_367, 0))
357 );
358 assert_eq!(
359 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds and 8 milliseconds"),
360 Ok(Duration::new(38_898_367, 8_000_000))
361 );
362 assert_eq!(
363 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds, 8 milliseconds and 9 nanoseconds"),
364 Ok(Duration::new(38_898_367, 8_000_009))
365 );
366 }
367
368 #[test]
369 fn test_years() {
370 assert_eq!(years("0 years"), Ok(0));
371 assert_eq!(years("0 year"), Ok(0));
372 assert_eq!(years("0 y"), Ok(0));
373 assert_eq!(years("0years"), Ok(0));
374 assert_eq!(years("0year"), Ok(0));
375 assert_eq!(years("0y"), Ok(0));
376 assert_eq!(years("1 year"), Ok(1));
377 assert_eq!(years("1 y"), Ok(1));
378 assert_eq!(years("1year"), Ok(1));
379 assert_eq!(years("1y"), Ok(1));
380 assert_eq!(years("2 years"), Ok(2));
381 assert_eq!(years("2 year"), Ok(2));
382 assert_eq!(years("2 y"), Ok(2));
383 assert_eq!(years("2years"), Ok(2));
384 assert_eq!(years("2year"), Ok(2));
385 assert_eq!(years("2y"), Ok(2));
386 }
387
388 #[test]
389 fn test_months() {
390 assert_eq!(months("1 year"), Ok(12));
391 assert_eq!(months("0 months"), Ok(0));
392 assert_eq!(months("0 month"), Ok(0));
393 assert_eq!(months("0 mo"), Ok(0));
394 assert_eq!(months("0months"), Ok(0));
395 assert_eq!(months("0month"), Ok(0));
396 assert_eq!(months("0mo"), Ok(0));
397 assert_eq!(months("1 month"), Ok(1));
398 assert_eq!(months("1 mo"), Ok(1));
399 assert_eq!(months("1month"), Ok(1));
400 assert_eq!(months("1mo"), Ok(1));
401 assert_eq!(months("2 months"), Ok(2));
402 assert_eq!(months("2 month"), Ok(2));
403 assert_eq!(months("2 mo"), Ok(2));
404 assert_eq!(months("2months"), Ok(2));
405 assert_eq!(months("2month"), Ok(2));
406 assert_eq!(months("2mo"), Ok(2));
407 }
408
409 #[test]
410 fn test_weeks() {
411 assert_eq!(weeks("1 year"), Ok(52));
412 assert_eq!(weeks("1 month"), Ok(4));
413 assert_eq!(weeks("0 weeks"), Ok(0));
414 assert_eq!(weeks("0 week"), Ok(0));
415 assert_eq!(weeks("0 w"), Ok(0));
416 assert_eq!(weeks("0weeks"), Ok(0));
417 assert_eq!(weeks("0week"), Ok(0));
418 assert_eq!(weeks("0w"), Ok(0));
419 assert_eq!(weeks("1 week"), Ok(1));
420 assert_eq!(weeks("1 w"), Ok(1));
421 assert_eq!(weeks("1week"), Ok(1));
422 assert_eq!(weeks("1w"), Ok(1));
423 assert_eq!(weeks("2 weeks"), Ok(2));
424 assert_eq!(weeks("2 week"), Ok(2));
425 assert_eq!(weeks("2 w"), Ok(2));
426 assert_eq!(weeks("2weeks"), Ok(2));
427 assert_eq!(weeks("2week"), Ok(2));
428 assert_eq!(weeks("2w"), Ok(2));
429 }
430
431 #[test]
432 fn test_days() {
433 assert_eq!(days("1 year"), Ok(365));
434 assert_eq!(days("1 month"), Ok(30));
435 assert_eq!(days("1 week"), Ok(7));
436 assert_eq!(days("0 days"), Ok(0));
437 assert_eq!(days("0 day"), Ok(0));
438 assert_eq!(days("0 d"), Ok(0));
439 assert_eq!(days("0days"), Ok(0));
440 assert_eq!(days("0day"), Ok(0));
441 assert_eq!(days("0d"), Ok(0));
442 assert_eq!(days("1 day"), Ok(1));
443 assert_eq!(days("1 d"), Ok(1));
444 assert_eq!(days("1day"), Ok(1));
445 assert_eq!(days("1d"), Ok(1));
446 assert_eq!(days("2 days"), Ok(2));
447 assert_eq!(days("2 day"), Ok(2));
448 assert_eq!(days("2 d"), Ok(2));
449 assert_eq!(days("2days"), Ok(2));
450 assert_eq!(days("2day"), Ok(2));
451 assert_eq!(days("2d"), Ok(2));
452 }
453
454 #[test]
455 fn test_hours() {
456 assert_eq!(hours("1 year"), Ok(8760));
457 assert_eq!(hours("1 month"), Ok(720));
458 assert_eq!(hours("1 week"), Ok(168));
459 assert_eq!(hours("1 day"), Ok(24));
460 assert_eq!(hours("0 hours"), Ok(0));
461 assert_eq!(hours("0 hour"), Ok(0));
462 assert_eq!(hours("0 h"), Ok(0));
463 assert_eq!(hours("0hours"), Ok(0));
464 assert_eq!(hours("0hour"), Ok(0));
465 assert_eq!(hours("0h"), Ok(0));
466 assert_eq!(hours("1 hour"), Ok(1));
467 assert_eq!(hours("1 h"), Ok(1));
468 assert_eq!(hours("1hour"), Ok(1));
469 assert_eq!(hours("1h"), Ok(1));
470 assert_eq!(hours("2 hours"), Ok(2));
471 assert_eq!(hours("2 hour"), Ok(2));
472 assert_eq!(hours("2 h"), Ok(2));
473 assert_eq!(hours("2hours"), Ok(2));
474 assert_eq!(hours("2hour"), Ok(2));
475 assert_eq!(hours("2h"), Ok(2));
476 }
477
478 #[test]
479 fn test_minutes() {
480 assert_eq!(minutes("1 year"), Ok(525_600));
481 assert_eq!(minutes("1 month"), Ok(43_200));
482 assert_eq!(minutes("1 week"), Ok(10_080));
483 assert_eq!(minutes("1 day"), Ok(1440));
484 assert_eq!(minutes("1 hour"), Ok(60));
485 assert_eq!(minutes("2 minutes"), Ok(2));
486 assert_eq!(minutes("1 minute"), Ok(1));
487 assert_eq!(minutes("2minutes"), Ok(2));
488 assert_eq!(minutes("1minute"), Ok(1));
489 assert_eq!(minutes("2 mins"), Ok(2));
490 assert_eq!(minutes("1 min"), Ok(1));
491 assert_eq!(minutes("2mins"), Ok(2));
492 assert_eq!(minutes("1min"), Ok(1));
493 }
494
495 #[test]
496 fn test_seconds() {
497 assert_eq!(seconds("1 year"), Ok(31_536_000));
498 assert_eq!(seconds("1 month"), Ok(2_592_000));
499 assert_eq!(seconds("1 week"), Ok(604_800));
500 assert_eq!(seconds("1 day"), Ok(86_400));
501 assert_eq!(seconds("1 hour"), Ok(3_600));
502 assert_eq!(seconds("1 minute"), Ok(60));
503 assert_eq!(seconds("2 seconds"), Ok(2));
504 assert_eq!(seconds("1 second"), Ok(1));
505 assert_eq!(seconds("2seconds"), Ok(2));
506 assert_eq!(seconds("1second"), Ok(1));
507 assert_eq!(seconds("2 secs"), Ok(2));
508 assert_eq!(seconds("1 sec"), Ok(1));
509 assert_eq!(seconds("2secs"), Ok(2));
510 assert_eq!(seconds("1sec"), Ok(1));
511 assert_eq!(seconds("2 s"), Ok(2));
512 assert_eq!(seconds("1 s"), Ok(1));
513 assert_eq!(seconds("2s"), Ok(2));
514 assert_eq!(seconds("1s"), Ok(1));
515 }
516
517 #[test]
518 fn test_milliseconds() {
519 assert_eq!(milliseconds("1 second"), Ok(1000));
520 assert_eq!(milliseconds("2 milliseconds"), Ok(2));
521 assert_eq!(milliseconds("1 millisecond"), Ok(1));
522 assert_eq!(milliseconds("2milliseconds"), Ok(2));
523 assert_eq!(milliseconds("1millisecond"), Ok(1));
524 assert_eq!(milliseconds("2 ms"), Ok(2));
525 assert_eq!(milliseconds("1 ms"), Ok(1));
526 assert_eq!(milliseconds("2ms"), Ok(2));
527 assert_eq!(milliseconds("1ms"), Ok(1));
528 }
529
530 #[test]
531 fn test_nanoseconds() {
532 assert_eq!(nanoseconds("1 second"), Ok(1_000_000_000));
533 assert_eq!(nanoseconds("2 nanoseconds"), Ok(2));
534 assert_eq!(nanoseconds("1 nanosecond"), Ok(1));
535 assert_eq!(nanoseconds("2nanoseconds"), Ok(2));
536 assert_eq!(nanoseconds("1nanosecond"), Ok(1));
537 assert_eq!(nanoseconds("2 ns"), Ok(2));
538 assert_eq!(nanoseconds("1 ns"), Ok(1));
539 assert_eq!(nanoseconds("2ns"), Ok(2));
540 assert_eq!(nanoseconds("1ns"), Ok(1));
541 }
542}
543
544mod time {
545 pub const SECONDS_PER_MINUTE: u64 = 60;
547
548 pub const SECONDS_PER_HOUR: u64 = SECONDS_PER_MINUTE * 60;
550
551 pub const SECONDS_PER_DAY: u64 = SECONDS_PER_HOUR * 24;
553
554 pub const SECONDS_PER_WEEK: u64 = SECONDS_PER_DAY * 7;
556
557 pub const SECONDS_PER_MONTH: u64 = SECONDS_PER_DAY * 30;
559
560 pub const SECONDS_PER_YEAR: u64 = SECONDS_PER_DAY * 365;
562
563 pub const NANOSECONDS_PER_MILLISECONDS: u32 = 1_000_000;
565
566 #[derive(Clone, Debug, Default, PartialEq)]
568 pub struct Duration {
569 pub years: Option<u64>,
570 pub months: Option<u64>,
571 pub weeks: Option<u64>,
572 pub days: Option<u64>,
573 pub hours: Option<u64>,
574 pub minutes: Option<u64>,
575 pub seconds: Option<u64>,
576 pub milliseconds: Option<u32>,
577 pub nanoseconds: Option<u32>,
578 }
579
580 impl Duration {
581 pub fn to_std(&self) -> std::time::Duration {
584 let seconds = vec![
585 self.years.map_or(0, |v| v * SECONDS_PER_YEAR),
586 self.months.map_or(0, |v| v * SECONDS_PER_MONTH),
587 self.weeks.map_or(0, |v| v * SECONDS_PER_WEEK),
588 self.days.map_or(0, |v| v * SECONDS_PER_DAY),
589 self.hours.map_or(0, |v| v * SECONDS_PER_HOUR),
590 self.minutes.map_or(0, |v| v * SECONDS_PER_MINUTE),
591 self.seconds.map_or(0, |v| v),
592 ];
593
594 let nanoseconds = vec![
595 self.milliseconds
596 .map_or(0, |v| v * NANOSECONDS_PER_MILLISECONDS),
597 self.nanoseconds.map_or(0, |v| v),
598 ];
599
600 std::time::Duration::new(seconds.iter().sum(), nanoseconds.iter().sum())
601 }
602 }
603
604 #[cfg(test)]
605 mod tests {
606 use super::*;
607
608 #[test]
609 fn test_duration_to_std() {
610 assert_eq!(
611 crate::time::Duration {
612 nanoseconds: Some(1),
613 ..Default::default()
614 }
615 .to_std(),
616 std::time::Duration::new(0, 1)
617 );
618
619 assert_eq!(
620 crate::time::Duration {
621 milliseconds: Some(1),
622 ..Default::default()
623 }
624 .to_std(),
625 std::time::Duration::new(0, NANOSECONDS_PER_MILLISECONDS)
626 );
627
628 assert_eq!(
629 crate::time::Duration {
630 seconds: Some(1),
631 ..Default::default()
632 }
633 .to_std(),
634 std::time::Duration::new(1, 0)
635 );
636
637 assert_eq!(
638 crate::time::Duration {
639 minutes: Some(1),
640 ..Default::default()
641 }
642 .to_std(),
643 std::time::Duration::new(SECONDS_PER_MINUTE, 0) );
645
646 assert_eq!(
647 crate::time::Duration {
648 hours: Some(1),
649 ..Default::default()
650 }
651 .to_std(),
652 std::time::Duration::new(SECONDS_PER_HOUR, 0) );
654
655 assert_eq!(
656 crate::time::Duration {
657 days: Some(1),
658 ..Default::default()
659 }
660 .to_std(),
661 std::time::Duration::new(SECONDS_PER_DAY, 0) );
663
664 assert_eq!(
665 crate::time::Duration {
666 weeks: Some(1),
667 ..Default::default()
668 }
669 .to_std(),
670 std::time::Duration::new(SECONDS_PER_WEEK, 0) );
672
673 assert_eq!(
674 crate::time::Duration {
675 months: Some(1),
676 ..Default::default()
677 }
678 .to_std(),
679 std::time::Duration::new(SECONDS_PER_MONTH, 0) );
681
682 assert_eq!(
683 crate::time::Duration {
684 years: Some(1),
685 ..Default::default()
686 }
687 .to_std(),
688 std::time::Duration::new(SECONDS_PER_YEAR, 0) );
690
691 assert_eq!(
692 crate::time::Duration {
693 nanoseconds: Some(1),
694 milliseconds: Some(2),
695 seconds: Some(3),
696 ..Default::default()
697 }
698 .to_std(),
699 std::time::Duration::new(3, 2 * NANOSECONDS_PER_MILLISECONDS + 1)
700 );
701
702 assert_eq!(
703 crate::time::Duration {
704 nanoseconds: Some(1),
705 milliseconds: Some(2),
706 seconds: Some(3),
707 minutes: Some(4),
708 hours: Some(5),
709 ..Default::default()
710 }
711 .to_std(),
712 std::time::Duration::new(
713 3 + (4 * SECONDS_PER_MINUTE) + (5 * SECONDS_PER_HOUR),
714 2 * NANOSECONDS_PER_MILLISECONDS + 1
715 ) );
717 }
718 }
719}
720
721mod parser {
722 use nom::branch::alt;
723 use nom::bytes::complete::tag;
724 use nom::character::complete::{digit0, multispace0};
725 use nom::combinator::{all_consuming, map, map_res, opt, recognize};
726 use nom::error::context;
727 use nom::sequence::{delimited, preceded, terminated, tuple};
728 use nom::IResult;
729
730 pub fn duration(input: &str) -> IResult<&str, crate::time::Duration> {
731 let parser = tuple((
732 opt(terminated(years, delimiter)),
733 opt(terminated(months, delimiter)),
734 opt(terminated(weeks, delimiter)),
735 opt(terminated(days, delimiter)),
736 opt(terminated(hours, delimiter)),
737 opt(terminated(minutes, delimiter)),
738 opt(terminated(seconds, delimiter)),
739 opt(terminated(milliseconds, delimiter)),
740 opt(terminated(nanoseconds, delimiter)),
741 ));
742
743 map(
744 all_consuming(parser),
745 |(years, months, weeks, days, hours, minutes, seconds, milliseconds, nanoseconds)| {
746 crate::time::Duration {
747 years,
748 months,
749 weeks,
750 days,
751 hours,
752 minutes,
753 seconds,
754 milliseconds,
755 nanoseconds,
756 }
757 },
758 )(input)
759 }
760
761 fn delimiter(input: &str) -> IResult<&str, &str> {
762 terminated(
763 recognize(opt(alt((
764 tag(","),
765 delimited(multispace0, tag("and"), multispace0),
766 )))),
767 multispace0,
768 )(input)
769 }
770
771 pub fn years(input: &str) -> IResult<&str, u64> {
772 context(
773 "years",
774 terminated(unsigned_integer_64, preceded(multispace0, year)),
775 )(input)
776 }
777
778 fn year(input: &str) -> IResult<&str, &str> {
779 context("year", alt((tag("years"), tag("year"), tag("y"))))(input)
780 }
781
782 pub fn months(input: &str) -> IResult<&str, u64> {
783 context(
784 "months",
785 terminated(unsigned_integer_64, preceded(multispace0, month)),
786 )(input)
787 }
788
789 fn month(input: &str) -> IResult<&str, &str> {
790 context("month", alt((tag("months"), tag("month"), tag("mo"))))(input)
791 }
792
793 pub fn weeks(input: &str) -> IResult<&str, u64> {
794 context(
795 "weeks",
796 terminated(unsigned_integer_64, preceded(multispace0, week)),
797 )(input)
798 }
799
800 fn week(input: &str) -> IResult<&str, &str> {
801 context("week", alt((tag("weeks"), tag("week"), tag("w"))))(input)
802 }
803
804 pub fn days(input: &str) -> IResult<&str, u64> {
805 context(
806 "days",
807 terminated(unsigned_integer_64, preceded(multispace0, day)),
808 )(input)
809 }
810
811 fn day(input: &str) -> IResult<&str, &str> {
812 context("day", alt((tag("days"), tag("day"), tag("d"))))(input)
813 }
814
815 pub fn hours(input: &str) -> IResult<&str, u64> {
816 context(
817 "hours",
818 terminated(unsigned_integer_64, preceded(multispace0, hour)),
819 )(input)
820 }
821
822 fn hour(input: &str) -> IResult<&str, &str> {
823 context("hour", alt((tag("hours"), tag("hour"), tag("h"))))(input)
824 }
825
826 pub fn minutes(input: &str) -> IResult<&str, u64> {
827 context(
828 "minutes",
829 terminated(unsigned_integer_64, preceded(multispace0, minute)),
830 )(input)
831 }
832
833 fn minute(input: &str) -> IResult<&str, &str> {
834 context(
835 "minute",
836 alt((tag("minutes"), tag("minute"), tag("mins"), tag("min"))),
837 )(input)
838 }
839
840 pub fn seconds(input: &str) -> IResult<&str, u64> {
841 context(
842 "seconds",
843 terminated(unsigned_integer_64, preceded(multispace0, second)),
844 )(input)
845 }
846
847 fn second(input: &str) -> IResult<&str, &str> {
848 context(
849 "second",
850 alt((
851 tag("seconds"),
852 tag("second"),
853 tag("secs"),
854 tag("sec"),
855 tag("s"),
856 )),
857 )(input)
858 }
859
860 pub fn milliseconds(input: &str) -> IResult<&str, u32> {
861 context(
862 "milliseconds",
863 terminated(unsigned_integer_32, preceded(multispace0, millisecond)),
864 )(input)
865 }
866
867 fn millisecond(input: &str) -> IResult<&str, &str> {
868 context(
869 "millisecond",
870 alt((tag("milliseconds"), tag("millisecond"), tag("ms"))),
871 )(input)
872 }
873
874 pub fn nanoseconds(input: &str) -> IResult<&str, u32> {
875 context(
876 "nanoseconds",
877 terminated(unsigned_integer_32, preceded(multispace0, nanosecond)),
878 )(input)
879 }
880
881 fn nanosecond(input: &str) -> IResult<&str, &str> {
882 context(
883 "nanosecond",
884 alt((tag("nanoseconds"), tag("nanosecond"), tag("ns"))),
885 )(input)
886 }
887
888 fn unsigned_integer_32(input: &str) -> IResult<&str, u32> {
889 context("unsigned_integer_32", map_res(digit0, str::parse::<u32>))(input)
890 }
891
892 fn unsigned_integer_64(input: &str) -> IResult<&str, u64> {
893 context("unsigned_integer_64", map_res(digit0, str::parse::<u64>))(input)
894 }
895
896 #[cfg(test)]
897 mod tests {
898 use super::*;
899
900 use nom::error::{Error, ErrorKind};
901 use nom::Err;
902
903 #[test]
904 fn test_duration() {
905 assert_eq!(
906 duration("1 year"),
907 Ok((
908 "",
909 crate::time::Duration {
910 years: Some(1),
911 ..Default::default()
912 }
913 ))
914 );
915
916 assert_eq!(
917 duration("1 month"),
918 Ok((
919 "",
920 crate::time::Duration {
921 months: Some(1),
922 ..Default::default()
923 }
924 ))
925 );
926
927 assert_eq!(
928 duration("1 week"),
929 Ok((
930 "",
931 crate::time::Duration {
932 weeks: Some(1),
933 ..Default::default()
934 }
935 ))
936 );
937
938 assert_eq!(
939 duration("1 day"),
940 Ok((
941 "",
942 crate::time::Duration {
943 days: Some(1),
944 ..Default::default()
945 }
946 ))
947 );
948
949 assert_eq!(
950 duration("1 hour"),
951 Ok((
952 "",
953 crate::time::Duration {
954 hours: Some(1),
955 ..Default::default()
956 }
957 ))
958 );
959
960 assert_eq!(
961 duration("1 minute"),
962 Ok((
963 "",
964 crate::time::Duration {
965 minutes: Some(1),
966 ..Default::default()
967 }
968 ))
969 );
970
971 assert_eq!(
972 duration("1 second"),
973 Ok((
974 "",
975 crate::time::Duration {
976 seconds: Some(1),
977 ..Default::default()
978 }
979 ))
980 );
981
982 assert_eq!(
983 duration("1 millisecond"),
984 Ok((
985 "",
986 crate::time::Duration {
987 milliseconds: Some(1),
988 ..Default::default()
989 }
990 ))
991 );
992
993 assert_eq!(
994 duration("1 nanosecond"),
995 Ok((
996 "",
997 crate::time::Duration {
998 nanoseconds: Some(1),
999 ..Default::default()
1000 }
1001 ))
1002 );
1003
1004 assert_eq!(
1005 duration("1 year, 2 months"),
1006 Ok((
1007 "",
1008 crate::time::Duration {
1009 years: Some(1),
1010 months: Some(2),
1011 ..Default::default()
1012 }
1013 ))
1014 );
1015
1016 assert_eq!(
1017 duration("1 year 2 months"),
1018 Ok((
1019 "",
1020 crate::time::Duration {
1021 years: Some(1),
1022 months: Some(2),
1023 ..Default::default()
1024 }
1025 ))
1026 );
1027
1028 assert_eq!(
1029 duration("1 year and 2 months"),
1030 Ok((
1031 "",
1032 crate::time::Duration {
1033 years: Some(1),
1034 months: Some(2),
1035 ..Default::default()
1036 }
1037 ))
1038 );
1039
1040 assert_eq!(
1041 duration("1 year, 2 months, 3 weeks"),
1042 Ok((
1043 "",
1044 crate::time::Duration {
1045 years: Some(1),
1046 months: Some(2),
1047 weeks: Some(3),
1048 ..Default::default()
1049 }
1050 ))
1051 );
1052
1053 assert_eq!(
1054 duration("1 year, 2 months, 3 weeks, 4 days"),
1055 Ok((
1056 "",
1057 crate::time::Duration {
1058 years: Some(1),
1059 months: Some(2),
1060 weeks: Some(3),
1061 days: Some(4),
1062 ..Default::default()
1063 }
1064 ))
1065 );
1066
1067 assert_eq!(
1068 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours"),
1069 Ok((
1070 "",
1071 crate::time::Duration {
1072 years: Some(1),
1073 months: Some(2),
1074 weeks: Some(3),
1075 days: Some(4),
1076 hours: Some(5),
1077 ..Default::default()
1078 }
1079 ))
1080 );
1081
1082 assert_eq!(
1083 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes"),
1084 Ok((
1085 "",
1086 crate::time::Duration {
1087 years: Some(1),
1088 months: Some(2),
1089 weeks: Some(3),
1090 days: Some(4),
1091 hours: Some(5),
1092 minutes: Some(6),
1093 ..Default::default()
1094 }
1095 ))
1096 );
1097
1098 assert_eq!(
1099 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds"),
1100 Ok((
1101 "",
1102 crate::time::Duration {
1103 years: Some(1),
1104 months: Some(2),
1105 weeks: Some(3),
1106 days: Some(4),
1107 hours: Some(5),
1108 minutes: Some(6),
1109 seconds: Some(7),
1110 ..Default::default()
1111 }
1112 ))
1113 );
1114
1115 assert_eq!(
1116 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds"),
1117 Ok((
1118 "",
1119 crate::time::Duration {
1120 years: Some(1),
1121 months: Some(2),
1122 weeks: Some(3),
1123 days: Some(4),
1124 hours: Some(5),
1125 minutes: Some(6),
1126 seconds: Some(7),
1127 ..Default::default()
1128 }
1129 ))
1130 );
1131
1132 assert_eq!(
1133 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds and 8 milliseconds"),
1134 Ok((
1135 "",
1136 crate::time::Duration {
1137 years: Some(1),
1138 months: Some(2),
1139 weeks: Some(3),
1140 days: Some(4),
1141 hours: Some(5),
1142 minutes: Some(6),
1143 seconds: Some(7),
1144 milliseconds: Some(8),
1145 ..Default::default()
1146 }
1147 ))
1148 );
1149
1150 assert_eq!(
1151 duration("1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds, 8 milliseconds and 9 nanoseconds"),
1152 Ok((
1153 "",
1154 crate::time::Duration {
1155 years: Some(1),
1156 months: Some(2),
1157 weeks: Some(3),
1158 days: Some(4),
1159 hours: Some(5),
1160 minutes: Some(6),
1161 seconds: Some(7),
1162 milliseconds: Some(8),
1163 nanoseconds: Some(9),
1164 }
1165 ))
1166 );
1167 }
1168
1169 #[test]
1170 fn test_years() {
1171 assert_eq!(years("2 years"), Ok(("", 2)));
1172 assert_eq!(years("2 year"), Ok(("", 2)));
1173 assert_eq!(years("2years"), Ok(("", 2)));
1174 assert_eq!(years("2year"), Ok(("", 2)));
1175 assert_eq!(years("2 y"), Ok(("", 2)));
1176 assert_eq!(years("2y"), Ok(("", 2)));
1177 }
1178
1179 #[test]
1180 fn test_year() {
1181 assert_eq!(year("years"), Ok(("", "years")));
1182 assert_eq!(year("year"), Ok(("", "year")));
1183 assert_eq!(year("y"), Ok(("", "y")));
1184 }
1185
1186 #[test]
1187 fn test_months() {
1188 assert_eq!(months("2 months"), Ok(("", 2)));
1189 assert_eq!(months("2 month"), Ok(("", 2)));
1190 assert_eq!(months("2months"), Ok(("", 2)));
1191 assert_eq!(months("2month"), Ok(("", 2)));
1192 assert_eq!(months("2 mo"), Ok(("", 2)));
1193 assert_eq!(months("2mo"), Ok(("", 2)));
1194 }
1195
1196 #[test]
1197 fn test_month() {
1198 assert_eq!(month("months"), Ok(("", "months")));
1199 assert_eq!(month("month"), Ok(("", "month")));
1200 assert_eq!(month("mo"), Ok(("", "mo")));
1201 }
1202
1203 #[test]
1204 fn test_weeks() {
1205 assert_eq!(weeks("2 weeks"), Ok(("", 2)));
1206 assert_eq!(weeks("2 week"), Ok(("", 2)));
1207 assert_eq!(weeks("2weeks"), Ok(("", 2)));
1208 assert_eq!(weeks("2week"), Ok(("", 2)));
1209 assert_eq!(weeks("2 w"), Ok(("", 2)));
1210 assert_eq!(weeks("2w"), Ok(("", 2)));
1211 }
1212
1213 #[test]
1214 fn test_week() {
1215 assert_eq!(week("weeks"), Ok(("", "weeks")));
1216 assert_eq!(week("week"), Ok(("", "week")));
1217 assert_eq!(week("w"), Ok(("", "w")));
1218 }
1219
1220 #[test]
1221 fn test_days() {
1222 assert_eq!(days("2 days"), Ok(("", 2)));
1223 assert_eq!(days("2 day"), Ok(("", 2)));
1224 assert_eq!(days("2days"), Ok(("", 2)));
1225 assert_eq!(days("2day"), Ok(("", 2)));
1226 assert_eq!(days("2 d"), Ok(("", 2)));
1227 assert_eq!(days("2d"), Ok(("", 2)));
1228 }
1229
1230 #[test]
1231 fn test_day() {
1232 assert_eq!(day("days"), Ok(("", "days")));
1233 assert_eq!(day("day"), Ok(("", "day")));
1234 assert_eq!(day("d"), Ok(("", "d")));
1235 }
1236
1237 #[test]
1238 fn test_hours() {
1239 assert_eq!(hours("2 hours"), Ok(("", 2)));
1240 assert_eq!(hours("2 hour"), Ok(("", 2)));
1241 assert_eq!(hours("2hours"), Ok(("", 2)));
1242 assert_eq!(hours("2hour"), Ok(("", 2)));
1243 assert_eq!(hours("2 h"), Ok(("", 2)));
1244 assert_eq!(hours("2h"), Ok(("", 2)));
1245 }
1246
1247 #[test]
1248 fn test_hour() {
1249 assert_eq!(hour("hours"), Ok(("", "hours")));
1250 assert_eq!(hour("hour"), Ok(("", "hour")));
1251 assert_eq!(hour("h"), Ok(("", "h")));
1252 }
1253
1254 #[test]
1255 fn test_minutes() {
1256 assert_eq!(minutes("2 minutes"), Ok(("", 2)));
1257 assert_eq!(minutes("1 minute"), Ok(("", 1)));
1258 assert_eq!(minutes("2minutes"), Ok(("", 2)));
1259 assert_eq!(minutes("1minute"), Ok(("", 1)));
1260 assert_eq!(minutes("2 mins"), Ok(("", 2)));
1261 assert_eq!(minutes("1 min"), Ok(("", 1)));
1262 assert_eq!(minutes("2mins"), Ok(("", 2)));
1263 assert_eq!(minutes("1min"), Ok(("", 1)));
1264 }
1265
1266 #[test]
1267 fn test_minute() {
1268 assert_eq!(minute("minutes"), Ok(("", "minutes")));
1269 assert_eq!(minute("minute"), Ok(("", "minute")));
1270 assert_eq!(minute("mins"), Ok(("", "mins")));
1271 assert_eq!(minute("min"), Ok(("", "min")));
1272 }
1273
1274 #[test]
1275 fn test_seconds() {
1276 assert_eq!(seconds("2 seconds"), Ok(("", 2)));
1277 assert_eq!(seconds("1 second"), Ok(("", 1)));
1278 assert_eq!(seconds("2seconds"), Ok(("", 2)));
1279 assert_eq!(seconds("1second"), Ok(("", 1)));
1280 assert_eq!(seconds("2 secs"), Ok(("", 2)));
1281 assert_eq!(seconds("1 sec"), Ok(("", 1)));
1282 assert_eq!(seconds("2secs"), Ok(("", 2)));
1283 assert_eq!(seconds("1sec"), Ok(("", 1)));
1284 assert_eq!(seconds("1 s"), Ok(("", 1)));
1285 assert_eq!(seconds("1s"), Ok(("", 1)));
1286 }
1287
1288 #[test]
1289 fn test_second() {
1290 assert_eq!(second("seconds"), Ok(("", "seconds")));
1291 assert_eq!(second("second"), Ok(("", "second")));
1292 assert_eq!(second("secs"), Ok(("", "secs")));
1293 assert_eq!(second("sec"), Ok(("", "sec")));
1294 assert_eq!(second("s"), Ok(("", "s")));
1295 }
1296
1297 #[test]
1298 fn test_milliseconds() {
1299 assert_eq!(milliseconds("2 milliseconds"), Ok(("", 2)));
1300 assert_eq!(milliseconds("1 millisecond"), Ok(("", 1)));
1301 assert_eq!(milliseconds("1 ms"), Ok(("", 1)));
1302
1303 assert_eq!(milliseconds("2milliseconds"), Ok(("", 2)));
1304 assert_eq!(milliseconds("1millisecond"), Ok(("", 1)));
1305 assert_eq!(milliseconds("1ms"), Ok(("", 1)));
1306 }
1307
1308 #[test]
1309 fn test_millisecond() {
1310 assert_eq!(millisecond("milliseconds"), Ok(("", "milliseconds")));
1311 assert_eq!(millisecond("millisecond"), Ok(("", "millisecond")));
1312 assert_eq!(millisecond("ms"), Ok(("", "ms")));
1313 }
1314
1315 #[test]
1316 fn test_nanoseconds() {
1317 assert_eq!(nanoseconds("2 nanoseconds"), Ok(("", 2)));
1318 assert_eq!(nanoseconds("1 nanosecond"), Ok(("", 1)));
1319 assert_eq!(nanoseconds("1 ns"), Ok(("", 1)));
1320
1321 assert_eq!(nanoseconds("2nanoseconds"), Ok(("", 2)));
1322 assert_eq!(nanoseconds("1nanosecond"), Ok(("", 1)));
1323 assert_eq!(nanoseconds("1ns"), Ok(("", 1)));
1324 }
1325
1326 #[test]
1327 fn test_nanosecond() {
1328 assert_eq!(nanosecond("nanoseconds"), Ok(("", "nanoseconds")));
1329 assert_eq!(nanosecond("nanosecond"), Ok(("", "nanosecond")));
1330 assert_eq!(nanosecond("ns"), Ok(("", "ns")));
1331 }
1332
1333 #[test]
1334 fn test_u64() {
1335 assert_eq!(unsigned_integer_64("0"), Ok(("", 0)));
1336 assert_eq!(unsigned_integer_64("1"), Ok(("", 1)));
1337 assert_eq!(
1338 unsigned_integer_64("18446744073709551615"),
1339 Ok(("", 18_446_744_073_709_551_615))
1340 );
1341
1342 assert_eq!(
1343 unsigned_integer_64("18446744073709551616"),
1344 Err(Err::Error(Error::new(
1345 "18446744073709551616",
1346 ErrorKind::MapRes
1347 )))
1348 );
1349 }
1350 }
1351}