#![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<String>,
pub surname: Option<String>,
}
#[derive(Debug)]
pub enum UserCommand {
Create,
SetName {
name: String,
surname: Option<String>,
},
}
#[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<String>,
},
}
#[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<Utc>,
_event_id: Option<u64>,
) -> Result<Self::State, Self::Error> {
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<Utc>,
_event_id: Option<u64>,
) -> 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<Vec<Self::Event>, 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<Vec<Self::Event>, Self::Error> {
match command {
UserCommand::Create => Err(UserError::AlreadyCreated),
UserCommand::SetName { name, surname } => {
Ok(vec![UserEvent::NameChanged { name, surname }])
}
}
}
}