#![allow(dead_code)]
use proc_macro::TokenStream;
use proc_macro2::{Ident, Group};
use syn::{Token, LitInt, parse_macro_input, ExprBlock, LitFloat};
use quote::ToTokens;
mod parse;
mod gen;
struct CSS(Vec<Rule>);
struct Rule {
selector: Selector,
group: Group,
declarations: Declarations,
}
enum Selector {
Simple {
ident: Option<CSSIdent>,
class: Option<(Token![.], CSSIdent)>,
id: Option<(Token![#], CSSIdent)>,
},
Colon {
colon: Token![:],
ident: CSSIdent,
arg: Option<(Group, Value)>,
},
Sub {
left: Box<Selector>,
right: Box<Selector>,
},
Gt {
left: Box<Selector>,
gt: Token![>],
right: Box<Selector>,
},
Plus {
left: Box<Selector>,
plus: Token![+],
right: Box<Selector>,
},
Tilde {
left: Box<Selector>,
tilde: Token![~],
right: Box<Selector>,
},
Comma {
left: Box<Selector>,
comma: Token![,],
right: Box<Selector>,
},
}
struct Declarations(Vec<Declaration>);
struct Declaration {
ident: CSSIdent,
colon: Token![:],
value: Vec<Value>,
semicolon: Token![;],
}
enum Value {
ColorCode { pound: Token![#], value: LitInt },
Ident(CSSIdent),
Int(LitInt),
Float(LitFloat),
IntPerc(LitInt, Token![%]),
FloatPerc(LitFloat, Token![%]),
Function { ident: CSSIdent, group: Group, args: Args },
Block(ExprBlock),
}
struct Args(Vec<Value>);
struct CSSIdent(Vec<CSSIdentSegment>);
enum CSSIdentSegment {
Ident(Ident),
Minus(Token![-]),
}
#[proc_macro]
pub fn css(input: TokenStream) -> TokenStream {
parse_macro_input!(input as CSS).into_token_stream().into()
}
#[proc_macro]
pub fn css_rule(input: TokenStream) -> TokenStream {
parse_macro_input!(input as Rule).into_token_stream().into()
}
#[proc_macro]
pub fn css_value(input: TokenStream) -> TokenStream {
parse_macro_input!(input as Value).into_token_stream().into()
}