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