docx_codegen/
lib.rs

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