diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
commit | 4f9fe856a25ab29345b90e7725509e9ee38a37be (patch) | |
tree | e4ffd8a9374cae7b21f7cbfb352927e0e074aff6 /vendor/tracing-subscriber/src/fmt/time/time_crate.rs | |
parent | Adding upstream version 1.68.2+dfsg1. (diff) | |
download | rustc-5cd5bd4daf55da04d2c8e7c06c3067a027cfbfc2.tar.xz rustc-5cd5bd4daf55da04d2c8e7c06c3067a027cfbfc2.zip |
Adding upstream version 1.69.0+dfsg1.upstream/1.69.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | vendor/tracing-subscriber/src/fmt/time/time_crate.rs | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/vendor/tracing-subscriber/src/fmt/time/time_crate.rs b/vendor/tracing-subscriber/src/fmt/time/time_crate.rs new file mode 100644 index 000000000..60d57fd0b --- /dev/null +++ b/vendor/tracing-subscriber/src/fmt/time/time_crate.rs @@ -0,0 +1,470 @@ +use crate::fmt::{format::Writer, time::FormatTime, writer::WriteAdaptor}; +use std::fmt; +use time::{format_description::well_known, formatting::Formattable, OffsetDateTime, UtcOffset}; + +/// Formats the current [local time] using a [formatter] from the [`time` crate]. +/// +/// To format the current [UTC time] instead, use the [`UtcTime`] type. +/// +/// <div class="example-wrap" style="display:inline-block"> +/// <pre class="compile_fail" style="white-space:normal;font:inherit;"> +/// <strong>Warning</strong>: The <a href = "https://docs.rs/time/0.3/time/"><code>time</code> +/// crate</a> must be compiled with <code>--cfg unsound_local_offset</code> in order to use +/// local timestamps. When this cfg is not enabled, local timestamps cannot be recorded, and +/// events will be logged without timestamps. +/// +/// Alternatively, [`OffsetTime`] can log with a local offset if it is initialized early. +/// +/// See the <a href="https://docs.rs/time/0.3.4/time/#feature-flags"><code>time</code> +/// documentation</a> for more details. +/// </pre></div> +/// +/// [local time]: time::OffsetDateTime::now_local +/// [UTC time]: time::OffsetDateTime::now_utc +/// [formatter]: time::formatting::Formattable +/// [`time` crate]: time +#[derive(Clone, Debug)] +#[cfg_attr( + docsrs, + doc(cfg(all(unsound_local_offset, feature = "time", feature = "local-time"))) +)] +#[cfg(feature = "local-time")] +pub struct LocalTime<F> { + format: F, +} + +/// Formats the current [UTC time] using a [formatter] from the [`time` crate]. +/// +/// To format the current [local time] instead, use the [`LocalTime`] type. +/// +/// [local time]: time::OffsetDateTime::now_local +/// [UTC time]: time::OffsetDateTime::now_utc +/// [formatter]: time::formatting::Formattable +/// [`time` crate]: time +#[cfg_attr(docsrs, doc(cfg(feature = "time")))] +#[derive(Clone, Debug)] +pub struct UtcTime<F> { + format: F, +} + +/// Formats the current time using a fixed offset and a [formatter] from the [`time` crate]. +/// +/// This is typically used as an alternative to [`LocalTime`]. `LocalTime` determines the offset +/// every time it formats a message, which may be unsound or fail. With `OffsetTime`, the offset is +/// determined once. This makes it possible to do so while the program is still single-threaded and +/// handle any errors. However, this also means the offset cannot change while the program is +/// running (the offset will not change across DST changes). +/// +/// [formatter]: time::formatting::Formattable +/// [`time` crate]: time +#[derive(Clone, Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "time")))] +pub struct OffsetTime<F> { + offset: time::UtcOffset, + format: F, +} + +// === impl LocalTime === + +#[cfg(feature = "local-time")] +impl LocalTime<well_known::Rfc3339> { + /// Returns a formatter that formats the current [local time] in the + /// [RFC 3339] format (a subset of the [ISO 8601] timestamp format). + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time}; + /// + /// let collector = tracing_subscriber::fmt() + /// .with_timer(time::LocalTime::rfc_3339()); + /// # drop(collector); + /// ``` + /// + /// [local time]: time::OffsetDateTime::now_local + /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 + /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 + pub fn rfc_3339() -> Self { + Self::new(well_known::Rfc3339) + } +} + +#[cfg(feature = "local-time")] +impl<F: Formattable> LocalTime<F> { + /// Returns a formatter that formats the current [local time] using the + /// [`time` crate] with the provided provided format. The format may be any + /// type that implements the [`Formattable`] trait. + /// + /// + /// <div class="example-wrap" style="display:inline-block"> + /// <pre class="compile_fail" style="white-space:normal;font:inherit;"> + /// <strong>Warning</strong>: The <a href = "https://docs.rs/time/0.3/time/"> + /// <code>time</code> crate</a> must be compiled with <code>--cfg + /// unsound_local_offset</code> in order to use local timestamps. When this + /// cfg is not enabled, local timestamps cannot be recorded, and + /// events will be logged without timestamps. + /// + /// See the <a href="https://docs.rs/time/0.3.4/time/#feature-flags"> + /// <code>time</code> documentation</a> for more details. + /// </pre></div> + /// + /// Typically, the format will be a format description string, or one of the + /// `time` crate's [well-known formats]. + /// + /// If the format description is statically known, then the + /// [`format_description!`] macro should be used. This is identical to the + /// [`time::format_description::parse`] method, but runs at compile-time, + /// throwing an error if the format description is invalid. If the desired format + /// is not known statically (e.g., a user is providing a format string), then the + /// [`time::format_description::parse`] method should be used. Note that this + /// method is fallible. + /// + /// See the [`time` book] for details on the format description syntax. + /// + /// # Examples + /// + /// Using the [`format_description!`] macro: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::LocalTime}; + /// use time::macros::format_description; + /// + /// let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]")); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using [`time::format_description::parse`]: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::LocalTime}; + /// + /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") + /// .expect("format string should be valid!"); + /// let timer = LocalTime::new(time_format); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using the [`format_description!`] macro requires enabling the `time` + /// crate's "macros" feature flag. + /// + /// Using a [well-known format][well-known formats] (this is equivalent to + /// [`LocalTime::rfc_3339`]): + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::LocalTime}; + /// + /// let timer = LocalTime::new(time::format_description::well_known::Rfc3339); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// [local time]: time::OffsetDateTime::now_local() + /// [`time` crate]: time + /// [`Formattable`]: time::formatting::Formattable + /// [well-known formats]: time::format_description::well_known + /// [`format_description!`]: time::macros::format_description! + /// [`time::format_description::parse`]: time::format_description::parse() + /// [`time` book]: https://time-rs.github.io/book/api/format-description.html + pub fn new(format: F) -> Self { + Self { format } + } +} + +#[cfg(feature = "local-time")] +impl<F> FormatTime for LocalTime<F> +where + F: Formattable, +{ + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + let now = OffsetDateTime::now_local().map_err(|_| fmt::Error)?; + format_datetime(now, w, &self.format) + } +} + +#[cfg(feature = "local-time")] +impl<F> Default for LocalTime<F> +where + F: Formattable + Default, +{ + fn default() -> Self { + Self::new(F::default()) + } +} + +// === impl UtcTime === + +impl UtcTime<well_known::Rfc3339> { + /// Returns a formatter that formats the current [UTC time] in the + /// [RFC 3339] format, which is a subset of the [ISO 8601] timestamp format. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time}; + /// + /// let collector = tracing_subscriber::fmt() + /// .with_timer(time::UtcTime::rfc_3339()); + /// # drop(collector); + /// ``` + /// + /// [local time]: time::OffsetDateTime::now_utc + /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 + /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 + pub fn rfc_3339() -> Self { + Self::new(well_known::Rfc3339) + } +} + +impl<F: Formattable> UtcTime<F> { + /// Returns a formatter that formats the current [UTC time] using the + /// [`time` crate], with the provided provided format. The format may be any + /// type that implements the [`Formattable`] trait. + /// + /// Typically, the format will be a format description string, or one of the + /// `time` crate's [well-known formats]. + /// + /// If the format description is statically known, then the + /// [`format_description!`] macro should be used. This is identical to the + /// [`time::format_description::parse`] method, but runs at compile-time, + /// failing an error if the format description is invalid. If the desired format + /// is not known statically (e.g., a user is providing a format string), then the + /// [`time::format_description::parse`] method should be used. Note that this + /// method is fallible. + /// + /// See the [`time` book] for details on the format description syntax. + /// + /// # Examples + /// + /// Using the [`format_description!`] macro: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::UtcTime}; + /// use time::macros::format_description; + /// + /// let timer = UtcTime::new(format_description!("[hour]:[minute]:[second]")); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using the [`format_description!`] macro requires enabling the `time` + /// crate's "macros" feature flag. + /// + /// Using [`time::format_description::parse`]: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::UtcTime}; + /// + /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") + /// .expect("format string should be valid!"); + /// let timer = UtcTime::new(time_format); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using a [well-known format][well-known formats] (this is equivalent to + /// [`UtcTime::rfc_3339`]): + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::UtcTime}; + /// + /// let timer = UtcTime::new(time::format_description::well_known::Rfc3339); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// [UTC time]: time::OffsetDateTime::now_utc() + /// [`time` crate]: time + /// [`Formattable`]: time::formatting::Formattable + /// [well-known formats]: time::format_description::well_known + /// [`format_description!`]: time::macros::format_description! + /// [`time::format_description::parse`]: time::format_description::parse + /// [`time` book]: https://time-rs.github.io/book/api/format-description.html + pub fn new(format: F) -> Self { + Self { format } + } +} + +impl<F> FormatTime for UtcTime<F> +where + F: Formattable, +{ + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + format_datetime(OffsetDateTime::now_utc(), w, &self.format) + } +} + +impl<F> Default for UtcTime<F> +where + F: Formattable + Default, +{ + fn default() -> Self { + Self::new(F::default()) + } +} + +// === impl OffsetTime === + +#[cfg(feature = "local-time")] +impl OffsetTime<well_known::Rfc3339> { + /// Returns a formatter that formats the current time using the [local time offset] in the [RFC + /// 3339] format (a subset of the [ISO 8601] timestamp format). + /// + /// Returns an error if the local time offset cannot be determined. This typically occurs in + /// multithreaded programs. To avoid this problem, initialize `OffsetTime` before forking + /// threads. When using Tokio, this means initializing `OffsetTime` before the Tokio runtime. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time}; + /// + /// let collector = tracing_subscriber::fmt() + /// .with_timer(time::OffsetTime::local_rfc_3339().expect("could not get local offset!")); + /// # drop(collector); + /// ``` + /// + /// Using `OffsetTime` with Tokio: + /// + /// ``` + /// use tracing_subscriber::fmt::time::OffsetTime; + /// + /// #[tokio::main] + /// async fn run() { + /// tracing::info!("runtime initialized"); + /// + /// // At this point the Tokio runtime is initialized, and we can use both Tokio and Tracing + /// // normally. + /// } + /// + /// fn main() { + /// // Because we need to get the local offset before Tokio spawns any threads, our `main` + /// // function cannot use `tokio::main`. + /// tracing_subscriber::fmt() + /// .with_timer(OffsetTime::local_rfc_3339().expect("could not get local time offset")) + /// .init(); + /// + /// // Even though `run` is written as an `async fn`, because we used `tokio::main` on it + /// // we can call it as a synchronous function. + /// run(); + /// } + /// ``` + /// + /// [local time offset]: time::UtcOffset::current_local_offset + /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 + /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 + pub fn local_rfc_3339() -> Result<Self, time::error::IndeterminateOffset> { + Ok(Self::new( + UtcOffset::current_local_offset()?, + well_known::Rfc3339, + )) + } +} + +impl<F: time::formatting::Formattable> OffsetTime<F> { + /// Returns a formatter that formats the current time using the [`time` crate] with the provided + /// provided format and [timezone offset]. The format may be any type that implements the + /// [`Formattable`] trait. + /// + /// + /// Typically, the offset will be the [local offset], and format will be a format description + /// string, or one of the `time` crate's [well-known formats]. + /// + /// If the format description is statically known, then the + /// [`format_description!`] macro should be used. This is identical to the + /// [`time::format_description::parse`] method, but runs at compile-time, + /// throwing an error if the format description is invalid. If the desired format + /// is not known statically (e.g., a user is providing a format string), then the + /// [`time::format_description::parse`] method should be used. Note that this + /// method is fallible. + /// + /// See the [`time` book] for details on the format description syntax. + /// + /// # Examples + /// + /// Using the [`format_description!`] macro: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::OffsetTime}; + /// use time::macros::format_description; + /// use time::UtcOffset; + /// + /// let offset = UtcOffset::current_local_offset().expect("should get local offset!"); + /// let timer = OffsetTime::new(offset, format_description!("[hour]:[minute]:[second]")); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using [`time::format_description::parse`]: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::OffsetTime}; + /// use time::UtcOffset; + /// + /// let offset = UtcOffset::current_local_offset().expect("should get local offset!"); + /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") + /// .expect("format string should be valid!"); + /// let timer = OffsetTime::new(offset, time_format); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using the [`format_description!`] macro requires enabling the `time` + /// crate's "macros" feature flag. + /// + /// Using a [well-known format][well-known formats] (this is equivalent to + /// [`OffsetTime::local_rfc_3339`]): + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::OffsetTime}; + /// use time::UtcOffset; + /// + /// let offset = UtcOffset::current_local_offset().expect("should get local offset!"); + /// let timer = OffsetTime::new(offset, time::format_description::well_known::Rfc3339); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// [`time` crate]: time + /// [timezone offset]: time::UtcOffset + /// [`Formattable`]: time::formatting::Formattable + /// [local offset]: time::UtcOffset::current_local_offset() + /// [well-known formats]: time::format_description::well_known + /// [`format_description!`]: time::macros::format_description + /// [`time::format_description::parse`]: time::format_description::parse + /// [`time` book]: https://time-rs.github.io/book/api/format-description.html + pub fn new(offset: time::UtcOffset, format: F) -> Self { + Self { offset, format } + } +} + +impl<F> FormatTime for OffsetTime<F> +where + F: time::formatting::Formattable, +{ + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + let now = OffsetDateTime::now_utc().to_offset(self.offset); + format_datetime(now, w, &self.format) + } +} + +fn format_datetime( + now: OffsetDateTime, + into: &mut Writer<'_>, + fmt: &impl Formattable, +) -> fmt::Result { + let mut into = WriteAdaptor::new(into); + now.format_into(&mut into, fmt) + .map_err(|_| fmt::Error) + .map(|_| ()) +} |