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]);
}