1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use syn::{parse_macro_input, DeriveInput, Result};
5
6use crate::container::{Container, SealedContainer};
7use crate::dto_info::DtoInfo;
8use crate::expand::expand;
9use crate::parse::{parse_struct_attrs, StructAttr};
10
11mod container;
12mod dto_info;
13mod expand;
14mod helpers;
15mod mapping;
16mod parse;
17
18#[proc_macro_derive(Dto, attributes(dto))]
19pub fn dto_macro_derive(input: TokenStream) -> TokenStream {
20 let input = parse_macro_input!(input as DeriveInput);
21
22 match process_dto_macro_derive(&input) {
23 Ok(tokens) => tokens,
24 Err(ref error) => error.to_compile_error().into(),
25 }
26}
27
28fn process_dto_macro_derive(input: &DeriveInput) -> Result<TokenStream> {
29 let dto_info = DtoInfo::from_derive(input)?;
30
31 let mut cont = Container::new(&dto_info);
32
33 parse_struct_attrs(&input.attrs, |attr| match attr {
34 StructAttr::Entity(a) => cont.set_entity(a.entity, a.span),
35 StructAttr::Request(a) => cont.set_request(a.span),
36 StructAttr::Response(a) => cont.set_response(a.span),
37 StructAttr::Map(a) => cont.add_mapping(a.mapping, a.span),
38 StructAttr::Skip(a) => cont.add_skips(&a.skips, a.span),
39 })?;
40
41 Ok(expand(&cont.seal()?).into())
42}