#![cfg_attr(doc, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
#![forbid(unsafe_code)]
#![deny(
anonymous_parameters,
rust_2018_idioms,
trivial_casts,
trivial_numeric_casts,
unreachable_pub, // some known bugs that are overridden
const_err,
illegal_floating_point_literal_pattern,
late_bound_lifetime_arguments,
path_statements,
patterns_in_fns_without_body,
clippy::all
)]
#![warn(
unused_extern_crates,
missing_copy_implementations,
missing_debug_implementations,
single_use_lifetimes,
unused_qualifications,
variant_size_differences,
clippy::pedantic,
clippy::nursery,
clippy::missing_docs_in_private_items,
clippy::dbg_macro,
clippy::decimal_literal_representation,
clippy::get_unwrap,
clippy::option_unwrap_used,
clippy::print_stdout,
clippy::result_unwrap_used
)]
#![allow(
clippy::suspicious_arithmetic_impl,
clippy::inline_always,
clippy::cast_possible_wrap,
clippy::cast_lossless,
clippy::module_name_repetitions,
clippy::must_use_candidate // rust-lang/rust-clippy#4779
)]
#![cfg_attr(test, allow(clippy::cognitive_complexity, clippy::too_many_lines))]
#![doc(html_favicon_url = "https://avatars0.githubusercontent.com/u/55999857")]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/55999857")]
#[macro_use]
extern crate alloc;
#[cfg(feature = "panicking-api")]
#[cfg_attr(doc, doc(cfg(feature = "panicking-api")))]
macro_rules! format_conditional {
($conditional:ident) => {
format!(concat!(stringify!($conditional), "={}"), $conditional)
};
($first_conditional:ident, $($conditional:ident),*) => {{
let mut s = alloc::string::String::new();
s.push_str(&format_conditional!($first_conditional));
$(s.push_str(&format!(concat!(", ", stringify!($conditional), "={}"), $conditional));)*
s
}}
}
#[cfg(feature = "panicking-api")]
#[cfg_attr(doc, doc(cfg(feature = "panicking-api")))]
macro_rules! assert_value_in_range {
($value:ident in $start:expr => $end:expr) => {
if !($start..=$end).contains(&$value) {
panic!(
concat!(stringify!($value), " must be in the range {}..={} (was {})"),
$start,
$end,
$value,
);
}
};
($value:ident in $start:expr => $end:expr, given $($conditional:ident),+ $(,)?) => {
if !($start..=$end).contains(&$value) {
panic!(
concat!(stringify!($value), " must be in the range {}..={} given{} (was {})"),
$start,
$end,
&format_conditional!($($conditional),+),
$value,
);
};
};
}
macro_rules! ensure_value_in_range {
($value:ident in $start:expr => $end:expr) => {
if !($start..=$end).contains(&$value) {
return Err(ComponentRangeError {
name: stringify!($value),
minimum: i64::from($start),
maximum: i64::from($end),
value: i64::from($value),
given: Vec::new(),
});
}
};
($value:ident in $start:expr => $end:expr, given $($conditional:ident),+ $(,)?) => {
if !($start..=$end).contains(&$value) {
return Err(ComponentRangeError {
name: stringify!($value),
minimum: i64::from($start),
maximum: i64::from($end),
value: i64::from($value),
given: vec![$((stringify!($conditional), i64::from($conditional))),+],
});
};
};
}
#[cfg(all(test, feature = "std"))]
macro_rules! assert_panics {
($e:expr $(, $message:literal)?) => {
#[allow(box_pointers)]
{
if std::panic::catch_unwind(move || $e).is_ok() {
panic!(concat!(
"assertion failed: expected `",
stringify!($e),
"` to panic",
$(concat!(" (", $message, ")"))?
));
}
}
};
}
mod date;
mod duration;
mod error;
mod format;
#[cfg(feature = "std")]
mod instant;
pub mod internals;
mod numerical_traits;
mod offset_date_time;
mod primitive_date_time;
#[cfg(feature = "serde")]
mod serde;
mod sign;
mod time;
mod utc_offset;
mod weekday;
pub use self::time::Time;
pub use date::{days_in_year, is_leap_year, weeks_in_year, Date};
pub use duration::Duration;
pub use error::{ComponentRangeError, ConversionRangeError, Error};
pub(crate) use format::DeferredFormat;
pub use format::{validate_format_string, ParseError};
#[cfg(feature = "std")]
pub use instant::Instant;
pub use numerical_traits::{NumericalDuration, NumericalStdDuration, NumericalStdDurationShort};
pub use offset_date_time::OffsetDateTime;
pub use primitive_date_time::PrimitiveDateTime;
pub use sign::Sign;
pub use utc_offset::UtcOffset;
pub use weekday::Weekday;
pub mod prelude {
pub use crate::{NumericalDuration as _, NumericalStdDuration as _};
}
#[cfg(not(feature = "std"))]
mod no_std_prelude {
#![allow(unused_imports)]
pub(crate) use alloc::{
borrow::ToOwned,
boxed::Box,
string::{String, ToString},
vec::Vec,
};
}
#[cfg(all(feature = "std", feature = "deprecated"))]
#[cfg_attr(tarpaulin, skip)]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(since = "0.2.0", note = "Use `Instant`")]
pub type PreciseTime = Instant;
#[cfg(all(feature = "std", feature = "deprecated"))]
#[cfg_attr(tarpaulin, skip)]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(since = "0.2.0", note = "Use `Instant`")]
pub type SteadyTime = Instant;
#[cfg(all(feature = "std", feature = "deprecated"))]
#[cfg_attr(tarpaulin, skip)]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(
since = "0.2.0",
note = "Use `PrimitiveDateTime::now() - PrimitiveDateTime::unix_epoch()` to get a `Duration` \
since a known epoch."
)]
#[inline]
pub fn precise_time_ns() -> u64 {
use core::convert::TryInto;
(PrimitiveDateTime::now() - PrimitiveDateTime::unix_epoch())
.whole_nanoseconds()
.try_into()
.expect("You really shouldn't be using this in the year 2554...")
}
#[cfg(all(feature = "std", feature = "deprecated"))]
#[cfg_attr(tarpaulin, skip)]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(
since = "0.2.0",
note = "Use `PrimitiveDateTime::now() - PrimitiveDateTime::unix_epoch()` to get a `Duration` \
since a known epoch."
)]
#[inline]
pub fn precise_time_s() -> f64 {
(PrimitiveDateTime::now() - PrimitiveDateTime::unix_epoch()).as_seconds_f64()
}