distributed/domain_event/
descriptor.rs1use std::borrow::Cow;
2use std::fmt;
3
4use serde::{Deserialize, Serialize};
5
6use super::{DOMAIN_EVENT_BODY_CODEC, DOMAIN_EVENT_BODY_CODEC_VERSION};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum DomainEventBodyKind {
12 State,
14 Event,
16 Deletion,
18}
19
20#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
22pub struct DomainEventBodyDescriptor {
23 pub kind: DomainEventBodyKind,
25 pub type_name: Cow<'static, str>,
27 pub version: u64,
29 pub schema: Cow<'static, str>,
31 pub fingerprint: Cow<'static, str>,
33 pub codec: Cow<'static, str>,
35 pub codec_version: u16,
37}
38
39impl DomainEventBodyDescriptor {
40 pub const fn distributed_json(
42 kind: DomainEventBodyKind,
43 type_name: &'static str,
44 version: u64,
45 schema: &'static str,
46 fingerprint: &'static str,
47 ) -> Self {
48 Self {
49 kind,
50 type_name: Cow::Borrowed(type_name),
51 version,
52 schema: Cow::Borrowed(schema),
53 fingerprint: Cow::Borrowed(fingerprint),
54 codec: Cow::Borrowed(DOMAIN_EVENT_BODY_CODEC),
55 codec_version: DOMAIN_EVENT_BODY_CODEC_VERSION,
56 }
57 }
58}
59
60#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
62pub struct DomainStateDescriptor {
63 pub type_name: Cow<'static, str>,
65 pub version: u64,
67 pub schema: Cow<'static, str>,
69 pub fingerprint: Cow<'static, str>,
71 pub codec: Cow<'static, str>,
73 pub codec_version: u16,
75}
76
77impl DomainStateDescriptor {
78 pub const fn distributed_json(
80 type_name: &'static str,
81 version: u64,
82 schema: &'static str,
83 fingerprint: &'static str,
84 ) -> Self {
85 Self {
86 type_name: Cow::Borrowed(type_name),
87 version,
88 schema: Cow::Borrowed(schema),
89 fingerprint: Cow::Borrowed(fingerprint),
90 codec: Cow::Borrowed(DOMAIN_EVENT_BODY_CODEC),
91 codec_version: DOMAIN_EVENT_BODY_CODEC_VERSION,
92 }
93 }
94
95 pub fn event(self, name: impl Into<Cow<'static, str>>, version: u64) -> DomainEventDescriptor {
97 DomainEventDescriptor {
98 name: name.into(),
99 version,
100 body: self.into(),
101 }
102 }
103}
104
105impl From<DomainStateDescriptor> for DomainEventBodyDescriptor {
106 fn from(state: DomainStateDescriptor) -> Self {
107 Self {
108 kind: DomainEventBodyKind::State,
109 type_name: state.type_name,
110 version: state.version,
111 schema: state.schema,
112 fingerprint: state.fingerprint,
113 codec: state.codec,
114 codec_version: state.codec_version,
115 }
116 }
117}
118
119#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
121pub struct DomainEventDescriptor {
122 pub name: Cow<'static, str>,
124 pub version: u64,
126 pub body: DomainEventBodyDescriptor,
128}
129
130impl DomainEventDescriptor {
131 pub fn state<S: DomainState>(name: impl Into<Cow<'static, str>>, version: u64) -> Self {
133 S::DESCRIPTOR.clone().event(name, version)
134 }
135}
136
137pub trait DomainState: Serialize {
143 const DESCRIPTOR: DomainStateDescriptor;
145}
146
147pub trait DomainEvent: Serialize {
149 const DESCRIPTOR: DomainEventDescriptor;
151}
152
153#[doc(hidden)]
159pub trait DomainEventContract {
160 const EVENT_NAME: &'static str;
162
163 const EVENT_VERSION: u64;
165
166 fn descriptor() -> DomainEventDescriptor;
168}
169
170#[doc(hidden)]
175pub trait DomainEventBodyContract<B: Serialize>: DomainEventContract {}
176
177#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
179pub struct DomainDeletion<K> {
180 pub key: K,
182 pub incarnation: u64,
184}
185
186impl<K> DomainDeletion<K> {
187 pub fn new(key: K, incarnation: u64) -> Result<Self, DomainDeletionError> {
193 if incarnation == 0 {
194 return Err(DomainDeletionError);
195 }
196 Ok(Self { key, incarnation })
197 }
198}
199
200#[derive(Clone, Copy, Debug, PartialEq, Eq)]
202pub struct DomainDeletionError;
203
204impl fmt::Display for DomainDeletionError {
205 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
206 formatter.write_str("domain deletion incarnation must be non-zero")
207 }
208}
209
210impl std::error::Error for DomainDeletionError {}