Skip to main content

ankurah_core/util/
cast.rs

1//! Macros for ergonomic entity creation.
2
3/// Macro for ergonomic entity creation with automatic `.into()` on fields.
4///
5/// Transforms struct initialization to call `.into()` on each field value:
6/// ```rust,ignore
7/// use ankurah::into;
8///
9/// // This:
10/// into!(ConnectionEvent { &user, session: &session_view, timestamp: ts })
11///
12/// // Expands to:
13/// ConnectionEvent { user: (&user).into(), session: (&session_view).into(), timestamp: ts.into() }
14/// ```
15///
16/// This works because:
17/// - Views implement `From<&View> for Ref<Model>` (blanket impl in entity_ref.rs)
18/// - All types implement `Into<Self>` (reflexive impl)
19#[macro_export]
20macro_rules! into {
21    ($ty:ident { $($tt:tt)* }) => {
22        $crate::into!(@expand $ty {} $($tt)*)
23    };
24    (@expand $ty:ident { $($out:tt)* }) => { $ty { $($out)* } };
25    (@expand $ty:ident { $($out:tt)* } ,) => { $ty { $($out)* } };
26    // Shorthand ref: &field, ...
27    (@expand $ty:ident { $($out:tt)* } & $field:ident, $($rest:tt)*) => {
28        $crate::into!(@expand $ty { $($out)* $field: (&$field).into(), } $($rest)*)
29    };
30    (@expand $ty:ident { $($out:tt)* } & $field:ident) => {
31        $crate::into!(@expand $ty { $($out)* $field: (&$field).into(), })
32    };
33    // Shorthand: field, ...
34    (@expand $ty:ident { $($out:tt)* } $field:ident, $($rest:tt)*) => {
35        $crate::into!(@expand $ty { $($out)* $field: ($field).into(), } $($rest)*)
36    };
37    (@expand $ty:ident { $($out:tt)* } $field:ident) => {
38        $crate::into!(@expand $ty { $($out)* $field: ($field).into(), })
39    };
40    // Explicit: field: expr, ...
41    (@expand $ty:ident { $($out:tt)* } $field:ident : $value:expr, $($rest:tt)*) => {
42        $crate::into!(@expand $ty { $($out)* $field: ($value).into(), } $($rest)*)
43    };
44    (@expand $ty:ident { $($out:tt)* } $field:ident : $value:expr) => {
45        $crate::into!(@expand $ty { $($out)* $field: ($value).into(), })
46    };
47}
48
49/// Macro for creating entities with automatic `.into()` on fields.
50///
51/// Combines a transaction's `create` call with the `into!` macro:
52/// ```rust,ignore
53/// use ankurah::create;
54///
55/// // This:
56/// create!(trx, ConnectionEvent { &user, session: &session_view, timestamp: ts })
57///
58/// // Expands to:
59/// trx.create(&into!(ConnectionEvent { &user, session: &session_view, timestamp: ts }))
60/// ```
61#[macro_export]
62macro_rules! create {
63    ($trx:expr, $ty:ident { $($tt:tt)* }) => {
64        $trx.create(&$crate::into!($ty { $($tt)* }))
65    };
66}