//! The [`Duration`] struct and its associated `impl`s.

use core::cmp::Ordering;
use core::fmt;
use core::iter::Sum;
use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
use core::time::Duration as StdDuration;

use deranged::RangedI32;
use num_conv::prelude::*;

use crate::convert::*;
use crate::error;
use crate::internal_macros::{
    const_try_opt, expect_opt, impl_add_assign, impl_div_assign, impl_mul_assign, impl_sub_assign,
};
#[cfg(feature = "std")]
use crate::Instant;

/// By explicitly inserting this enum where padding is expected, the compiler is able to better
/// perform niche value optimization.
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub(crate) enum Padding {
    #[allow(clippy::missing_docs_in_private_items)]
    Optimize,
}

/// The type of the `nanosecond` field of `Duration`.
type Nanoseconds =
    RangedI32<{ -(Nanosecond::per(Second) as i32 - 1) }, { Nanosecond::per(Second) as i32 - 1 }>;

/// A span of time with nanosecond precision.
///
/// Each `Duration` is composed of a whole number of seconds and a fractional part represented in
/// nanoseconds.
///
/// This implementation allows for negative durations, unlike [`core::time::Duration`].
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Duration {
    /// Number of whole seconds.
    seconds: i64,
    /// Number of nanoseconds within the second. The sign always matches the `seconds` field.
    // Sign must match that of `seconds` (though this is not a safety requirement).
    nanoseconds: Nanoseconds,
    #[allow(clippy::missing_docs_in_private_items)]
    padding: Padding,
}

impl fmt::Debug for Duration {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Duration")
            .field("seconds", &self.seconds)
            .field("nanoseconds", &self.nanoseconds)
            .finish()
    }
}

impl Default for Duration {
    fn default() -> Self {
        Self {
            seconds: 0,
            nanoseconds: Nanoseconds::new_static::<0>(),
            padding: Padding::Optimize,
        }
    }
}

/// This is adapted from the [`std` implementation][std], which uses mostly bit
/// operations to ensure the highest precision:
///
/// Changes from `std` are marked and explained below.
///
/// [std]: https://github.com/rust-lang/rust/blob/3a37c2f0523c87147b64f1b8099fc9df22e8c53e/library/core/src/time.rs#L1262-L1340
#[rustfmt::skip] // Skip `rustfmt` because it reformats the arguments of the macro weirdly.
macro_rules! try_from_secs {
    (
        secs = $secs: expr,
        mantissa_bits = $mant_bits: literal,
        exponent_bits = $exp_bits: literal,
        offset = $offset: literal,
        bits_ty = $bits_ty:ty,
        bits_ty_signed = $bits_ty_signed:ty,
        double_ty = $double_ty:ty,
        float_ty = $float_ty:ty,
        is_nan = $is_nan:expr,
        is_overflow = $is_overflow:expr,
    ) => {{
        'value: {
            const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
            const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
            const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;

            // Change from std: No error check for negative values necessary.

            let bits = $secs.to_bits();
            let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
            let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;

            let (secs, nanos) = if exp < -31 {
                // the input represents less than 1ns and can not be rounded to it
                (0u64, 0u32)
            } else if exp < 0 {
                // the input is less than 1 second
                let t = <$double_ty>::from(mant) << ($offset + exp);
                let nanos_offset = $mant_bits + $offset;
                let nanos_tmp = u128::from(Nanosecond::per(Second)) * u128::from(t);
                let nanos = (nanos_tmp >> nanos_offset) as u32;

                let rem_mask = (1 << nanos_offset) - 1;
                let rem_msb_mask = 1 << (nanos_offset - 1);
                let rem = nanos_tmp & rem_mask;
                let is_tie = rem == rem_msb_mask;
                let is_even = (nanos & 1) == 0;
                let rem_msb = nanos_tmp & rem_msb_mask == 0;
                let add_ns = !(rem_msb || (is_even && is_tie));

                // f32 does not have enough precision to trigger the second branch
                // since it can not represent numbers between 0.999_999_940_395 and 1.0.
                let nanos = nanos + add_ns as u32;
                if ($mant_bits == 23) || (nanos != Nanosecond::per(Second)) {
                    (0, nanos)
                } else {
                    (1, 0)
                }
            } else if exp < $mant_bits {
                let secs = u64::from(mant >> ($mant_bits - exp));
                let t = <$double_ty>::from((mant << exp) & MANT_MASK);
                let nanos_offset = $mant_bits;
                let nanos_tmp = <$double_ty>::from(Nanosecond::per(Second)) * t;
                let nanos = (nanos_tmp >> nanos_offset) as u32;

                let rem_mask = (1 << nanos_offset) - 1;
                let rem_msb_mask = 1 << (nanos_offset - 1);
                let rem = nanos_tmp & rem_mask;
                let is_tie = rem == rem_msb_mask;
                let is_even = (nanos & 1) == 0;
                let rem_msb = nanos_tmp & rem_msb_mask == 0;
                let add_ns = !(rem_msb || (is_even && is_tie));

                // f32 does not have enough precision to trigger the second branch.
                // For example, it can not represent numbers between 1.999_999_880...
                // and 2.0. Bigger values result in even smaller precision of the
                // fractional part.
                let nanos = nanos + add_ns as u32;
                if ($mant_bits == 23) || (nanos != Nanosecond::per(Second)) {
                    (secs, nanos)
                } else {
                    (secs + 1, 0)
                }
            } else if exp < 63 {
                // Change from std: The exponent here is 63 instead of 64,
                // because i64::MAX + 1 is 2^63.

                // the input has no fractional part
                let secs = u64::from(mant) << (exp - $mant_bits);
                (secs, 0)
            } else if bits == (i64::MIN as $float_ty).to_bits() {
                // Change from std: Signed integers are asymmetrical in that
                // iN::MIN is -iN::MAX - 1. So for example i8 covers the
                // following numbers -128..=127. The check above (exp < 63)
                // doesn't cover i64::MIN as that is -2^63, so we have this
                // additional case to handle the asymmetry of iN::MIN.
                break 'value Self::new_ranged_unchecked(i64::MIN, Nanoseconds::new_static::<0>());
            } else if $secs.is_nan() {
                // Change from std: std doesn't differentiate between the error
                // cases.
                $is_nan
            } else {
                $is_overflow
            };

            // Change from std: All the code is mostly unmodified in that it
            // simply calculates an unsigned integer. Here we extract the sign
            // bit and assign it to the number. We basically manually do two's
            // complement here, we could also use an if and just negate the
            // numbers based on the sign, but it turns out to be quite a bit
            // slower.
            let mask = (bits as $bits_ty_signed) >> ($mant_bits + $exp_bits);
            #[allow(trivial_numeric_casts)]
            let secs_signed = ((secs as i64) ^ (mask as i64)) - (mask as i64);
            #[allow(trivial_numeric_casts)]
            let nanos_signed = ((nanos as i32) ^ (mask as i32)) - (mask as i32);
            // Safety: `nanos_signed` is in range.
            unsafe { Self::new_unchecked(secs_signed, nanos_signed) }
        }
    }};
}

