rust_asio 0.5.3

Asynchronous I/O library
Documentation
use std::mem;
use std::time::{Duration, SystemTime, Instant};

#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
#[doc(hidden)]
pub struct Expiry(Duration);

impl Expiry {
    pub fn now() -> Expiry {
        Instant::now().into_expiry()
    }

    pub fn as_secs(&self) -> u64 {
        self.0.as_secs()
    }

    pub fn subsec_nanos(&self) -> u32 {
        self.0.subsec_nanos()
    }
}

impl Default for Expiry {
    fn default() -> Expiry {
        Expiry(Duration::new(i64::max_value() as u64, 0))
    }
}

#[doc(hidden)]
pub trait IntoExpiry {
    fn into_expiry(self) -> Expiry;
}

impl IntoExpiry for Instant {
    fn into_expiry(self) -> Expiry {
        Expiry(self.duration_since(unsafe { mem::zeroed() }))
    }
}

impl IntoExpiry for SystemTime {
    fn into_expiry(self) -> Expiry {
        Expiry(Expiry::now().0 + self.elapsed().unwrap())
    }
}


pub trait Clock : Send + 'static {
    type Duration;

    type TimePoint;

    #[doc(hidden)]
    fn expires_at(timepoint: Self::TimePoint) -> Expiry;

    #[doc(hidden)]
    fn expires_from(duration: Self::Duration) -> Expiry;

    #[doc(hidden)]
    fn elapsed_at(timepoint: Self::TimePoint) -> Duration;

    #[doc(hidden)]
    fn elapsed_from(duration: Self::Duration) -> Duration;
}

/// Provides a monotonic clock.
pub struct SteadyClock;

impl Clock for SteadyClock {
    type Duration = Duration;

    type TimePoint = Instant;

    #[doc(hidden)]
    fn expires_at(timepoint: Self::TimePoint) -> Expiry {
        timepoint.into_expiry()
    }

    #[doc(hidden)]
    fn expires_from(duration: Self::Duration) -> Expiry {
        (Instant::now() + duration).into_expiry()
    }

    #[doc(hidden)]
    fn elapsed_at(timepoint: Self::TimePoint) -> Duration {
        timepoint.elapsed()
    }

    #[doc(hidden)]
    fn elapsed_from(duration: Self::Duration) -> Duration {
        duration
    }
}

/// Provides a real-time clock.
pub struct SystemClock;

impl Clock for SystemClock {
    type Duration = Duration;

    type TimePoint = SystemTime;

    #[doc(hidden)]
    fn expires_at(timepoint: Self::TimePoint) -> Expiry {
        timepoint.into_expiry()
    }

    #[doc(hidden)]
    fn expires_from(duration: Self::Duration) -> Expiry {
        (Instant::now() + duration).into_expiry()
    }

    #[doc(hidden)]
    fn elapsed_at(timepoint: Self::TimePoint) -> Duration {
        timepoint.elapsed().unwrap()
    }

    #[doc(hidden)]
    fn elapsed_from(duration: Self::Duration) -> Duration {
        duration
    }
}

#[test]
fn test_expiry() {
    let a = Instant::now().into_expiry();
    let b = SystemTime::now().into_expiry();
    assert!((a.0.as_secs() - b.0.as_secs()) <= 1);
}