1#[macro_export]
2macro_rules! migration_info_helper {
3 (@table($name:expr)) => {
4 $crate::MigrationInfo::Table($name)
5 };
6 (@index($name:expr)) => {
7 $crate::MigrationInfo::Index($name)
8 };
9 (@column($t:expr, $c:expr)) => {
10 $crate::MigrationInfo::Column {
11 table: $t,
12 column: $c,
13 }
14 };
15 (@adhoc($info:expr)) => {
16 *$info
17 };
18}
19
20#[macro_export]
21macro_rules! sql_params {
22 ($p:ident sql) => {};
23 ($p:ident info) => {};
24 ($p:ident $field:ident [skip_primary_key]) => {
25 for u in $field
26 .iter()
27 .filter(|u| !$crate::FieldMeta::is_primary_key(*u))
28 {
29 $p.push($crate::FieldUpdate::to_value(u));
30 }
31 };
32 ($p:ident $field:ident) => {
33 $crate::ToParams::add_params($field, &mut $p);
34 };
35}
36
37#[macro_export]
38macro_rules! define_sql {
39 (
40 $enum_name:ident
41 $(
42 $( @$mtype:ident ( $($margs:tt)* ) )?
43 $name:ident $( { $($field:ident : $ftype:ty $( [ $mode:ident ] )? ),* $(,)? } )? => $sql:expr
44 ),* $(,)?
45 ) => {
46 #[derive(Clone, Debug)]
47 pub enum $enum_name<'a> {
48 $(
49 #[allow(dead_code)]
50 $name $( { $($field : $ftype),* } )?,
51 )*
52 }
53
54 impl<'a> $crate::Query for $enum_name<'a> {
55 fn build(&self) -> Result<(::std::borrow::Cow<'static, str>, Vec<$crate::DatabaseValue>), $crate::Error> {
56 match self {
57 $(
58 $enum_name::$name $( { $($field,)* } )? => {
59 $( $(let _ = &$field;)* )?
60 let sql: Result<::std::borrow::Cow<'static, str>, _> =
61 $crate::IntoResultCow::into_result_cow($sql);
62
63 sql.map(|sql| {
64 #[allow(unused_mut)]
65 let mut v = Vec::new();
66 $(
67 $(
68 $crate::sql_params!(v $field $( [$mode] )? );
69 )*
70 )?
71 (sql, v)
72 })
73 },
74 )*
75 }
76 }
77 }
78
79 impl<'a> $crate::MigrationMeta for $enum_name<'a> {
80 fn migration_info(&self) -> Option<$crate::MigrationInfo> {
81 match self {
82 $(
83 $enum_name::$name $( { $($field,)* } )? => {
84 $( $(let _ = $field;)* )?
85 None $( .or(Some($crate::migration_info_helper!(@$mtype($($margs)*)))) )?
86 }
87 ),*
88 }
89 }
90 }
91 };
92}
93
94#[macro_export]
95macro_rules! is_pk_helper {
96 (@pk) => {
97 true
98 };
99}
100
101#[macro_export]
102macro_rules! define_model {
103 ($(#[$struct_meta:meta])* $name:ident, $enum_name:ident, $update_enum:ident {
104 $( $(#[$field_meta:meta])* $field:ident : $ftype:ty $( [ $mode:ident ] )? ),* $(,)?
105 }) => {
106 #[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
107 $(#[$struct_meta])*
108 pub struct $name {
109 $( $(#[$field_meta])* pub $field : $ftype ),*
110 }
111
112 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
113 #[allow(non_camel_case_types, dead_code)]
114 pub enum $enum_name {
115 $( $field ),*
116 }
117
118 impl $enum_name {
119 #[allow(dead_code)]
120 pub fn as_str(&self) -> &'static str {
121 match self {
122 $( Self::$field => stringify!($field) ),*
123 }
124 }
125 }
126
127 #[allow(non_camel_case_types, dead_code)]
128 #[derive(Debug, Clone)]
129 pub enum $update_enum {
130 $( $field($ftype) ),*
131 }
132
133 impl $crate::FieldUpdate for $update_enum {
134 fn field(&self) -> &'static str {
135 match self {
136 $( Self::$field(_) => stringify!($field) ),*
137 }
138 }
139 fn to_value(&self) -> $crate::DatabaseValue {
140 match self {
141 $( Self::$field(v) => v.clone().into() ),*
142 }
143 }
144 }
145
146 impl $crate::FieldMeta for $update_enum {
147 fn is_primary_key(&self) -> bool {
148 match self {
149 $( Self::$field(_) => {
150 false $( || $crate::is_pk_helper!(@$mode) )?
151 } ),*
152 }
153 }
154 }
155
156 impl $crate::ToParams for $update_enum {
157 fn add_params(&self, params: &mut Vec<$crate::DatabaseValue>) {
158 match self {
159 $( Self::$field(v) => params.push(v.clone().into()) ),*
160 }
161 }
162 }
163 };
164}