eventuary-core 0.1.0

Core event model and async IO traits for eventuary
Documentation
use serde::Serialize;
use serde::de::DeserializeOwned;

use crate::Payload;
use crate::error::Result;
use crate::event::EventId;

pub trait Snapshot: Sized {
    fn take_snapshot(&self) -> Result<Payload>;
    fn from_snapshot(payload: &Payload) -> Result<Self>;
    fn snapshot_event_id(&self) -> EventId;
}

pub trait SnapshotEventId {
    fn snapshot_event_id(&self) -> EventId;
}

impl<T: Serialize + DeserializeOwned + SnapshotEventId> Snapshot for T {
    fn take_snapshot(&self) -> Result<Payload> {
        Payload::from_json(self)
    }

    fn from_snapshot(payload: &Payload) -> Result<Self> {
        payload.to_json()
    }

    fn snapshot_event_id(&self) -> EventId {
        SnapshotEventId::snapshot_event_id(self)
    }
}

#[cfg(test)]
mod tests {
    use std::str::FromStr;

    use super::*;

    use serde::Deserialize;

    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
    struct Counter {
        last_event: String,
        value: u64,
    }

    impl SnapshotEventId for Counter {
        fn snapshot_event_id(&self) -> EventId {
            EventId::from_str(&self.last_event).unwrap()
        }
    }

    #[test]
    fn snapshot_roundtrip() {
        let event_id = EventId::new();
        let counter = Counter {
            last_event: event_id.to_string(),
            value: 42,
        };
        let payload = counter.take_snapshot().unwrap();
        let restored: Counter = Counter::from_snapshot(&payload).unwrap();
        assert_eq!(restored, counter);
        assert_eq!(Snapshot::snapshot_event_id(&restored), event_id);
    }
}