1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

/// Macro utility to easily declare the various fields of a model for use while
/// building queries.
///
/// # Example
/// ```
/// #![feature(generic_const_exprs)]
///
/// // making modules for the example, but it is not needed.
/// mod user {
///   // the macros generate code that need all of the types of the `model` module
///   // so it is shorter to fully import it.
///   use surreal_simple_querybuilder::model;
///
///   use super::file::schema::File;
///   
///   model!(User {
///     id,
///     handle,
///
///     files<File>
///   });
/// }
///
/// mod file {
///   use surreal_simple_querybuilder::model;

///
///   use super::user::schema::User;
///
///   model!(File {
///     id,
///     name,
///
///     // this is how a field that references a foreign type is declared. Allowing
///     // you to access the User's fields easily even if starting from the File
///     // type itself.
///     author<User>
///   });
/// }
///
/// fn main() {
///   // the macro generates a `model` module with two elements in it:
///   //  - a `File` struct
///   //  - a `model` constant whose type is `File` so you can use it directly
///   //    without instantiating a new File each time.
///   use file::schema::model as file;
///
///   // you are now able to use the file constant and any of its fields as it they
///   // were strings, but in a safer manner as it is checked at compile time
///   // if the fields exist.
///   //
///   // note that `to_string()` is used here, but it is not needed when the fields
///   // are passed to the QueryBuilder
///   assert_eq!("author", file.author.to_string());
///
///   // accessing one of the Author's field from the file type
///   assert_eq!("author.handle", file.author().handle.to_string());
///
///   // supports cyclical references
///   assert_eq!("author.files.author.files.name", file.author().files().author().files().name.to_string());
///
///   // the ToNodeBuilder trait is also implemented for the models
///   use surreal_simple_querybuilder::node_builder::ToNodeBuilder;
///
///   assert_eq!("author.files = $author_files", file.author().files.equals_parameterized());
///
///   // if the type is passed rather than a field, then the type is written instead
///   assert_eq!("User", file.author().to_string());
///
///   use user::schema::model as user;
///   assert_eq!("User:john", "john".as_named_label(&user.to_string()));
///
///   // using `format!` rather than the QueryBuilder to keep it simple:
///   let query = format!(
///     "select {} from {file} as TheFile",
///     file.author().handle.from_alias("TheFile")
///   );
///
///   assert_eq!("select TheFile.author.handle from File as TheFile", query);
/// }
/// ```
pub mod model;

/// Contains a trait for simplifying the building of relationships between nodes
pub mod node_builder;

/// Contains the query builder for simplifying the building of Surreal QL queries.
/// Particularely useful when composing variables and conditional queries
pub mod querybuilder;

/// Contains the `Foreign<T>` type used to represent fields that may or may not be
/// loaded.
// pub mod foreign;
pub mod foreign_key;

pub mod prelude;