db_key_macro/
lib.rs

1#![doc = include_str!("../README.md")]
2#![forbid(future_incompatible)]
3#![warn(missing_docs, missing_debug_implementations, bare_trait_objects)]
4
5use proc_macro::TokenStream;
6use syn::{
7    self,
8    parse_macro_input,
9    Attribute,
10    DeriveInput,
11    ItemMod,
12    parse_quote,
13};
14
15mod parse;
16mod field;
17
18use crate::parse::DBKey;
19
20#[doc = include_str!("../README-attrib.md")]
21#[proc_macro_attribute]
22pub fn db_key(attr: TokenStream, input: TokenStream) -> TokenStream {
23    // This needs to be done here because any errors are output as a TokenStream.
24    let input = parse_macro_input!(input as DeriveInput);
25    let db_key = DBKey::attribute(attr.into(), input);
26    db_key.generate().into()
27}
28
29#[doc = include_str!("../README-derive.md")]
30#[proc_macro_derive(DBKey, attributes(key, default, min, max, name))]
31pub fn db_key_derive(input: TokenStream) -> TokenStream {
32    // This needs to be done here because any errors are output as a TokenStream.
33    let input = parse_macro_input!(input as DeriveInput);
34    let db_key = DBKey::derive(input);
35    db_key.generate().into()
36}
37
38/// Add a documenation line to a vector of `Attribute`.
39pub(crate) fn add_doc(docs: &mut Vec<Attribute>, doc: &str) {
40    // There is probably a better way to do this, but this was the easiest way I found to do so.
41    let item_mod: ItemMod = parse_quote! {
42        #[doc = #doc]
43        mod doc;
44    };
45    for attr in item_mod.attrs.iter() {
46        if attr.path().is_ident("doc") {
47            docs.push(attr.clone());
48        }
49    }
50}