codama_macros/
lib.rs

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
use codama_attributes::{AttributeContext, CodamaAttribute};
use codama_errors::{CodamaError, CodamaResult};
use codama_koroks::CrateKorok;
use codama_stores::CrateStore;
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;

#[proc_macro_derive(CodamaAccount, attributes(codama))]
pub fn codama_account_derive(input: TokenStream) -> TokenStream {
    codama_derive(input.into())
        .unwrap_or_else(CodamaError::into_compile_error)
        .into()
}

#[proc_macro_derive(CodamaAccounts, attributes(codama))]
pub fn codama_accounts_derive(input: TokenStream) -> TokenStream {
    codama_derive(input.into())
        .unwrap_or_else(CodamaError::into_compile_error)
        .into()
}

#[proc_macro_derive(CodamaInstruction, attributes(codama))]
pub fn codama_instruction_derive(input: TokenStream) -> TokenStream {
    codama_derive(input.into())
        .unwrap_or_else(CodamaError::into_compile_error)
        .into()
}

#[proc_macro_derive(CodamaInstructions, attributes(codama))]
pub fn codama_instructions_derive(input: TokenStream) -> TokenStream {
    codama_derive(input.into())
        .unwrap_or_else(CodamaError::into_compile_error)
        .into()
}

#[proc_macro_derive(CodamaType, attributes(codama))]
pub fn codama_type_derive(input: TokenStream) -> TokenStream {
    codama_derive(input.into())
        .unwrap_or_else(CodamaError::into_compile_error)
        .into()
}

fn codama_derive(input: TokenStream2) -> CodamaResult<TokenStream2> {
    let store = CrateStore::hydrate(input)?;
    CrateKorok::parse(&store)?;
    Ok(quote! {})
}

#[proc_macro_attribute]
pub fn codama(attr: TokenStream, input: TokenStream) -> TokenStream {
    codama_attribute(attr.into(), input.into())
        .unwrap_or_else(CodamaError::into_compile_error)
        .into()
}

fn codama_attribute(attr: TokenStream2, input: TokenStream2) -> CodamaResult<TokenStream2> {
    let attr: syn::Attribute = syn::parse_quote! { #[codama(#attr)] };
    let item: syn::Item = syn::parse2(input.clone())?;
    let ctx: AttributeContext = (&item).into();
    CodamaAttribute::parse(&attr, &ctx)?;
    Ok(input)
}