ready-active-safe 0.1.3

Lifecycle engine for externally driven systems
Documentation
# Clock

*Requires feature `time`.*

A source of monotonic time for lifecycles.

A clock returns the current [`Instant`](instant.md). The meaning of "now"
depends on the implementation:

- [`ManualClock`]manual_clock.md — deterministic, controlled by tests
- [`SystemClock`]system_clock.md — monotonic wall time (requires `std`)

## The Trait

```rust
use ready_active_safe::time::{Clock, Instant, ManualClock};

let clock = ManualClock::new(Instant::from_nanos(0));
let now = clock.now();
assert_eq!(now.as_nanos(), 0);
```

## Using a Clock with Events

Time composes via events. Encode time into your event type and let the
machine inspect it:

```rust
use ready_active_safe::prelude::*;
use ready_active_safe::time::{Clock, Instant, ManualClock, Deadline};
use std::time::Duration;

#[derive(Debug, Clone, PartialEq, Eq)]
enum Mode { Active, TimedOut }

#[derive(Debug)]
enum Event { Tick(Instant) }

struct TimedSystem { deadline: Deadline }

impl Machine for TimedSystem {
    type Mode = Mode;
    type Event = Event;
    type Command = ();

    fn initial_mode(&self) -> Mode { Mode::Active }

    fn on_event(&self, mode: &Mode, event: &Event) -> Decision<Mode, ()> {
        match (mode, event) {
            (Mode::Active, Event::Tick(now)) if self.deadline.is_expired(*now) => {
                transition(Mode::TimedOut)
            }
            _ => stay(),
        }
    }
}

let clock = ManualClock::new(Instant::from_nanos(0));
let deadline = Deadline::at(Instant::from_nanos(1_000_000_000));
let system = TimedSystem { deadline };

// Before deadline
let d = system.decide(&Mode::Active, &Event::Tick(clock.now()));
assert!(d.is_stay());

// After deadline
clock.advance(Duration::from_secs(2));
let d = system.decide(&Mode::Active, &Event::Tick(clock.now()));
assert_eq!(d.target_mode(), Some(&Mode::TimedOut));
```

## See Also

- [`Instant`]instant.md — the value returned by `now()`
- [`Deadline`]deadline.md — an expiration point
- [`ManualClock`]manual_clock.md — test-friendly clock
- [`SystemClock`]system_clock.md — production clock