use crate::{
crdts::ValueType,
sentinel::{KeySentinel, Sentinel, TypeSentinel, ValueSentinel, Visit},
};
use std::{convert::Infallible, fmt::Debug};
#[derive(Default)]
pub struct RecordingSentinel {
path: Vec<String>,
pub changes_seen: Vec<String>,
}
impl RecordingSentinel {
pub fn new() -> RecordingSentinel {
RecordingSentinel {
path: vec![],
changes_seen: vec![],
}
}
}
impl Sentinel for RecordingSentinel {
type Error = Infallible;
}
impl<K: Debug> Visit<K> for RecordingSentinel {
fn enter(&mut self, key: &K) -> Result<(), Self::Error> {
self.path.push(format!("{key:?}"));
Ok(())
}
fn exit(&mut self) -> Result<(), Self::Error> {
self.path.pop();
Ok(())
}
}
impl KeySentinel for RecordingSentinel {
fn create_key(&mut self) -> Result<(), Self::Error> {
self.changes_seen
.push(format!("create_key at {}", self.path.join("/")));
Ok(())
}
fn delete_key(&mut self) -> Result<(), Self::Error> {
self.changes_seen
.push(format!("delete_key at {}", self.path.join("/")));
Ok(())
}
}
impl<V: Debug> ValueSentinel<V> for RecordingSentinel {
fn set(&mut self, value: &V) -> Result<(), Self::Error> {
self.changes_seen.push(format!("set {value:?}"));
Ok(())
}
fn unset(&mut self, value: V) -> Result<(), Self::Error> {
self.changes_seen.push(format!("unset {:?}", &value));
Ok(())
}
}
impl<V: Debug> TypeSentinel<V> for RecordingSentinel {
fn set_type(&mut self, value_type: ValueType<V>) -> Result<(), Self::Error> {
self.changes_seen.push(format!("set_type {value_type:?}"));
Ok(())
}
fn unset_type(&mut self, value_type: ValueType<V>) -> Result<(), Self::Error> {
self.changes_seen.push(format!("unset_type {value_type:?}"));
Ok(())
}
}