light_magic/
macros.rs

1/// Joins Data of different `Tables` in the Database together
2///
3/// ```
4/// use light_magic::{
5///     atomic::DataStore,
6///     join,
7///     serde::{Deserialize, Serialize},
8///     table::{PrimaryKey, Table},
9/// };
10///
11/// #[derive(Default, Debug, Serialize, Deserialize)]
12/// struct Database {
13///    user: Table<User>,
14///    criminal: Table<Criminal>,
15/// }
16///
17/// impl DataStore for Database {}
18///
19/// #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
20/// struct User {
21///     id: usize,
22///     name: String,
23///     kind: String,
24/// }
25///
26/// impl PrimaryKey for User {
27///     type PrimaryKeyType = usize;
28///
29///     fn primary_key(&self) -> &Self::PrimaryKeyType {
30///         &self.id
31///     }
32/// }
33///
34/// #[derive(Default, Debug, Clone, Serialize, Deserialize)]
35/// struct Criminal {
36///     user_name: String,
37///     entry: String,
38/// }
39///
40/// impl PrimaryKey for Criminal {
41///     type PrimaryKeyType = String;
42///
43///     fn primary_key(&self) -> &Self::PrimaryKeyType {
44///         &self.user_name
45///     }
46/// }
47///
48/// let db = Database::open_in_memory();
49/// // Firstly specify the Database which should be used, then the key,
50/// // and lastly the joined items with the field which will be compared with the key
51/// let joined = join!(db.read(), "Nils", user => name, criminal => user_name);
52/// ```
53#[macro_export]
54macro_rules! join {
55    ($db:expr, $key:expr, $($table:ident => $field:ident),* $(,)?) => {{
56        $crate::paste::paste! {
57            let mut combined_results = Vec::new();
58
59            $(
60                let [<$table _results>]: Vec<_> = $db.$table.values()
61                    .filter(|val| val.$field == $key)
62                    .cloned()
63                    .collect();
64            )*
65
66            let len = vec![$([<$table _results>].len()),*].into_iter().min().unwrap_or(0);
67
68            for i in 0..len {
69                combined_results.push((
70                    $([<$table _results>][i].clone(),)*
71                ));
72            }
73
74            combined_results
75        }
76    }}
77}