impl Duration {
    // region: constants
    /// Equivalent to `0.seconds()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::ZERO, 0.seconds());
    /// ```
    pub const ZERO: Self = Self::seconds(0);

    /// Equivalent to `1.nanoseconds()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::NANOSECOND, 1.nanoseconds());
    /// ```
    pub const NANOSECOND: Self = Self::nanoseconds(1);

    /// Equivalent to `1.microseconds()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::MICROSECOND, 1.microseconds());
    /// ```
    pub const MICROSECOND: Self = Self::microseconds(1);

    /// Equivalent to `1.milliseconds()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::MILLISECOND, 1.milliseconds());
    /// ```
    pub const MILLISECOND: Self = Self::milliseconds(1);

    /// Equivalent to `1.seconds()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::SECOND, 1.seconds());
    /// ```
    pub const SECOND: Self = Self::seconds(1);

    /// Equivalent to `1.minutes()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::MINUTE, 1.minutes());
    /// ```
    pub const MINUTE: Self = Self::minutes(1);

    /// Equivalent to `1.hours()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::HOUR, 1.hours());
    /// ```
    pub const HOUR: Self = Self::hours(1);

    /// Equivalent to `1.days()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::DAY, 1.days());
    /// ```
    pub const DAY: Self = Self::days(1);

    /// Equivalent to `1.weeks()`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::WEEK, 1.weeks());
    /// ```
    pub const WEEK: Self = Self::weeks(1);

    /// The minimum possible duration. Adding any negative duration to this will cause an overflow.
    pub const MIN: Self = Self::new_ranged(i64::MIN, Nanoseconds::MIN);

    /// The maximum possible duration. Adding any positive duration to this will cause an overflow.
    pub const MAX: Self = Self::new_ranged(i64::MAX, Nanoseconds::MAX);
    // endregion constants

    // region: is_{sign}
    /// Check if a duration is exactly zero.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert!(0.seconds().is_zero());
    /// assert!(!1.nanoseconds().is_zero());
    /// ```
    pub const fn is_zero(self) -> bool {
        self.seconds == 0 && self.nanoseconds.get() == 0
    }

    /// Check if a duration is negative.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert!((-1).seconds().is_negative());
    /// assert!(!0.seconds().is_negative());
    /// assert!(!1.seconds().is_negative());
    /// ```
    pub const fn is_negative(self) -> bool {
        self.seconds < 0 || self.nanoseconds.get() < 0
    }

    /// Check if a duration is positive.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert!(1.seconds().is_positive());
    /// assert!(!0.seconds().is_positive());
    /// assert!(!(-1).seconds().is_positive());
    /// ```
    pub const fn is_positive(self) -> bool {
        self.seconds > 0 || self.nanoseconds.get() > 0
    }
    // endregion is_{sign}

    // region: abs
    /// Get the absolute value of the duration.
    ///
    /// This method saturates the returned value if it would otherwise overflow.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.seconds().abs(), 1.seconds());
    /// assert_eq!(0.seconds().abs(), 0.seconds());
    /// assert_eq!((-1).seconds().abs(), 1.seconds());
    /// ```
    pub const fn abs(self) -> Self {
        match self.seconds.checked_abs() {
            Some(seconds) => Self::new_ranged_unchecked(seconds, self.nanoseconds.abs()),
            None => Self::MAX,
        }
    }

    /// Convert the existing `Duration` to a `std::time::Duration` and its sign. This returns a
    /// [`std::time::Duration`] and does not saturate the returned value (unlike [`Duration::abs`]).
    ///
    /// ```rust
    /// # use time::ext::{NumericalDuration, NumericalStdDuration};
    /// assert_eq!(1.seconds().unsigned_abs(), 1.std_seconds());
    /// assert_eq!(0.seconds().unsigned_abs(), 0.std_seconds());
    /// assert_eq!((-1).seconds().unsigned_abs(), 1.std_seconds());
    /// ```
    pub const fn unsigned_abs(self) -> StdDuration {
        StdDuration::new(
            self.seconds.unsigned_abs(),
            self.nanoseconds.get().unsigned_abs(),
        )
    }
    // endregion abs

    // region: constructors
    /// Create a new `Duration` without checking the validity of the components.
    ///
    /// # Safety
    ///
    /// - `nanoseconds` must be in the range `-999_999_999..=999_999_999`.
    ///
    /// While the sign of `nanoseconds` is required to be the same as the sign of `seconds`, this is
    /// not a safety invariant.
    pub(crate) const unsafe fn new_unchecked(seconds: i64, nanoseconds: i32) -> Self {
        Self::new_ranged_unchecked(
            seconds,
            // Safety: The caller must uphold the safety invariants.
            unsafe { Nanoseconds::new_unchecked(nanoseconds) },
        )
    }

    /// Create a new `Duration` without checking the validity of the components.
    pub(crate) const fn new_ranged_unchecked(seconds: i64, nanoseconds: Nanoseconds) -> Self {
        if seconds < 0 {
            debug_assert!(nanoseconds.get() <= 0);
        } else if seconds > 0 {
            debug_assert!(nanoseconds.get() >= 0);
        }

        Self {
            seconds,
            nanoseconds,
            padding: Padding::Optimize,
        }
    }

