// Prefer runtime checks if possible, as otherwise tests can't be run at all if something is // changed. use std::borrow::Borrow; use std::error::Error as StdError; use std::fmt::{Debug, Display}; use std::hash::Hash; use std::iter::Sum; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use std::panic::{RefUnwindSafe, UnwindSafe}; use std::time::{Duration as StdDuration, Instant as StdInstant, SystemTime}; use quickcheck::Arbitrary; use rand08::distributions::{Distribution as DistributionRand08, Standard as StandardRand08}; use rand09::distr::{Distribution as DistributionRand09, StandardUniform as StandardUniformRand09}; use serde::{Deserialize, Serialize}; #[expect(deprecated)] use time::Instant; use time::format_description::well_known::iso8601; use time::format_description::{BorrowedFormatItem, Component, modifier, well_known}; use time::formatting::Formattable; use time::parsing::{Parsable, Parsed}; use time::{ Date, Duration, Error, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday, error, ext, }; #[expect(clippy::cognitive_complexity, reason = "all test the same thing")] #[test] fn alignment() { macro_rules! assert_alignment { ($t:ty, $alignment:expr) => { let alignment = $alignment; assert_eq!( align_of::<$t>(), alignment, "alignment of `{}` was {}", stringify!($t), alignment, ); }; } assert_alignment!(Date, 4); assert_alignment!(Duration, 8); assert_alignment!(OffsetDateTime, 4); assert_alignment!(PrimitiveDateTime, 4); assert_alignment!(UtcDateTime, 4); assert_alignment!(Time, 4); assert_alignment!(UtcOffset, 1); assert_alignment!(error::ComponentRange, 8); assert_alignment!(error::ConversionRange, 1); assert_alignment!(error::DifferentVariant, 1); assert_alignment!(error::IndeterminateOffset, 1); assert_alignment!(modifier::Day, 1); assert_alignment!(modifier::Hour, 1); assert_alignment!(modifier::Minute, 1); assert_alignment!(modifier::Month, 1); assert_alignment!(modifier::OffsetHour, 1); assert_alignment!(modifier::OffsetMinute, 1); assert_alignment!(modifier::OffsetSecond, 1); assert_alignment!(modifier::Ordinal, 1); assert_alignment!(modifier::Period, 1); assert_alignment!(modifier::Second, 1); assert_alignment!(modifier::Subsecond, 1); assert_alignment!(modifier::WeekNumber, 1); assert_alignment!(modifier::Weekday, 1); assert_alignment!(modifier::Year, 1); assert_alignment!(well_known::Rfc2822, 1); assert_alignment!(well_known::Rfc3339, 1); assert_alignment!( well_known::Iso8601<{ iso8601::Config::DEFAULT.encode() }>, 1 ); assert_alignment!(iso8601::Config, 1); assert_alignment!(iso8601::DateKind, 1); assert_alignment!(iso8601::FormattedComponents, 1); assert_alignment!(iso8601::OffsetPrecision, 1); assert_alignment!(iso8601::TimePrecision, 1); assert_alignment!(Parsed, align_of::()); assert_alignment!(Month, 1); assert_alignment!(Weekday, 1); assert_alignment!(Error, 8); assert_alignment!(error::Format, 8); assert_alignment!(error::InvalidFormatDescription, 8); assert_alignment!(error::Parse, 8); assert_alignment!(error::ParseFromDescription, 8); assert_alignment!(error::TryFromParsed, 8); assert_alignment!(Component, 2); assert_alignment!(BorrowedFormatItem<'_>, 8); assert_alignment!(modifier::MonthRepr, 1); assert_alignment!(modifier::Padding, 1); assert_alignment!(modifier::SubsecondDigits, 1); assert_alignment!(modifier::WeekNumberRepr, 1); assert_alignment!(modifier::WeekdayRepr, 1); assert_alignment!(modifier::YearRepr, 1); } #[expect(clippy::cognitive_complexity, reason = "all test the same thing")] #[test] fn size() { macro_rules! assert_size { ($t:ty, $size:literal, $opt_size:literal) => { assert!( size_of::<$t>() <= $size, concat!("size of `{}` used to be ", $size, ", but is now {}"), stringify!($t), size_of::<$t>(), ); assert!( size_of::>() <= $opt_size, concat!( "size of `Option<{}>` used to be ", $opt_size, ", but is now {}" ), stringify!($t), size_of::>(), ); }; } assert_size!(Date, 4, 4); assert_size!(Duration, 16, 16); assert_size!(OffsetDateTime, 16, 16); assert_size!(PrimitiveDateTime, 12, 12); assert_size!(UtcDateTime, 12, 12); assert_size!(Time, 8, 8); assert_size!(UtcOffset, 3, 4); assert_size!(error::ComponentRange, 24, 24); assert_size!(error::ConversionRange, 0, 1); assert_size!(error::DifferentVariant, 0, 1); assert_size!(error::IndeterminateOffset, 0, 1); assert_size!(modifier::Day, 1, 1); assert_size!(modifier::Hour, 2, 2); assert_size!(modifier::Minute, 1, 1); assert_size!(modifier::Month, 3, 3); assert_size!(modifier::OffsetHour, 2, 2); assert_size!(modifier::OffsetMinute, 1, 1); assert_size!(modifier::OffsetSecond, 1, 1); assert_size!(modifier::Ordinal, 1, 1); assert_size!(modifier::Period, 2, 2); assert_size!(modifier::Second, 1, 1); assert_size!(modifier::Subsecond, 1, 1); assert_size!(modifier::WeekNumber, 2, 2); assert_size!(modifier::Weekday, 3, 3); assert_size!(modifier::Year, 5, 5); assert_size!(well_known::Rfc2822, 0, 1); assert_size!(well_known::Rfc3339, 0, 1); assert_size!( well_known::Iso8601<{ iso8601::Config::DEFAULT.encode() }>, 0, 1 ); assert_size!(iso8601::Config, 7, 7); assert_size!(iso8601::DateKind, 1, 1); assert_size!(iso8601::FormattedComponents, 1, 1); assert_size!(iso8601::OffsetPrecision, 1, 1); assert_size!(iso8601::TimePrecision, 2, 2); assert_size!(Parsed, 64, 64); assert_size!(Month, 1, 1); assert_size!(Weekday, 1, 1); assert_size!(Error, 48, 48); assert_size!(error::Format, 24, 24); assert_size!(error::InvalidFormatDescription, 48, 48); assert_size!(error::Parse, 32, 32); assert_size!(error::ParseFromDescription, 24, 24); assert_size!(error::TryFromParsed, 24, 24); assert_size!(Component, 6, 6); assert_size!(BorrowedFormatItem<'_>, 24, 24); assert_size!(modifier::MonthRepr, 1, 1); assert_size!(modifier::Padding, 1, 1); assert_size!(modifier::SubsecondDigits, 1, 1); assert_size!(modifier::WeekNumberRepr, 1, 1); assert_size!(modifier::WeekdayRepr, 1, 1); assert_size!(modifier::YearRepr, 1, 1); } macro_rules! assert_obj_safe { ($($xs:path),+ $(,)?) => { $(const _: Option<&dyn $xs> = None;)+ }; } assert_obj_safe!(ext::NumericalDuration); assert_obj_safe!(ext::NumericalStdDuration); // `Parsable` is not object safe. // `Formattable` is not object safe. macro_rules! assert_impl { ($(#[$meta:meta])* $($(@$lifetimes:lifetime),+ ;)? $type:ty: $($trait:path),+ $(,)?) => { $(#[$meta])* const _: fn() = || { fn assert_impl_all<$($($lifetimes,)+)? T: ?Sized $(+ $trait)+>() {} assert_impl_all::<$type>(); }; }; } assert_impl! { @'a; Date: Add, Add, AddAssign, AddAssign, Arbitrary, Clone, Debug, Deserialize<'a>, Display, Hash, Ord, PartialEq, PartialOrd, Serialize, Sub, Sub, Sub, SubAssign, SubAssign, TryFrom, Copy, Eq, RefUnwindSafe, Send, Sync, Unpin, UnwindSafe, } assert_impl! { @'a; Duration: Add, Add, AddAssign, AddAssign, Arbitrary, Clone, Debug, Default, Deserialize<'a>, Div, Div, Div, Div, Div, Div, Div, Div, Div, Div, DivAssign, DivAssign, DivAssign, DivAssign, DivAssign, DivAssign, DivAssign, DivAssign, Hash, Mul, Mul, Mul, Mul, Mul, Mul, Mul, Mul, MulAssign, MulAssign, MulAssign, MulAssign, MulAssign, MulAssign, MulAssign, MulAssign, Neg, Ord, PartialEq, PartialEq, PartialOrd, PartialOrd, Serialize, Sub, Sub, SubAssign, SubAssign, Sum<&'a Duration>, Sum, TryFrom, Copy, Eq, RefUnwindSafe, Send, Sync, Unpin, UnwindSafe, } assert_impl! { #[expect(deprecated)] Instant: Add, Add, AddAssign, AddAssign, AsRef, Borrow, Clone, Debug, From, Hash, Ord, PartialEq, PartialEq, PartialOrd, PartialOrd, Sub, Sub, Sub, Sub, SubAssign, SubAssign, Copy, Eq, RefUnwindSafe, Send, Sync, Unpin, UnwindSafe, } assert_impl! { @'a; OffsetDateTime: Add, Add, AddAssign, AddAssign, Arbitrary, Clone, Debug, Deserialize<'a>, Display, From, Hash, Ord, PartialEq, PartialEq, PartialOrd, PartialOrd, Serialize, Sub, Sub, Sub, Sub, SubAssign, SubAssign, TryFrom, Copy, Eq, RefUnwindSafe, Send, Sync, Unpin, UnwindSafe, } assert_impl! { @'a; PrimitiveDateTime: Add, Add, AddAssign, AddAssign, Arbitrary, Clone, Debug, Deserialize<'a>, Display, Hash, Ord, PartialEq, PartialOrd, Serialize, Sub, Sub, Sub, SubAssign, SubAssign, TryFrom, Copy, Eq, RefUnwindSafe, Send, Sync, Unpin, UnwindSafe, } assert_impl! { @'a; UtcDateTime: Add, Add, AddAssign, AddAssign, Arbitrary, Clone, Debug, Deserialize<'a>, Display, Hash, Ord, PartialEq, PartialEq, PartialEq, PartialOrd, PartialOrd, PartialOrd, Serialize, Sub, Sub, Sub, Sub, SubAssign, SubAssign, TryFrom, Copy, Eq, RefUnwindSafe, Send, Sync, Unpin, UnwindSafe, } assert_impl! { @'a; Time: Add, Add, AddAssign, AddAssign, Arbitrary, Clone, Debug, Deserialize<'a>, Display, Hash, Ord, PartialEq