#![allow(dead_code)] use chrono::{DateTime, Utc}; use minicbor::{Decode, Encode}; use thiserror::Error; use timesource::{Aggregate, TimesourceEvent}; use uuid::Uuid; #[derive(Debug, Clone, PartialEq, Eq)] pub struct UserState { pub name: Option, pub surname: Option, } #[derive(Debug)] pub enum UserCommand { Create, SetName { name: String, surname: Option, }, } #[derive(Debug, Clone, PartialEq, Eq, TimesourceEvent, Decode, Encode)] #[timesource(encoding = "cbor")] pub enum UserEvent { #[b(0)] Created, #[b(1)] NameChanged { #[b(0)] name: String, #[b(2)] surname: Option, }, } #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum UserError { #[error("Already created")] AlreadyCreated, #[error("Not yet created")] NotYetCreated, } #[derive(Debug, Default, Clone, Copy)] pub struct UserAggregate; impl Aggregate for UserAggregate { type State = UserState; type Event = UserEvent; type Command = UserCommand; type Error = UserError; fn apply_first( _: Uuid, event: &Self::Event, _: DateTime, _event_id: Option, ) -> Result { if let UserEvent::Created = event { return Ok(UserState { name: None, surname: None, }); } Err(UserError::NotYetCreated) } fn apply_next( state: &mut Self::State, event: &Self::Event, _: DateTime, _event_id: Option, ) -> Result<(), Self::Error> { match event { UserEvent::Created { .. } => Err(UserError::AlreadyCreated), UserEvent::NameChanged { name, surname } => { state.name = Some(name.clone()); state.surname = surname.clone(); Ok(()) } } } fn handle_first(command: Self::Command) -> Result, Self::Error> { if let UserCommand::Create = command { return Ok(vec![UserEvent::Created]); } Err(UserError::NotYetCreated) } fn handle_next( _state: &Self::State, command: Self::Command, ) -> Result, Self::Error> { match command { UserCommand::Create => Err(UserError::AlreadyCreated), UserCommand::SetName { name, surname } => { Ok(vec![UserEvent::NameChanged { name, surname }]) } } } }