hard_xml_derive/
lib.rs

1#![recursion_limit = "256"]
2
3extern crate proc_macro;
4
5mod attrs;
6mod duplicate_mode;
7mod read;
8mod types;
9mod utils;
10mod write;
11
12use proc_macro::TokenStream;
13use quote::quote;
14use syn::{parse_macro_input, DeriveInput};
15use types::Element;
16
17#[proc_macro_derive(XmlRead, attributes(xml))]
18pub fn derive_xml_read(input: TokenStream) -> TokenStream {
19    let input = parse_macro_input!(input as DeriveInput);
20
21    let name = &input.ident;
22    let generics = &input.generics;
23
24    let params = &generics.params;
25
26    let where_clause = &generics.where_clause;
27
28    let input_lifetime = utils::gen_input_lifetime(generics);
29
30    let mut params_with_input_lifetime = generics.params.clone();
31
32    params_with_input_lifetime.insert(0, input_lifetime.into());
33
34    let element = match Element::parse(input.clone()) {
35        Ok(element) => element,
36        Err(errors) => {
37            return errors
38                .into_iter()
39                .map(syn::Error::into_compile_error)
40                .collect::<proc_macro2::TokenStream>()
41                .into()
42        }
43    };
44    let impl_read = read::impl_read(element);
45
46    let gen = quote! {
47        impl <#params_with_input_lifetime> ::hard_xml::XmlRead<'__input> for #name <#params>
48            #where_clause
49        {
50            fn from_reader(
51                mut reader: &mut ::hard_xml::XmlReader<'__input>
52            ) -> ::hard_xml::XmlResult<Self> {
53                use ::hard_xml::xmlparser::{ElementEnd, Token, Tokenizer};
54                use ::hard_xml::XmlError;
55                #impl_read
56            }
57        }
58    };
59
60    gen.into()
61}
62
63#[proc_macro_derive(XmlWrite, attributes(xml))]
64pub fn derive_xml_write(input: TokenStream) -> TokenStream {
65    let input = parse_macro_input!(input as DeriveInput);
66
67    let name = &input.ident;
68    let generics = &input.generics;
69
70    let params = &generics.params;
71
72    let where_clause = &generics.where_clause;
73
74    let element = match Element::parse(input.clone()) {
75        Ok(element) => element,
76        Err(errors) => {
77            return errors
78                .into_iter()
79                .map(syn::Error::into_compile_error)
80                .collect::<proc_macro2::TokenStream>()
81                .into()
82        }
83    };
84    let impl_write = write::impl_write(element);
85
86    let gen = quote! {
87        impl <#params> ::hard_xml::XmlWrite for #name <#params>
88            #where_clause
89        {
90            fn to_writer<W: std::io::Write>(
91                &self,
92                mut writer: &mut ::hard_xml::XmlWriter<W>
93            ) -> ::hard_xml::XmlResult<()> {
94                #impl_write
95
96                Ok(())
97            }
98        }
99    };
100
101    gen.into()
102}