Skip to main content

looprs_core/
macros.rs

1/// Define a newtype wrapper around `String` with common trait impls.
2///
3/// Generates a struct with:
4/// - `new(impl Into<String>) -> Self`
5/// - `as_str() -> &str`
6/// - `Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize`
7/// - `#[serde(transparent)]`
8/// - `Display` (delegates to inner string)
9///
10/// # Example
11///
12/// ```
13/// use looprs_core::newtype_id;
14///
15/// newtype_id!(UserId);
16///
17/// let id = UserId::new("u-42");
18/// assert_eq!(id.as_str(), "u-42");
19/// assert_eq!(format!("{id}"), "u-42");
20/// ```
21#[macro_export]
22macro_rules! newtype_id {
23    ($name:ident) => {
24        #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
25        #[serde(transparent)]
26        pub struct $name(String);
27
28        impl $name {
29            pub fn new(value: impl Into<String>) -> Self {
30                Self(value.into())
31            }
32
33            pub fn as_str(&self) -> &str {
34                &self.0
35            }
36        }
37
38        impl std::fmt::Display for $name {
39            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40                f.write_str(&self.0)
41            }
42        }
43    };
44}
45
46/// Define a domain event enum with auto-generated `name()` method.
47///
48/// Generates an enum with:
49/// - `#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]`
50/// - `fn name(&self) -> &'static str` returning the variant name as a string
51///
52/// # Example
53///
54/// ```
55/// use looprs_core::domain_event;
56///
57/// domain_event!(MyEvent {
58///     Started,
59///     Stopped,
60/// });
61///
62/// assert_eq!(MyEvent::Started.name(), "Started");
63/// assert_eq!(MyEvent::Stopped.name(), "Stopped");
64/// ```
65#[macro_export]
66macro_rules! domain_event {
67    ($name:ident { $($variant:ident),* $(,)? }) => {
68        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
69        pub enum $name {
70            $($variant),*
71        }
72
73        impl $name {
74            pub fn name(&self) -> &'static str {
75                match self {
76                    $(Self::$variant => stringify!($variant)),*
77                }
78            }
79        }
80    };
81}