xmlparser_derive_core/
lib.rs

1#![recursion_limit = "256"]
2
3extern crate proc_macro;
4
5mod types;
6mod xml_read;
7mod xml_write;
8
9use proc_macro::TokenStream;
10use quote::quote;
11use syn::{parse_macro_input, DeriveInput, GenericParam};
12
13use crate::{types::Element, xml_read::read, xml_write::write};
14
15#[proc_macro_derive(XmlRead, attributes(xml))]
16pub fn derive_xml_read(input: TokenStream) -> TokenStream {
17    let input = parse_macro_input!(input as DeriveInput);
18
19    let name = &input.ident;
20    let generics = &input.generics;
21
22    let lifetime = match &generics.params.last() {
23        Some(GenericParam::Lifetime(lt)) => Some(lt),
24        _ => None,
25    };
26
27    let element = Element::parse(&input);
28
29    let impl_read = read(&element);
30
31    let gen = quote! {
32        impl #generics #name #generics {
33            pub fn from_str(
34                string: & #lifetime str
35            ) -> xmlparser_derive::XmlResult<#name #generics> {
36                let mut reader = xmlparser::Tokenizer::from(string).peekable();
37                Self::from_reader(&mut reader)
38            }
39
40            pub fn from_reader(
41                mut reader: &mut xmlparser_derive::XmlReader #generics
42            ) -> xmlparser_derive::XmlResult<#name #generics> {
43                use xmlparser::{ElementEnd, Token, Tokenizer};
44                use xmlparser_derive::XmlError;
45
46                #impl_read
47            }
48        }
49    };
50
51    gen.into()
52}
53
54#[proc_macro_derive(XmlWrite, attributes(xml))]
55pub fn derive_xml_write(input: TokenStream) -> TokenStream {
56    let input = parse_macro_input!(input as DeriveInput);
57
58    let name = &input.ident;
59    let generics = &input.generics;
60
61    let element = Element::parse(&input);
62
63    let impl_write = write(&element);
64
65    let gen = quote! {
66        impl #generics #name #generics {
67            pub fn to_string(&self) -> xmlparser_derive::XmlResult<String> {
68                let mut writer = vec![];
69
70                self.to_writer(&mut writer)?;
71
72                Ok(String::from_utf8(writer)?)
73            }
74
75            pub fn to_writer<W: std::io::Write>(
76                &self,
77                mut writer: W
78            ) -> xmlparser_derive::XmlResult<()> {
79                #impl_write
80
81                Ok(())
82            }
83        }
84    };
85
86    gen.into()
87}