Struct Stopwatch

Source
pub struct Stopwatch<I: Instant> {
    pub elapsed: Duration,
    pub start: Option<I>,
}
Expand description

A stopwatch measures and accumulates elapsed time between starts and stops.

Stopwatches work with any type that implements Instant.

§Notes

It is possible to craft two stopwatches whose internal components differ, but are equal according to PartialEq, Eq, and Hash.

let elapsed = Duration::from_secs(10);
let start = Instant::now();
let sw_1 = Sw {
    elapsed,
    start: Some(start),
};
let sw_2 = Sw {
    // `elapsed()` is 1s less
    elapsed: elapsed - Duration::from_secs(1),
    // now with start pushed back, `elapsed()` is equal
    start: Some(start - Duration::from_secs(1)),
};

// different components, but they are equal!
assert_eq!(sw_1, sw_2);

Fields§

§elapsed: Duration

Accumulated elapsed time.

§start: Option<I>

The instant at which the stopwatch was started, if it is running. Otherwise, None.

Implementations§

Source§

impl<I: Instant> Stopwatch<I>

Source

pub const fn new() -> Self

Returns a stopped stopwatch with zero elapsed time.

§Examples
let sw = Sw::new();
assert!(sw.is_stopped());
assert_eq!(sw.elapsed(), Duration::ZERO);
Source

pub fn new_started() -> Self

Returns a running stopwatch initialized with zero elapsed time.

§Examples
let sw = Sw::new_started();
assert!(sw.is_running());
Source

pub const fn new_started_at(start: I) -> Self

Returns a stopwatch initialized with zero elapsed time, started at the given instant.

§Examples
let now = Instant::now();
let sw_1 = Sw::new_started_at(now);
let sw_2 = Sw::new_started_at(now);
// they've both started at the same time
assert_eq!(sw_1, sw_2);
// (and had zero elapsed time when they started)
assert_eq!(sw_1.elapsed_at(now), Duration::ZERO);
Source

pub const fn with_elapsed(elapsed: Duration) -> Self

Returns a stopped stopwatch with the given elapsed time.

§Examples
let sw = Sw::with_elapsed(Duration::from_secs(1));
assert!(sw.is_stopped());
assert_eq!(sw.elapsed(), Duration::from_secs(1));
Source

pub fn with_elapsed_started(elapsed: Duration) -> Self

Returns a running stopwatch initialized with the given elapsed time.

§Examples
let sw = Sw::with_elapsed_started(Duration::from_secs(1));
assert!(sw.is_running());
assert!(sw.elapsed() >= Duration::from_secs(1));
Source

pub const fn from_raw(elapsed: Duration, start: Option<I>) -> Self

Returns a stopwatch from its raw parts.

See the top-level documentation for more details.

Source

pub const fn is_running(&self) -> bool

Returns true if the stopwatch is running.

§Examples
let sw = Sw::new_started();
assert!(sw.is_running());
Source

pub const fn is_stopped(&self) -> bool

Returns true if the stopwatch is stopped.

§Examples
let sw = Sw::new();
assert!(sw.is_stopped());
Source

pub fn elapsed(&self) -> Duration

Returns the total time elapsed. If overflow occurs, the elapsed time is saturated to Duration::MAX.

§Examples
let sw = Sw::new_started();
thread::sleep(Duration::from_millis(100));
assert!(sw.elapsed() >= Duration::from_millis(100));
Source

pub fn elapsed_at(&self, anchor: I) -> Duration

Returns the total time elapsed, measured as if the current time were anchor. If overflow occurs, the elapsed time is saturated to Duration::MAX.

§Notes

anchor saturates to the last instant the stopwatch was started.

§Examples
let sw_1 = Sw::new_started();
let sw_2 = sw_1;
let anchor = Instant::now();
assert!(sw_1.elapsed_at(anchor) == sw_2.elapsed_at(anchor));
Source

pub fn checked_elapsed(&self) -> Option<Duration>

Computes the total time elapsed. If overflow occurred, returns None.

§Examples
let mut sw = Sw::new_started();
thread::sleep(Duration::from_millis(100));
assert!(sw.checked_elapsed().unwrap() >= Duration::from_millis(100));
sw += Duration::MAX;
assert!(sw.checked_elapsed().is_none());
Source

pub fn checked_elapsed_at(&self, anchor: I) -> Option<Duration>

