use crate::typings::{self, CRUD};
use std::time;
pub struct Projector<T: Clone + PartialEq> {
pub event_log: Vec<typings::Event<T>>,
pub projection: Vec<T>,
}
impl<T: Clone + PartialEq> Projector<T> {
pub fn new(event_log: Vec<typings::Event<T>>) -> Projector<T> {
Projector {
projection: Self::project_all(&event_log),
event_log,
}
}
pub fn add_event(&mut self, event: typings::Event<T>) {
Self::project_one(&mut self.projection, &event);
self.event_log.push(event);
}
pub fn project_at(&self, at: &time::Instant) -> Vec<T> {
let mut list: Vec<T> = Vec::new();
self.event_log
.iter()
.take_while(|event| &event.date <= at)
.for_each(|event| Self::project_one(&mut list, &event));
list
}
fn project_all(event_log: &Vec<typings::Event<T>>) -> Vec<T> {
let mut list: Vec<T> = Vec::new();
event_log
.iter()
.for_each(|event| Self::project_one(&mut list, &event));
list
}
fn project_one(list: &mut Vec<T>, event: &typings::Event<T>) {
let maybe_i = list.iter().position(|el| el == &event.data);
match event.operation {
CRUD::Create => {
if let Some(_) = maybe_i {
} else {
list.push(event.data.clone());
}
}
CRUD::Update => {
if let Some(i) = maybe_i {
list.splice(i..i, vec![event.data.clone()]);
} else {
}
}
CRUD::Delete => {
if let Some(i) = maybe_i {
list.splice(i..i, vec![]);
} else {
}
}
};
}
}