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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
pub mod codegen;
pub mod parser;
use codegen::query as query_codegen;
use codegen::action as action_codegen;
use codegen::collection as collection_codegen;
use codegen::error_code as error_code_codegen;
use deluxe::ExtractAttributes;
use parser::query as query_parser;
use parser::action as action_parser;
use parser::collection as collection_parser;
use parser::error_code as error_code_parser;
use proc_macro2::TokenStream;
use quote::ToTokens;
use syn::ItemEnum;
use syn::Variant;
use syn::{
    parse::{Parse, ParseStream, Result as ParseResult},
    Ident, ItemFn, ItemMod, ItemStruct,
};

#[derive(Debug)]
pub struct CollectionMod {
    pub action_fns: Vec<ActionFn>,
    pub name: Ident,
    pub collection_mod: ItemMod,
}

impl Parse for CollectionMod {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let collection_mod = <ItemMod as Parse>::parse(input)?;
        collection_parser::parse(&collection_mod)
    }
}

impl From<&CollectionMod> for TokenStream {
    fn from(collection_mod: &CollectionMod) -> Self {
        collection_codegen::generate(collection_mod)
    }
}

impl ToTokens for CollectionMod {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.extend::<TokenStream>(self.into());
    }
}

#[derive(Debug)]
pub struct ActionFn {
    pub raw_method: ItemFn,
    pub name: Ident,
    pub handle_get_ident: Ident,
    pub handle_post_ident: Ident,
    pub action_ident: Ident,
    pub action_query_ident: Option<Ident>,
    pub route_path: String,
}

#[derive(Debug)]
pub struct ActionStruct {
    pub name: Ident,
    pub raw_struct: ItemStruct,
    pub attributes: ActionAttributesStruct,
}

impl Parse for ActionStruct {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let action_struct = <ItemStruct as Parse>::parse(input)?;
        action_parser::parse(&action_struct)
    }
}

impl From<&ActionStruct> for TokenStream {
    fn from(action_struct: &ActionStruct) -> Self {
        action_codegen::generate(action_struct)
    }
}

impl ToTokens for ActionStruct {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.extend::<TokenStream>(self.into());
    }
}

#[derive(Debug, ExtractAttributes)]
#[deluxe(attributes(action))]
pub struct ActionAttributesStruct {
    pub icon: String,
    pub title: String,
    pub description: String,
    pub label: String,
}

#[derive(Debug)]
pub struct QueryStruct {
    pub name: Ident,
    pub raw_struct: ItemStruct,
}

impl Parse for QueryStruct {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let query_struct = <ItemStruct as Parse>::parse(input)?;
        query_parser::parse(&query_struct)
    }
}

impl From<&QueryStruct> for TokenStream {
    fn from(query_struct: &QueryStruct) -> Self {
        query_codegen::generate(query_struct)
    }
}

impl ToTokens for QueryStruct {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.extend::<TokenStream>(self.into());
    }
}

#[derive(Debug)]
pub struct ErrorEnum {
    pub name: Ident,
    pub raw_enum: ItemEnum,
    pub error_variants: Vec<ErrorVariant>,
}

impl Parse for ErrorEnum {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let error_enum = <ItemEnum as Parse>::parse(input)?;
        error_code_parser::parse(&error_enum)
    }
}

impl From<&ErrorEnum> for TokenStream {
    fn from(error_enum: &ErrorEnum) -> Self {
        error_code_codegen::generate(error_enum)
    }
}

impl ToTokens for ErrorEnum {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.extend::<TokenStream>(self.into());
    }
}

#[derive(Debug, ExtractAttributes)]
#[deluxe(attributes(error))]
pub struct ErrorAttributesStruct {
    pub msg: String,
}

#[derive(Debug)]
pub struct ErrorVariant {
    pub name: Ident,
    pub raw_variant: Variant,
    pub msg: String,
}