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>
impl<I: Instant> Stopwatch<I>
Sourcepub const fn new() -> Self
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);
Sourcepub fn new_started() -> Self
pub fn new_started() -> Self
Returns a running stopwatch initialized with zero elapsed time.
§Examples
let sw = Sw::new_started();
assert!(sw.is_running());
Sourcepub const fn new_started_at(start: I) -> Self
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);
Sourcepub const fn with_elapsed(elapsed: Duration) -> Self
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));
Sourcepub fn with_elapsed_started(elapsed: Duration) -> Self
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));
Sourcepub const fn from_raw(elapsed: Duration, start: Option<I>) -> Self
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.
Sourcepub const fn is_running(&self) -> bool
pub const fn is_running(&self) -> bool
Returns true
if the stopwatch is running.
§Examples
let sw = Sw::new_started();
assert!(sw.is_running());
Sourcepub const fn is_stopped(&self) -> bool
pub const fn is_stopped(&self) -> bool
Sourcepub fn elapsed(&self) -> Duration
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));
Sourcepub fn elapsed_at(&self, anchor: I) -> Duration
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));
Sourcepub fn checked_elapsed(&self) -> Option<Duration>
pub fn checked_elapsed(&self) -> Option<Duration>
Sourcepub fn checked_elapsed_at(&self, anchor: I) -> Option<Duration>
pub fn checked_elapsed_at(&self, anchor: I) -> Option<Duration>
Sourcepub fn start(&mut self)
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);
Sourcepub fn start_at(&mut self, anchor: I)
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));
Sourcepub fn stop(&mut self)
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);
Sourcepub fn stop_at(&mut self, anchor: I)
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
. UseStopwatch::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);
Sourcepub fn checked_stop(&mut self) -> bool
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());
Sourcepub fn checked_stop_at(&mut self, anchor: I) -> bool
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.
Sourcepub fn toggle_at(&mut self, anchor: I)
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());
Sourcepub fn checked_toggle(&mut self) -> bool
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());
Sourcepub fn checked_toggle_at(&mut self, anchor: I) -> bool
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.
Sourcepub fn reset(&mut self)
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());
Sourcepub fn reset_in_place(&mut self)
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());
Sourcepub fn reset_in_place_at(&mut self, start: I)
pub fn reset_in_place_at(&mut self, start: I)
Sourcepub fn set(&mut self, new: Duration)
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));
Sourcepub fn set_in_place(&mut self, new: Duration)
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());
Sourcepub fn set_in_place_at(&mut self, new: Duration, anchor: I)
pub fn set_in_place_at(&mut self, new: Duration, anchor: I)
Sourcepub fn replace(&mut self, new: Duration) -> Duration
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));
Sourcepub fn replace_at(&mut self, new: Duration, anchor: I) -> Duration
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
.
Sourcepub const fn saturating_add(self, dur: Duration) -> Self
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);
Sourcepub fn saturating_sub(self, dur: Duration) -> Self
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);
Sourcepub fn saturating_sub_at(self, dur: Duration, anchor: I) -> Self
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 toDuration::MAX
and thendur
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);
Sourcepub const fn checked_add(self, dur: Duration) -> Option<Self>
pub const fn checked_add(self, dur: Duration) -> Option<Self>
Sourcepub fn checked_sub(self, dur: Duration) -> Option<Self>
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)),
);
Sourcepub fn checked_sub_at(self, dur: Duration, anchor: I) -> Option<Self>
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>
impl<I: Instant> Add<Duration> for Stopwatch<I>
Source§fn add(self, dur: Duration) -> Self::Output
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§impl<I: Instant> AddAssign<Duration> for Stopwatch<I>
impl<I: Instant> AddAssign<Duration> for Stopwatch<I>
Source§fn add_assign(&mut self, dur: Duration)
fn add_assign(&mut self, dur: Duration)
+=
operation. Read moreSource§impl<I: Instant> Default for Stopwatch<I>
impl<I: Instant> Default for Stopwatch<I>
Source§fn default() -> Self
fn default() -> Self
Returns the default stopwatch. Same as calling Stopwatch::new
.
Source§impl<I: Instant> PartialEq for Stopwatch<I>
impl<I: Instant> PartialEq for Stopwatch<I>
Source§impl<I: Instant> Sub<Duration> for Stopwatch<I>
impl<I: Instant> Sub<Duration> for Stopwatch<I>
Source§fn sub(self, dur: Duration) -> Self::Output
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§impl<I: Instant> SubAssign<Duration> for Stopwatch<I>
impl<I: Instant> SubAssign<Duration> for Stopwatch<I>
Source§fn sub_assign(&mut self, dur: Duration)
fn sub_assign(&mut self, dur: Duration)
-=
operation. Read more