1#![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}