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 {}