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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#[macro_use] extern crate quote; #[macro_use] extern crate syn; extern crate darling; extern crate proc_macro; extern crate proc_macro2; use darling::{FromDeriveInput, FromMeta}; use proc_macro::TokenStream; use proc_macro2::Span; use syn::{DeriveInput, ItemStruct}; #[derive(Default, FromMeta, Debug)] #[darling(default)] struct SaveArgs { output_type: Option<String>, dsl_name: String, } #[derive(FromDeriveInput, Debug)] #[darling(attributes(save_opts), forward_attrs(allow, doc, cfg))] struct SaveOpts { ident: syn::Ident, attrs: Vec<syn::Attribute>, opts: SaveArgs, } #[proc_macro_derive(DSave, attributes(save_opts))] pub fn diesel_save(input: TokenStream) -> TokenStream { let input_clone = input.clone(); let derive_input = parse_macro_input!(input as DeriveInput); let attrs = match SaveOpts::from_derive_input(&derive_input) { Ok(val) => val, Err(err) => { return err.write_errors().into(); } }; let struct_item: ItemStruct = parse_macro_input!(input_clone); let ident = struct_item.ident; let output_type = syn::Ident::new(&attrs.opts.output_type.unwrap(), Span::call_site()); let dsl = syn::Ident::new(&attrs.opts.dsl_name, Span::call_site()); quote!( impl DSave for #ident { type Output = #output_type; fn save(&self, conn: &PgConnection) -> Result<Self::Output>{ diesel::insert_into(dsl :: #dsl) .values(self) .get_result(conn) .map_err( |e| e.into()) } fn save_vec(values: &[Self], conn: &PgConnection) -> Result<usize> where Self: std::marker::Sized { diesel::insert_into(dsl :: #dsl) .values(values) .execute(conn) .map_err( |e| e.into()) } } ) .into() } #[derive(Default, FromMeta, Debug)] #[darling(default)] struct EncDecArgs { sub_key: String, } #[derive(FromDeriveInput, Debug)] #[darling(attributes(encdec_opts), forward_attrs(allow, doc, cfg))] struct EncDecOpts { ident: syn::Ident, attrs: Vec<syn::Attribute>, opts: EncDecArgs, } #[proc_macro_derive(Encrypted, attributes(encdec_opts))] pub fn encryption(input: TokenStream) -> TokenStream { let derive_input = parse_macro_input!(input as DeriveInput); let attrs = match EncDecOpts::from_derive_input(&derive_input) { Ok(val) => val, Err(err) => { return err.write_errors().into(); } }; let sub_key = attrs.opts.sub_key; let ident = derive_input.ident; quote!( impl Encrypted for #ident { fn ekey(&self) -> Result<String> { encode_ekey_util(self.id as u64, #sub_key) } } ) .into() } #[proc_macro_derive(Decrypted, attributes(encdec_opts))] pub fn decryption(input: TokenStream) -> TokenStream { let derive_input = parse_macro_input!(input as DeriveInput); let attrs = match EncDecOpts::from_derive_input(&derive_input) { Ok(val) => val, Err(err) => { return err.write_errors().into(); } }; let sub_key = attrs.opts.sub_key; let ident = derive_input.ident; quote!( impl Decrypted for #ident { fn dkey(&self, ekey: &str) -> Result<u64> { decode_ekey_util(ekey, #sub_key) } } ) .into() }