    /// Create a new `Duration` with the provided seconds and nanoseconds. If nanoseconds is at
    /// least ±10<sup>9</sup>, it will wrap to the number of seconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::new(1, 0), 1.seconds());
    /// assert_eq!(Duration::new(-1, 0), (-1).seconds());
    /// assert_eq!(Duration::new(1, 2_000_000_000), 3.seconds());
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    pub const fn new(mut seconds: i64, mut nanoseconds: i32) -> Self {
        seconds = expect_opt!(
            seconds.checked_add(nanoseconds as i64 / Nanosecond::per(Second) as i64),
            "overflow constructing `time::Duration`"
        );
        nanoseconds %= Nanosecond::per(Second) as i32;

        if seconds > 0 && nanoseconds < 0 {
            // `seconds` cannot overflow here because it is positive.
            seconds -= 1;
            nanoseconds += Nanosecond::per(Second) as i32;
        } else if seconds < 0 && nanoseconds > 0 {
            // `seconds` cannot overflow here because it is negative.
            seconds += 1;
            nanoseconds -= Nanosecond::per(Second) as i32;
        }

        // Safety: `nanoseconds` is in range due to the modulus above.
        unsafe { Self::new_unchecked(seconds, nanoseconds) }
    }

    /// Create a new `Duration` with the provided seconds and nanoseconds.
    pub(crate) const fn new_ranged(mut seconds: i64, mut nanoseconds: Nanoseconds) -> Self {
        if seconds > 0 && nanoseconds.get() < 0 {
            // `seconds` cannot overflow here because it is positive.
            seconds -= 1;
            // Safety: `nanoseconds` is negative with a maximum of 999,999,999, so adding a billion
            // to it is guaranteed to result in an in-range value.
            nanoseconds = unsafe {
                Nanoseconds::new_unchecked(nanoseconds.get() + Nanosecond::per(Second) as i32)
            };
        } else if seconds < 0 && nanoseconds.get() > 0 {
            // `seconds` cannot overflow here because it is negative.
            seconds += 1;
            // Safety: `nanoseconds` is positive with a minimum of -999,999,999, so subtracting a
            // billion from it is guaranteed to result in an in-range value.
            nanoseconds = unsafe {
                Nanoseconds::new_unchecked(nanoseconds.get() - Nanosecond::per(Second) as i32)
            };
        }

        Self::new_ranged_unchecked(seconds, nanoseconds)
    }

    /// Create a new `Duration` with the given number of weeks. Equivalent to
    /// `Duration::seconds(weeks * 604_800)`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::weeks(1), 604_800.seconds());
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    pub const fn weeks(weeks: i64) -> Self {
        Self::seconds(expect_opt!(
            weeks.checked_mul(Second::per(Week) as _),
            "overflow constructing `time::Duration`"
        ))
    }

    /// Create a new `Duration` with the given number of days. Equivalent to
    /// `Duration::seconds(days * 86_400)`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::days(1), 86_400.seconds());
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    pub const fn days(days: i64) -> Self {
        Self::seconds(expect_opt!(
            days.checked_mul(Second::per(Day) as _),
            "overflow constructing `time::Duration`"
        ))
    }

    /// Create a new `Duration` with the given number of hours. Equivalent to
    /// `Duration::seconds(hours * 3_600)`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::hours(1), 3_600.seconds());
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    pub const fn hours(hours: i64) -> Self {
        Self::seconds(expect_opt!(
            hours.checked_mul(Second::per(Hour) as _),
            "overflow constructing `time::Duration`"
        ))
    }

    /// Create a new `Duration` with the given number of minutes. Equivalent to
    /// `Duration::seconds(minutes * 60)`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::minutes(1), 60.seconds());
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    pub const fn minutes(minutes: i64) -> Self {
        Self::seconds(expect_opt!(
            minutes.checked_mul(Second::per(Minute) as _),
            "overflow constructing `time::Duration`"
        ))
    }

    /// Create a new `Duration` with the given number of seconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::seconds(1), 1_000.milliseconds());
    /// ```
    pub const fn seconds(seconds: i64) -> Self {
        Self::new_ranged_unchecked(seconds, Nanoseconds::new_static::<0>())
    }

    /// Creates a new `Duration` from the specified number of seconds represented as `f64`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::seconds_f64(0.5), 0.5.seconds());
    /// assert_eq!(Duration::seconds_f64(-0.5), -0.5.seconds());
    /// ```
    pub fn seconds_f64(seconds: f64) -> Self {
        try_from_secs!(
            secs = seconds,
            mantissa_bits = 52,
            exponent_bits = 11,
            offset = 44,
            bits_ty = u64,
            bits_ty_signed = i64,
            double_ty = u128,
            float_ty = f64,
            is_nan = crate::expect_failed("passed NaN to `time::Duration::seconds_f64`"),
            is_overflow = crate::expect_failed("overflow constructing `time::Duration`"),
        )
    }

    /// Creates a new `Duration` from the specified number of seconds represented as `f32`.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::seconds_f32(0.5), 0.5.seconds());
    /// assert_eq!(Duration::seconds_f32(-0.5), (-0.5).seconds());
    /// ```
    pub fn seconds_f32(seconds: f32) -> Self {
        try_from_secs!(
            secs = seconds,
            mantissa_bits = 23,
            exponent_bits = 8,
            offset = 41,
            bits_ty = u32,
            bits_ty_signed = i32,
            double_ty = u64,
            float_ty = f32,
            is_nan = crate::expect_failed("passed NaN to `time::Duration::seconds_f32`"),
            is_overflow = crate::expect_failed("overflow constructing `time::Duration`"),
        )
    }

    /// Creates a new `Duration` from the specified number of seconds
    /// represented as `f64`. Any values that are out of bounds are saturated at
    /// the minimum or maximum respectively. `NaN` gets turned into a `Duration`
    /// of 0 seconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::saturating_seconds_f64(0.5), 0.5.seconds());
    /// assert_eq!(Duration::saturating_seconds_f64(-0.5), -0.5.seconds());
    /// assert_eq!(
    ///     Duration::saturating_seconds_f64(f64::NAN),
    ///     Duration::new(0, 0),
    /// );
    /// assert_eq!(
    ///     Duration::saturating_seconds_f64(f64::NEG_INFINITY),
    ///     Duration::MIN,
    /// );
    /// assert_eq!(
    ///     Duration::saturating_seconds_f64(f64::INFINITY),
    ///     Duration::MAX,
    /// );
    /// ```
    pub fn saturating_seconds_f64(seconds: f64) -> Self {
        try_from_secs!(
            secs = seconds,
            mantissa_bits = 52,
            exponent_bits = 11,
            offset = 44,
            bits_ty = u64,
            bits_ty_signed = i64,
            double_ty = u128,
            float_ty = f64,
            is_nan = return Self::ZERO,
            is_overflow = return if seconds < 0.0 { Self::MIN } else { Self::MAX },
        )
    }

