1#![allow(dead_code)]
16use proc_macro::TokenStream;
17use proc_macro2::{Ident, Group};
18use syn::{Token, LitInt, parse_macro_input, ExprBlock, LitFloat};
19use quote::ToTokens;
20
21mod parse;
22mod gen;
23
24struct CSS(Vec<Rule>);
25
26struct Rule {
27 selector: Selector,
28 group: Group,
29 declarations: Declarations,
30}
31
32enum Selector {
33 Any(Token![*]),
34 Simple {
35 ident: Option<CSSIdent>,
36 class: Option<(Token![.], CSSIdent)>,
37 id: Option<(Token![#], CSSIdent)>,
38 },
39 Colon {
40 colon: Token![:],
41 ident: CSSIdent,
42 arg: Option<(Group, Value)>,
43 },
44 Sub {
45 left: Box<Selector>,
46 right: Box<Selector>,
47 },
48 Gt {
49 left: Box<Selector>,
50 gt: Token![>],
51 right: Box<Selector>,
52 },
53 Plus {
54 left: Box<Selector>,
55 plus: Token![+],
56 right: Box<Selector>,
57 },
58 Tilde {
59 left: Box<Selector>,
60 tilde: Token![~],
61 right: Box<Selector>,
62 },
63 Comma {
64 left: Box<Selector>,
65 comma: Token![,],
66 right: Box<Selector>,
67 },
68}
69
70struct Declarations(Vec<Declaration>);
71
72struct Declaration {
73 ident: CSSIdent,
74 colon: Token![:],
75 value: Vec<Value>,
76 semicolon: Token![;],
77}
78
79enum Value {
80 ColorCode { pound: Token![#], value: LitInt },
81 Ident(CSSIdent),
82 Int(LitInt),
83 Float(LitFloat),
84 IntPerc(LitInt, Token![%]),
85 FloatPerc(LitFloat, Token![%]),
86 Function { ident: CSSIdent, group: Group, args: Args },
87 Block(ExprBlock),
88}
89
90struct Args(Vec<Value>);
91
92struct CSSIdent(Vec<CSSIdentSegment>);
93
94enum CSSIdentSegment {
95 Ident(Ident),
96 Minus(Token![-]),
97}
98
99#[proc_macro]
100pub fn css(input: TokenStream) -> TokenStream {
101 parse_macro_input!(input as CSS).into_token_stream().into()
102}
103
104#[proc_macro]
105pub fn css_rule(input: TokenStream) -> TokenStream {
106 parse_macro_input!(input as Rule).into_token_stream().into()
107}
108
109#[proc_macro]
110pub fn css_value(input: TokenStream) -> TokenStream {
111 parse_macro_input!(input as Value).into_token_stream().into()
112}