rune_modules/
time.rs

1//! The native `time` module for the [Rune Language].
2//!
3//! [Rune Language]: https://rune-rs.github.io
4//!
5//! ## Usage
6//!
7//! Add the following to your `Cargo.toml`:
8//!
9//! ```toml
10//! rune-modules = { version = "0.14.1", features = ["time"] }
11//! ```
12//!
13//! Install it into your context:
14//!
15//! ```rust
16//! let mut context = rune::Context::with_default_modules()?;
17//! context.install(rune_modules::time::module(true)?)?;
18//! # Ok::<_, rune::support::Error>(())
19//! ```
20//!
21//! Use it in Rune:
22//!
23//! ```rust,ignore
24//! use time;
25//!
26//! fn main() {
27//!     time::sleep(time::Duration::from_secs(10)).await;
28//!     println("Message after 10 seconds!");
29//! }
30//! ```
31
32use core::cmp::Ordering;
33use core::hash::Hash;
34
35use rune::alloc::fmt::TryWrite;
36use rune::runtime::{Formatter, Hasher, Mut, VmResult};
37use rune::{docstring, item, vm_panic, Any, ContextError, Module, ToConstValue};
38
39const NANOS_PER_SEC: u32 = 1_000_000_000;
40
41/// Construct the `time` module.
42pub fn module(_stdio: bool) -> Result<Module, ContextError> {
43    let mut m = Module::with_crate("time")?;
44
45    m.function_meta(sleep)?;
46    m.function_meta(interval)?;
47    m.function_meta(interval_at)?;
48
49    m.ty::<Duration>()?;
50
51    m.function_meta(Duration::new__meta)?;
52    m.function_meta(Duration::from_secs__meta)?;
53    m.function_meta(Duration::from_millis__meta)?;
54    m.function_meta(Duration::from_micros__meta)?;
55    m.function_meta(Duration::from_nanos__meta)?;
56    m.function_meta(Duration::is_zero__meta)?;
57    m.function_meta(Duration::as_secs__meta)?;
58    m.function_meta(Duration::subsec_millis__meta)?;
59    m.function_meta(Duration::subsec_micros__meta)?;
60    m.function_meta(Duration::subsec_nanos__meta)?;
61    m.function_meta(Duration::as_millis__meta)?;
62    m.function_meta(Duration::as_micros__meta)?;
63    m.function_meta(Duration::as_nanos__meta)?;
64    m.function_meta(Duration::as_secs_f64__meta)?;
65    m.function_meta(Duration::from_secs_f64__meta)?;
66    m.function_meta(Duration::add__meta)?;
67    m.function_meta(Duration::add_assign__meta)?;
68    m.function_meta(Duration::partial_eq__meta)?;
69    m.implement_trait::<Duration>(item!(::std::cmp::PartialEq))?;
70    m.function_meta(Duration::eq__meta)?;
71    m.implement_trait::<Duration>(item!(::std::cmp::Eq))?;
72    m.function_meta(Duration::partial_cmp__meta)?;
73    m.implement_trait::<Duration>(item!(::std::cmp::PartialOrd))?;
74    m.function_meta(Duration::cmp__meta)?;
75    m.implement_trait::<Duration>(item!(::std::cmp::Ord))?;
76    m.function_meta(Duration::hash__meta)?;
77    m.function_meta(Duration::debug_fmt__meta)?;
78    m.function_meta(Duration::clone__meta)?;
79    m.implement_trait::<Duration>(item!(::std::clone::Clone))?;
80
81    m.constant(
82        "SECOND",
83        Duration {
84            inner: tokio::time::Duration::from_secs(1),
85        },
86    )
87    .build_associated::<Duration>()?
88    .docs(docstring! {
89        /// The duration of one second.
90        ///
91        /// # Examples
92        ///
93        /// ```rune
94        /// use time::Duration;
95        ///
96        /// let duration = Duration::SECOND;
97        /// ```
98    })?;
99
100    m.constant(
101        "MILLISECOND",
102        Duration {
103            inner: tokio::time::Duration::from_millis(1),
104        },
105    )
106    .build_associated::<Duration>()?
107    .docs(docstring! {
108        /// The duration of one millisecond.
109        ///
110        /// # Examples
111        ///
112        /// ```rune
113        /// use time::Duration;
114        ///
115        /// let duration = Duration::MILLISECOND;
116        /// ```
117    })?;
118
119    m.constant(
120        "MICROSECOND",
121        Duration {
122            inner: tokio::time::Duration::from_micros(1),
123        },
124    )
125    .build_associated::<Duration>()?
126    .docs(docstring! {
127        /// The duration of one microsecond.
128        ///
129        /// # Examples
130        ///
131        /// ```rune
132        /// use time::Duration;
133        ///
134        /// let duration = Duration::MICROSECOND;
135        /// ```
136    })?;
137
138    m.constant(
139        "NANOSECOND",
140        Duration {
141            inner: tokio::time::Duration::from_nanos(1),
142        },
143    )
144    .build_associated::<Duration>()?
145    .docs(docstring! {
146        /// The duration of one nanosecond.
147        ///
148        /// # Examples
149        ///
150        /// ```rune
151        /// use time::Duration;
152        ///
153        /// let duration = Duration::NANOSECOND;
154        /// ```
155    })?;
156
157    m.constant(
158        "ZERO",
159        Duration {
160            inner: tokio::time::Duration::ZERO,
161        },
162    )
163    .build_associated::<Duration>()?
164    .docs(docstring! {
165        /// A duration of zero time.
166        ///
167        /// # Examples
168        ///
169        /// ```rune
170        /// use time::Duration;
171        ///
172        /// let duration = Duration::ZERO;
173        /// ```
174    })?;
175
176    m.constant(
177        "MAX",
178        Duration {
179            inner: tokio::time::Duration::MAX,
180        },
181    )
182    .build_associated::<Duration>()?
183    .docs(docstring! {
184        /// The maximum duration.
185        ///
186        /// # Examples
187        ///
188        /// ```rune
189        /// use time::Duration;
190        ///
191        /// let duration = Duration::MAX;
192        /// assert!(Duration::ZERO < Duration::MAX);
193        /// ```
194    })?;
195
196    m.ty::<Instant>()?;
197    m.function_meta(Instant::now__meta)?;
198    m.function_meta(Instant::duration_since__meta)?;
199    m.function_meta(Instant::elapsed__meta)?;
200    m.function_meta(Instant::add__meta)?;
201    m.function_meta(Instant::add_assign__meta)?;
202    m.function_meta(Instant::partial_eq__meta)?;
203    m.implement_trait::<Instant>(item!(::std::cmp::PartialEq))?;
204    m.function_meta(Instant::eq__meta)?;
205    m.implement_trait::<Instant>(item!(::std::cmp::Eq))?;
206    m.function_meta(Instant::partial_cmp__meta)?;
207    m.implement_trait::<Instant>(item!(::std::cmp::PartialOrd))?;
208    m.function_meta(Instant::cmp__meta)?;
209    m.implement_trait::<Instant>(item!(::std::cmp::Ord))?;
210    m.function_meta(Instant::hash__meta)?;
211    m.function_meta(Instant::debug_fmt__meta)?;
212    m.function_meta(Instant::clone__meta)?;
213    m.implement_trait::<Instant>(item!(::std::clone::Clone))?;
214
215    m.ty::<Interval>()?;
216    m.function("tick", Interval::tick)
217        .build_associated::<Interval>()?;
218    m.function_meta(Interval::reset__meta)?;
219    m.function_meta(Interval::reset_immediately__meta)?;
220    m.function_meta(Interval::reset_after__meta)?;
221    m.function_meta(Interval::reset_at__meta)?;
222
223    Ok(m)
224}
225
226/// Waits until duration has elapsed.
227///
228/// # Examples
229///
230/// ```rune,no_run
231/// use time::Duration;
232///
233/// let duration = Duration::from_secs(10);
234/// time::sleep(duration).await;
235/// println!("Surprise!");
236/// ```
237#[rune::function]
238async fn sleep(duration: Duration) {
239    tokio::time::sleep(duration.inner).await;
240}
241
242/// Creates new [`Interval`] that yields with interval of `period`. The first
243/// tick completes immediately.
244///
245/// An interval will tick indefinitely. At any time, the [`Interval`] value can
246/// be dropped. This cancels the interval.
247///
248/// # Examples
249///
250/// ```rune,no_run
251/// use time::Duration;
252///
253/// let duration = Duration::from_millis(10);
254/// let interval = time::interval(duration);
255///
256/// interval.tick().await; // ticks immediately
257/// interval.tick().await; // ticks after 10ms
258/// interval.tick().await; // ticks after 10ms
259///
260/// println!("approximately 20ms have elapsed...");
261/// ```
262#[rune::function]
263async fn interval(period: Duration) -> Interval {
264    Interval {
265        inner: tokio::time::interval(period.inner),
266    }
267}
268
269/// Creates new [`Interval`] that yields with interval of `period` with the
270/// first tick completing at `start`.
271///
272/// An interval will tick indefinitely. At any time, the [`Interval`] value can
273/// be dropped. This cancels the interval.
274///
275/// # Vm Panics
276///
277/// This function panics if `period` is zero.
278///
279/// # Examples
280///
281/// ```rune,no_run
282/// use time::{Duration, Instant};
283///
284/// let start = Instant::now() + Duration::from_millis(50);
285/// let interval = time::interval_at(start, Duration::from_millis(10));
286///
287/// interval.tick().await; // ticks after 50ms
288/// interval.tick().await; // ticks after 10ms
289/// interval.tick().await; // ticks after 10ms
290///
291/// println!("approximately 70ms have elapsed...");
292/// ```
293#[rune::function]
294async fn interval_at(start: Instant, period: Duration) -> Interval {
295    Interval {
296        inner: tokio::time::interval_at(start.inner, period.inner),
297    }
298}
299
300/// A `Duration` type to represent a span of time, typically used for system
301/// timeouts.
302///
303/// Each `Duration` is composed of a whole number of seconds and a fractional part
304/// represented in nanoseconds. If the underlying system does not support
305/// nanosecond-level precision, APIs binding a system timeout will typically round up
306/// the number of nanoseconds.
307///
308/// # Examples
309///
310/// ```rune
311/// use time::Duration;
312///
313/// let five_seconds = Duration::new(5, 0);
314/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
315///
316/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
317/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
318///
319/// let ten_millis = Duration::from_millis(10);
320/// ```
321#[derive(Debug, Clone, Copy, Any, ToConstValue)]
322#[rune(item = ::time)]
323pub struct Duration {
324    #[const_value(with = self::const_duration)]
325    inner: tokio::time::Duration,
326}
327
328impl Duration {
329    /// Converts [`Duration`] into a [`std::time::Duration`].
330    pub fn into_std(self) -> std::time::Duration {
331        std::time::Duration::new(self.inner.as_secs(), self.inner.subsec_nanos())
332    }
333
334    /// Creates a [`Duration`] from a [`std::time::Duration`].
335    pub fn from_std(duration: std::time::Duration) -> Self {
336        Self {
337            inner: tokio::time::Duration::new(duration.as_secs(), duration.subsec_nanos()),
338        }
339    }
340
341    /// Converts [`Duration`] into a [`tokio::time::Duration`].
342    ///
343    /// # Example
344    ///
345    /// ```
346    /// use rune_modules::time::Duration;
347    ///
348    /// let duration = Duration::from_secs(5);
349    /// let tokio_duration = duration.into_tokio();
350    /// ```
351    pub fn into_tokio(self) -> tokio::time::Duration {
352        self.inner
353    }
354
355    /// Creates a [`Duration`] from a [`tokio::time::Duration`].
356    ///
357    /// # Example
358    ///
359    /// ```
360    /// use rune_modules::time::Duration;
361    ///
362    /// let tokio_duration = tokio::time::Duration::from_secs(5);
363    /// let duration = Duration::from_tokio(tokio_duration);
364    /// ```
365    pub fn from_tokio(duration: tokio::time::Duration) -> Self {
366        Self { inner: duration }
367    }
368
369    /// Creates a new `Duration` from the specified number of whole seconds and
370    /// additional nanoseconds.
371    ///
372    /// If the number of nanoseconds is greater than 1 billion (the number of
373    /// nanoseconds in a second), then it will carry over into the seconds provided.
374    ///
375    /// # Vm Panics
376    ///
377    /// This constructor will panic if the carry from the nanoseconds overflows
378    /// the seconds counter.
379    ///
380    /// # Examples
381    ///
382    /// ```rune
383    /// use time::Duration;
384    ///
385    /// let five_seconds = Duration::new(5, 0);
386    /// ```
387    #[rune::function(keep, path = Self::new)]
388    pub fn new(secs: u64, nanos: u32) -> VmResult<Self> {
389        if nanos >= NANOS_PER_SEC && secs.checked_add((nanos / NANOS_PER_SEC) as u64).is_none() {
390            vm_panic!("overflow in Duration::new");
391        }
392
393        VmResult::Ok(Self {
394            inner: tokio::time::Duration::new(secs, nanos),
395        })
396    }
397
398    /// Creates a new `Duration` from the specified number of whole seconds.
399    ///
400    /// # Examples
401    ///
402    /// ```rune
403    /// use time::Duration;
404    ///
405    /// let duration = Duration::from_secs(5);
406    /// ```
407    #[rune::function(keep, path = Self::from_secs)]
408    pub const fn from_secs(secs: u64) -> Self {
409        Self {
410            inner: tokio::time::Duration::from_secs(secs),
411        }
412    }
413
414    /// Creates a new `Duration` from the specified number of milliseconds.
415    ///
416    /// # Examples
417    ///
418    /// ```rune
419    /// use time::Duration;
420    ///
421    /// let duration = Duration::from_millis(2569);
422    /// ```
423    #[rune::function(keep, path = Self::from_millis)]
424    pub const fn from_millis(millis: u64) -> Self {
425        Self {
426            inner: tokio::time::Duration::from_millis(millis),
427        }
428    }
429
430    /// Creates a new `Duration` from the specified number of microseconds.
431    ///
432    /// # Examples
433    ///
434    /// ```rune
435    /// use time::Duration;
436    ///
437    /// let duration = Duration::from_micros(1_000_002);
438    /// ```
439    #[rune::function(keep, path = Self::from_micros)]
440    #[inline]
441    pub const fn from_micros(micros: u64) -> Self {
442        Self {
443            inner: tokio::time::Duration::from_micros(micros),
444        }
445    }
446
447    /// Creates a new `Duration` from the specified number of nanoseconds.
448    ///
449    /// Note: Using this on the return value of `as_nanos()` might cause unexpected behavior:
450    /// `as_nanos()` returns a u128, and can return values that do not fit in u64, e.g. 585 years.
451    /// Instead, consider using the pattern `Duration::new(d.as_secs(), d.subsec_nanos())`
452    /// if you cannot copy/clone the Duration directly.
453    ///
454    /// # Examples
455    ///
456    /// ```rune
457    /// use time::Duration;
458    ///
459    /// let duration = Duration::from_nanos(1_000_000_123);
460    /// ```
461    #[rune::function(keep, path = Self::from_nanos)]
462    #[inline]
463    pub const fn from_nanos(nanos: u64) -> Self {
464        Self {
465            inner: tokio::time::Duration::from_nanos(nanos),
466        }
467    }
468
469    /// Returns true if this `Duration` spans no time.
470    ///
471    /// # Examples
472    ///
473    /// ```rune
474    /// use time::Duration;
475    ///
476    /// assert!(Duration::ZERO.is_zero());
477    /// assert!(Duration::new(0, 0).is_zero());
478    /// assert!(Duration::from_nanos(0).is_zero());
479    /// assert!(Duration::from_secs(0).is_zero());
480    ///
481    /// assert!(!Duration::new(1, 1).is_zero());
482    /// assert!(!Duration::from_nanos(1).is_zero());
483    /// assert!(!Duration::from_secs(1).is_zero());
484    /// ```
485    #[rune::function(keep)]
486    #[inline]
487    pub const fn is_zero(&self) -> bool {
488        self.inner.is_zero()
489    }
490
491    /// Returns the number of _whole_ seconds contained by this `Duration`.
492    ///
493    /// The returned value does not include the fractional (nanosecond) part of
494    /// the duration, which can be obtained using [`subsec_nanos`].
495    ///
496    /// # Examples
497    ///
498    /// ```rune
499    /// use time::Duration;
500    ///
501    /// let duration = Duration::new(5, 730023852);
502    /// assert_eq!(duration.as_secs(), 5);
503    /// ```
504    ///
505    /// To determine the total number of seconds represented by the `Duration`
506    /// including the fractional part, use [`as_secs_f64`] or [`as_secs_f32`]
507    ///
508    /// [`as_secs_f64`]: Duration::as_secs_f64
509    /// [`as_secs_f32`]: Duration::as_secs_f32
510    /// [`subsec_nanos`]: Duration::subsec_nanos
511    #[rune::function(keep)]
512    #[inline]
513    pub const fn as_secs(&self) -> u64 {
514        self.inner.as_secs()
515    }
516
517    /// Returns the fractional part of this `Duration`, in whole milliseconds.
518    ///
519    /// This method does **not** return the length of the duration when
520    /// represented by milliseconds. The returned number always represents a
521    /// fractional portion of a second (i.e., it is less than one thousand).
522    ///
523    /// # Examples
524    ///
525    /// ```rune
526    /// use time::Duration;
527    ///
528    /// let duration = Duration::from_millis(5432);
529    /// assert_eq!(duration.as_secs(), 5);
530    /// assert_eq!(duration.subsec_millis(), 432);
531    /// ```
532    #[rune::function(keep)]
533    #[inline]
534    pub const fn subsec_millis(&self) -> u32 {
535        self.inner.subsec_millis()
536    }
537
538    /// Returns the fractional part of this `Duration`, in whole microseconds.
539    ///
540    /// This method does **not** return the length of the duration when
541    /// represented by microseconds. The returned number always represents a
542    /// fractional portion of a second (i.e., it is less than one million).
543    ///
544    /// # Examples
545    ///
546    /// ```rune
547    /// use time::Duration;
548    ///
549    /// let duration = Duration::from_micros(1_234_567);
550    /// assert_eq!(duration.as_secs(), 1);
551    /// assert_eq!(duration.subsec_micros(), 234_567);
552    /// ```
553    #[rune::function(keep)]
554    #[inline]
555    pub const fn subsec_micros(&self) -> u32 {
556        self.inner.subsec_micros()
557    }
558
559    /// Returns the fractional part of this `Duration`, in nanoseconds.
560    ///
561    /// This method does **not** return the length of the duration when
562    /// represented by nanoseconds. The returned number always represents a
563    /// fractional portion of a second (i.e., it is less than one billion).
564    ///
565    /// # Examples
566    ///
567    /// ```rune
568    /// use time::Duration;
569    ///
570    /// let duration = Duration::from_millis(5010);
571    /// assert_eq!(duration.as_secs(), 5);
572    /// assert_eq!(duration.subsec_nanos(), 10_000_000);
573    /// ```
574    #[rune::function(keep)]
575    #[inline]
576    pub const fn subsec_nanos(&self) -> u32 {
577        self.inner.subsec_nanos()
578    }
579
580    /// Returns the total number of whole milliseconds contained by this
581    /// `Duration`.
582    ///
583    /// # Examples
584    ///
585    /// ```rune
586    /// use time::Duration;
587    ///
588    /// let duration = Duration::new(5, 730023852);
589    /// assert_eq!(duration.as_millis(), 5730);
590    /// ```
591    #[rune::function(keep)]
592    #[inline]
593    pub const fn as_millis(&self) -> u128 {
594        self.inner.as_millis()
595    }
596
597    /// Returns the total number of whole microseconds contained by this
598    /// `Duration`.
599    ///
600    /// # Examples
601    ///
602    /// ```rune
603    /// use time::Duration;
604    ///
605    /// let duration = Duration::new(5, 730023852);
606    /// assert_eq!(duration.as_micros(), 5730023);
607    /// ```
608    #[rune::function(keep)]
609    #[inline]
610    pub const fn as_micros(&self) -> u128 {
611        self.inner.as_micros()
612    }
613
614    /// Returns the total number of nanoseconds contained by this `Duration`.
615    ///
616    /// # Examples
617    ///
618    /// ```rune
619    /// use time::Duration;
620    ///
621    /// let duration = Duration::new(5, 730023852);
622    /// assert_eq!(duration.as_nanos(), 5730023852);
623    /// ```
624    #[rune::function(keep)]
625    #[inline]
626    pub const fn as_nanos(&self) -> u128 {
627        self.inner.as_nanos()
628    }
629
630    /// Returns the number of seconds contained by this `Duration` as `f64`.
631    ///
632    /// The returned value does include the fractional (nanosecond) part of the
633    /// duration.
634    ///
635    /// # Examples
636    ///
637    /// ```rune
638    /// use time::Duration;
639    ///
640    /// let duration = Duration::from_secs(60).as_secs_f64();
641    /// ```
642    #[rune::function(keep)]
643    #[inline]
644    pub fn as_secs_f64(&self) -> f64 {
645        self.inner.as_secs_f64()
646    }
647
648    /// Creates a new `Duration` from the specified number of seconds represented
649    /// as `f64`.
650    ///
651    /// # Examples
652    ///
653    /// ```rune
654    /// use time::Duration;
655    ///
656    /// let duration = Duration::from_secs_f64(0.0);
657    /// ```
658    #[rune::function(keep, path = Self::from_secs_f64)]
659    pub fn from_secs_f64(secs: f64) -> VmResult<Self> {
660        match tokio::time::Duration::try_from_secs_f64(secs) {
661            Ok(duration) => VmResult::Ok(Self { inner: duration }),
662            Err(e) => vm_panic!(e),
663        }
664    }
665
666    /// Add a duration to this instant and return a new instant.
667    ///
668    /// # Examples
669    ///
670    /// ```rune
671    /// use time::Duration;
672    ///
673    /// let first = Duration::SECOND;
674    /// let second = first + Duration::SECOND;
675    ///
676    /// assert!(first < second);
677    /// ```
678    #[rune::function(keep, instance, protocol = ADD)]
679    #[inline]
680    fn add(&self, rhs: &Duration) -> VmResult<Self> {
681        let Some(inner) = self.inner.checked_add(rhs.inner) else {
682            vm_panic!("overflow when adding durations")
683        };
684
685        VmResult::Ok(Self { inner })
686    }
687
688    /// Add a duration to this instant and return a new instant.
689    ///
690    /// # Examples
691    ///
692    /// ```rune
693    /// use time::Duration;
694    ///
695    /// let first = Duration::SECOND;
696    /// let second = first.clone();
697    /// second += Duration::SECOND;
698    ///
699    /// assert!(first < second);
700    /// ```
701    #[rune::function(keep, instance, protocol = ADD_ASSIGN)]
702    #[inline]
703    fn add_assign(&mut self, rhs: &Duration) -> VmResult<()> {
704        let Some(inner) = self.inner.checked_add(rhs.inner) else {
705            vm_panic!("overflow when adding duration to instant")
706        };
707
708        self.inner = inner;
709        VmResult::Ok(())
710    }
711
712    /// Test two durations for partial equality.
713    ///
714    /// # Examples
715    ///
716    /// ```rune
717    /// use std::ops::partial_eq;
718    ///
719    /// use time::Duration;
720    ///
721    /// let millis = Duration::MILLISECOND;
722    /// let second = Duration::SECOND;
723    ///
724    /// assert_eq!(partial_eq(millis, millis), true);
725    /// assert_eq!(partial_eq(millis, second), false);
726    /// assert_eq!(partial_eq(second, millis), false);
727    /// ```
728    #[rune::function(keep, instance, protocol = PARTIAL_EQ)]
729    #[inline]
730    fn partial_eq(&self, rhs: &Self) -> bool {
731        PartialEq::eq(&self.inner, &rhs.inner)
732    }
733
734    /// Test two durations for total equality.
735    ///
736    /// # Examples
737    ///
738    /// ```rune
739    /// use std::ops::eq;
740    ///
741    /// use time::Duration;
742    ///
743    /// let millis = Duration::MILLISECOND;
744    /// let second = Duration::SECOND;
745    ///
746    /// assert_eq!(eq(millis, millis), true);
747    /// assert_eq!(eq(millis, second), false);
748    /// assert_eq!(eq(second, millis), false);
749    /// ```
750    #[rune::function(keep, instance, protocol = EQ)]
751    #[inline]
752    fn eq(&self, rhs: &Self) -> bool {
753        PartialEq::eq(&self.inner, &rhs.inner)
754    }
755
756    /// Perform a partial ordered comparison between two durations.
757    ///
758    /// # Examples
759    ///
760    /// ```rune
761    /// use time::Duration;
762    ///
763    /// let millis = Duration::MILLISECOND;
764    /// let second = Duration::SECOND;
765    ///
766    /// assert!(millis < second);
767    /// assert!(second > millis);
768    /// assert!(millis == millis);
769    /// ```
770    ///
771    /// Using explicit functions:
772    ///
773    /// ```rune
774    /// use std::cmp::Ordering;
775    /// use std::ops::partial_cmp;
776    ///
777    /// use time::Duration;
778    ///
779    /// let millis = Duration::MILLISECOND;
780    /// let second = Duration::SECOND;
781    ///
782    /// assert_eq!(partial_cmp(millis, second), Some(Ordering::Less));
783    /// assert_eq!(partial_cmp(second, millis), Some(Ordering::Greater));
784    /// assert_eq!(partial_cmp(millis, millis), Some(Ordering::Equal));
785    /// ```
786    #[rune::function(keep, instance, protocol = PARTIAL_CMP)]
787    #[inline]
788    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
789        PartialOrd::partial_cmp(&self.inner, &rhs.inner)
790    }
791
792    /// Perform a totally ordered comparison between two durations.
793    ///
794    /// # Examples
795    ///
796    /// ```rune
797    /// use std::cmp::Ordering;
798    /// use std::ops::cmp;
799    ///
800    /// use time::Duration;
801    ///
802    /// let millis = Duration::MILLISECOND;
803    /// let second = Duration::SECOND;
804    ///
805    /// assert_eq!(cmp(millis, second), Ordering::Less);
806    /// assert_eq!(cmp(second, millis), Ordering::Greater);
807    /// assert_eq!(cmp(millis, millis), Ordering::Equal);
808    /// ```
809    #[rune::function(keep, instance, protocol = CMP)]
810    #[inline]
811    fn cmp(&self, rhs: &Self) -> Ordering {
812        Ord::cmp(&self.inner, &rhs.inner)
813    }
814
815    /// Hash the duration.
816    ///
817    /// # Examples
818    ///
819    /// ```rune
820    /// use std::ops::hash;
821    ///
822    /// use time::Duration;
823    ///
824    /// let second = Duration::SECOND;
825    ///
826    /// assert_eq!(hash(second), hash(second));
827    /// ```
828    #[rune::function(keep, instance, protocol = HASH)]
829    fn hash(&self, hasher: &mut Hasher) {
830        self.inner.hash(hasher);
831    }
832
833    /// Write a debug representation of the duration.
834    ///
835    /// # Examples
836    ///
837    /// ```rune
838    /// use time::Duration;
839    ///
840    /// let second = Duration::SECOND;
841    ///
842    /// println!("{second:?}");
843    /// ```
844    #[rune::function(keep, instance, protocol = DEBUG_FMT)]
845    fn debug_fmt(&self, f: &mut Formatter) -> VmResult<()> {
846        rune::vm_write!(f, "{:?}", self.inner)
847    }
848
849    /// Clone the current duration.
850    ///
851    /// # Examples
852    ///
853    /// ```rune
854    /// use time::Duration;
855    ///
856    /// let first = Duration::SECOND;
857    /// let second = Duration::SECOND;
858    /// second += Duration::SECOND;
859    ///
860    /// assert!(first < second);
861    /// ```
862    #[rune::function(keep, instance, protocol = CLONE)]
863    fn clone(&self) -> Self {
864        Self { inner: self.inner }
865    }
866}
867
868mod const_duration {
869    use rune::runtime::{ConstValue, RuntimeError, Value};
870    use tokio::time::Duration;
871
872    #[inline]
873    pub(super) fn to_const_value(duration: Duration) -> Result<ConstValue, RuntimeError> {
874        let secs = duration.as_secs();
875        let nanos = duration.subsec_nanos();
876        rune::to_const_value((secs, nanos))
877    }
878
879    #[inline]
880    pub(super) fn from_const_value(value: &ConstValue) -> Result<Duration, RuntimeError> {
881        let (secs, nanos) = rune::from_const_value::<(u64, u32)>(value)?;
882        Ok(Duration::new(secs, nanos))
883    }
884
885    #[inline]
886    pub(super) fn from_value(value: Value) -> Result<Duration, RuntimeError> {
887        let (secs, nanos) = rune::from_value::<(u64, u32)>(value)?;
888        Ok(Duration::new(secs, nanos))
889    }
890}
891
892/// Interval returned by [`interval`] and [`interval_at`].
893///
894/// This type allows you to wait on a sequence of instants with a certain
895/// duration between each instant. Unlike calling [`sleep`] in a loop, this lets
896/// you count the time spent between the calls to [`sleep`] as well.
897#[derive(Debug, Any)]
898#[rune(item = ::time)]
899pub struct Interval {
900    inner: tokio::time::Interval,
901}
902
903impl Interval {
904    /// Completes when the next instant in the interval has been reached.
905    ///
906    /// # Cancel safety
907    ///
908    /// This method is cancellation safe. If `tick` is used as the branch in a `select` and
909    /// another branch completes first, then no tick has been consumed.
910    ///
911    /// # Examples
912    ///
913    /// ```rune,no_run
914    /// use time::Duration;
915    ///
916    /// let  interval = time::interval(Duration::from_millis(10));
917    ///
918    /// interval.tick().await;
919    /// println!("approximately 0ms have elapsed. The first tick completes immediately.");
920    /// interval.tick().await;
921    /// interval.tick().await;
922    ///
923    /// println!("approximately 20ms have elapsed...");
924    /// ```
925    pub async fn tick(mut internal: Mut<Interval>) {
926        internal.inner.tick().await;
927    }
928
929    /// Resets the interval to complete one period after the current time.
930    ///
931    /// This is equivalent to calling `reset_at(Instant::now() + period)`.
932    ///
933    /// # Examples
934    ///
935    /// ```rune,no_run
936    /// use time::Duration;
937    ///
938    /// let interval = time::interval(Duration::from_millis(100));
939    /// interval.tick().await;
940    ///
941    /// time::sleep(Duration::from_millis(50)).await;
942    /// interval.reset();
943    ///
944    /// interval.tick().await;
945    /// interval.tick().await;
946    ///
947    /// println!("approximately 250ms have elapsed...");
948    /// ```
949    #[rune::function(instance, keep)]
950    fn reset(&mut self) {
951        self.inner.reset();
952    }
953
954    /// Resets the interval immediately.
955    ///
956    /// This is equivalent to calling `reset_at(Instant::now())`.
957    ///
958    /// # Examples
959    ///
960    /// ```rune,no_run
961    /// use time::Duration;
962    ///
963    /// let interval = time::interval(Duration::from_millis(100));
964    /// interval.tick().await;
965    ///
966    /// time::sleep(Duration::from_millis(50)).await;
967    /// interval.reset_immediately();
968    ///
969    /// interval.tick().await;
970    /// interval.tick().await;
971    ///
972    /// println!("approximately 150ms have elapsed...");
973    /// ```
974    #[rune::function(instance, keep)]
975    fn reset_immediately(&mut self) {
976        self.inner.reset_immediately();
977    }
978
979    /// Resets the interval to complete one period after the current time.
980    ///
981    /// This is equivalent to calling `reset_at(Instant::now() + period)`.
982    ///
983    /// # Examples
984    ///
985    /// ```rune,no_run
986    /// use time::Duration;
987    ///
988    /// let interval = time::interval(Duration::from_millis(100));
989    /// interval.tick().await;
990    ///
991    /// time::sleep(Duration::from_millis(50)).await;
992    /// interval.reset();
993    ///
994    /// interval.tick().await;
995    /// interval.tick().await;
996    ///
997    /// println!("approximately 250ms have elapsed...");
998    /// ```
999    #[rune::function(instance, keep)]
1000    fn reset_after(&mut self, after: Duration) {
1001        self.inner.reset_after(after.inner);
1002    }
1003
1004    /// Resets the interval to complete one period after the current time.
1005    ///
1006    /// This is equivalent to calling `reset_at(Instant::now() + period)`.
1007    ///
1008    /// # Examples
1009    ///
1010    /// ```rune,no_run
1011    /// use time::Duration;
1012    ///
1013    /// let interval = time::interval(Duration::from_millis(100));
1014    /// interval.tick().await;
1015    ///
1016    /// time::sleep(Duration::from_millis(50)).await;
1017    /// interval.reset();
1018    ///
1019    /// interval.tick().await;
1020    /// interval.tick().await;
1021    ///
1022    /// println!("approximately 250ms have elapsed...");
1023    /// ```
1024    #[rune::function(instance, keep)]
1025    fn reset_at(&mut self, deadline: Instant) {
1026        self.inner.reset_at(deadline.inner);
1027    }
1028}
1029
1030/// A measurement of a monotonically nondecreasing clock.
1031/// Opaque and useful only with `Duration`.
1032///
1033/// Instants are always guaranteed to be no less than any previously measured
1034/// instant when created, and are often useful for tasks such as measuring
1035/// benchmarks or timing how long an operation takes.
1036///
1037/// Note, however, that instants are not guaranteed to be **steady**. In other
1038/// words, each tick of the underlying clock may not be the same length (e.g.
1039/// some seconds may be longer than others). An instant may jump forwards or
1040/// experience time dilation (slow down or speed up), but it will never go
1041/// backwards.
1042///
1043/// Instants are opaque types that can only be compared to one another. There is
1044/// no method to get "the number of seconds" from an instant. Instead, it only
1045/// allows measuring the duration between two instants (or comparing two
1046/// instants).
1047///
1048/// The size of an `Instant` struct may vary depending on the target operating
1049/// system.
1050#[derive(Debug, Any)]
1051#[rune(item = ::time)]
1052pub struct Instant {
1053    inner: tokio::time::Instant,
1054}
1055
1056impl Instant {
1057    /// Returns an instant corresponding to `now`.
1058    ///
1059    /// # Examples
1060    ///
1061    /// ```rune
1062    /// use time::{Duration, Instant};
1063    ///
1064    /// let instant = Instant::now();
1065    /// ```
1066    #[rune::function(keep, path = Self::now)]
1067    pub fn now() -> Instant {
1068        Instant {
1069            inner: tokio::time::Instant::now(),
1070        }
1071    }
1072
1073    /// Returns the amount of time elapsed from another instant to this one, or
1074    /// zero duration if that instant is later than this one.
1075    ///
1076    /// # Examples
1077    ///
1078    /// ```rune,no_run
1079    /// use time::{Duration, Instant};
1080    ///
1081    /// let instant = Instant::now();
1082    ///
1083    /// let three_secs = Duration::from_secs(3);
1084    /// time::sleep(three_secs).await;
1085    ///
1086    /// let now = Instant::now();
1087    /// let duration_since = now.duration_since(instant);
1088    /// ```
1089    #[rune::function(instance, keep)]
1090    pub fn duration_since(&self, earlier: Instant) -> Duration {
1091        Duration {
1092            inner: tokio::time::Instant::duration_since(&self.inner, earlier.inner),
1093        }
1094    }
1095
1096    /// Returns the amount of time elapsed since this instant was created, or
1097    /// zero duration if that this instant is in the future.
1098    ///
1099    /// # Examples
1100    ///
1101    /// ```rune,no_run
1102    /// use time::{Duration, Instant};
1103    ///
1104    /// let instant = Instant::now();
1105    ///
1106    /// let three_secs = Duration::from_secs(3);
1107    /// time::sleep(three_secs).await;
1108    ///
1109    /// let elapsed = instant.elapsed();
1110    /// ```
1111    #[rune::function(instance, keep)]
1112    pub fn elapsed(&self) -> Duration {
1113        Duration {
1114            inner: tokio::time::Instant::elapsed(&self.inner),
1115        }
1116    }
1117
1118    /// Add a duration to this instant and return a new instant.
1119    ///
1120    /// # Examples
1121    ///
1122    /// ```rune
1123    /// use time::{Duration, Instant};
1124    ///
1125    /// let first = Instant::now();
1126    /// let second = first + Duration::SECOND;
1127    ///
1128    /// assert!(first < second);
1129    /// ```
1130    #[rune::function(keep, instance, protocol = ADD)]
1131    #[inline]
1132    fn add(&self, rhs: &Duration) -> VmResult<Self> {
1133        let Some(inner) = self.inner.checked_add(rhs.inner) else {
1134            vm_panic!("overflow when adding duration to instant")
1135        };
1136
1137        VmResult::Ok(Self { inner })
1138    }
1139
1140    /// Add a duration to this instant and return a new instant.
1141    ///
1142    /// # Examples
1143    ///
1144    /// ```rune
1145    /// use std::ops::partial_eq;
1146    /// use time::{Duration, Instant};
1147    ///
1148    /// let first = Instant::now();
1149    /// let second = first.clone();
1150    /// second += Duration::SECOND;
1151    ///
1152    /// assert!(first < second);
1153    /// ```
1154    #[rune::function(keep, instance, protocol = ADD_ASSIGN)]
1155    #[inline]
1156    fn add_assign(&mut self, rhs: &Duration) -> VmResult<()> {
1157        let Some(inner) = self.inner.checked_add(rhs.inner) else {
1158            vm_panic!("overflow when adding duration to instant")
1159        };
1160
1161        self.inner = inner;
1162        VmResult::Ok(())
1163    }
1164
1165    /// Test two instants for partial equality.
1166    ///
1167    /// # Examples
1168    ///
1169    /// ```rune
1170    /// use std::ops::partial_eq;
1171    /// use time::{Duration, Instant};
1172    ///
1173    /// let first = Instant::now();
1174    /// let second = first + Duration::SECOND;
1175    ///
1176    /// assert_eq!(partial_eq(first, first), true);
1177    /// assert_eq!(partial_eq(first, second), false);
1178    /// assert_eq!(partial_eq(second, first), false);
1179    /// ```
1180    #[rune::function(keep, instance, protocol = PARTIAL_EQ)]
1181    #[inline]
1182    fn partial_eq(&self, rhs: &Self) -> bool {
1183        PartialEq::eq(&self.inner, &rhs.inner)
1184    }
1185
1186    /// Test two instants for total equality.
1187    ///
1188    /// # Examples
1189    ///
1190    /// ```rune
1191    /// use std::ops::eq;
1192    /// use time::{Duration, Instant};
1193    ///
1194    /// let first = Instant::now();
1195    /// let second = first + Duration::SECOND;
1196    ///
1197    /// assert_eq!(eq(first, first), true);
1198    /// assert_eq!(eq(first, second), false);
1199    /// assert_eq!(eq(second, first), false);
1200    /// ```
1201    #[rune::function(keep, instance, protocol = EQ)]
1202    #[inline]
1203    fn eq(&self, rhs: &Self) -> bool {
1204        PartialEq::eq(&self.inner, &rhs.inner)
1205    }
1206
1207    /// Perform a partial ordered comparison between two instants.
1208    ///
1209    /// # Examples
1210    ///
1211    /// ```rune
1212    /// use time::{Duration, Instant};
1213    ///
1214    /// let first = Instant::now();
1215    /// let second = first + Duration::SECOND;
1216    ///
1217    /// assert!(first < second);
1218    /// assert!(second > first);
1219    /// assert!(first == first);
1220    /// ```
1221    ///
1222    /// Using explicit functions:
1223    ///
1224    /// ```rune
1225    /// use std::cmp::Ordering;
1226    /// use std::ops::partial_cmp;
1227    ///
1228    /// use time::{Duration, Instant};
1229    ///
1230    /// let first = Instant::now();
1231    /// let second = first + Duration::SECOND;
1232    ///
1233    /// assert_eq!(partial_cmp(first, second), Some(Ordering::Less));
1234    /// assert_eq!(partial_cmp(second, first), Some(Ordering::Greater));
1235    /// assert_eq!(partial_cmp(first, first), Some(Ordering::Equal));
1236    /// ```
1237    #[rune::function(keep, instance, protocol = PARTIAL_CMP)]
1238    #[inline]
1239    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1240        PartialOrd::partial_cmp(&self.inner, &rhs.inner)
1241    }
1242
1243    /// Perform a totally ordered comparison between two instants.
1244    ///
1245    /// # Examples
1246    ///
1247    /// ```rune
1248    /// use std::cmp::Ordering;
1249    /// use std::ops::cmp;
1250    /// use time::{Duration, Instant};
1251    ///
1252    /// let first = Instant::now();
1253    /// let second = first + Duration::SECOND;
1254    ///
1255    /// assert_eq!(cmp(first, second), Ordering::Less);
1256    /// assert_eq!(cmp(second, first), Ordering::Greater);
1257    /// assert_eq!(cmp(first, first), Ordering::Equal);
1258    /// ```
1259    #[rune::function(keep, instance, protocol = CMP)]
1260    #[inline]
1261    fn cmp(&self, rhs: &Self) -> Ordering {
1262        Ord::cmp(&self.inner, &rhs.inner)
1263    }
1264
1265    /// Hash the instant.
1266    ///
1267    /// # Examples
1268    ///
1269    /// ```rune
1270    /// use std::ops::hash;
1271    /// use time::{Duration, Instant};
1272    ///
1273    /// let now = Instant::now();
1274    ///
1275    /// assert_eq!(hash(now), hash(now));
1276    /// ```
1277    #[rune::function(keep, instance, protocol = HASH)]
1278    fn hash(&self, hasher: &mut Hasher) {
1279        self.inner.hash(hasher);
1280    }
1281
1282    /// Write a debug representation of the instant.
1283    ///
1284    /// # Examples
1285    ///
1286    /// ```rune
1287    /// use time::Instant;
1288    ///
1289    /// let now = Instant::now();
1290    ///
1291    /// println!("{now:?}");
1292    /// ```
1293    #[rune::function(keep, instance, protocol = DEBUG_FMT)]
1294    fn debug_fmt(&self, f: &mut Formatter) -> VmResult<()> {
1295        rune::vm_write!(f, "{:?}", self.inner)
1296    }
1297
1298    /// Clone the current instant.
1299    ///
1300    /// # Examples
1301    ///
1302    /// ```rune
1303    /// use time::{Duration, Instant};
1304    ///
1305    /// let first = Instant::now();
1306    /// let second = first.clone();
1307    /// second += Duration::SECOND;
1308    ///
1309    /// assert!(first < second);
1310    /// ```
1311    #[rune::function(keep, instance, protocol = CLONE)]
1312    fn clone(&self) -> Self {
1313        Self { inner: self.inner }
1314    }
1315}