    /// Creates a new `Duration` from the specified number of seconds
    /// represented as `f32`. Any values that are out of bounds are saturated at
    /// the minimum or maximum respectively. `NaN` gets turned into a `Duration`
    /// of 0 seconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::saturating_seconds_f32(0.5), 0.5.seconds());
    /// assert_eq!(Duration::saturating_seconds_f32(-0.5), (-0.5).seconds());
    /// assert_eq!(
    ///     Duration::saturating_seconds_f32(f32::NAN),
    ///     Duration::new(0, 0),
    /// );
    /// assert_eq!(
    ///     Duration::saturating_seconds_f32(f32::NEG_INFINITY),
    ///     Duration::MIN,
    /// );
    /// assert_eq!(
    ///     Duration::saturating_seconds_f32(f32::INFINITY),
    ///     Duration::MAX,
    /// );
    /// ```
    pub fn saturating_seconds_f32(seconds: f32) -> Self {
        try_from_secs!(
            secs = seconds,
            mantissa_bits = 23,
            exponent_bits = 8,
            offset = 41,
            bits_ty = u32,
            bits_ty_signed = i32,
            double_ty = u64,
            float_ty = f32,
            is_nan = return Self::ZERO,
            is_overflow = return if seconds < 0.0 { Self::MIN } else { Self::MAX },
        )
    }

    /// Creates a new `Duration` from the specified number of seconds
    /// represented as `f64`. Returns `None` if the `Duration` can't be
    /// represented.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::checked_seconds_f64(0.5), Some(0.5.seconds()));
    /// assert_eq!(Duration::checked_seconds_f64(-0.5), Some(-0.5.seconds()));
    /// assert_eq!(Duration::checked_seconds_f64(f64::NAN), None);
    /// assert_eq!(Duration::checked_seconds_f64(f64::NEG_INFINITY), None);
    /// assert_eq!(Duration::checked_seconds_f64(f64::INFINITY), None);
    /// ```
    pub fn checked_seconds_f64(seconds: f64) -> Option<Self> {
        Some(try_from_secs!(
            secs = seconds,
            mantissa_bits = 52,
            exponent_bits = 11,
            offset = 44,
            bits_ty = u64,
            bits_ty_signed = i64,
            double_ty = u128,
            float_ty = f64,
            is_nan = return None,
            is_overflow = return None,
        ))
    }

    /// Creates a new `Duration` from the specified number of seconds
    /// represented as `f32`. Returns `None` if the `Duration` can't be
    /// represented.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::checked_seconds_f32(0.5), Some(0.5.seconds()));
    /// assert_eq!(Duration::checked_seconds_f32(-0.5), Some(-0.5.seconds()));
    /// assert_eq!(Duration::checked_seconds_f32(f32::NAN), None);
    /// assert_eq!(Duration::checked_seconds_f32(f32::NEG_INFINITY), None);
    /// assert_eq!(Duration::checked_seconds_f32(f32::INFINITY), None);
    /// ```
    pub fn checked_seconds_f32(seconds: f32) -> Option<Self> {
        Some(try_from_secs!(
            secs = seconds,
            mantissa_bits = 23,
            exponent_bits = 8,
            offset = 41,
            bits_ty = u32,
            bits_ty_signed = i32,
            double_ty = u64,
            float_ty = f32,
            is_nan = return None,
            is_overflow = return None,
        ))
    }

    /// Create a new `Duration` with the given number of milliseconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::milliseconds(1), 1_000.microseconds());
    /// assert_eq!(Duration::milliseconds(-1), (-1_000).microseconds());
    /// ```
    pub const fn milliseconds(milliseconds: i64) -> Self {
        // Safety: `nanoseconds` is guaranteed to be in range because of the modulus.
        unsafe {
            Self::new_unchecked(
                milliseconds / Millisecond::per(Second) as i64,
                (milliseconds % Millisecond::per(Second) as i64
                    * Nanosecond::per(Millisecond) as i64) as _,
            )
        }
    }

    /// Create a new `Duration` with the given number of microseconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::microseconds(1), 1_000.nanoseconds());
    /// assert_eq!(Duration::microseconds(-1), (-1_000).nanoseconds());
    /// ```
    pub const fn microseconds(microseconds: i64) -> Self {
        // Safety: `nanoseconds` is guaranteed to be in range because of the modulus.
        unsafe {
            Self::new_unchecked(
                microseconds / Microsecond::per(Second) as i64,
                (microseconds % Microsecond::per(Second) as i64
                    * Nanosecond::per(Microsecond) as i64) as _,
            )
        }
    }

    /// Create a new `Duration` with the given number of nanoseconds.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(Duration::nanoseconds(1), 1.microseconds() / 1_000);
    /// assert_eq!(Duration::nanoseconds(-1), (-1).microseconds() / 1_000);
    /// ```
    pub const fn nanoseconds(nanoseconds: i64) -> Self {
        // Safety: `nanoseconds` is guaranteed to be in range because of the modulus.
        unsafe {
            Self::new_unchecked(
                nanoseconds / Nanosecond::per(Second) as i64,
                (nanoseconds % Nanosecond::per(Second) as i64) as _,
            )
        }
    }

    /// Create a new `Duration` with the given number of nanoseconds.
    ///
    /// As the input range cannot be fully mapped to the output, this should only be used where it's
    /// known to result in a valid value.
    pub(crate) const fn nanoseconds_i128(nanoseconds: i128) -> Self {
        let seconds = nanoseconds / Nanosecond::per(Second) as i128;
        let nanoseconds = nanoseconds % Nanosecond::per(Second) as i128;

        if seconds > i64::MAX as i128 || seconds < i64::MIN as i128 {
            crate::expect_failed("overflow constructing `time::Duration`");
        }

        // Safety: `nanoseconds` is guaranteed to be in range because of the modulus above.
        unsafe { Self::new_unchecked(seconds as _, nanoseconds as _) }
    }
    // endregion constructors

    // region: getters
    /// Get the number of whole weeks in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.weeks().whole_weeks(), 1);
    /// assert_eq!((-1).weeks().whole_weeks(), -1);
    /// assert_eq!(6.days().whole_weeks(), 0);
    /// assert_eq!((-6).days().whole_weeks(), 0);
    /// ```
    pub const fn whole_weeks(self) -> i64 {
        self.whole_seconds() / Second::per(Week) as i64
    }

