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}