microrm-macros 0.2.5

Procedural macro implementations for the microrm crate.
Documentation
use proc_macro::TokenStream;
use quote::quote;

mod entity;
mod index;
mod modelable;

fn parse_microrm_ref(attrs: &[syn::Attribute]) -> proc_macro2::TokenStream {
    for attr in attrs {
        if attr.path.segments.is_empty() {
            continue;
        }

        if attr.tokens.is_empty() && attr.path.segments.last().unwrap().ident == "microrm_internal"
        {
            return quote! { crate };
        }
    }

    quote! { ::microrm }
}

/// Turns a serializable/deserializable struct into a microrm entity model.
///
/// There are two important visible effects:
/// - Provides an implementation of `microrm::entity::Entity`
/// - Defines a <struct-name>Columns enum
///
/// Note that names are converted from CamelCase to snake_case and vice versa
/// where applicable, so a struct named `TestModel` is given a table name `test_model`
/// and a struct field named `field_name` is given a variant name of `FieldName`.
///
/// The `#[microrm...]` attributes can be used to control the derivation somewhat.
/// The following are understood for the Entity struct:
/// - `#[microrm_internal]`: this is internal to the microrm crate (of extremely limited usefulness
/// outside the microrm library)
///
/// The following are understood on individual fields:
/// - `#[microrm_foreign]`: this is a foreign key (and the field must be of a type implementing `EntityID`)
#[proc_macro_derive(Entity, attributes(microrm_internal, microrm_foreign))]
pub fn derive_entity(tokens: TokenStream) -> TokenStream {
    entity::derive(tokens)
}

/// Marks a struct or enum as able to be directly used in an Entity to correspond to a single database column.
#[proc_macro_derive(Modelable, attributes(microrm_internal))]
pub fn derive_modelable(tokens: TokenStream) -> TokenStream {
    modelable::derive(tokens)
}

/// Defines a struct to represent a optionally-unique index on a table.
///
/// Suppose the following `Entity` definition is used:
///
/// ```ignore
/// #[derive(Entity,Serialize,Deserialize)]
/// struct SystemUser {
///     username: String,
///     hashed_password: String
/// }
/// ```
///
/// We can now use `make_index!` to define an index on the username field:
/// ```ignore
/// make_index!(SystemUsernameIndex, SystemUserColumns::Username)
/// ```
///
/// This index can be made unique by adding a `!` prior to the type name, as:
/// ```ignore
/// make_index!(!SystemUsernameUniqueIndex, SystemUserColumns::Username)
/// ```
#[proc_macro]
pub fn make_index(tokens: TokenStream) -> TokenStream {
    index::do_make_index(tokens, quote! { ::microrm })
}

/// For internal use inside the microrm library. See `make_index`.
#[proc_macro]
pub fn make_index_internal(tokens: TokenStream) -> TokenStream {
    index::do_make_index(tokens, quote! { crate })
}

/*#[proc_macro]
pub fn query(tokens: TokenStream) -> TokenStream {
    query::do_query(tokens)
}
*/