    /// Get the number of whole days in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.days().whole_days(), 1);
    /// assert_eq!((-1).days().whole_days(), -1);
    /// assert_eq!(23.hours().whole_days(), 0);
    /// assert_eq!((-23).hours().whole_days(), 0);
    /// ```
    pub const fn whole_days(self) -> i64 {
        self.whole_seconds() / Second::per(Day) as i64
    }

    /// Get the number of whole hours in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.hours().whole_hours(), 1);
    /// assert_eq!((-1).hours().whole_hours(), -1);
    /// assert_eq!(59.minutes().whole_hours(), 0);
    /// assert_eq!((-59).minutes().whole_hours(), 0);
    /// ```
    pub const fn whole_hours(self) -> i64 {
        self.whole_seconds() / Second::per(Hour) as i64
    }

    /// Get the number of whole minutes in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.minutes().whole_minutes(), 1);
    /// assert_eq!((-1).minutes().whole_minutes(), -1);
    /// assert_eq!(59.seconds().whole_minutes(), 0);
    /// assert_eq!((-59).seconds().whole_minutes(), 0);
    /// ```
    pub const fn whole_minutes(self) -> i64 {
        self.whole_seconds() / Second::per(Minute) as i64
    }

    /// Get the number of whole seconds in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.seconds().whole_seconds(), 1);
    /// assert_eq!((-1).seconds().whole_seconds(), -1);
    /// assert_eq!(1.minutes().whole_seconds(), 60);
    /// assert_eq!((-1).minutes().whole_seconds(), -60);
    /// ```
    pub const fn whole_seconds(self) -> i64 {
        self.seconds
    }

    /// Get the number of fractional seconds in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.5.seconds().as_seconds_f64(), 1.5);
    /// assert_eq!((-1.5).seconds().as_seconds_f64(), -1.5);
    /// ```
    pub fn as_seconds_f64(self) -> f64 {
        self.seconds as f64 + self.nanoseconds.get() as f64 / Nanosecond::per(Second) as f64
    }

    /// Get the number of fractional seconds in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.5.seconds().as_seconds_f32(), 1.5);
    /// assert_eq!((-1.5).seconds().as_seconds_f32(), -1.5);
    /// ```
    pub fn as_seconds_f32(self) -> f32 {
        self.seconds as f32 + self.nanoseconds.get() as f32 / Nanosecond::per(Second) as f32
    }

    /// Get the number of whole milliseconds in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.seconds().whole_milliseconds(), 1_000);
    /// assert_eq!((-1).seconds().whole_milliseconds(), -1_000);
    /// assert_eq!(1.milliseconds().whole_milliseconds(), 1);
    /// assert_eq!((-1).milliseconds().whole_milliseconds(), -1);
    /// ```
    pub const fn whole_milliseconds(self) -> i128 {
        self.seconds as i128 * Millisecond::per(Second) as i128
            + self.nanoseconds.get() as i128 / Nanosecond::per(Millisecond) as i128
    }

    /// Get the number of milliseconds past the number of whole seconds.
    ///
    /// Always in the range `-1_000..1_000`.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.4.seconds().subsec_milliseconds(), 400);
    /// assert_eq!((-1.4).seconds().subsec_milliseconds(), -400);
    /// ```
    // Allow the lint, as the value is guaranteed to be less than 1000.
    pub const fn subsec_milliseconds(self) -> i16 {
        (self.nanoseconds.get() / Nanosecond::per(Millisecond) as i32) as _
    }

    /// Get the number of whole microseconds in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.milliseconds().whole_microseconds(), 1_000);
    /// assert_eq!((-1).milliseconds().whole_microseconds(), -1_000);
    /// assert_eq!(1.microseconds().whole_microseconds(), 1);
    /// assert_eq!((-1).microseconds().whole_microseconds(), -1);
    /// ```
    pub const fn whole_microseconds(self) -> i128 {
        self.seconds as i128 * Microsecond::per(Second) as i128
            + self.nanoseconds.get() as i128 / Nanosecond::per(Microsecond) as i128
    }

    /// Get the number of microseconds past the number of whole seconds.
    ///
    /// Always in the range `-1_000_000..1_000_000`.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.0004.seconds().subsec_microseconds(), 400);
    /// assert_eq!((-1.0004).seconds().subsec_microseconds(), -400);
    /// ```
    pub const fn subsec_microseconds(self) -> i32 {
        self.nanoseconds.get() / Nanosecond::per(Microsecond) as i32
    }

    /// Get the number of nanoseconds in the duration.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.microseconds().whole_nanoseconds(), 1_000);
    /// assert_eq!((-1).microseconds().whole_nanoseconds(), -1_000);
    /// assert_eq!(1.nanoseconds().whole_nanoseconds(), 1);
    /// assert_eq!((-1).nanoseconds().whole_nanoseconds(), -1);
    /// ```
    pub const fn whole_nanoseconds(self) -> i128 {
        self.seconds as i128 * Nanosecond::per(Second) as i128 + self.nanoseconds.get() as i128
    }

    /// Get the number of nanoseconds past the number of whole seconds.
    ///
    /// The returned value will always be in the range `-1_000_000_000..1_000_000_000`.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(1.000_000_400.seconds().subsec_nanoseconds(), 400);
    /// assert_eq!((-1.000_000_400).seconds().subsec_nanoseconds(), -400);
    /// ```
    pub const fn subsec_nanoseconds(self) -> i32 {
        self.nanoseconds.get()
    }

    /// Get the number of nanoseconds past the number of whole seconds.
    #[cfg(feature = "quickcheck")]
    pub(crate) const fn subsec_nanoseconds_ranged(self) -> Nanoseconds {
        self.nanoseconds
    }
    // endregion getters

