[][src]Struct phantom_newtype::Instant

pub struct Instant<Unit, Repr>(_, _);

Instant<Unit> provides a type-safe way to keep absolute time of some events, expressed in Units (CPU ticks, seconds from epoch, years from birth, etc).

You can compare instants:

use phantom_newtype::Instant;

enum SecondsFromEpoch {}
type UnixTime = Instant<SecondsFromEpoch, i64>;

assert_eq!(true, UnixTime::from(3) < UnixTime::from(5));
assert_eq!(false, UnixTime::from(3) > UnixTime::from(5));
assert_eq!(true, UnixTime::from(3) != UnixTime::from(5));
assert_eq!(true, UnixTime::from(5) == UnixTime::from(5));
assert_eq!(false, UnixTime::from(5) != UnixTime::from(5));

assert_eq!(vec![UnixTime::from(3), UnixTime::from(5)].iter().max().unwrap(),
           &UnixTime::from(5));

Instants support basic arithmetics, you can:

  • Subtract an instant from another instant to get amount of units between them.
  • Add/subtract amount of units to/from an instant to get another instant.
use phantom_newtype::{Amount, Instant};

enum SecondsFromEpoch {}

type UnixTime = Instant<SecondsFromEpoch, i64>;
type TimeDiff = Amount<SecondsFromEpoch, i64>;

let epoch = UnixTime::from(0);
let some_date = UnixTime::from(123456789);
let diff = TimeDiff::from(123456789);

assert_eq!(some_date - epoch, diff);
assert_eq!(some_date - diff, epoch);
assert_eq!(epoch + diff, some_date);

Direct multiplication of instants is not supported, however, you can scale them by a scalar or divide to get a scalar back:

use phantom_newtype::Instant;

enum SecondsFromEpoch {}
type UnixTime = Instant<SecondsFromEpoch, i64>;

let x = UnixTime::from(123456);
assert_eq!(x * 3, UnixTime::from(3 * 123456));
assert_eq!(1, x / x);
assert_eq!(3, (x * 3) / x);

Note that the unit is only available at compile time, thus using Instant instead of u64 doesn't incur any runtime penalty:

use phantom_newtype::Instant;

enum SecondsFromEpoch {}

let ms = Instant::<SecondsFromEpoch, u64>::from(10);
assert_eq!(std::mem::size_of_val(&ms), std::mem::size_of::<u64>());

Instants can be serialized and deserialized with serde. Serialized forms of Instant<Unit, Repr> and Repr are identical.

#[cfg(feature = "serde")] {
use phantom_newtype::Instant;
use serde::{Serialize, Deserialize};
use serde_json;

enum SecondsFromEpoch {}
type UnixTime = Instant<SecondsFromEpoch, i64>;

let repr: u64 = 123456;
let time = UnixTime::from(repr);
assert_eq!(serde_json::to_string(&time).unwrap(), serde_json::to_string(&repr).unwrap());

let copy: UnitTime = serde_json::from_str(&serde_json::to_string(&time).unwrap()).unwrap();
assert_eq!(copy, time);
}

You can also declare constants of Instant<Unit, Repr> using new function:

use phantom_newtype::Instant;

enum SecondsFromEpoch {}
type UnixTime = Instant<SecondsFromEpoch, u64>;

const EPOCH: UnixTime = UnixTime::new(0);

Instants can be sent between threads if the Repr allows it, no matter which Unit is used.

use phantom_newtype::Instant;

type Cell = std::cell::RefCell<i64>;
type CellInstant = Instant<Cell, i64>;
const I: CellInstant = CellInstant::new(1234);

let instant_from_thread = std::thread::spawn(|| &I).join().unwrap();
assert_eq!(I, *instant_from_thread);

Methods

impl<Unit, Repr: Copy> Instant<Unit, Repr>[src]

pub fn get(&self) -> Repr[src]

Returns the wrapped value.

use phantom_newtype::Instant;

enum Apples {}

let three_apples = Instant::<Apples, u64>::from(3);
assert_eq!(9, (three_apples * 3).get());

impl<Unit, Repr> Instant<Unit, Repr>[src]

pub const fn new(repr: Repr) -> Instant<Unit, Repr>[src]

new is a synonym for from that can be evaluated in compile time. The main use-case of this functions is defining constants.

impl<Unit: Default, Repr: Copy> Instant<Unit, Repr>[src]

pub fn unit(&self) -> Unit[src]

Provides a useful shortcut to access units of an instant if they implement the Default trait:

