Coverage Report

Created: 2026-08-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/time-0.3.13/src/lib.rs
Line
Count
Source
1
//! # Feature flags
2
//!
3
//! This crate exposes a number of features. These can be enabled or disabled as shown
4
//! [in Cargo's documentation](https://doc.rust-lang.org/cargo/reference/features.html). Features
5
//! are _disabled_ by default unless otherwise noted.
6
//!
7
//! Reliance on a given feature is always indicated alongside the item definition.
8
//!
9
//! - `std` (_enabled by default, implicitly enables `alloc`_)
10
//!
11
//!   This enables a number of features that depend on the standard library.
12
//!
13
//! - `alloc` (_enabled by default via `std`_)
14
//!
15
//!   Enables a number of features that require the ability to dynamically allocate memory.
16
//!
17
//! - `macros`
18
//!
19
//!   Enables macros that provide compile-time verification of values and intuitive syntax.
20
//!
21
//! - `formatting` (_implicitly enables `std`_)
22
//!
23
//!   Enables formatting of most structs.
24
//!
25
//! - `parsing`
26
//!
27
//!   Enables parsing of most structs.
28
//!
29
//! - `local-offset` (_implicitly enables `std`_)
30
//!
31
//!   This feature enables a number of methods that allow obtaining the system's UTC offset.
32
//!
33
//! - `large-dates`
34
//!
35
//!   By default, only years within the ±9999 range (inclusive) are supported. If you need support
36
//!   for years outside this range, consider enabling this feature; the supported range will be
37
//!   increased to ±999,999.
38
//!
39
//!   Note that enabling this feature has some costs, as it means forgoing some optimizations.
40
//!   Ambiguities may be introduced when parsing that would not otherwise exist.
41
//!
42
//! - `serde`
43
//!
44
//!   Enables [serde](https://docs.rs/serde) support for all types except [`Instant`].
45
//!
46
//! - `serde-human-readable` (_implicitly enables `serde`, `formatting`, and `parsing`_)
47
//!
48
//!   Allows serde representations to use a human-readable format. This is determined by the
49
//!   serializer, not the user. If this feature is not enabled or if the serializer requests a
50
//!   non-human-readable format, a format optimized for binary representation will be used.
51
//!
52
//!   Libraries should never enable this feature, as the decision of what format to use should be up
53
//!   to the user.
54
//!
55
//! - `serde-well-known` (_implicitly enables `serde/alloc`, `formatting`, and `parsing`_)
56
//!
57
//!   Enables support for serializing and deserializing well-known formats using serde's
58
//!   [`#[with]` attribute](https://serde.rs/field-attrs.html#with).
59
//!
60
//! - `rand`
61
//!
62
//!   Enables [rand](https://docs.rs/rand) support for all types.
63
//!
64
//! - `quickcheck` (_implicitly enables `alloc`_)
65
//!
66
//!   Enables [quickcheck](https://docs.rs/quickcheck) support for all types except [`Instant`].
67
//!
68
//! - `wasm-bindgen`
69
//!
70
//!   Enables [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) support for converting
71
//!   [JavaScript dates](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Date.html), as
72
//!   well as obtaining the UTC offset from JavaScript.
73
//!
74
//! One pseudo-feature flag that is only available to end users is the `unsound_local_offset` cfg.
75
//! As the name indicates, using the feature is unsound, and [may cause unexpected segmentation
76
//! faults](https://github.com/time-rs/time/issues/293). Unlike other flags, this is deliberately
77
//! only available to end users; this is to ensure that a user doesn't have unsound behavior without
78
//! knowing it. To enable this behavior, you must use `RUSTFLAGS="--cfg unsound_local_offset" cargo
79
//! build` or similar. Note: This flag is _not tested anywhere_, including in the regular test of
80
//! the powerset of all feature flags. Use at your own risk. Without this flag, any method that
81
//! requires the local offset will return the `Err` variant when otherwise unsound.
82
83
#![doc(html_playground_url = "https://play.rust-lang.org")]
84
#![cfg_attr(__time_03_docs, feature(doc_cfg, doc_auto_cfg, doc_notable_trait))]
85
#![cfg_attr(
86
    __time_03_docs,
87
    deny(rustdoc::broken_intra_doc_links, rustdoc::private_intra_doc_links)
88
)]
89
#![cfg_attr(not(feature = "std"), no_std)]
90
#![deny(
91
    anonymous_parameters,
92
    clippy::all,
93
    const_err,
94
    illegal_floating_point_literal_pattern,