    // region: checked arithmetic
    /// Computes `self + rhs`, returning `None` if an overflow occurred.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(5.seconds().checked_add(5.seconds()), Some(10.seconds()));
    /// assert_eq!(Duration::MAX.checked_add(1.nanoseconds()), None);
    /// assert_eq!((-5).seconds().checked_add(5.seconds()), Some(0.seconds()));
    /// ```
    pub const fn checked_add(self, rhs: Self) -> Option<Self> {
        let mut seconds = const_try_opt!(self.seconds.checked_add(rhs.seconds));
        let mut nanoseconds = self.nanoseconds.get() + rhs.nanoseconds.get();

        if nanoseconds >= Nanosecond::per(Second) as _ || seconds < 0 && nanoseconds > 0 {
            nanoseconds -= Nanosecond::per(Second) as i32;
            seconds = const_try_opt!(seconds.checked_add(1));
        } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0
        {
            nanoseconds += Nanosecond::per(Second) as i32;
            seconds = const_try_opt!(seconds.checked_sub(1));
        }

        // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling.
        unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) }
    }

    /// Computes `self - rhs`, returning `None` if an overflow occurred.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(5.seconds().checked_sub(5.seconds()), Some(Duration::ZERO));
    /// assert_eq!(Duration::MIN.checked_sub(1.nanoseconds()), None);
    /// assert_eq!(5.seconds().checked_sub(10.seconds()), Some((-5).seconds()));
    /// ```
    pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
        let mut seconds = const_try_opt!(self.seconds.checked_sub(rhs.seconds));
        let mut nanoseconds = self.nanoseconds.get() - rhs.nanoseconds.get();

        if nanoseconds >= Nanosecond::per(Second) as _ || seconds < 0 && nanoseconds > 0 {
            nanoseconds -= Nanosecond::per(Second) as i32;
            seconds = const_try_opt!(seconds.checked_add(1));
        } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0
        {
            nanoseconds += Nanosecond::per(Second) as i32;
            seconds = const_try_opt!(seconds.checked_sub(1));
        }

        // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling.
        unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) }
    }

    /// Computes `self * rhs`, returning `None` if an overflow occurred.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(5.seconds().checked_mul(2), Some(10.seconds()));
    /// assert_eq!(5.seconds().checked_mul(-2), Some((-10).seconds()));
    /// assert_eq!(5.seconds().checked_mul(0), Some(0.seconds()));
    /// assert_eq!(Duration::MAX.checked_mul(2), None);
    /// assert_eq!(Duration::MIN.checked_mul(2), None);
    /// ```
    pub const fn checked_mul(self, rhs: i32) -> Option<Self> {
        // Multiply nanoseconds as i64, because it cannot overflow that way.
        let total_nanos = self.nanoseconds.get() as i64 * rhs as i64;
        let extra_secs = total_nanos / Nanosecond::per(Second) as i64;
        let nanoseconds = (total_nanos % Nanosecond::per(Second) as i64) as _;
        let seconds = const_try_opt!(
            const_try_opt!(self.seconds.checked_mul(rhs as _)).checked_add(extra_secs)
        );

        // Safety: `nanoseconds` is guaranteed to be in range because of the modulus above.
        unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) }
    }

    /// Computes `self / rhs`, returning `None` if `rhs == 0` or if the result would overflow.
    ///
    /// ```rust
    /// # use time::ext::NumericalDuration;
    /// assert_eq!(10.seconds().checked_div(2), Some(5.seconds()));
    /// assert_eq!(10.seconds().checked_div(-2), Some((-5).seconds()));
    /// assert_eq!(1.seconds().checked_div(0), None);
    /// ```
    pub const fn checked_div(self, rhs: i32) -> Option<Self> {
        let (secs, extra_secs) = (
            const_try_opt!(self.seconds.checked_div(rhs as i64)),
            self.seconds % (rhs as i64),
        );
        let (mut nanos, extra_nanos) = (self.nanoseconds.get() / rhs, self.nanoseconds.get() % rhs);
        nanos += ((extra_secs * (Nanosecond::per(Second) as i64) + extra_nanos as i64)
            / (rhs as i64)) as i32;

        // Safety: `nanoseconds` is in range.
        unsafe { Some(Self::new_unchecked(secs, nanos)) }
    }
    // endregion checked arithmetic

    // region: saturating arithmetic
    /// Computes `self + rhs`, saturating if an overflow occurred.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(5.seconds().saturating_add(5.seconds()), 10.seconds());
    /// assert_eq!(Duration::MAX.saturating_add(1.nanoseconds()), Duration::MAX);
    /// assert_eq!(
    ///     Duration::MIN.saturating_add((-1).nanoseconds()),
    ///     Duration::MIN
    /// );
    /// assert_eq!((-5).seconds().saturating_add(5.seconds()), Duration::ZERO);
    /// ```
    pub const fn saturating_add(self, rhs: Self) -> Self {
        let (mut seconds, overflow) = self.seconds.overflowing_add(rhs.seconds);
        if overflow {
            if self.seconds > 0 {
                return Self::MAX;
            }
            return Self::MIN;
        }
        let mut nanoseconds = self.nanoseconds.get() + rhs.nanoseconds.get();

        if nanoseconds >= Nanosecond::per(Second) as _ || seconds < 0 && nanoseconds > 0 {
            nanoseconds -= Nanosecond::per(Second) as i32;
            seconds = match seconds.checked_add(1) {
                Some(seconds) => seconds,
                None => return Self::MAX,
            };
        } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0
        {
            nanoseconds += Nanosecond::per(Second) as i32;
            seconds = match seconds.checked_sub(1) {
                Some(seconds) => seconds,
                None => return Self::MIN,
            };
        }

        // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling.
        unsafe { Self::new_unchecked(seconds, nanoseconds) }
    }

    /// Computes `self - rhs`, saturating if an overflow occurred.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(5.seconds().saturating_sub(5.seconds()), Duration::ZERO);
    /// assert_eq!(Duration::MIN.saturating_sub(1.nanoseconds()), Duration::MIN);
    /// assert_eq!(
    ///     Duration::MAX.saturating_sub((-1).nanoseconds()),
    ///     Duration::MAX
    /// );
    /// assert_eq!(5.seconds().saturating_sub(10.seconds()), (-5).seconds());
    /// ```
    pub const fn saturating_sub(self, rhs: Self) -> Self {
        let (mut seconds, overflow) = self.seconds.overflowing_sub(rhs.seconds);
        if overflow {
            if self.seconds > 0 {
                return Self::MAX;
            }
            return Self::MIN;
        }
        let mut nanoseconds = self.nanoseconds.get() - rhs.nanoseconds.get();

        if nanoseconds >= Nanosecond::per(Second) as _ || seconds < 0 && nanoseconds > 0 {
            nanoseconds -= Nanosecond::per(Second) as i32;
            seconds = match seconds.checked_add(1) {
                Some(seconds) => seconds,
                None => return Self::MAX,
            };
        } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0
        {
            nanoseconds += Nanosecond::per(Second) as i32;
            seconds = match seconds.checked_sub(1) {
                Some(seconds) => seconds,
                None => return Self::MIN,
            };
        }

        // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling.
        unsafe { Self::new_unchecked(seconds, nanoseconds) }
    }

    /// Computes `self * rhs`, saturating if an overflow occurred.
    ///
    /// ```rust
    /// # use time::{Duration, ext::NumericalDuration};
    /// assert_eq!(5.seconds().saturating_mul(2), 10.seconds());
    /// assert_eq!(5.seconds().saturating_mul(-2), (-10).seconds());
    /// assert_eq!(5.seconds().saturating_mul(0), Duration::ZERO);
    /// assert_eq!(Duration::MAX.saturating_mul(2), Duration::MAX);
    /// assert_eq!(Duration::MIN.saturating_mul(2), Duration::MIN);
    /// assert_eq!(Duration::MAX.saturating_mul(-2), Duration::MIN);
    /// assert_eq!(Duration::MIN.saturating_mul(-2), Duration::MAX);
    /// ```
    pub const fn saturating_mul(self, rhs: i32) -> Self {
        // Multiply nanoseconds as i64, because it cannot overflow that way.
        let total_nanos = self.nanoseconds.get() as i64 * rhs as i64;
        let extra_secs = total_nanos / Nanosecond::per(Second) as i64;
        let nanoseconds = (total_nanos % Nanosecond::per(Second) as i64) as _;
        let (seconds, overflow1) = self.seconds.overflowing_mul(rhs as _);
        if overflow1 {
            if self.seconds > 0 && rhs > 0 || self.seconds < 0 && rhs < 0 {
                return Self::MAX;
            }
            return Self::MIN;
        }
        let (seconds, overflow2) = seconds.overflowing_add(extra_secs);
        if overflow2 {
            if self.seconds > 0 && rhs > 0 {
                return Self::MAX;
            }
            return Self::MIN;
        }

        // Safety: `nanoseconds` is guaranteed to be in range because of to the modulus above.
        unsafe { Self::new_unchecked(seconds, nanoseconds) }
    }
    // endregion saturating arithmetic

    /// Runs a closure, returning the duration of time it took to run. The return value of the
    /// closure is provided in the second part of the tuple.
    #[cfg(feature = "std")]
    #[deprecated(
        since = "0.3.32",
        note = "extremely limited use case, not intended for benchmarking"
    )]
    pub fn time_fn<T>(f: impl FnOnce() -> T) -> (Self, T) {
        let start = Instant::now();
        let return_value = f();
        let end = Instant::now();

        (end - start, return_value)
    }
}

