use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use super::parse::EntityDef;
use crate::utils::marker;
pub fn generate(entity: &EntityDef) -> TokenStream {
if !entity.has_events() {
return TokenStream::new();
}
let vis = &entity.vis;
let entity_name = entity.name();
let event_name = format_ident!("{}Event", entity_name);
let id_field = entity.id_field();
let id_type = id_field.ty();
let id_name = id_field.name();
let soft_delete_variants = if entity.is_soft_delete() {
quote! {
SoftDeleted {
id: #id_type,
},
Restored {
id: #id_type,
},
}
} else {
TokenStream::new()
};
let soft_delete_kind_arms = if entity.is_soft_delete() {
quote! {
Self::SoftDeleted { .. } => entity_core::EventKind::SoftDeleted,
Self::Restored { .. } => entity_core::EventKind::Restored,
}
} else {
TokenStream::new()
};
let soft_delete_id_arms = if entity.is_soft_delete() {
quote! {
Self::SoftDeleted { id } => id,
Self::Restored { id } => id,
}
} else {
TokenStream::new()
};
let marker = marker::generated();
let serde_derives = if entity.has_streams() {
quote! { , ::serde::Serialize, ::serde::Deserialize }
} else {
TokenStream::new()
};
quote! {
#marker
#[derive(Debug, Clone #serde_derives)]
#vis enum #event_name {
Created(#entity_name),
Updated {
old: #entity_name,
new: #entity_name,
},
HardDeleted {
id: #id_type,
},
#soft_delete_variants
}
impl #event_name {
pub fn created(entity: #entity_name) -> Self {
Self::Created(entity)
}
pub fn updated(old: #entity_name, new: #entity_name) -> Self {
Self::Updated { old, new }
}
pub fn hard_deleted(id: #id_type) -> Self {
Self::HardDeleted { id }
}
}
impl entity_core::EntityEvent for #event_name {
type Id = #id_type;
fn kind(&self) -> entity_core::EventKind {
match self {
Self::Created(_) => entity_core::EventKind::Created,
Self::Updated { .. } => entity_core::EventKind::Updated,
Self::HardDeleted { .. } => entity_core::EventKind::HardDeleted,
#soft_delete_kind_arms
}
}
fn entity_id(&self) -> &Self::Id {
match self {
Self::Created(e) => &e.#id_name,
Self::Updated { new, .. } => &new.#id_name,
Self::HardDeleted { id } => id,
#soft_delete_id_arms
}
}
}
}
}