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}