Computes the total time elapsed, measured as if the current time were anchor. If overflow occurred, returns None.

§Notes

anchor saturates to the last instant the stopwatch was started.

Source

pub fn start(&mut self)

Starts measuring the time elapsed.

§Examples
let mut sw = Sw::new();
sw.start();

let then = sw.elapsed();
thread::sleep(Duration::from_millis(100));
let now = sw.elapsed();
assert!(then != now);
Source

pub fn start_at(&mut self, anchor: I)

Starts measuring the time elapsed as if the current time were anchor. If the stopwatch is already running, the prior start time is overwritten.

§Notes

If anchor is ahead of the present, elapsed will return Duration::ZERO until the current time catches up to it.

§Examples
let mut sw_1 = Sw::new();
let mut sw_2 = Sw::new();

let start = Instant::now();
// off to the races! at the same time!
sw_1.start_at(start);
sw_2.start_at(start);

thread::sleep(Duration::from_millis(100));
let anchor = Instant::now();

assert_eq!(sw_1.elapsed_at(anchor), sw_2.elapsed_at(anchor)); // 'twas a tie
assert!(sw_1.elapsed_at(anchor) >= Duration::from_millis(100));
Source

pub fn stop(&mut self)

Stops measuring the time elapsed since the last start.

§Notes

Overflows of the new elapsed time are saturated to Duration::MAX. Use Stopwatch::checked_stop to explicitly check for overflow.

§Examples
let mut sw = Sw::new_started();
sw.stop();

let then = sw.elapsed();
thread::sleep(Duration::from_millis(100));
let now = sw.elapsed();
assert!(then == now);
Source

pub fn stop_at(&mut self, anchor: I)

Stops measuring the time elapsed since the last start as if the current time were anchor.

§Notes
  • If anchor is earlier than the last start, there is no effect on the elapsed time.

  • Overflows of the new elapsed time are saturated to Duration::MAX. Use Stopwatch::checked_stop_at to explicitly check for overflow.

§Examples
let mut sw_1 = Sw::new_started();
let mut sw_2 = sw_1;
let stop = Instant::now();
sw_1.stop_at(stop);
sw_2.stop_at(stop);
assert_eq!(sw_1, sw_2);
Source

pub fn checked_stop(&mut self) -> bool

Tries to stop the stopwatch. If the new elapsed time overflows, returns false without mutating the stopwatch.

§Examples
let mut sw = Sw::new_started();
assert!(sw.checked_stop());
sw.set(Duration::MAX);
sw.start();
assert!(!sw.checked_stop());
Source

pub fn checked_stop_at(&mut self, anchor: I) -> bool

Tries to stop the stopwatch, as if the current time were anchor. If the new elapsed time overflows, returns false without mutating the stopwatch.

§Notes

If anchor is earlier than the last start, there is no effect on the elapsed time.

Source

pub fn toggle(&mut self)

Toggles whether the stopwatch is running or stopped.

§Notes

See stop for details about how overflow is handled.

§Examples
let mut sw = Sw::new();
sw.toggle();
assert!(sw.is_running());
sw.toggle();
assert!(sw.is_stopped());
Source

pub fn toggle_at(&mut self, anchor: I)

Toggles whether the stopwatch is running or stopped, as if the current time were anchor.

§Notes

See start_at and stop_at for notes about the chronology of anchor, as well as what happens if overflow occurs.

§Examples
let mut left = Sw::new();
let mut right = Sw::new_started();

// perfect swap of left and right running
let now = Instant::now();
left.toggle_at(now);
right.toggle_at(now);

assert!(left.is_running());
assert!(right.is_stopped());
Source

pub fn checked_toggle(&mut self) -> bool

Tries to toggle whether the stopwatch is running or stopped. If the new elapsed time overflows, returns false without mutating the stopwatch.

§Examples
let mut sw = Sw::with_elapsed_started(Duration::MAX);
thread::sleep(Duration::from_millis(100));
// whoops, new elapsed time can't be Duration::MAX + 100ms
assert!(!sw.checked_toggle());
Source

pub fn checked_toggle_at(&mut self, anchor: I) -> bool

Tries to toggle whether the stopwatch is running or stopped, as if the current time were anchor. If the new elapsed time overflows, returns false without mutating the stopwatch.

Source

pub fn reset(&mut self)

Stops and resets the elapsed time to zero.

