use crate::*;
use quote::quote;
use proc_macro2::TokenStream;
impl ToTokens for CSS {
fn to_tokens(&self, tokens: &mut TokenStream) {
let rules = &self.0;
let s = quote! {
inline_css::CSS(vec![#(#rules),*])
};
tokens.extend(s)
}
}
impl ToTokens for Rule {
fn to_tokens(&self, tokens: &mut TokenStream) {
let selector = &self.selector;
let declarations = &self.declarations.0;
let s = quote! {
inline_css::Rule {
selector: #selector,
declarations: vec![#(#declarations),*],
}
};
tokens.extend(s)
}
}
impl ToTokens for Selector {
fn to_tokens(&self, tokens: &mut TokenStream) {
let s = match self {
Self::Any(_) => quote! { inline_css::Selector::Any },
Self::Simple { ident, class, id } => {
let ident = ident.as_ref().map_or(
quote! { None },
|i| quote! { Some(#i) },
);
let class = class.as_ref().map_or(
quote! { None },
|(_, i)| quote! { Some(#i) },
);
let id = id.as_ref().map_or(
quote! { None },
|(_, i)| quote! { Some(#i) },
);
quote! {
inline_css::Selector::Simple {
ty: #ident,
class: #class,
id: #id,
}
}
},
Self::Colon { ident, arg, .. } => {
let arg = if let Some((_, arg)) = arg {
quote! { Some(#arg) }
} else {
quote! { None }
};
quote! {
inline_css::Selector::Colon {
name: #ident,
arg: #arg,
}
}
},
Self::Sub { left, right } => {
quote! {
inline_css::Selector::Sub {
left: Box::new(#left),
right: Box::new(#right),
}
}
},
Self::Gt { left, right, .. } => {
quote! {
inline_css::Selector::Gt {
left: Box::new(#left),
right: Box::new(#right),
}
}
},
Self::Plus { left, right, .. } => {
quote! {
inline_css::Selector::Plus {
left: Box::new(#left),
right: Box::new(#right),
}
}
},
Self::Tilde { left, right, .. } => {
quote! {
inline_css::Selector::Tilde {
left: Box::new(#left),
right: Box::new(#right),
}
}
},
Self::Comma { left, right, .. } => {
quote! {
inline_css::Selector::Comma {
left: Box::new(#left),
right: Box::new(#right),
}
}
},
};
tokens.extend(s)
}
}
impl ToTokens for Declaration {
fn to_tokens(&self, tokens: &mut TokenStream) {
let ident = &self.ident;
let value = &self.value;
let s = quote! {
inline_css::Declaration {
name: #ident,
value: vec![#(#value),*],
}
};
tokens.extend(s)
}
}
impl ToTokens for Value {
fn to_tokens(&self, tokens: &mut TokenStream) {
let s = match self {
Self::ColorCode { value, .. } => quote! { inline_css::Value::ColorCode(#value) },
Self::Ident(name) => quote! { inline_css::Value::Ident(#name) },
Self::Int(i) => {
let value: i32 = i.base10_parse().unwrap_or_else(|e| {
panic!("Failed to parse {i}: {e}")
});
let suffix = match i.suffix() {
"m" => "em",
sfx => sfx,
};
quote! {
inline_css::Value::Int(#value, #suffix.to_string())
}
},
Self::Float(f) => {
let value: f32 = f.base10_parse().unwrap();
let suffix = match f.suffix() {
"m" => "em",
sfx => sfx,
};
quote! {
inline_css::Value::Float(#value, #suffix.to_string())
}
},
Self::IntPerc(i, _) => quote! { inline_css::Value::Int(#i, "%".to_string()) },
Self::FloatPerc(f, _) => quote! { inline_css::Value::Float(#f, "%".to_string()) },
Self::Function { ident, args, .. } => {
let args = args.0.iter();
quote! {
inline_css::Value::Function {
name: #ident,
args: vec![#(#args),*],
}
}
},
Self::Block(b) => {
quote! {
#[allow(unused_braces)]
Into::<inline_css::Value>::into(#b)
}
},
};
tokens.extend(s)
}
}
impl ToTokens for CSSIdent {
fn to_tokens(&self, tokens: &mut TokenStream) {
let mut s = String::new();
for seg in &self.0 {
match seg {
CSSIdentSegment::Ident(i) => s.push_str(&i.to_string()),
CSSIdentSegment::Minus(_) => s.push('-'),
}
}
let s = quote! { #s.to_string() };
tokens.extend(s)
}
}