Struct timemachine::TimeMachine[][src]

pub struct TimeMachine<S: Clone> { /* fields omitted */ }

A time-based mod 24(*60*60) state machine.

State transitions are added with add_transition, and you can get the state at a given time with get_state.

If your state type implements Default, you can also use get_state_or_default and map_states_or_default.

If the crate feature napchart is enabled, you can also use from_napchart.

Implementations

impl<S: Clone> TimeMachine<S>[src]

pub fn new() -> Self[src]

Creates a new, empty timemachine.

Hypothetically you can call TimeMachine::default() but the compiler gets mad if your state type doesn’t also implement default.

use timemachine::TimeMachine;
use timemachine::Time;
use timemachine::ErrorKind;

let mut tm: TimeMachine<i32> = TimeMachine::new();

assert_eq!(tm.get_state(&Time::midnight()), Err(ErrorKind::EmptyTimeMachine));

pub fn map_states<F, R>(self, mapfn: F) -> TimeMachine<R> where
    F: Fn(S) -> R,
    R: Clone
[src]

Maps a TimeMachine<S> into a TimeMachine<R> with a mapping function.

use timemachine::TimeMachine;
use timemachine::Time;

let mut tm: TimeMachine<i32> = TimeMachine::new();
// Adds a transition to state `-50` at midnight.
tm.add_transition(Time::midnight(), -50);
// Adds a transition to state `73` at 6AM.
tm.add_transition(Time::new_h(6), 73);
// Adds a transition to state `25` at noon.
tm.add_transition(Time::noon(), 25);
// Adds a transition to state `-37` at 6PM.
tm.add_transition(Time::new_h(18), -37);

// Map the TimeMachine<i32> to a TimeMachine<bool> by mapping
// positive values to true and negative values to false
let mut tm: TimeMachine<bool> = tm.map_states(|s| s >= 0);

assert_eq!(tm.get_state(&Time::new_h(1)).unwrap(), false);
assert_eq!(tm.get_state(&Time::new_h(7)).unwrap(), true);
assert_eq!(tm.get_state(&Time::new_h(13)).unwrap(), true);
assert_eq!(tm.get_state(&Time::new_h(19)).unwrap(), false);

pub fn add_transition(&mut self, time: Time, state: S)[src]

Adds a transition to the given state at the given time to the timemachine.

use timemachine::TimeMachine;
use timemachine::Time;

let mut tm: TimeMachine<bool> = TimeMachine::new();
// Adds a transition to state `false` at midnight.
tm.add_transition(Time::midnight(), false);
// Adds a transition to state `true` at noon.
tm.add_transition(Time::noon(), true);
assert_eq!(tm.get_state(&Time::new_h(6)).unwrap(), false);
assert_eq!(tm.get_state(&Time::new_h(18)).unwrap(), true);

pub fn get_state(&self, time: &Time) -> Result<S, ErrorKind>[src]

Returns the state that the timemachine is in at the given time.

use timemachine::TimeMachine;
use timemachine::Time;

let mut tm: TimeMachine<bool> = TimeMachine::new();
tm.add_transition(Time::midnight(), false);
tm.add_transition(Time::noon(), true);

let state_3am = tm.get_state(&Time::new_h(3)).unwrap();
assert_eq!(state_3am, false);

let state_6am = tm.get_state(&Time::new_h(6)).unwrap();
assert_eq!(state_6am, false);

let state_6pm = tm.get_state(&Time::new_h(18)).unwrap();
assert_eq!(state_6pm, true);

let state_9pm = tm.get_state(&Time::new_h(21)).unwrap();
assert_eq!(state_9pm, true);

pub fn get_state_progress(&self, _time: &Time) -> Result<(S, f64, S), ErrorKind>[src]

Returns a tuple of the current state, the progress through the current state, and the next state. This is useful for things like interpolating a value between two states.

use timemachine::TimeMachine;
use timemachine::Time;

