es_entity/
macros.rs

1#[macro_export]
2macro_rules! idempotency_guard {
3    ($events:expr, $( $pattern:pat $(if $guard:expr)? ),+ $(,)?) => {
4        for event in $events {
5            match event {
6                $(
7                    $pattern $(if $guard)? => return $crate::FromIdempotentIgnored::from_ignored(),
8                )+
9                _ => {}
10            }
11        }
12    };
13    ($events:expr, $( $pattern:pat $(if $guard:expr)? ),+,
14     => $break_pattern:pat $(if $break_guard:expr)?) => {
15        for event in $events {
16            match event {
17                $($pattern $(if $guard)? => return $crate::FromIdempotentIgnored::from_ignored(),)+
18                $break_pattern $(if $break_guard)? => break,
19                _ => {}
20            }
21        }
22    };
23}
24
25#[macro_export]
26macro_rules! es_query {
27    ($prefix:literal, $db:expr, $query:expr) => ({
28        $crate::expand_es_query!(
29            ignore_prefix = $prefix,
30            executor = $db,
31            sql = $query
32        )
33    });
34    ($prefix:literal, $db:expr, $query:expr, $($args:tt)*) => ({
35        $crate::expand_es_query!(
36            ignore_prefix = $prefix,
37            executor = $db,
38            sql = $query,
39            args = [$($args)*]
40        )
41    });
42    ($db:expr, $query:expr) => ({
43        $crate::expand_es_query!(
44            executor = $db,
45            sql = $query
46        )
47    });
48    ($db:expr, $query:expr, $($args:tt)*) => ({
49        $crate::expand_es_query!(
50            executor = $db,
51            sql = $query,
52            args = [$($args)*]
53        )
54    });
55}
56
57#[macro_export]
58macro_rules! from_es_entity_error {
59    ($name:ident) => {
60        impl $name {
61            pub fn was_not_found(&self) -> bool {
62                matches!(self, $name::EsEntityError($crate::EsEntityError::NotFound))
63            }
64            pub fn was_concurrent_modification(&self) -> bool {
65                matches!(
66                    self,
67                    $name::EsEntityError($crate::EsEntityError::ConcurrentModification)
68                )
69            }
70        }
71        impl From<$crate::EsEntityError> for $name {
72            fn from(e: $crate::EsEntityError) -> Self {
73                $name::EsEntityError(e)
74            }
75        }
76    };
77}
78
79// Helper macro for common entity_id implementations (internal use only)
80#[doc(hidden)]
81#[macro_export]
82macro_rules! __entity_id_common_impls {
83    ($name:ident) => {
84        impl $name {
85            #[allow(clippy::new_without_default)]
86            pub fn new() -> Self {
87                $crate::prelude::uuid::Uuid::new_v4().into()
88            }
89        }
90
91        impl From<$crate::prelude::uuid::Uuid> for $name {
92            fn from(uuid: $crate::prelude::uuid::Uuid) -> Self {
93                Self(uuid)
94            }
95        }
96
97        impl From<$name> for $crate::prelude::uuid::Uuid {
98            fn from(id: $name) -> Self {
99                id.0
100            }
101        }
102
103        impl From<&$name> for $crate::prelude::uuid::Uuid {
104            fn from(id: &$name) -> Self {
105                id.0
106            }
107        }
108
109        impl std::fmt::Display for $name {
110            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111                write!(f, "{}", self.0)
112            }
113        }
114
115        impl std::str::FromStr for $name {
116            type Err = $crate::prelude::uuid::Error;
117
118            fn from_str(s: &str) -> Result<Self, Self::Err> {
119                Ok(Self($crate::prelude::uuid::Uuid::parse_str(s)?))
120            }
121        }
122    };
123}
124
125// Helper macro for GraphQL-specific entity_id implementations (internal use only)
126#[doc(hidden)]
127#[macro_export]
128macro_rules! __entity_id_graphql_impls {
129    ($name:ident) => {
130        impl From<$crate::graphql::UUID> for $name {
131            fn from(id: $crate::graphql::UUID) -> Self {
132                $name($crate::prelude::uuid::Uuid::from(&id))
133            }
134        }
135
136        impl From<&$crate::graphql::UUID> for $name {
137            fn from(id: &$crate::graphql::UUID) -> Self {
138                $name($crate::prelude::uuid::Uuid::from(id))
139            }
140        }
141    };
142}
143
144// Helper macro for additional conversions (internal use only)
145#[doc(hidden)]
146#[macro_export]
147macro_rules! __entity_id_conversions {
148    ($($from:ty => $to:ty),* $(,)?) => {
149        $(
150            impl From<$from> for $to {
151                fn from(id: $from) -> Self {
152                    <$to>::from($crate::prelude::uuid::Uuid::from(id))
153                }
154            }
155            impl From<$to> for $from {
156                fn from(id: $to) -> Self {
157                    <$from>::from($crate::prelude::uuid::Uuid::from(id))
158                }
159            }
160        )*
161    };
162}
163
164#[cfg(all(feature = "graphql", feature = "json-schema"))]
165#[macro_export]
166macro_rules! entity_id {
167    // Match identifiers without conversions
168    ($($name:ident),+ $(,)?) => {
169        $crate::entity_id! { $($name),+ ; }
170    };
171    ($($name:ident),+ $(,)? ; $($from:ty => $to:ty),* $(,)?) => {
172        $(
173            #[derive(
174                $crate::prelude::sqlx::Type,
175                Debug,
176                Clone,
177                Copy,
178                PartialEq,
179                Eq,
180                PartialOrd,
181                Ord,
182                Hash,
183                $crate::prelude::serde::Deserialize,
184                $crate::prelude::serde::Serialize,
185                $crate::prelude::schemars::JsonSchema,
186            )]
187            #[serde(transparent)]
188            #[sqlx(transparent)]
189            pub struct $name($crate::prelude::uuid::Uuid);
190            $crate::__entity_id_common_impls!($name);
191            $crate::__entity_id_graphql_impls!($name);
192        )+
193        $crate::__entity_id_conversions!($($from => $to),*);
194    };
195}
196
197#[cfg(all(feature = "graphql", not(feature = "json-schema")))]
198#[macro_export]
199macro_rules! entity_id {
200    // Match identifiers without conversions
201    ($($name:ident),+ $(,)?) => {
202        $crate::entity_id! { $($name),+ ; }
203    };
204    ($($name:ident),+ $(,)? ; $($from:ty => $to:ty),* $(,)?) => {
205        $(
206            #[derive(
207                $crate::prelude::sqlx::Type,
208                Debug,
209                Clone,
210                Copy,
211                PartialEq,
212                Eq,
213                PartialOrd,
214                Ord,
215                Hash,
216                $crate::prelude::serde::Deserialize,
217                $crate::prelude::serde::Serialize,
218            )]
219            #[serde(transparent)]
220            #[sqlx(transparent)]
221            pub struct $name($crate::prelude::uuid::Uuid);
222            $crate::__entity_id_common_impls!($name);
223            $crate::__entity_id_graphql_impls!($name);
224        )+
225        $crate::__entity_id_conversions!($($from => $to),*);
226    };
227}
228
229#[cfg(all(feature = "json-schema", not(feature = "graphql")))]
230#[macro_export]
231macro_rules! entity_id {
232    // Match identifiers without conversions
233    ($($name:ident),+ $(,)?) => {
234        $crate::entity_id! { $($name),+ ; }
235    };
236    ($($name:ident),+ $(,)? ; $($from:ty => $to:ty),* $(,)?) => {
237        $(
238            #[derive(
239                $crate::prelude::sqlx::Type,
240                Debug,
241                Clone,
242                Copy,
243                PartialEq,
244                Eq,
245                PartialOrd,
246                Ord,
247                Hash,
248                $crate::prelude::serde::Deserialize,
249                $crate::prelude::serde::Serialize,
250                $crate::prelude::schemars::JsonSchema,
251            )]
252            #[serde(transparent)]
253            #[sqlx(transparent)]
254            pub struct $name($crate::prelude::uuid::Uuid);
255            $crate::__entity_id_common_impls!($name);
256        )+
257        $crate::__entity_id_conversions!($($from => $to),*);
258    };
259}
260
261#[cfg(all(not(feature = "json-schema"), not(feature = "graphql")))]
262#[macro_export]
263macro_rules! entity_id {
264    // Match identifiers without conversions
265    ($($name:ident),+ $(,)?) => {
266        $crate::entity_id! { $($name),+ ; }
267    };
268    ($($name:ident),+ $(,)? ; $($from:ty => $to:ty),* $(,)?) => {
269        $(
270            #[derive(
271                $crate::prelude::sqlx::Type,
272                Debug,
273                Clone,
274                Copy,
275                PartialEq,
276                Eq,
277                PartialOrd,
278                Ord,
279                Hash,
280                $crate::prelude::serde::Deserialize,
281                $crate::prelude::serde::Serialize,
282            )]
283            #[serde(transparent)]
284            #[sqlx(transparent)]
285            pub struct $name($crate::prelude::uuid::Uuid);
286            $crate::__entity_id_common_impls!($name);
287        )+
288        $crate::__entity_id_conversions!($($from => $to),*);
289    };
290}