aurora_db/macros.rs
1/// Constructs an Aurora `Value` from Rust literals.
2///
3/// This macro provides a JSON-like syntax for creating strongly-typed Aurora values
4/// without the overhead of JSON serialization. It is used internally by `object!`
5/// and `array!`, but can also be used directly.
6///
7/// # Examples
8///
9/// ```
10/// # use aurora_db::value;
11/// let v_null = value!(null);
12/// let v_bool = value!(true);
13/// let v_num = value!(42);
14/// let v_str = value!("hello");
15/// ```
16#[macro_export]
17macro_rules! value {
18 // Hide unexpected uses of the macro
19 (null) => {
20 $crate::parser::ast::Value::Null
21 };
22 (true) => {
23 $crate::parser::ast::Value::Boolean(true)
24 };
25 (false) => {
26 $crate::parser::ast::Value::Boolean(false)
27 };
28 ([]) => {
29 $crate::parser::ast::Value::Array(std::vec::Vec::new())
30 };
31 ([ $( $tt:tt )+ ]) => {
32 $crate::array!( $( $tt )+ )
33 };
34 ({}) => {
35 $crate::parser::ast::Value::Object(std::collections::HashMap::new())
36 };
37 ({ $( $k:tt : $v:tt ),* $(,)? }) => {
38 $crate::object!( $( $k : $v ),* )
39 };
40 // Handle already constructed Values (nested macro calls)
41 ($val:expr) => {
42 $crate::parser::ast::Value::from($val)
43 };
44}
45
46/// Constructs an Aurora `Value::Object` (HashMap) from key-value pairs.
47///
48/// Supports both JSON-style `{ "key": value }` and arrow-style `{ "key" => value }` syntax.
49///
50/// # Examples
51///
52/// ```
53/// # use aurora_db::object;
54/// let user = object!({
55/// "id": "u1",
56/// "name": "Alice",
57/// "active": true
58/// });
59/// ```
60#[macro_export]
61macro_rules! object {
62 ({ $( $k:tt : $v:tt ),* $(,)? }) => {
63 $crate::object!( $( $k : $v ),* )
64 };
65 ($($k:expr => $v:tt),* $(,)?) => {
66 $crate::parser::ast::Value::Object(std::collections::HashMap::from([
67 $( ($k.into(), $crate::value!($v)) ),*
68 ]))
69 };
70 ($($k:tt : $v:tt),* $(,)?) => {
71 $crate::parser::ast::Value::Object(std::collections::HashMap::from([
72 $( ($k.into(), $crate::value!($v)) ),*
73 ]))
74 };
75}
76
77/// Constructs an Aurora `Value::Array` (Vec) from a list of values.
78///
79/// # Examples
80///
81/// ```
82/// # use aurora_db::array;
83/// let tags = array!["rust", "database", 2024];
84/// ```
85#[macro_export]
86macro_rules! array {
87 ($($val:expr),* $(,)?) => {
88 $crate::parser::ast::Value::Array(std::vec![
89 $( $crate::value!($val) ),*
90 ])
91 };
92}
93
94/// Creates a `(String, ExecutionOptions)` tuple to be executed by `db.execute()`.
95///
96/// This macro is the primary way to execute parametrized AQL queries and mutations
97/// in Rust. It automatically binds Rust variables to AQL variables using the native
98/// Aurora `Value` system, ensuring safety and performance.
99///
100/// # Examples
101///
102/// ```
103/// # use aurora_db::{Aurora, doc};
104/// # async fn example(db: Aurora) -> Result<(), Box<dyn std::error::Error>> {
105/// let min_age = 18;
106///
107/// // Simple query without variables
108/// let res = db.execute(doc!("query { users { id name } }")).await?;
109///
110/// // Query with variables
111/// let res = db.execute(doc!(
112/// "query($minAge: Int) {
113/// users(where: { age: { gte: $minAge } }) {
114/// name
115/// }
116/// }",
117/// { "minAge": min_age }
118/// )).await?;
119/// # Ok(())
120/// # }
121/// ```
122#[macro_export]
123macro_rules! doc {
124 ($query:expr) => {
125 (
126 $query.to_string(),
127 $crate::parser::executor::ExecutionOptions::default(),
128 )
129 };
130 ($query:expr, { $( $k:tt : $v:tt ),* $(,)? }) => {
131 (
132 $query.to_string(),
133 $crate::parser::executor::ExecutionOptions {
134 variables: std::collections::HashMap::from([
135 $( ($k.into(), $crate::value!($v)) ),*
136 ]),
137 ..std::default::Default::default()
138 }
139 )
140 };
141}