atomic-instant-full 0.1.1

A wrapper around Instant and AtomicUsize to implement most of the features of AtomicUsize
Documentation
use std::{
    sync::atomic::Ordering,
    time::{Duration, Instant},
};

use crate::AtomicInstant;

impl AtomicInstant {
    /// Adds a Duration the the current instant, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    ///
    /// # Examples
    ///
    /// ```rust
    /// use atomic_instant_full::AtomicInstant;
    /// use std::sync::atomic::Ordering;
    /// use std::time::{Duration, Instant};
    ///
    /// let now = Instant::now();
    /// let dur = Duration::from_secs(5);
    /// let foo = AtomicInstant::new(now);
    ///
    /// assert_eq!(foo.fetch_add(dur, Ordering::SeqCst), now);
    /// assert_eq!(foo.load(Ordering::SeqCst), now + dur);
    /// ```
    pub fn fetch_add(&self, val: Duration, order: Ordering) -> Instant {
        self.instant_from_offset_nanos(self.offset_nanos.fetch_add(val.into_nanos(), order))
    }

    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// Overflow location is at the initial Instant with which this AtomicInstant was initialised
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// # Examples
    ///
    /// ```rust
    /// use atomic_instant_full::AtomicInstant;
    /// use std::sync::atomic::Ordering;
    /// use std::time::{Duration, Instant};
    ///
    /// let now = Instant::now();
    /// let dur = Duration::from_secs(5);
    /// let not_now = now + dur;
    /// let foo = AtomicInstant::new(now);
    ///
    /// // Add first because otherwise the AtomicUsize overflows
    /// assert_eq!(foo.fetch_add(dur, Ordering::SeqCst), now);
    /// assert_eq!(foo.fetch_sub(dur, Ordering::SeqCst), not_now);
    /// assert_eq!(foo.load(Ordering::SeqCst), now);
    /// ```
    pub fn fetch_sub(&self, val: Duration, order: Ordering) -> Instant {
        self.instant_from_offset_nanos(self.offset_nanos.fetch_sub(val.into_nanos(), order))
    }
}
trait IntoNanos {
    fn into_nanos(self) -> usize;
}
impl IntoNanos for Duration {
    fn into_nanos(self) -> usize {
        self.as_nanos().try_into().unwrap()
    }
}