§Examples
let mut sw = Sw::with_elapsed_started(Duration::from_secs(1));
sw.reset();
assert_eq!(sw, Sw::new());
Source

pub fn reset_in_place(&mut self)

Resets the elapsed time to zero without affecting whether the stopwatch is running.

§Examples
let mut sw = Sw::with_elapsed_started(Duration::from_secs(1));
sw.reset_in_place();
assert!(sw.is_running());
// new elapsed time is close to zero
assert!(sw.elapsed() < Duration::from_millis(1));

sw.stop();
sw.reset_in_place();
assert_eq!(sw, Sw::new());
Source

pub fn reset_in_place_at(&mut self, start: I)

Resets the elapsed time to zero without affecting whether the stopwatch is running.

§Notes

See start_at for notes about the chronology of anchor.

Source

pub fn set(&mut self, new: Duration)

Stops and sets the total elapsed time to new.

§Examples
let mut sw = Sw::new();
sw.set(Duration::from_secs(1));
assert_eq!(sw.elapsed(), Duration::from_secs(1));
Source

pub fn set_in_place(&mut self, new: Duration)

Sets the total elapsed time to new without affecting whether the stopwatch is running.

§Examples
let mut sw = Sw::new();
sw.set_in_place(Duration::from_secs(1));
assert_eq!(sw.elapsed(), Duration::from_secs(1));
assert!(sw.is_stopped());

sw.start();
sw.set_in_place(Duration::from_secs(2));
assert!(sw.elapsed() >= Duration::from_secs(2));
assert!(sw.is_running());
Source

pub fn set_in_place_at(&mut self, new: Duration, anchor: I)

Sets the total elapsed time to new as if the current time were anchor, and without affecting whether the stopwatch is running.

§Notes

See start_at for notes about the chronology of anchor.

Source

pub fn replace(&mut self, new: Duration) -> Duration

Stops and sets the total elapsed time to new, returning the previous elapsed time.

§Examples
let mut sw = Sw::with_elapsed(Duration::from_secs(3));
let previous = sw.replace(Duration::from_secs(1));
assert_eq!(previous, Duration::from_secs(3));
assert_eq!(sw.elapsed(), Duration::from_secs(1));
Source

pub fn replace_at(&mut self, new: Duration, anchor: I) -> Duration

Stops and sets the total elapsed time to new, returning the previous elapsed time as if the current time were anchor.

§Notes

See elapsed_at for notes about the chronology of anchor.

Source

pub const fn saturating_add(self, dur: Duration) -> Self

Adds dur to the total elapsed time. If overflow occurred, the total elapsed time is set to Duration::MAX.

let mut sw = Sw::with_elapsed(Duration::from_secs(1));
sw = sw.saturating_add(Duration::from_secs(1));
assert_eq!(sw.elapsed(), Duration::from_secs(2));
sw = sw.saturating_add(Duration::MAX);
assert_eq!(sw.elapsed(), Duration::MAX);
Source

pub fn saturating_sub(self, dur: Duration) -> Self

Subtracts dur from the total elapsed time. If underflow occurred, the total elapsed time is set to Duration::ZERO.

§Notes

See the documentation for saturating_sub_at for notes about positive overflow.

§Examples
let mut sw = Sw::with_elapsed(Duration::from_secs(1));
sw = sw.saturating_sub(Duration::from_secs(1));
assert_eq!(sw.elapsed(), Duration::ZERO);
sw = sw.saturating_sub(Duration::from_secs(1));
assert_eq!(sw.elapsed(), Duration::ZERO);
Source

pub fn saturating_sub_at(self, dur: Duration, anchor: I) -> Self

Subtracts dur from the total elapsed time, as if the current time were anchor. If underflow occurred, the total elapsed time is set to Duration::ZERO.

§Notes
  • If the elapsed time is overflowing (as in, exceeds Duration::MAX prior to subtraction), the elapsed time is clamped to Duration::MAX and then dur is subtracted from that.

  • anchor saturates to the last instant the stopwatch was started.

§Examples
let mut sw = Sw::new_started();
thread::sleep(Duration::from_millis(100));
let now = Instant::now();
sw = sw.saturating_sub_at(Duration::from_secs(1), now);
assert_eq!(sw.elapsed_at(now), Duration::ZERO);
Source

pub const fn checked_add(self, dur: Duration) -> Option<Self>

Adds dur to the total elapsed time. If overflow occurred, returns None.

