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
/*
* @Author: plucky
* @Date: 2022-09-04 00:01:24
* @LastEditTime: 2022-10-24 11:02:28
* @Description:
*/
extern crate proc_macro;
use impl_by_field::*;
use proc_macro::TokenStream;
use impl_crud::generate_crud;
use quote::quote;
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields};
mod util;
mod impl_by_field;
mod db_type;
mod impl_crud;
/// `#[derive(Crud)]`
/// generate get, get_by, query_by, update, delete, insert.
///
/// attributes:
///
/// `#[orm_pk]`
/// default first field is primary key or set.
///
/// `#[orm_seq]`
/// sequence field, auto increment. insert will ignore this field.
///
/// `#[orm_rename= "name"]`
/// rename table name or field name.
/// default table name by struct name to_table_case: UserDetail => user_details.
/// default field name by field name to_snake_case: UserDetail => user_detail.
///
/// `#[orm_ignore]`
/// ignore field.
///
/// `#[orm_update]`
/// generate method update_xxx.
///
/// `#[orm_by]`
/// generate query_by_field,update_by_field,delete_by_field.
///
#[proc_macro_derive(Crud,
attributes(
orm_pk, // default first field is primary key or set
orm_seq, // sequence field, auto increment. insert will ignore this field
orm_update, // generate method update_xxx.
orm_rename, // rename table name or field name
orm_ignore, // ignore field
orm_by, // query_by_field,update_by_field,delete_by_field
)
)]
pub fn sql_derive_crud(input: TokenStream) -> TokenStream{
let input = parse_macro_input!(input as DeriveInput);
// if let Err(e) = check_attributes_sql(&input.attrs){
// return e.to_compile_error().into();
// }
generate_crud(input)
}
/// impl sqlx::FromRow trait.
///
/// if use `#[derive(FromRow)]` macro, must use `#[derive(Crud)]` macro.
///
/// if you don't want to use `#[derive(co_orm::FromRow)]` macro,
/// you can use `#[derive(sqlx::FromRow)]` macro or impl `sqlx::FromRow` trait.
///
/// if using sqlx::FromRow, `#[orm_ignore]` add `#[sql::defult]` .
///
#[proc_macro_derive(FromRow)]
pub fn sql_derive_form_row(input: TokenStream) -> TokenStream{
let input = parse_macro_input!(input as DeriveInput);
let struct_name = &input.ident;
let fields = match &input.data {
Data::Struct(DataStruct {fields: Fields::Named(fields),..
}) => &fields.named,
_ => panic!("expected a struct with named fields"),
};
let fields_all = fields.iter().collect::<Vec<_>>();
let generate_from_row = generate_impl_from_row(&fields_all, struct_name);
TokenStream::from(quote! {
#generate_from_row
})
}