microrm_macros/
lib.rs

1//! This crate contains procedural macros to simplify the use of the `microrm` crate.
2
3use proc_macro::TokenStream;
4
5mod entity;
6mod index;
7mod schema;
8mod value;
9
10/// `Entity` trait derivation procedural macro.
11///
12/// This macro performs most of the heavy lifting, type-system wise, of the entire microrm library:
13/// - Derives `Entity` for the given structure,
14/// - Defines and derives `EntityPart` for each field in the source structure,
15/// - Defines an `EntityID` type,
16/// - Derives a `std::fmt::Debug` implementation for the structure that handles some of the
17///   `microrm::schema` types nicely.
18///
19/// The prerequisites for this macro are:
20/// - Must be applied on a struct with named fields,
21/// - All fields of the given struct must derive the `Datum` trait.
22///
23/// Three attributes, applied to fields, modify the behaviour of the generation as follows:
24/// - The `unique` attribute causes the resulting sqlite table to attach a unique constraint for
25///   the given column. Note that this is a restriction that is applied per-column, not over all
26///   columns tagged with `#[unique]`.
27/// - The `elide` attribute removes the datum field from several end-user-visible iterations, such
28///   as the `Debug` impl. Useful for hiding fields that hold secret information that shouldn't be
29///   visible in log files.
30/// - The `key` attribute adds a field to the search key defined for this entity, for smoother
31///   access. This attribute can be applied to multiple fields, and the key-uniqueness constraint is
32///   applied across the tuple of all columns with the attribute. Note that this is not _quite_ the
33///   primary key for the table, as internally the integral ID is used as the primary key; it can be
34///   thought of as the 'secondary key' for the table.
35///
36/// For example:
37///
38/// ```ignore
39/// #[derive(Entity)]
40/// struct ExampleEntity {
41///     /// UUID for this entity
42///     #[unique]
43///     id: String,
44///
45///     /// Stored email address, part of lookup key
46///     #[key]
47///     email: String,
48///
49///     /// Stored name, part of lookup key
50///     #[key]
51///     name: String,
52///
53///     /// Sensitive data that should never be in log files
54///     #[elide]
55///     sin: String,
56/// }
57/// ```
58#[proc_macro_derive(Entity, attributes(unique, elide, key, migratable))]
59pub fn derive_entity(tokens: TokenStream) -> TokenStream {
60    entity::derive(tokens)
61}
62
63/// `Schema` trait derivation procedural macro.
64///
65/// This macro sets up some helper types required for implementing the `Database` trait, in
66/// addition to actually implementing the `Database` trait itself.
67///
68/// The prerequisites for this macro are:
69/// - Must be applied on a struct with named fields,
70/// - All fields of the given struct must derive the `DatabaseItem` trait.
71///
72/// Refer to the `microrm` examples for example usage.
73#[proc_macro_derive(Schema, attributes(name))]
74pub fn derive_schema(tokens: TokenStream) -> TokenStream {
75    schema::derive(tokens)
76}
77
78/// Index columns specification macro.
79///
80/// This macro uses the type indirection set up in microrm to take a list of struct fields, such as
81/// `SomeStruct::field_a, SomeStruct::field_b`, and converts it to an EntityPartList for the
82/// relevant entity.
83#[proc_macro]
84pub fn index_cols(tokens: TokenStream) -> TokenStream {
85    index::index_cols(tokens)
86}
87
88/// Value specification, for values stored inline as JSON in an `Entity` field.
89#[proc_macro_derive(Value)]
90pub fn value(tokens: TokenStream) -> TokenStream {
91    value::derive(tokens)
92}