event_driven_core/
message.rs

1use crate::prelude::OutBox;
2use downcast_rs::{impl_downcast, Downcast};
3use serde::Serialize;
4use serde_json::Value;
5use std::{any::Any, collections::VecDeque, fmt::Debug};
6
7pub trait Message: Sync + Send + Any + Downcast {
8	fn externally_notifiable(&self) -> bool {
9		false
10	}
11	fn internally_notifiable(&self) -> bool {
12		false
13	}
14
15	fn metadata(&self) -> MessageMetadata;
16	fn outbox(&self) -> OutBox {
17		let metadata = self.metadata();
18		OutBox::new(metadata.aggregate_id, metadata.topic, self.state())
19	}
20	fn message_clone(&self) -> Box<dyn Message>;
21
22	fn state(&self) -> String;
23
24	fn to_message(self) -> Box<dyn Message + 'static>;
25}
26
27impl_downcast!(Message);
28impl Debug for dyn Message {
29	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30		write!(f, "{}", self.metadata().topic)
31	}
32}
33
34pub struct MessageMetadata {
35	pub aggregate_id: String,
36	pub topic: String,
37}
38
39// Trait To Mark Event As Mail Sendable. Note that template_name must be specified.
40pub trait MailSendable: Message + Serialize + Send + Sync + 'static {
41	fn template_name(&self) -> String;
42	fn to_json(&self) -> Value {
43		serde_json::to_value(self).unwrap()
44	}
45}
46
47pub trait Command: 'static + Send + Any + Sync + Debug {}
48
49pub trait Aggregate: Send + Sync + Default {
50	fn collect_events(&mut self) -> VecDeque<Box<dyn Message>> {
51		if !self.events().is_empty() {
52			self.take_events()
53		} else {
54			VecDeque::new()
55		}
56	}
57	fn events(&self) -> &std::collections::VecDeque<Box<dyn Message>>;
58
59	fn take_events(&mut self) -> std::collections::VecDeque<Box<dyn Message>>;
60	fn raise_event(&mut self, event: Box<dyn Message>);
61}