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}