diff options
Diffstat (limited to 'third_party/rust/time/src/lib.rs')
-rw-r--r-- | third_party/rust/time/src/lib.rs | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/third_party/rust/time/src/lib.rs b/third_party/rust/time/src/lib.rs new file mode 100644 index 0000000000..b9868c1788 --- /dev/null +++ b/third_party/rust/time/src/lib.rs @@ -0,0 +1,357 @@ +//! # Feature flags +//! +//! This crate exposes a number of features. These can be enabled or disabled as shown +//! [in Cargo's documentation](https://doc.rust-lang.org/cargo/reference/features.html). Features +//! are _disabled_ by default unless otherwise noted. +//! +//! Reliance on a given feature is always indicated alongside the item definition. +//! +//! - `std` (_enabled by default, implicitly enables `alloc`_) +//! +//! This enables a number of features that depend on the standard library. +//! +//! - `alloc` (_enabled by default via `std`_) +//! +//! Enables a number of features that require the ability to dynamically allocate memory. +//! +//! - `macros` +//! +//! Enables macros that provide compile-time verification of values and intuitive syntax. +//! +//! - `formatting` (_implicitly enables `std`_) +//! +//! Enables formatting of most structs. +//! +//! - `parsing` +//! +//! Enables parsing of most structs. +//! +//! - `local-offset` (_implicitly enables `std`_) +//! +//! This feature enables a number of methods that allow obtaining the system's UTC offset. +//! +//! - `large-dates` +//! +//! By default, only years within the ±9999 range (inclusive) are supported. If you need support +//! for years outside this range, consider enabling this feature; the supported range will be +//! increased to ±999,999. +//! +//! Note that enabling this feature has some costs, as it means forgoing some optimizations. +//! Ambiguities may be introduced when parsing that would not otherwise exist. +//! +//! - `serde` +//! +//! Enables [serde](https://docs.rs/serde) support for all types except [`Instant`]. +//! +//! - `serde-human-readable` (_implicitly enables `serde`, `formatting`, and `parsing`_) +//! +//! Allows serde representations to use a human-readable format. This is determined by the +//! serializer, not the user. If this feature is not enabled or if the serializer requests a +//! non-human-readable format, a format optimized for binary representation will be used. +//! +//! Libraries should never enable this feature, as the decision of what format to use should be up +//! to the user. +//! +//! - `serde-well-known` (_implicitly enables `serde-human-readable`_) +//! +//! _This feature flag is deprecated and will be removed in a future breaking release. Use the +//! `serde-human-readable` feature instead._ +//! +//! Enables support for serializing and deserializing well-known formats using serde's +//! [`#[with]` attribute](https://serde.rs/field-attrs.html#with). +//! +//! - `rand` +//! +//! Enables [rand](https://docs.rs/rand) support for all types. +//! +//! - `quickcheck` (_implicitly enables `alloc`_) +//! +//! Enables [quickcheck](https://docs.rs/quickcheck) support for all types except [`Instant`]. +//! +//! - `wasm-bindgen` +//! +//! Enables [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) support for converting +//! [JavaScript dates](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Date.html), as +//! well as obtaining the UTC offset from JavaScript. +//! +//! <small> +//! One feature only available to end users is the <code>unsound_local_offset</code> cfg. This +//! enables obtaining the system's UTC offset even when it is unsound. To enable this, use the +//! <code>RUSTFLAGS</code> environment variable. This is untested and officially unsupported. Do not +//! use this unless you understand the risk. +//! </small> + +#![doc(html_playground_url = "https://play.rust-lang.org")] +#![cfg_attr(__time_03_docs, feature(doc_auto_cfg, doc_notable_trait))] +#![cfg_attr(not(feature = "std"), no_std)] +#![deny( + anonymous_parameters, + clippy::all, + clippy::alloc_instead_of_core, + clippy::explicit_auto_deref, + clippy::obfuscated_if_else, + clippy::std_instead_of_core, + clippy::undocumented_unsafe_blocks, + const_err, + illegal_floating_point_literal_pattern, + late_bound_lifetime_arguments, + path_statements, + patterns_in_fns_without_body, + rust_2018_idioms, + trivial_casts, + trivial_numeric_casts, + unreachable_pub, + unsafe_op_in_unsafe_fn, + unused_extern_crates, + rustdoc::broken_intra_doc_links, + rustdoc::private_intra_doc_links +)] +#![warn( + clippy::dbg_macro, + clippy::decimal_literal_representation, + clippy::get_unwrap, + clippy::missing_docs_in_private_items, + clippy::nursery, + clippy::print_stdout, + clippy::todo, + clippy::unimplemented, + clippy::unnested_or_patterns, + clippy::unwrap_in_result, + clippy::unwrap_used, + clippy::use_debug, + deprecated_in_future, + missing_copy_implementations, + missing_debug_implementations, + unused_qualifications, + variant_size_differences +)] +#![allow( + clippy::redundant_pub_crate, // suggests bad style + clippy::option_if_let_else, // suggests terrible code + clippy::unused_peekable, // temporary due to bug: remove when Rust 1.66 is released + clippy::std_instead_of_core, // temporary due to bug: remove when Rust 1.66 is released +)] +#![doc(html_favicon_url = "https://avatars0.githubusercontent.com/u/55999857")] +#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/55999857")] +#![doc(test(attr(deny(warnings))))] + +#[allow(unused_extern_crates)] +#[cfg(feature = "alloc")] +extern crate alloc; + +// region: macros +/// Helper macro for easily implementing `OpAssign`. +macro_rules! __impl_assign { + ($sym:tt $op:ident $fn:ident $target:ty : $($(#[$attr:meta])* $t:ty),+) => {$( + #[allow(unused_qualifications)] + $(#[$attr])* + impl core::ops::$op<$t> for $target { + fn $fn(&mut self, rhs: $t) { + *self = *self $sym rhs; + } + } + )+}; +} + +/// Implement `AddAssign` for the provided types. +macro_rules! impl_add_assign { + ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { + __impl_assign!(+ AddAssign add_assign $target : $($(#[$attr])* $t),+); + }; +} + +/// Implement `SubAssign` for the provided types. +macro_rules! impl_sub_assign { + ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { + __impl_assign!(- SubAssign sub_assign $target : $($(#[$attr])* $t),+); + }; +} + +/// Implement `MulAssign` for the provided types. +macro_rules! impl_mul_assign { + ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { + __impl_assign!(* MulAssign mul_assign $target : $($(#[$attr])* $t),+); + }; +} + +/// Implement `DivAssign` for the provided types. +macro_rules! impl_div_assign { + ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { + __impl_assign!(/ DivAssign div_assign $target : $($(#[$attr])* $t),+); + }; +} + +/// Division of integers, rounding the resulting value towards negative infinity. +macro_rules! div_floor { + ($a:expr, $b:expr) => {{ + let _a = $a; + let _b = $b; + + let (_quotient, _remainder) = (_a / _b, _a % _b); + + if (_remainder > 0 && _b < 0) || (_remainder < 0 && _b > 0) { + _quotient - 1 + } else { + _quotient + } + }}; +} + +/// Cascade an out-of-bounds value. +macro_rules! cascade { + (@ordinal ordinal) => {}; + (@year year) => {}; + + // Cascade an out-of-bounds value from "from" to "to". + ($from:ident in $min:literal.. $max:literal => $to:tt) => { + #[allow(unused_comparisons, unused_assignments)] + if $from >= $max { + $from -= $max - $min; + $to += 1; + } else if $from < $min { + $from += $max - $min; + $to -= 1; + } + }; + + // Special case the ordinal-to-year cascade, as it has different behavior. + ($ordinal:ident => $year:ident) => { + // We need to actually capture the idents. Without this, macro hygiene causes errors. + cascade!(@ordinal $ordinal); + cascade!(@year $year); + #[allow(unused_assignments)] + if $ordinal > crate::util::days_in_year($year) as i16 { + $ordinal -= crate::util::days_in_year($year) as i16; + $year += 1; + } else if $ordinal < 1 { + $year -= 1; + $ordinal += crate::util::days_in_year($year) as i16; + } + }; +} + +/// Returns `Err(error::ComponentRange)` if the value is not in range. +macro_rules! ensure_value_in_range { + ($value:ident in $start:expr => $end:expr) => {{ + let _start = $start; + let _end = $end; + #[allow(trivial_numeric_casts, unused_comparisons)] + if $value < _start || $value > _end { + return Err(crate::error::ComponentRange { + name: stringify!($value), + minimum: _start as _, + maximum: _end as _, + value: $value as _, + conditional_range: false, + }); + } + }}; + + ($value:ident conditionally in $start:expr => $end:expr) => {{ + let _start = $start; + let _end = $end; + #[allow(trivial_numeric_casts, unused_comparisons)] + if $value < _start || $value > _end { + return Err(crate::error::ComponentRange { + name: stringify!($value), + minimum: _start as _, + maximum: _end as _, + value: $value as _, + conditional_range: true, + }); + } + }}; +} + +/// Try to unwrap an expression, returning if not possible. +/// +/// This is similar to the `?` operator, but does not perform `.into()`. Because of this, it is +/// usable in `const` contexts. +macro_rules! const_try { + ($e:expr) => { + match $e { + Ok(value) => value, + Err(error) => return Err(error), + } + }; +} + +/// Try to unwrap an expression, returning if not possible. +/// +/// This is similar to the `?` operator, but is usable in `const` contexts. +macro_rules! const_try_opt { + ($e:expr) => { + match $e { + Some(value) => value, + None => return None, + } + }; +} + +/// Try to unwrap an expression, panicking if not possible. +/// +/// This is similar to `$e.expect($message)`, but is usable in `const` contexts. +macro_rules! expect_opt { + ($e:expr, $message:literal) => { + match $e { + Some(value) => value, + None => crate::expect_failed($message), + } + }; +} +// endregion macros + +mod date; +mod duration; +pub mod error; +pub mod ext; +#[cfg(any(feature = "formatting", feature = "parsing"))] +pub mod format_description; +#[cfg(feature = "formatting")] +pub mod formatting; +#[cfg(feature = "std")] +mod instant; +#[cfg(feature = "macros")] +pub mod macros; +mod month; +mod offset_date_time; +#[cfg(feature = "parsing")] +pub mod parsing; +mod primitive_date_time; +#[cfg(feature = "quickcheck")] +mod quickcheck; +#[cfg(feature = "rand")] +mod rand; +#[cfg(feature = "serde")] +#[allow(missing_copy_implementations, missing_debug_implementations)] +pub mod serde; +mod sys; +#[cfg(test)] +mod tests; +mod time; +mod utc_offset; +pub mod util; +mod weekday; + +pub use crate::date::Date; +pub use crate::duration::Duration; +pub use crate::error::Error; +#[cfg(feature = "std")] +pub use crate::instant::Instant; +pub use crate::month::Month; +pub use crate::offset_date_time::OffsetDateTime; +pub use crate::primitive_date_time::PrimitiveDateTime; +pub use crate::time::Time; +pub use crate::utc_offset::UtcOffset; +pub use crate::weekday::Weekday; + +/// An alias for [`std::result::Result`] with a generic error from the time crate. +pub type Result<T> = core::result::Result<T, Error>; + +/// This is a separate function to reduce the code size of `expect_opt!`. +#[inline(never)] +#[cold] +#[track_caller] +const fn expect_failed(message: &str) -> ! { + panic!("{}", message) +} |