eventful-test-shared 0.1.0-alpha.0

A library for event sourcing in Rust
Documentation
use eventful::{DefaultWithPersistenceId, Effect, EntityName, EntityWrapperTrait, EventName, EventSourcedEntity, EventWrapperTrait, NamedEntity};
use serde::{Deserialize, Serialize};
use strum::IntoStaticStr;

#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, IntoStaticStr)]
pub enum FrogEvent {
    Hopped { distance_mm: u32 },
    Swam { distance_mm: u32 },
    Ate,
}

#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, IntoStaticStr)]
pub enum CatEvent {
    Created,
    Ran { distance_mm: u32 },
    Ate,
    Purred,
}

#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq)]
pub enum AnimalEvents {
    FrogEvents(FrogEvent),
    CatEvents(CatEvent),
}

impl From<CatEvent> for AnimalEvents {
    fn from(value: CatEvent) -> Self {
        AnimalEvents::CatEvents(value)
    }
}

impl From<AnimalEvents> for Option<CatEvent> {
    fn from(value: AnimalEvents) -> Self {
        match value {
            AnimalEvents::CatEvents(e) => Some(e),
            _ => None,
        }
    }
}

impl EventName for AnimalEvents {
    fn event_name(&self) -> &'static str {
        match self {
            AnimalEvents::FrogEvents(e) => e.into(),
            AnimalEvents::CatEvents(e) => e.into(),
        }
    }
}

impl EntityName for AnimalEvents {
    fn entity_name(&self) -> &'static str {
        match self {
            AnimalEvents::FrogEvents(_) => "frog",
            AnimalEvents::CatEvents(_) => "cat",
        }
    }
}

impl EventWrapperTrait for AnimalEvents {}

#[derive(Clone, Debug)]
pub struct FrogModel {
    pub name: String,
    pub hopped_distance_mm: u32,
    pub swam_distance_mm: u32,
    pub eat_count: u32,
}

impl NamedEntity for FrogModel {
    fn entity_name() -> &'static str {
        "FrogModel"
    }
}

#[derive(Debug)]
pub enum CatCommand {
    Create,
    Run { distance_mm: u32 },
}

#[derive(Clone, Debug, PartialEq)]
pub struct CatModel {
    pub name: String,
    pub ran_distance_mm: u32,
    pub eat_count: u32,
    pub purr_count: u32,
}

impl DefaultWithPersistenceId for CatModel {
    fn default_with_persistence_id(persistence_id: &str) -> Self {
        Self {
            name: persistence_id.to_string(),
            ran_distance_mm: 0,
            eat_count: 0,
            purr_count: 0,
        }
    }
}

impl EventSourcedEntity for CatModel {
    type Command = CatCommand;
    type Event = CatEvent;

    fn persistence_id(&self) -> String {
        self.name.clone()
    }

    fn process_command(&self, command: Self::Command) -> Effect<Self::Event> {
        match command {
            CatCommand::Create => {
                let events = vec![];
                Effect::StoreEvents(events)
            }
            CatCommand::Run { distance_mm: _ } => {
                let events = vec![];
                Effect::StoreEvents(events)
            }
        }
    }

    fn consume_event(&mut self, event: Self::Event) {
        match event {
            CatEvent::Created => {
                self.name = self.persistence_id();
            }
            CatEvent::Ran { distance_mm } => {
                self.ran_distance_mm += distance_mm;
            }
            CatEvent::Ate => {
                self.eat_count += 1;
            }
            CatEvent::Purred => {
                self.purr_count += 1;
            }
        }
    }
}

impl From<AnimalEntityWrapper> for Option<CatModel> {
    fn from(value: AnimalEntityWrapper) -> Self {
        match value {
            AnimalEntityWrapper::Cat(v) => Some(v),
            _ => None,
        }
    }
}

impl From<CatModel> for AnimalEntityWrapper {
    fn from(value: CatModel) -> Self {
        AnimalEntityWrapper::Cat(value)
    }
}

impl NamedEntity for CatModel {
    fn entity_name() -> &'static str {
        "CatModel"
    }
}

#[derive(Clone, Debug)]
pub enum AnimalEntityWrapper {
    Frog(FrogModel),
    Cat(CatModel),
}

impl EntityName for AnimalEntityWrapper {
    fn entity_name(&self) -> &'static str {
        match self {
            AnimalEntityWrapper::Cat(_) => CatModel::entity_name(),
            AnimalEntityWrapper::Frog(_) => FrogModel::entity_name(),
        }
    }
}

impl EntityWrapperTrait for AnimalEntityWrapper {}