use phantom_newtype::Instant;

#[derive(Debug, Default)]
struct SecondsFromEpoch;
let when = Instant::<SecondsFromEpoch, i64>::from(5);

assert_eq!("5 SecondsFromEpoch", format!("{} {:?}", when, when.unit()));

impl<Unit, Repr> Instant<Unit, Repr> where
    Unit: DisplayerOf<Instant<Unit, Repr>>, 
[src]

pub fn display(&self) -> DisplayProxy<Self, Unit>[src]

display provides a machanism to implement a custom display for phantom types.

use phantom_newtype::{Instant, DisplayerOf};
use std::fmt;

struct YearUnit;
type YearAD = Instant<YearUnit, u64>;

impl DisplayerOf<YearAD> for YearUnit {
  fn display(year: &YearAD, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    write!(f, "{} AD", year.get())
  }
}

assert_eq!(format!("{}", YearAD::from(1221).display()), "1221 AD");

Trait Implementations

impl<Unit, Repr: Copy> From<Repr> for Instant<Unit, Repr>[src]

impl<Unit, Repr: Copy> Clone for Instant<Unit, Repr>[src]

impl<Unit, Repr: Copy> Copy for Instant<Unit, Repr>[src]

impl<Unit, Repr: Eq> Eq for Instant<Unit, Repr>[src]

impl<Unit, Repr: Ord> Ord for Instant<Unit, Repr>[src]

impl<Unit, Repr: PartialEq> PartialEq<Instant<Unit, Repr>> for Instant<Unit, Repr>[src]

impl<Unit, Repr: PartialOrd> PartialOrd<Instant<Unit, Repr>> for Instant<Unit, Repr>[src]

impl<Unit, Repr> Display for Instant<Unit, Repr> where
    Repr: Display
[src]

impl<Unit, Repr> Debug for Instant<Unit, Repr> where
    Repr: Debug
[src]

impl<Unit, Repr> Div<Instant<Unit, Repr>> for Instant<Unit, Repr> where
    Repr: Div<Repr> + Copy
[src]

type Output = <Repr as Div>::Output

The resulting type after applying the / operator.

impl<Unit, Repr> Sub<Instant<Unit, Repr>> for Instant<Unit, Repr> where
    Repr: Sub + Copy
[src]

type Output = Amount<Unit, <Repr as Sub>::Output>

The resulting type after applying the - operator.

impl<Unit, Repr, Repr2> Sub<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
    Repr: SubAssign<Repr2> + Copy,
    Repr2: Copy
[src]

type Output = Self

The resulting type after applying the - operator.

impl<Unit, Repr, Repr2> Add<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
    Repr: AddAssign<Repr2> + Copy,
    Repr2: Copy
[src]

type Output = Self

The resulting type after applying the + operator.

impl<Unit, Repr> Mul<Repr> for Instant<Unit, Repr> where
    Repr: MulAssign + Copy
[src]

type Output = Self

The resulting type after applying the * operator.

impl<Unit, Repr, Repr2> AddAssign<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
    Repr: AddAssign<Repr2> + Copy,
    Repr2: Copy
[src]

impl<Unit, Repr, Repr2> SubAssign<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
    Repr: SubAssign<Repr2> + Copy,
    Repr2: Copy
[src]

impl<Unit, Repr> MulAssign<Repr> for Instant<Unit, Repr> where
    Repr: MulAssign + Copy
[src]

impl<Unit, Repr: Hash> Hash for Instant<Unit, Repr>[src]

impl<Unit, Repr: Serialize> Serialize for Instant<Unit, Repr>[src]

impl<'de, Unit, Repr> Deserialize<'de> for Instant<Unit, Repr> where
    Repr: Deserialize<'de>, 
[src]

Auto Trait Implementations

impl<Unit, Repr> Send for Instant<Unit, Repr> where
    Repr: Send,
    Unit: Send

impl<Unit, Repr> Sync for Instant<Unit, Repr> where
    Repr: Sync,
    Unit: Send

impl<Unit, Repr> Unpin for Instant<Unit, Repr> where
    Repr: Unpin,
    Unit: Unpin

impl<Unit, Repr> UnwindSafe for Instant<Unit, Repr> where
    Repr: UnwindSafe

impl<Unit, Repr> RefUnwindSafe for Instant<Unit, Repr> where
    Repr: RefUnwindSafe

Blanket Implementations

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> From<T> for T[src]

impl<T> From<!> for T[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> DeserializeOwned for T where
    T: Deserialize<'de>, 
[src]