// region: trait impls
/// The format returned by this implementation is not stable and must not be relied upon.
///
/// By default this produces an exact, full-precision printout of the duration.
/// For a concise, rounded printout instead, you can use the `.N` format specifier:
///
/// ```
/// # use time::Duration;
/// #
/// let duration = Duration::new(123456, 789011223);
/// println!("{duration:.3}");
/// ```
///
/// For the purposes of this implementation, a day is exactly 24 hours and a minute is exactly 60
/// seconds.
impl fmt::Display for Duration {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.is_negative() {
            f.write_str("-")?;
        }

        if let Some(_precision) = f.precision() {
            // Concise, rounded representation.

            if self.is_zero() {
                // Write a zero value with the requested precision.
                return (0.).fmt(f).and_then(|_| f.write_str("s"));
            }

            /// Format the first item that produces a value greater than 1 and then break.
            macro_rules! item {
                ($name:literal, $value:expr) => {
                    let value = $value;
                    if value >= 1.0 {
                        return value.fmt(f).and_then(|_| f.write_str($name));
                    }
                };
            }

            // Even if this produces a de-normal float, because we're rounding we don't really care.
            let seconds = self.unsigned_abs().as_secs_f64();

            item!("d", seconds / Second::per(Day) as f64);
            item!("h", seconds / Second::per(Hour) as f64);
            item!("m", seconds / Second::per(Minute) as f64);
            item!("s", seconds);
            item!("ms", seconds * Millisecond::per(Second) as f64);
            item!("µs", seconds * Microsecond::per(Second) as f64);
            item!("ns", seconds * Nanosecond::per(Second) as f64);
        } else {
            // Precise, but verbose representation.

            if self.is_zero() {
                return f.write_str("0s");
            }

            /// Format a single item.
            macro_rules! item {
                ($name:literal, $value:expr) => {
                    match $value {
                        0 => Ok(()),
                        value => value.fmt(f).and_then(|_| f.write_str($name)),
                    }
                };
            }

            let seconds = self.seconds.unsigned_abs();
            let nanoseconds = self.nanoseconds.get().unsigned_abs();

            item!("d", seconds / Second::per(Day).extend::<u64>())?;
            item!(
                "h",
                seconds / Second::per(Hour).extend::<u64>() % Hour::per(Day).extend::<u64>()
            )?;
            item!(
                "m",
                seconds / Second::per(Minute).extend::<u64>() % Minute::per(Hour).extend::<u64>()
            )?;
            item!("s", seconds % Second::per(Minute).extend::<u64>())?;
            item!("ms", nanoseconds / Nanosecond::per(Millisecond))?;
            item!(
                "µs",
                nanoseconds / Nanosecond::per(Microsecond).extend::<u32>()
                    % Microsecond::per(Millisecond).extend::<u32>()
            )?;
            item!(
                "ns",
                nanoseconds % Nanosecond::per(Microsecond).extend::<u32>()
            )?;
        }

        Ok(())
    }
}

impl TryFrom<StdDuration> for Duration {
    type Error = error::ConversionRange;

    fn try_from(original: StdDuration) -> Result<Self, error::ConversionRange> {
        Ok(Self::new(
            original
                .as_secs()
                .try_into()
                .map_err(|_| error::ConversionRange)?,
            original.subsec_nanos().cast_signed(),
        ))
    }
}

impl TryFrom<Duration> for StdDuration {
    type Error = error::ConversionRange;

    fn try_from(duration: Duration) -> Result<Self, error::ConversionRange> {
        Ok(Self::new(
            duration
                .seconds
                .try_into()
                .map_err(|_| error::ConversionRange)?,
            duration
                .nanoseconds
                .get()
                .try_into()
                .map_err(|_| error::ConversionRange)?,
        ))
    }
}

impl Add for Duration {
    type Output = Self;

    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    fn add(self, rhs: Self) -> Self::Output {
        self.checked_add(rhs)
            .expect("overflow when adding durations")
    }
}

