authbeam/
macros.rs

1#[macro_export]
2macro_rules! cache_sync {
3    (|$row:ident, $id:ident| $key:ident->($update:ident in $self:ident){1}) => {{
4        let as_str = stringify!($key);
5
6        let row_count = match $row.get(as_str) {
7            Some(s) => s,
8            None => "0",
9        }
10        .parse::<usize>()
11        .unwrap_or(0);
12
13        let count = $self
14            .base
15            .cache
16            .get(format!("rbeam.app.{}:{}", as_str, &$id))
17            .await
18            .unwrap_or_default()
19            .parse::<usize>()
20            .unwrap_or(0);
21
22        if count == 0 {
23            row_count
24        } else {
25            // ensure values sync (update the lesser value)
26            if row_count > count {
27                $self
28                    .base
29                    .cache
30                    .set(
31                        format!("rbeam.app.{}:{}", as_str, &$id),
32                        row_count.to_string(),
33                    )
34                    .await;
35            } else {
36                $self.$update(&$id, count).await.unwrap();
37            };
38
39            // ...
40            count
41        }
42    }};
43}
44
45#[macro_export]
46macro_rules! from_row {
47    ($row:ident->$name:ident(ref)) => {
48        $row.get(stringify!($name)).unwrap()
49    };
50
51    ($row:ident->$name:ident()) => {
52        $row.get(stringify!($name)).unwrap().to_string()
53    };
54
55    ($row:ident->$name:ident(ref)) => {
56        $row.get(stringify!($name)).unwrap()
57    };
58
59    ($row:ident->$name:ident()) => {
60        $row.get(stringify!($name)).unwrap().to_string()
61    };
62
63    ($row:ident->$name:ident(ref); $v:literal) => {
64        $row.get(stringify!($name)).unwrap_or($v)
65    };
66
67    ($row:ident->$name:ident(); $v:literal) => {
68        $row.get(stringify!($name)).unwrap_or($v).to_string()
69    };
70
71    ($row:ident->$name:ident(ref); $v:expr) => {
72        $row.get(stringify!($name)).unwrap_or($v)
73    };
74
75    ($row:ident->$name:ident(); $v:expr) => {
76        $row.get(stringify!($name)).unwrap_or($v).to_string()
77    };
78
79    ($row:ident->$name:ident($t:tt); $v:literal) => {
80        $row.get(stringify!($name))
81            .unwrap()
82            .parse::<$t>()
83            .unwrap_or($v)
84    };
85
86    ($row:ident->$name:ident($t:expr); $v:literal) => {
87        $row.get(stringify!($name))
88            .unwrap()
89            .parse::<$t>()
90            .unwrap_or($v)
91    };
92
93    ($row:ident->$name:ident(json); $e:expr) => {
94        match serde_json::from_str($row.get(stringify!($name)).unwrap()) {
95            Ok(de) => de,
96            Err(_) => return Err($e),
97        }
98    };
99
100    ($row:ident->$name:ident(json); $e:tt) => {
101        match serde_json::from_str($row.get(stringify!($name)).unwrap()) {
102            Ok(de) => de,
103            Err(_) => return Err($e),
104        }
105    };
106
107    ($row:ident->$name:ident(toml); $e:expr) => {
108        match toml::from_str($row.get(stringify!($name)).unwrap()) {
109            Ok(de) => de,
110            Err(_) => return Err($e),
111        }
112    };
113
114    ($row:ident->$name:ident(toml); $e:tt) => {
115        match toml::from_str($row.get(stringify!($name)).unwrap()) {
116            Ok(de) => de,
117            Err(_) => return Err($e),
118        }
119    };
120}
121
122#[macro_export]
123macro_rules! update_profile_count {
124    ($name:tt, $col:ident) => {
125        /// Update a profile count value.
126        ///
127        /// # Arguments
128        /// * `id`
129        /// * `count`
130        pub async fn $name(&self, id: &str, count: usize) -> Result<()> {
131            // update profile
132            let col_name = stringify!($col);
133            let query: String =
134                if (self.base.db.r#type == "sqlite") | (self.base.db.r#type == "mysql") {
135                    format!("UPDATE \"xprofiles\" SET \"{col_name}\" = ? WHERE \"id\" = ?")
136                } else {
137                    format!("UPDATE \"xprofiles\" SET \"{col_name}\" = ? WHERE \"id\" = ?")
138                };
139
140            let c = &self.base.db.client;
141            match sqlquery(&query)
142                .bind::<&i64>(&(count as i64))
143                .bind::<&str>(&id)
144                .execute(c)
145                .await
146            {
147                Ok(_) => {
148                    let username = self.get_profile_username(id).await;
149
150                    self.base
151                        .cache
152                        .remove(format!("rbeam.auth.profile:{id}"))
153                        .await;
154
155                    self.base
156                        .cache
157                        .get(format!("rbeam.auth.profile:{}", username))
158                        .await;
159
160                    Ok(())
161                }
162                Err(_) => Err(DatabaseError::Other),
163            }
164        }
165    };
166}
167
168/// Simplfy an error-forwarding match block.
169#[macro_export]
170macro_rules! simplify {
171    ($e:expr; Result) => {
172        match $e {
173            Ok(x) => x,
174            Err(e) => return Err(e),
175        }
176    };
177
178    ($e:expr; Err) => {
179        if let Err(e) = $e {
180            return Err(e);
181        }
182    };
183
184    ($e:expr; Option) => {
185        match $e {
186            Some(x) => x,
187            None => return None,
188        }
189    };
190
191    ($e:expr; None) => {
192        if let None = $e {
193            return None;
194        }
195    };
196
197    ($e:expr; Result; $v:expr) => {
198        match $e {
199            Ok(x) => x,
200            Err(e) => $v,
201        }
202    };
203
204    ($e:expr; Err; $v:expr) => {
205        if let Err(_) = $e {
206            return $v;
207        }
208    };
209
210    ($e:expr; Option; $v:expr) => {
211        match $e {
212            Some(x) => x,
213            None => return $v,
214        }
215    };
216
217    ($e:expr; None; $v:expr) => {
218        if let None = $e {
219            return $v;
220        }
221    };
222}
223
224/// Ignore (`let _ = ...`) something.
225#[macro_export]
226macro_rules! ignore {
227    ($e:expr) => {
228        let _ = $e;
229    };
230}
231
232pub fn serde_json_to_string<T: serde::Serialize>(value: T) -> Result<String, serde_json::Error> {
233    serde_json::to_string(&value)
234}