inline_xml_macros/
lib.rs

1// Copyright (C) 2023 Benjamin Stürz
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program.  If not, see <http://www.gnu.org/licenses/>.
15#![allow(dead_code)]
16extern crate proc_macro;
17use proc_macro::TokenStream;
18use proc_macro2::{Ident, Punct, Span};
19use quote::ToTokens;
20use syn::{token::{Lt, Gt, Div, Eq, And, Semi, Pound, Colon, Sub}, LitStr, ExprBlock, LitInt, parse_macro_input, LitFloat};
21
22mod parse;
23mod gen;
24mod impls;
25
26struct Xml(Vec<Content>);
27
28enum SimpleNameSeg {
29    Ident(Ident),
30    Minus(Sub),
31}
32
33#[derive(PartialEq)]
34struct SimpleName(Vec<SimpleNameSeg>);
35
36struct Name {
37    namespace: Option<(SimpleName, Colon)>,
38    name: SimpleName,
39}
40
41struct Tag {
42    lt: Lt,
43    name: Name,
44    attrs: Vec<Attr>,
45    tail: TagTail,
46}
47
48enum TagTail {
49    Simple {
50        slash: Div,
51        gt: Gt,
52    },
53    Complex {
54        gt: Gt,
55        inner: Xml,
56        lt: Lt,
57        slash: Div,
58        name2: Name,
59        gt2: Gt,
60    }
61}
62
63struct Attr {
64    name: Name,
65    eq: Eq,
66    value: Value,
67}
68
69enum Value {
70    Block(ExprBlock),
71    Str(LitStr),
72}
73
74enum Content {
75    Tag(Tag),
76    Escape {
77        amp: And,
78        escape: Escape,
79        semi: Semi,
80    },
81    Block(ExprBlock),
82    Punct(Punct),
83    Ident(Ident),
84    Str(LitStr),
85    Int(LitInt),
86    Float(LitFloat),
87}
88
89enum Escape {
90    Lt(Span),
91    Gt(Span),
92    Amp(Span),
93    Apos(Span),
94    Quot(Span),
95    X {
96        pound: Pound,
97        x: Ident,
98        value: u32
99    },
100    Int {
101        pound: Pound,
102        lit: LitInt,
103    }
104}
105
106
107#[proc_macro]
108pub fn xml(input: TokenStream) -> TokenStream {
109    parse_macro_input!(input as Xml).into_token_stream().into()
110}
111
112#[proc_macro]
113pub fn xml_tag(input: TokenStream) -> TokenStream {
114    parse_macro_input!(input as Tag).into_token_stream().into()
115}