impl Add<StdDuration> for Duration {
    type Output = Self;

    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    fn add(self, std_duration: StdDuration) -> Self::Output {
        self + Self::try_from(std_duration)
            .expect("overflow converting `std::time::Duration` to `time::Duration`")
    }
}

impl Add<Duration> for StdDuration {
    type Output = Duration;

    fn add(self, rhs: Duration) -> Self::Output {
        rhs + self
    }
}

impl_add_assign!(Duration: Self, StdDuration);

impl AddAssign<Duration> for StdDuration {
    /// # Panics
    ///
    /// This may panic if the resulting addition cannot be represented.
    fn add_assign(&mut self, rhs: Duration) {
        *self = (*self + rhs).try_into().expect(
            "Cannot represent a resulting duration in std. Try `let x = x + rhs;`, which will \
             change the type.",
        );
    }
}

impl Neg for Duration {
    type Output = Self;

    fn neg(self) -> Self::Output {
        Self::new_ranged_unchecked(-self.seconds, self.nanoseconds.neg())
    }
}

impl Sub for Duration {
    type Output = Self;

    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    fn sub(self, rhs: Self) -> Self::Output {
        self.checked_sub(rhs)
            .expect("overflow when subtracting durations")
    }
}

impl Sub<StdDuration> for Duration {
    type Output = Self;

    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    fn sub(self, rhs: StdDuration) -> Self::Output {
        self - Self::try_from(rhs)
            .expect("overflow converting `std::time::Duration` to `time::Duration`")
    }
}

impl Sub<Duration> for StdDuration {
    type Output = Duration;

    /// # Panics
    ///
    /// This may panic if an overflow occurs.
    fn sub(self, rhs: Duration) -> Self::Output {
        Duration::try_from(self)
            .expect("overflow converting `std::time::Duration` to `time::Duration`")
            - rhs
    }
}

impl_sub_assign!(Duration: Self, StdDuration);

impl SubAssign<Duration> for StdDuration {
    /// # Panics
    ///
    /// This may panic if the resulting subtraction can not be represented.
    fn sub_assign(&mut self, rhs: Duration) {
        *self = (*self - rhs).try_into().expect(
            "Cannot represent a resulting duration in std. Try `let x = x - rhs;`, which will \
             change the type.",
        );
    }
}

/// Implement `Mul` (reflexively) and `Div` for `Duration` for various types.
macro_rules! duration_mul_div_int {
    ($($type:ty),+) => {$(
        impl Mul<$type> for Duration {
            type Output = Self;

            fn mul(self, rhs: $type) -> Self::Output {
                Self::nanoseconds_i128(
                    self.whole_nanoseconds()
                        .checked_mul(rhs.cast_signed().extend::<i128>())
                        .expect("overflow when multiplying duration")
                )
            }
        }

        impl Mul<Duration> for $type {
            type Output = Duration;

            fn mul(self, rhs: Duration) -> Self::Output {
                rhs * self
            }
        }

        impl Div<$type> for Duration {
            type Output = Self;

            fn div(self, rhs: $type) -> Self::Output {
                Self::nanoseconds_i128(
                    self.whole_nanoseconds() / rhs.cast_signed().extend::<i128>()
                )
            }
        }
    )+};
}
duration_mul_div_int![i8, i16, i32, u8, u16, u32];

impl Mul<f32> for Duration {
    type Output = Self;

    fn mul(self, rhs: f32) -> Self::Output {
        Self::seconds_f32(self.as_seconds_f32() * rhs)
    }
}

impl Mul<Duration> for f32 {
    type Output = Duration;

    fn mul(self, rhs: Duration) -> Self::Output {
        rhs * self
    }
}

impl Mul<f64> for Duration {
    type Output = Self;

    fn mul(self, rhs: f64) -> Self::Output {
        Self::seconds_f64(self.as_seconds_f64() * rhs)
    }
}

impl Mul<Duration> for f64 {
    type Output = Duration;

    fn mul(self, rhs: Duration) -> Self::Output {
        rhs * self
    }
}

impl_mul_assign!(Duration: i8, i16, i32, u8, u16, u32, f32, f64);

impl Div<f32> for Duration {
    type Output = Self;

    fn div(self, rhs: f32) -> Self::Output {
        Self::seconds_f32(self.as_seconds_f32() / rhs)
    }
}

impl Div<f64> for Duration {
    type Output = Self;

    fn div(self, rhs: f64) -> Self::Output {
        Self::seconds_f64(self.as_seconds_f64() / rhs)
    }
}

impl_div_assign!(Duration: i8, i16, i32, u8, u16, u32, f32, f64);

impl Div for Duration {
    type Output = f64;

    fn div(self, rhs: Self) -> Self::Output {
        self.as_seconds_f64() / rhs.as_seconds_f64()
    }
}

impl Div<StdDuration> for Duration {
    type Output = f64;

    fn div(self, rhs: StdDuration) -> Self::Output {
        self.as_seconds_f64() / rhs.as_secs_f64()
    }
}

impl Div<Duration> for StdDuration {
    type Output = f64;

    fn div(self, rhs: Duration) -> Self::Output {
        self.as_secs_f64() / rhs.as_seconds_f64()
    }
}

impl PartialEq<StdDuration> for Duration {
    fn eq(&self, rhs: &StdDuration) -> bool {
        Ok(*self) == Self::try_from(*rhs)
    }
}

impl PartialEq<Duration> for StdDuration {
    fn eq(&self, rhs: &Duration) -> bool {
        rhs == self
    }
}

impl PartialOrd<StdDuration> for Duration {
    fn partial_cmp(&self, rhs: &StdDuration) -> Option<Ordering> {
        if rhs.as_secs() > i64::MAX.cast_unsigned() {
            return Some(Ordering::Less);
        }

        Some(
            self.seconds
                .cmp(&rhs.as_secs().cast_signed())
                .then_with(|| {
                    self.nanoseconds
                        .get()
                        .cmp(&rhs.subsec_nanos().cast_signed())
                }),
        )
    }
}

impl PartialOrd<Duration> for StdDuration {
    fn partial_cmp(&self, rhs: &Duration) -> Option<Ordering> {
        rhs.partial_cmp(self).map(Ordering::reverse)
    }
}

impl Sum for Duration {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.reduce(|a, b| a + b).unwrap_or_default()
    }
}

impl<'a> Sum<&'a Self> for Duration {
    fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
        iter.copied().sum()
    }
}
// endregion trait impls
