use proc_macro_error::proc_macro_error;
use quote::quote;
mod convert;
use convert::Convert;
mod path;
use path::extract_path;
mod parse;
use parse::{ColorResult, parse_color, extract_idents};
#[proc_macro]
#[proc_macro_error]
pub fn rgb(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (path, color, args) = extract_path(tokens.into());
let mut rgba = parse_color(color);
if let Some(args) = args {
rgba = rgba.with_idents(extract_idents(args))
}
match rgba {
ColorResult::Integers(ints) => {
let items = ints.to_int3();
quote!(#path (#(#items),*))
},
ColorResult::Floats(floats) => {
let items = floats.to_int3();
quote!(#path (#(#items),*))
},
ColorResult::Exprs(streams) => {
let streams = streams.into_iter().take(3)
.map(|x| x.unwrap_or(quote!(255)));
quote!(#path (#(#streams),*))
},
ColorResult::IntFields(ints, idents) => {
let items = ints.to_int3();
if idents.len() > 3 {
let idents = &idents[..3];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::FloatFields(floats, idents) => {
let items = floats.to_int3();
if idents.len() > 3 {
let idents = &idents[..3];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::ExprFields(streams, idents) => {
let streams = streams.into_iter().take(3)
.map(|x| x.unwrap_or(quote!(255)));
if idents.len() > 3 {
let idents = &idents[..3];
quote!(#path {#(#idents: #streams),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #streams),*})
}
}
}.into()
}
#[proc_macro]
#[proc_macro_error]
pub fn rgba(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (path, color, args) = extract_path(tokens.into());
let mut rgba = parse_color(color);
if let Some(args) = args {
rgba = rgba.with_idents(extract_idents(args))
}
match rgba {
ColorResult::Integers(ints) => {
let items = ints.to_int4();
quote!(#path (#(#items),*))
},
ColorResult::Floats(floats) => {
let items = floats.to_int4();
quote!(#path (#(#items),*))
},
ColorResult::Exprs(streams) => {
let streams = streams.into_iter()
.map(|x| x.unwrap_or(quote!(255)));
quote!(#path (#(#streams),*))
},
ColorResult::IntFields(ints, idents) => {
let items = ints.to_int4();
if idents.len() > 4 {
let idents = &idents[..4];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::FloatFields(floats, idents) => {
let items = floats.to_int4();
if idents.len() > 4 {
let idents = &idents[..4];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::ExprFields(streams, idents) => {
let streams = streams.into_iter()
.map(|x| x.unwrap_or(quote!(255)));
if idents.len() > 4 {
let idents = &idents[..4];
quote!(#path {#(#idents: #streams),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #streams),*})
}
}
}.into()
}
#[proc_macro]
#[proc_macro_error]
pub fn rgbf(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (path, color, args) = extract_path(tokens.into());
let mut rgba = parse_color(color);
if let Some(args) = args {
rgba = rgba.with_idents(extract_idents(args))
}
match rgba {
ColorResult::Integers(ints) => {
let items = ints.to_float3();
quote!(#path (#(#items),*))
},
ColorResult::Floats(floats) => {
let items = floats.to_float3();
quote!(#path (#(#items),*))
},
ColorResult::Exprs(streams) => {
let streams = streams.into_iter().take(3)
.map(|x| x.unwrap_or(quote!(1.0)));
quote!(#path (#(#streams),*))
},
ColorResult::IntFields(ints, idents) => {
let items = ints.to_float3();
if idents.len() > 3 {
let idents = &idents[..3];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::FloatFields(floats, idents) => {
let items = floats.to_float3();
if idents.len() > 3 {
let idents = &idents[..3];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::ExprFields(streams, idents) => {
let streams = streams.into_iter().take(3)
.map(|x| x.unwrap_or(quote!(1.0)));
if idents.len() > 3 {
let idents = &idents[..3];
quote!(#path {#(#idents: #streams),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #streams),*})
}
},
}.into()
}
#[proc_macro]
#[proc_macro_error]
pub fn rgbaf(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (path, color, args) = extract_path(tokens.into());
let mut rgba = parse_color(color);
if let Some(args) = args {
rgba = rgba.with_idents(extract_idents(args))
}
match rgba {
ColorResult::Integers(ints) => {
let items = ints.to_float4();
quote!(#path (#(#items),*))
},
ColorResult::Floats(floats) => {
let items = floats.to_float4();
quote!(#path (#(#items),*))
},
ColorResult::Exprs(streams) => {
let streams = streams.into_iter()
.map(|x| x.unwrap_or(quote!(1.0)));
quote!(#path (#(#streams),*))
},
ColorResult::IntFields(ints, idents) => {
let items = ints.to_float4();
if idents.len() > 4 {
let idents = &idents[..4];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::FloatFields(floats, idents) => {
let items = floats.to_float4();
if idents.len() > 4 {
let idents = &idents[..4];
quote!(#path {#(#idents: #items),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #items),*})
}
},
ColorResult::ExprFields(streams, idents) => {
let streams = streams.into_iter()
.map(|x| x.unwrap_or(quote!(1.0)));
if idents.len() > 4 {
let idents = &idents[..4];
quote!(#path {#(#idents: #streams),*, ..Default::default()})
} else {
quote!(#path {#(#idents: #streams),*})
}
}
}.into()
}