jackdauer/
lib.rs

1//! Use this crate to easily parse various time formats to durations.
2//!
3//! It provides stratight forward functions to parse durations from a
4//!  textual representation, into [`std::time::Duration`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html) instances.
5//! It focuses on providing a simple but deep interface, that's easy and
6//! intuitive to use, while remaining performant.
7//!
8//!
9//! # Installation
10//!
11//! Add it as a dependency to your `Cargo.toml`
12//! ```toml
13//! [dependencies]
14//! jackdauer = "0.1.0"
15//! ```
16//!
17//! # Examples
18//! ```rust
19//! use jackdauer::duration;
20//! use std::time::Duration;
21//!
22//! let nanoseconds = duration("1 nanosecond");
23//! let milliseconds = duration("2 milliseconds");
24//! let seconds = duration("3 seconds");
25//! let minutes = duration("4 minutes");
26//! let hours = duration("5 hours");
27//! let day = duration("6 days");
28//! let week = duration("7 weeks");
29//! let month = duration("8 months");
30//! let year = duration("9 months");
31//! let real_big_duration = duration("9 years, 8 months, 7 weeks and 6 days");
32//! let real_small_duration = duration("4 minutes 3 seconds, 2 milliseconds and 1 nanosecond");
33//! ```
34
35use std::time::Duration;
36
37/// Parses a `std::time::Duration` from a human readable string of characters.
38///
39/// The supported syntax for durations consists in a comma separated list of
40/// time values, followed by their respective time unit. Alternatively, the "and"
41/// keyword can be used in place of a comma. While time values are only accepted
42/// in their numerical form, time units are accepted in both their
43/// singular and plural forms.
44///
45/// If the provided string cannot' be parsed, a `ParseError` will be
46/// returned as part of the `Result`.
47///
48/// # Reference
49///
50/// The accepted time units formats are as follows:
51/// - **Years**: `years`, `year` and `y` are accepted
52/// - **Months**: `months`, `month`, and `mo` are accepted
53/// - **Weeks**: `weeks`, `week`, and `w` are accepted
54/// - **Days**: `days`, `day`, and `d` are accepted
55/// - **Hours**: `hours`, `hour`, and `h` are accepted
56/// - **Minutes**: `minutes` `mins`, and `min` are accepted
57/// - **Seconds**: `seconds`, `second`, `secs`, `sec` and `s` are accepted
58/// - **Milliseconds**: `milliseconds`, `millisecond`, `ms` are accepted
59/// - **Nanoseconds**: `nanoseconds`, `nanosecond`, `ns` are accepted
60///
61/// # Examples
62///
63/// ```rust
64/// use jackdauer::duration;
65///
66/// // Singular
67/// let nanoseconds = duration("1 nanosecond");
68///
69/// // Plural
70/// let milliseconds = duration("2 milliseconds");
71///
72/// // Full syntax example
73/// let small = duration("3 seconds, 2 milliseconds and 1 nanosecond");
74/// ```
75pub 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
81/// Returns the total number of years contained in the parsed human readable duration.
82///
83/// # Examples
84///
85/// ```rust
86/// use jackdauer::years;
87///
88/// assert_eq!(years("365 days"), Ok(1));
89/// assert_eq!(years("1 year"), Ok(1));
90/// assert_eq!(years("2 years"), Ok(2));
91/// assert_eq!(years("1 day"), Ok(0));
92/// ```
93pub 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
99/// Returns the total number of months contained in the parsed human readable duration.
100///
101/// # Examples
102///
103/// ```rust
104/// use jackdauer::months;
105///
106/// assert_eq!(months("30 days"), Ok(1));
107/// assert_eq!(months("1 month"), Ok(1));
108/// assert_eq!(months("2 months"), Ok(2));
109/// assert_eq!(months("1 year"), Ok(12));
110/// assert_eq!(months("1 week"), Ok(0));
111/// ```
112pub 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
118/// Returns the total number of weeks contained in the parsed human readable duration.
119///
120/// # Examples
121///
122/// ```rust
123/// use jackdauer::weeks;
124///
125/// assert_eq!(weeks("7 days"), Ok(1));
126/// assert_eq!(weeks("1 week"), Ok(1));
127/// assert_eq!(weeks("2 weeks"), Ok(2));
128/// assert_eq!(weeks("1 month"), Ok(4));
129/// assert_eq!(weeks("2 years"), Ok(104));
130/// assert_eq!(weeks("1 day"), Ok(0));
131/// ```
132pub 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
138/// Returns the total number of days contained in the parsed human readable duration.
139///
140/// # Examples
141///
142/// ```rust
143/// use jackdauer::days;
144///
145/// assert_eq!(days("24 hours"), Ok(1));
146/// assert_eq!(days("1 day"), Ok(1));
147/// assert_eq!(days("2 days"), Ok(2));
148/// assert_eq!(days("1 week"), Ok(7));
149/// assert_eq!(days("2 months"), Ok(60));
150/// assert_eq!(days("3 years"), Ok(1_095));
151/// assert_eq!(days("1 hour"), Ok(0))
152/// ```
153pub 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
159/// Returns the total number of hours contained in the parsed human readable duration.
160///
161/// # Examples
162///
163/// ```rust
164/// use jackdauer::hours;
165///
166/// assert_eq!(hours("60 minutes"), Ok(1));
167/// assert_eq!(hours("1 hour"), Ok(1));
168/// assert_eq!(hours("2 hours"), Ok(2));
169/// assert_eq!(hours("3 days"), Ok(72));
170/// assert_eq!(hours("4 weeks"), Ok(672));
171/// assert_eq!(hours("5 months"), Ok(3_600));
172/// assert_eq!(hours("6 years"), Ok(52_560));
173/// assert_eq!(hours("1 minute"), Ok(0));
174pub 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
180/// Returns the total number of minutes contained in the parsed human readable duration.
181///
182/// # Examples
183///
184/// ```rust
185/// use jackdauer::minutes;
186///
187/// assert_eq!(minutes("60 seconds"), Ok(1));
188/// assert_eq!(minutes("1 minute"), Ok(1));
189/// assert_eq!(minutes("2 minutes"), Ok(2));
190/// assert_eq!(minutes("3 hours"), Ok(180));
191/// assert_eq!(minutes("4 days"), Ok(5_760));
192/// assert_eq!(minutes("5 weeks"), Ok(50_400));
193/// assert_eq!(minutes("6 months"), Ok(259_200));
194/// assert_eq!(minutes("7 years"), Ok(3_679_200));
195/// assert_eq!(minutes("1 second"), Ok(0));
196pub 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
202/// Returns the total number of seconds contained in the parsed human readable duration.
203///
204/// # Examples
205///
206/// ```rust
207/// use jackdauer::seconds;
208///
209/// assert_eq!(seconds("1000 milliseconds"), Ok(1));
210/// assert_eq!(seconds("1 second"), Ok(1));
211/// assert_eq!(seconds("2 seconds"), Ok(2));
212/// assert_eq!(seconds("3 minutes"), Ok(180));
213/// assert_eq!(seconds("4 hours"), Ok(14_400));
214/// assert_eq!(seconds("5 days"), Ok(432_000));
215/// assert_eq!(seconds("6 weeks"), Ok(3_628_800));
216/// assert_eq!(seconds("7 months"), Ok(18_144_000));
217/// assert_eq!(seconds("8 years"), Ok(252_288_000));
218pub 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
224/// Returns the total number of milliseconds contained in the parsed human readable duration.
225///
226/// # Examples
227///
228/// ```rust
229/// use jackdauer::milliseconds;
230///
231/// assert_eq!(milliseconds("1000000 nanoseconds"), Ok(1));
232/// assert_eq!(milliseconds("1 millisecond"), Ok(1));
233/// assert_eq!(milliseconds("2 milliseconds"), Ok(2));
234/// assert_eq!(milliseconds("3 seconds"), Ok(3_000));
235/// assert_eq!(milliseconds("4 hours"), Ok(14_400_000));
236/// assert_eq!(milliseconds("5 days"), Ok(432_000_000));
237/// assert_eq!(milliseconds("6 weeks"), Ok(3_628_800_000));
238/// assert_eq!(milliseconds("7 months"), Ok(18_144_000_000));
239/// assert_eq!(milliseconds("8 years"), Ok(252_288_000_000));
240/// assert_eq!(milliseconds("9 nanoseconds"), Ok(0))
241pub 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
247/// Returns the total number of nanoseconds contained in the parsed human readable duration.
248///
249/// # Examples
250///
251/// ```rust
252/// use jackdauer::nanoseconds;
253///
254/// assert_eq!(nanoseconds("1 nanosecond"), Ok(1));
255/// assert_eq!(nanoseconds("2 nanoseconds"), Ok(2));
256/// assert_eq!(nanoseconds("3 milliseconds"), Ok(3_000_000));
257/// assert_eq!(nanoseconds("4 seconds"), Ok(4_000_000_000));
258/// assert_eq!(nanoseconds("5 hours"), Ok(18_000_000_000_000));
259/// assert_eq!(nanoseconds("6 days"), Ok(518_400_000_000_000));
260/// assert_eq!(nanoseconds("7 weeks"), Ok(4_233_600_000_000_000));
261/// assert_eq!(nanoseconds("8 months"), Ok(20_736_000_000_000_000));
262/// assert_eq!(nanoseconds("9 years"), Ok(283_824_000_000_000_000));
263pub 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    //! Error management
271    use std::fmt;
272
273    /// The error type indicating a provided human readable duration error
274    #[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    // Constant holding the amount of seconds in a minute
546    pub const SECONDS_PER_MINUTE: u64 = 60;
547
548    // Constant holding the amount of seconds in an hour
549    pub const SECONDS_PER_HOUR: u64 = SECONDS_PER_MINUTE * 60;
550
551    // Constant holding the amount of seconds in a day
552    pub const SECONDS_PER_DAY: u64 = SECONDS_PER_HOUR * 24;
553
554    // Constant holding the amount of seconds in a week
555    pub const SECONDS_PER_WEEK: u64 = SECONDS_PER_DAY * 7;
556
557    // Constant holding the amount of seconds in a 30 days month
558    pub const SECONDS_PER_MONTH: u64 = SECONDS_PER_DAY * 30;
559
560    // Constant holding the amount of seconds in a non leap year
561    pub const SECONDS_PER_YEAR: u64 = SECONDS_PER_DAY * 365;
562
563    // Constant holding the amount of nanoseconds in a millisecond
564    pub const NANOSECONDS_PER_MILLISECONDS: u32 = 1_000_000;
565
566    /// Internal representation of a Duration component.
567    #[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        /// Convert an internal representation of a Duration back into
582        /// a `std::time::Duration`.
583        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) // 60 seconds
644            );
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) // 60 seconds * 60 minutes
653            );
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) // 60 seconds * 60 minutes * 24 hours
662            );
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) // 60 seconds * 60 minutes * 24 hours * 7 days
671            );
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) // 60 seconds * 60 minutes * 24 hours * 30 days
680            );
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) // 60 seconds * 60 minutes * 24 hours * 365 days
689            );
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                ) // 3 seconds + (4 * 60 seconds) + (5 * 60 seconds * 60 minutes)
716            );
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}