let mut tm: TimeMachine<bool> = TimeMachine::new();
tm.add_transition(Time::midnight(), false);
tm.add_transition(Time::noon(), true);

// At 3AM, our current state is false, we are 25% through the current state,
// and our next state is true
let progress_3am = tm.get_state_progress(&Time::new_h(3)).unwrap();
assert_eq!(progress_3am, (false, 0.25f64, true));

// At 6AM, our current state is false, we are 50% through the current state,
// and our next state is true
let progress_6am = tm.get_state_progress(&Time::new_h(6)).unwrap();
assert_eq!(progress_6am, (false, 0.5f64, true));

// At 6PM, our current state is true, we are 50% through the current state,
// and our next state is false
let progress_6pm = tm.get_state_progress(&Time::new_h(18)).unwrap();
assert_eq!(progress_6pm, (true, 0.5f64, false));

// At 9PM, our current state is true, we are 75% through the current state,
// and our next state is false
let progress_9pm = tm.get_state_progress(&Time::new_h(21)).unwrap();
assert_eq!(progress_9pm, (true, 0.75f64, false));

impl<S: Clone + Default> TimeMachine<S>[src]

Extra functions if your state type implements Default

pub fn map_states_or_default<F, R>(self, mapfn: F) -> TimeMachine<R> where
    F: Fn(S) -> Option<R>,
    R: Clone + Default
[src]

Maps a TimeMachine<S> into a TimeMachine<R: Default> with a mapping function.

If the mapping function returns Some, the state is set to that value. If the mapping function returns None, the state is set to default().

use timemachine::TimeMachine;
use timemachine::Time;
use std::convert::TryInto;

let mut tm: TimeMachine<i8> = TimeMachine::new();
// Adds a transition to state `-50` at midnight.
tm.add_transition(Time::midnight(), -50);
// Adds a transition to state `73` at 6AM.
tm.add_transition(Time::new_h(6), 73);
// Adds a transition to state `25` at noon.
tm.add_transition(Time::noon(), 25);
// Adds a transition to state `-37` at 6PM.
tm.add_transition(Time::new_h(18), -37);

// Map the TimeMachine<i8> to a TimeMachine<u8> by mapping
// positive values to themselves and negative values to default
let mut tm: TimeMachine<u8> = tm.map_states_or_default(|s| s.try_into().ok());

assert_eq!(tm.get_state(&Time::new_h(1)).unwrap(), 0);
assert_eq!(tm.get_state(&Time::new_h(7)).unwrap(), 73);
assert_eq!(tm.get_state(&Time::new_h(13)).unwrap(), 25);
assert_eq!(tm.get_state(&Time::new_h(19)).unwrap(), 0);

pub fn get_state_or_default(&self, time: &Time) -> Result<S, ErrorKind>[src]

Returns the state that the timemachine is in at the given time. If the timemachine is empty, it will return S.default().

This method does not handle any errors except EmptyTimeMachine.

use timemachine::TimeMachine;
use timemachine::Time;
use timemachine::ErrorKind;

let mut tm: TimeMachine<i32> = TimeMachine::new();

assert_eq!(tm.get_state(&Time::midnight()), Err(ErrorKind::EmptyTimeMachine));
assert_eq!(tm.get_state_or_default(&Time::midnight()), Ok(0));

Trait Implementations

impl<S: Debug + Clone> Debug for TimeMachine<S>[src]

impl<S: Default + Clone> Default for TimeMachine<S>[src]

Auto Trait Implementations

impl<S> RefUnwindSafe for TimeMachine<S> where
    S: RefUnwindSafe

impl<S> Send for TimeMachine<S> where
    S: Send

impl<S> Sync for TimeMachine<S> where
    S: Sync

impl<S> Unpin for TimeMachine<S> where
    S: Unpin

impl<S> UnwindSafe for TimeMachine<S> where
    S: UnwindSafe

Blanket Implementations

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

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

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

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

impl<T, U> Into<U> for T where
    U: From<T>, 
[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.