event-simulation 0.2.2

A library for event based simulation of application state
Documentation
use std::{convert::Infallible, ops::Range};

use event_simulation::{MultiSimulation, SimulationInfo};

struct Counter;

impl SimulationInfo for Counter {
    type State = usize;
    type StateLoadingError = Infallible;
    type AccessData = usize;
    type LoadData = usize;
    type Event = usize;
    type EventContainer<'a> = Range<usize>;

    fn default_state(&self) -> usize {
        0
    }

    fn load_state(&self, data: usize) -> Result<usize, Infallible> {
        Ok(data)
    }

    unsafe fn clone_state(&self, state: &usize) -> usize {
        *state
    }

    unsafe fn data<'a>(&self, state: &'a usize) -> &'a usize {
        state
    }

    fn callables(_state: &usize) -> Range<usize> {
        0..1
    }

    fn revertables(_state: &usize) -> Range<usize> {
        0..0
    }

    fn callable(_state: &usize, event: usize) -> bool {
        event == 0
    }

    fn revertable(_state: &usize, _event: usize) -> bool {
        false
    }

    unsafe fn call(&self, state: &mut usize, _event: usize) {
        *state += 1;
    }

    unsafe fn revert(&self, state: &mut usize, _event: usize) {
        *state -= 1;
    }
}

fn with_states(count: usize) -> MultiSimulation<Counter> {
    let mut simulation = MultiSimulation::<Counter>::new(Counter);
    for value in 0..count {
        simulation.add_simulation_from_data(value).unwrap();
    }
    simulation
}

#[test]
fn iter_size_hint_matches_yielded_count() {
    let simulation = with_states(3);
    let mut iter = simulation.iter();
    let mut remaining = 3;

    assert_eq!(iter.size_hint(), (remaining, Some(remaining)));
    assert_eq!(iter.len(), remaining);

    while iter.next().is_some() {
        remaining -= 1;
        assert_eq!(iter.size_hint(), (remaining, Some(remaining)));
        assert_eq!(iter.len(), remaining);
    }

    assert_eq!(remaining, 0);
}

#[test]
fn iter_mut_size_hint_matches_yielded_count() {
    let mut simulation = with_states(4);
    let mut iter = simulation.iter_mut();
    let mut remaining = 4;

    assert_eq!(iter.len(), remaining);

    while iter.next().is_some() {
        remaining -= 1;
        assert_eq!(iter.size_hint(), (remaining, Some(remaining)));
    }

    assert_eq!(remaining, 0);
}

#[test]
fn remove_simulation_shifts_later_indices_down() {
    let mut simulation = with_states(3);

    assert_eq!(simulation.remove_simulation(0), Some(0));
    assert_eq!(simulation.states(), &[1, 2]);

    assert_eq!(simulation.remove_simulation(1), Some(2));
    assert_eq!(simulation.states(), &[1]);
}

#[test]
fn remove_simulation_out_of_bounds_leaves_states_untouched() {
    let mut simulation = with_states(2);

    assert_eq!(simulation.remove_simulation(2), None);
    assert_eq!(simulation.remove_simulation(usize::MAX), None);
    assert_eq!(simulation.states(), &[0, 1]);
}