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 100 101 102
#![doc = include_str!("../README.md")]
mod db;
mod join;
use proc_macro as pc;
use proc_macro2::Span;
use std::fmt;
use syn::Ident;
/// Printing errors at the current span
fn s_err(span: proc_macro2::Span, msg: impl fmt::Display) -> syn::Error {
syn::Error::new(span, msg)
}
/// Capitalizing ident
///
/// # Example
///
/// `user_name` => `UserName`
fn capitalize_ident(ident: &Ident) -> Ident {
let capitalized: String = ident
.to_string()
.split('_')
.map(|part| {
let mut c = part.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
}
})
.collect();
Ident::new(&capitalized, Span::call_site())
}
/// Pre-Extending ident
///
/// # Example
///
/// `pre_extend_ident(ident, "extend_")` => `extend_ident`
fn pre_extend_ident(ident: &Ident, pre_extend: &str) -> Ident {
Ident::new(
&(pre_extend.to_string() + &ident.to_string()),
Span::call_site(),
)
}
/// Creates the Database struct with the fitting logic
///
/// ## Functions
/// - `insert_#table`
/// - `get_#table`
/// - `edit_#table`
/// - `delete_#table`
/// - `search_#table`
///
/// ## Example
/// ```
/// use light_magic::db;
///
/// db! {
/// // `users` is the table name
/// // `{...}` is the table data
/// // the first field, like here `name`, is the `primary_key`
/// user => { id: usize, name: String, kind: String },
/// // using [...] after the table name you can add your own derives
/// // like here `PartialEq`
/// criminal: [PartialEq] => { user_name: String, entry: String }
/// }
/// ```
#[proc_macro]
pub fn db(input: pc::TokenStream) -> pc::TokenStream {
match db::db_inner(input.into()) {
Ok(result) => result.into(),
Err(e) => e.into_compile_error().into(),
}
}
/// Joins Data in the Database together
///
/// ## Example
/// ```
/// use light_magic::{db, join};
///
/// db! {
/// user => { id: usize, name: String, kind: String },
/// criminal => { user_name: String, entry: String }
/// }
///
/// let db = Database::new();
/// /// Firstly specify the to db which should be used, then the key,
/// /// and lastly the joined items with the field which should be joined
/// let joined = join!(db, "Nils", user => name, criminal => user_name);
/// ```
#[proc_macro]
pub fn join(input: pc::TokenStream) -> pc::TokenStream {
match join::join_inner(input.into()) {
Ok(result) => result.into(),
Err(e) => e.into_compile_error().into(),
}
}