//! This crate contains procedural macros to simplify the use of the `microrm` crate. use proc_macro::TokenStream; mod database; mod entity; mod index; mod value; /// `Entity` trait derivation procedural macro. /// /// This macro performs most of the heavy lifting, type-system wise, of the entire microrm library: /// - Derives `Entity` for the given structure, /// - Defines and derives `EntityPart` for each field in the source structure, /// - Defines an `EntityID` type, /// - Derives a `std::fmt::Debug` implementation for the structure that handles some of the /// `microrm::schema` types nicely. /// /// The prerequisites for this macro are: /// - Must be applied on a struct with named fields, /// - All fields of the given struct must derive the `Datum` trait. /// /// Three attributes, applied to fields, modify the behaviour of the generation as follows: /// - The `unique` attribute causes the resulting sqlite table to attach a unique constraint for /// the given column. Note that this is a restriction that is applied per-column, not over all /// columns tagged with `#[unique]`. /// - The `elide` attribute removes the datum field from several end-user-visible iterations, such /// as the `Debug` impl. Useful for hiding fields that hold secret information that shouldn't be /// visible in log files. /// - The `key` attribute adds a field to the search key defined for this entity, for smoother /// access. This attribute can be applied to multiple fields, and the key-uniqueness constraint is /// applied across the tuple of all columns with the attribute. Note that this is not _quite_ the /// primary key for the table, as internally the integral ID is used as the primary key; it can be /// thought of as the 'secondary key' for the table. /// /// For example: /// /// ```ignore /// #[derive(Entity)] /// struct ExampleEntity { /// /// UUID for this entity /// #[unique] /// id: String, /// /// /// Stored email address, part of lookup key /// #[key] /// email: String, /// /// /// Stored name, part of lookup key /// #[key] /// name: String, /// /// /// Sensitive data that should never be in log files /// #[elide] /// sin: String, /// } /// ``` #[proc_macro_derive(Entity, attributes(unique, elide, key))] pub fn derive_entity(tokens: TokenStream) -> TokenStream { entity::derive(tokens) } /// `Database` trait derivation procedural macro. /// /// This macro sets up some helper types required for implementing the `Database` trait, in /// addition to actually implementing the `Database` trait itself. /// /// The prerequisites for this macro are: /// - Must be applied on a struct with named fields, /// - All fields of the given struct must derive the `DatabaseItem` trait. /// /// Refer to the `microrm` examples for example usage. #[proc_macro_derive(Database)] pub fn derive_database(tokens: TokenStream) -> TokenStream { database::derive(tokens) } /// Index columns specification macro. /// /// This macro uses the type indirection set up in microrm to take a list of struct fields, such as /// `SomeStruct::field_a, SomeStruct::field_b`, and converts it to an EntityPartList for the /// relevant entity. #[proc_macro] pub fn index_cols(tokens: TokenStream) -> TokenStream { index::index_cols(tokens) } /// Value specification #[proc_macro_derive(Value)] pub fn value(tokens: TokenStream) -> TokenStream { value::derive(tokens) }