95
    late_bound_lifetime_arguments,
96
    path_statements,
97
    patterns_in_fns_without_body,
98
    rust_2018_idioms,
99
    trivial_casts,
100
    trivial_numeric_casts,
101
    unreachable_pub,
102
    unsafe_code,
103
    unsafe_op_in_unsafe_fn,
104
    unused_extern_crates
105
)]
106
#![warn(
107
    clippy::dbg_macro,
108
    clippy::decimal_literal_representation,
109
    clippy::get_unwrap,
110
    clippy::missing_docs_in_private_items,
111
    clippy::nursery,
112
    clippy::print_stdout,
113
    clippy::todo,
114
    clippy::unimplemented,
115
    clippy::unnested_or_patterns,
116
    clippy::unwrap_in_result,
117
    clippy::unwrap_used,
118
    clippy::use_debug,
119
    deprecated_in_future,
120
    missing_copy_implementations,
121
    missing_debug_implementations,
122
    unused_qualifications,
123
    variant_size_differences
124
)]
125
#![allow(clippy::redundant_pub_crate)]
126
#![doc(html_favicon_url = "https://avatars0.githubusercontent.com/u/55999857")]
127
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/55999857")]
128
#![doc(test(attr(deny(warnings))))]
129
130
#[allow(unused_extern_crates)]
131
#[cfg(feature = "alloc")]
132
extern crate alloc;
133
134
// region: macros
135
/// Helper macro for easily implementing `OpAssign`.
136
macro_rules! __impl_assign {
137
    ($sym:tt $op:ident $fn:ident $target:ty : $($(#[$attr:meta])* $t:ty),+) => {$(
138
        #[allow(unused_qualifications)]
139
        $(#[$attr])*
140
        impl core::ops::$op<$t> for $target {
141
0
            fn $fn(&mut self, rhs: $t) {
142
0
                *self = *self $sym rhs;
143
0
            }
Unexecuted instantiation: <time::date::Date as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::date::Date as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::date::Date as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::date::Date as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::offset_date_time::OffsetDateTime as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::offset_date_time::OffsetDateTime as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::offset_date_time::OffsetDateTime as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::offset_date_time::OffsetDateTime as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<f32>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<f64>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<f32>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<f64>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<i8>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<i16>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<i32>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<u8>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<u16>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<u32>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<i8>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<i16>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<i32>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<u8>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<u16>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<u32>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::AddAssign>::add_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::SubAssign>::sub_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <std::time::Instant as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <std::time::SystemTime as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <std::time::SystemTime as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <std::time::Instant as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
144
        }
145
    )+};
146
}
147
148
/// Implement `AddAssign` for the provided types.
149
macro_rules! impl_add_assign {
150
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
151
        __impl_assign!(+ AddAssign add_assign $target : $($(#[$attr])* $t),+);
152
    };
153
}
154
155
/// Implement `SubAssign` for the provided types.
156
macro_rules! impl_sub_assign {
157
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
158
        __impl_assign!(- SubAssign sub_assign $target : $($(#[$attr])* $t),+);
159
    };
160
}
161
162
/// Implement `MulAssign` for the provided types.
163
macro_rules! impl_mul_assign {
164
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
165
        __impl_assign!(* MulAssign mul_assign $target : $($(#[$attr])* $t),+);
166
    };
167
}
168
169
/// Implement `DivAssign` for the provided types.
170
macro_rules! impl_div_assign {
171
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
172
        __impl_assign!(/ DivAssign div_assign $target : $($(#[$attr])* $t),+);
173
    };
174
}
175
176
/// Division of integers, rounding the resulting value towards negative infinity.
177
macro_rules! div_floor {
178
    ($a:expr, $b:expr) => {{
179
        let _a = $a;
180
        let _b = $b;
181
182
        let (_quotient, _remainder) = (_a / _b, _a % _b);
183
184
        if (_remainder > 0 && _b < 0) || (_remainder < 0 && _b > 0) {
185
            _quotient - 1
186
        } else {
187
            _quotient
188
        }
189
    }};
190
}
191
192
/// Cascade an out-of-bounds value.
193
macro_rules! cascade {
194
    (@ordinal ordinal) => {};
195
    (@year year) => {};
196
197
    // Cascade an out-of-bounds value from "from" to "to".
198
    ($from:ident in $min:literal.. $max:literal => $to:tt) => {
199
        #[allow(unused_comparisons, unused_assignments)]
200
        if $from >= $max {
201
            $from -= $max - $min;
202
            $to += 1;
203
        } else if $from < $min {
204
            $from += $max - $min;
205
            $to -= 1;
206
        }
207
    };
208
209
    // Special case the ordinal-to-year cascade, as it has different behavior.
210
    ($ordinal:ident => $year:ident) => {
211
        // We need to actually capture the idents. Without this, macro hygiene causes errors.
212
        cascade!(@ordinal $ordinal);
213
        cascade!(@year $year);
214
        #[allow(unused_assignments)]
215
        if $ordinal > crate::util::days_in_year($year) {
216
            $year += 1;
217
            $ordinal = 1;
218
        } else if $ordinal == 0 {
219
            $year -= 1;
220
            $ordinal = crate::util::days_in_year($year);
221
        }
222
    };
223
}
224
225
/// Returns `Err(error::ComponentRange)` if the value is not in range.
226
macro_rules! ensure_value_in_range {
227
    ($value:ident in $start:expr => $end:expr) => {{
228
        let _start = $start;
229
        let _end = $end;
230
        #[allow(trivial_numeric_casts, unused_comparisons)]
231
        if $value < _start || $value > _end {
232
            return Err(crate::error::ComponentRange {
233
                name: stringify!($value),
234
                minimum: _start as _,
235
                maximum: _end as _,
236
                value: $value as _,
237
                conditional_range: false,
238
            });
239
        }
240
    }};
241
242
    ($value:ident conditionally in $start:expr => $end:expr) => {{
243
        let _start = $start;
244
        let _end = $end;
245
        #[allow(trivial_numeric_casts, unused_comparisons)]
246
        if $value < _start || $value > _end {
247
            return Err(crate::error::ComponentRange {
248
                name: stringify!($value),
249
                minimum: _start as _,
250
                maximum: _end as _,
251
                value: $value as _,
252
                conditional_range: true,
253
            });
254
        }
255
    }};
256
}
257
258
/// Try to unwrap an expression, returning if not possible.
259
///
260
/// This is similar to the `?` operator, but does not perform `.into()`. Because of this, it is
261
/// usable in `const` contexts.
262
macro_rules! const_try {
263
    ($e:expr) => {
264
        match $e {
265
            Ok(value) => value,
266
            Err(error) => return Err(error),
267
        }
268
    };
269
}
270
271
/// Try to unwrap an expression, returning if not possible.
272
///
273
/// This is similar to the `?` operator, but is usable in `const` contexts.
274
macro_rules! const_try_opt {
275
    ($e:expr) => {
276
        match $e {
277
            Some(value) => value,
278
            None => return None,
279
        }
280
    };
281
}
282
// endregion macros
283
284
mod date;
285
mod duration;
286
pub mod error;
287
pub mod ext;
288
#[cfg(any(feature = "formatting", feature = "parsing"))]
289
pub mod format_description;
290
#[cfg(feature = "formatting")]
291
pub mod formatting;
292
#[cfg(feature = "std")]
293
mod instant;
294
#[cfg(feature = "macros")]
295
pub mod macros;
296
mod month;
297
mod offset_date_time;
298
#[cfg(feature = "parsing")]
299
pub mod parsing;
300
mod primitive_date_time;
301
#[cfg(feature = "quickcheck")]
302
#[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
303
mod quickcheck;
304
#[cfg(feature = "rand")]
305
#[cfg_attr(__time_03_docs, doc(cfg(feature = "rand")))]
306
mod rand;
307
#[cfg(feature = "serde")]
308
#[cfg_attr(__time_03_docs, doc(cfg(feature = "serde")))]
309
#[allow(missing_copy_implementations, missing_debug_implementations)]
310
pub mod serde;
311
mod sys;
312
#[cfg(test)]
313
mod tests;
314
mod time;
315
mod utc_offset;
316
pub mod util;
317
mod weekday;
318
319
pub use crate::date::Date;
320
pub use crate::duration::Duration;
321
pub use crate::error::Error;
322
#[cfg(feature = "std")]
323
pub use crate::instant::Instant;
324
pub use crate::month::Month;
325
pub use crate::offset_date_time::OffsetDateTime;
326
pub use crate::primitive_date_time::PrimitiveDateTime;
327
pub use crate::time::Time;
328
pub use crate::utc_offset::UtcOffset;
329
pub use crate::weekday::Weekday;
330
331
/// An alias for [`std::result::Result`] with a generic error from the time crate.
332
pub type Result<T> = core::result::Result<T, Error>;