gloo_console/
timer.rs

1//! The `console.time` and `console.timeEnd` functions allow you to log the
2//! timing of named operations to the browser's developer tools console. You
3//! call `console.time("foo")` when the operation begins, and call
4//! `console.timeEnd("foo")` when it finishes.
5//!
6//! Additionally, these measurements will show up in your browser's profiler's
7//! "timeline" or "waterfall" view.
8//!
9//! [See MDN for more info](https://developer.mozilla.org/en-US/docs/Web/API/console#Timers).
10//!
11//! This API wraps both the `time` and `timeEnd` calls into a single type
12//! named `ConsoleTimer`, ensuring both are called.
13//!
14//! ## Scoped Measurement
15//!
16//! Wrap code to be measured in a closure with [`Timer::scope`].
17//!
18//! ```no_run
19//! use gloo_console::Timer;
20//!
21//! let value = Timer::scope("foo", || {
22//!     // Place code to be measured here
23//!     // Optionally return a value.
24//! });
25//! ```
26//!
27//! ## RAII-Style Measurement
28//!
29//! For scenarios where [`Timer::scope`] can't be used, like with
30//! asynchronous operations, you can use `ConsoleTimer::new` to create a timer.
31//! The measurement ends when the timer object goes out of scope / is dropped.
32//!
33//! ```no_run
34//! use gloo_console::Timer;
35//! use gloo_timers::callback::Timeout;
36//!
37//! // Start timing a new operation.
38//! let timer = Timer::new("foo");
39//!
40//! // And then asynchronously finish timing.
41//! let timeout = Timeout::new(1_000, move || {
42//!     drop(timer);
43//! });
44//! ```
45
46use web_sys::console;
47
48/// A console time measurement.
49///
50/// See [`Timer::scope`] for starting a labeled time measurement
51/// of code wrapped in a closure.
52#[derive(Debug)]
53pub struct Timer<'a> {
54    label: &'a str,
55}
56
57impl<'a> Timer<'a> {
58    /// Starts a console time measurement. The measurement
59    /// ends when the constructed `ConsoleTimer` object is dropped.
60    ///
61    /// # Example
62    ///
63    /// ```no_run
64    /// use gloo_console::Timer;
65    ///
66    /// let _timer = Timer::new("foo");
67    /// ```
68    pub fn new(label: &'a str) -> Timer<'a> {
69        console::time_with_label(label);
70        Timer { label }
71    }
72
73    /// Starts a scoped console time measurement
74    ///
75    /// # Example
76    ///
77    /// ```no_run
78    /// use gloo_console::Timer;
79    ///
80    /// let value = Timer::scope("foo", || {
81    ///     // Code to measure here
82    /// });
83    /// ```
84    pub fn scope<F, T>(label: &str, f: F) -> T
85    where
86        F: FnOnce() -> T,
87    {
88        let _timer = Timer::new(label);
89        f()
90    }
91}
92
93impl<'a> Drop for Timer<'a> {
94    fn drop(&mut self) {
95        console::time_end_with_label(self.label);
96    }
97}