§Examples
let mut sw = Sw::new();
sw = sw.checked_add(Duration::from_secs(1)).unwrap();
assert_eq!(sw.elapsed(), Duration::from_secs(1));
assert_eq!(sw.checked_add(Duration::MAX), None);
Source

pub fn checked_sub(self, dur: Duration) -> Option<Self>

Subtracts dur from the total elapsed time. If overflow occurred, returns None.

§Notes

See the documentation for checked_sub_at for notes about positive overflow.

§Examples
let mut sw = Sw::new();
assert_eq!(sw.checked_sub(Duration::from_secs(1)), None);
sw += Duration::from_secs(1);
assert_eq!(
    sw.checked_sub(Duration::from_secs(1)),
    Some(Sw::with_elapsed(Duration::ZERO)),
);
Source

pub fn checked_sub_at(self, dur: Duration, anchor: I) -> Option<Self>

Subtracts dur from the total elapsed time, as if the current time were anchor. If overflow occurred, returns None.

§Notes
  • Overflow occurs if the elapsed time overflows prior to subtraction.

  • anchor saturates to the last instant the stopwatch was started.

§Examples
let mut sw = Sw::new_started();
thread::sleep(Duration::from_millis(100));
let now = Instant::now();
// underflow yields `None`
assert_eq!(sw.checked_sub_at(Duration::from_secs(1), now), None);

// positive overflow yields `None`
sw.set_in_place(Duration::MAX);
assert_eq!(sw.checked_sub(Duration::ZERO), None);
assert_eq!(sw.checked_sub(Duration::from_secs(2)), None);

Trait Implementations§

Source§

impl<I: Instant> Add<Duration> for Stopwatch<I>

Source§

fn add(self, dur: Duration) -> Self::Output

Add dur to self.

Currently this is an alias to Stopwatch::checked_add, but that is not a stable guarentee. If you need a guarentee on the implementation, use the checked or saturating methods explicitly.

§Panics

Panics if overflow occurs.

Source§

type Output = Stopwatch<I>

The resulting type after applying the + operator.
Source§

impl<I: Instant> AddAssign<Duration> for Stopwatch<I>

Source§

fn add_assign(&mut self, dur: Duration)

Performs the += operation. Read more
Source§

impl<I: Clone + Instant> Clone for Stopwatch<I>

Source§

fn clone(&self) -> Stopwatch<I>

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<I: Debug + Instant> Debug for Stopwatch<I>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<I: Instant> Default for Stopwatch<I>

Source§

fn default() -> Self

Returns the default stopwatch. Same as calling Stopwatch::new.

Source§

impl<I: Instant + Hash> Hash for Stopwatch<I>

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Hashes self and rhs. These hashes are not dependent on the time of measurement, so they can be used to test equality.

§Support

I (the Instant type used by the stopwatch) must implement Hash.

1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<I: Instant> PartialEq for Stopwatch<I>

Source§

fn eq(&self, rhs: &Self) -> bool

Tests for equality between self and rhs.

Stopwatches are equal if whether they are running and their elapsed time are equal.

1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<I: Instant> Sub<Duration> for Stopwatch<I>

Source§

fn sub(self, dur: Duration) -> Self::Output

Subtract dur from self.

Currently this is an alias to Stopwatch::checked_sub, but that is not a stable guarentee. If you need a guarentee on the implementation, use the checked or saturating methods explicitly.

§Panics

Panics if overflow occurs.

Source§

type Output = Stopwatch<I>

The resulting type after applying the - operator.
Source§

impl<I: Instant> SubAssign<Duration> for Stopwatch<I>

Source§

fn sub_assign(&mut self, dur: Duration)

Performs the -= operation. Read more
Source§

impl<I: Copy + Instant> Copy for Stopwatch<I>

Source§

impl<I: Instant> Eq for Stopwatch<I>

Auto Trait Implementations§

§

impl<I> Freeze for Stopwatch<I>
where I: Freeze,

§

impl<I> RefUnwindSafe for Stopwatch<I>
where I: RefUnwindSafe,

§

impl<I> Send for Stopwatch<I>
where I: Send,

§

impl<I> Sync for Stopwatch<I>
where I: Sync,

§

impl<I> Unpin for Stopwatch<I>
where I: Unpin,

§

impl<I> UnwindSafe for Stopwatch<I>
where I: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.