use std::str::FromStr;
use crate::{Color, Error, Stream};
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum PaintFallback {
None,
CurrentColor,
Color(Color),
}
impl quote::ToTokens for PaintFallback {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
match self {
PaintFallback::None => quote::quote! {svgrtypes::PaintFallback::None},
PaintFallback::CurrentColor => quote::quote! {svgrtypes::PaintFallback::CurrentColor},
PaintFallback::Color(color) => quote::quote! {svgrtypes::PaintFallback::Color(#color)},
}
.to_tokens(tokens)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Paint<'a> {
None,
Inherit,
CurrentColor,
Color(Color),
FuncIRI(&'a str, Option<PaintFallback>),
}
impl<'a> Paint<'a> {
#[allow(clippy::should_implement_trait)]
pub fn from_str(text: &'a str) -> Result<Self, Error> {
let text = text.trim();
match text {
"none" => Ok(Paint::None),
"inherit" => Ok(Paint::Inherit),
"currentColor" => Ok(Paint::CurrentColor),
_ => {
let mut s = Stream::from(text);
if s.starts_with(b"url(") {
match s.parse_func_iri() {
Ok(link) => {
s.skip_spaces();
if !s.at_end() {
let fallback = s.slice_tail();
match fallback {
"none" => Ok(Paint::FuncIRI(link, Some(PaintFallback::None))),
"currentColor" => {
Ok(Paint::FuncIRI(link, Some(PaintFallback::CurrentColor)))
}
_ => {
let color = Color::from_str(fallback)?;
Ok(Paint::FuncIRI(link, Some(PaintFallback::Color(color))))
}
}
} else {
Ok(Paint::FuncIRI(link, None))
}
}
Err(_) => Err(Error::InvalidValue),
}
} else {
match Color::from_str(text) {
Ok(c) => Ok(Paint::Color(c)),
Err(_) => Err(Error::InvalidValue),
}
}
}
}
}
}
#[rustfmt::skip]
#[cfg(test)]
mod tests {
use super::*;
macro_rules! test {
($name:ident, $text:expr, $result:expr) => (
#[test]
fn $name() {
assert_eq!(Paint::from_str($text).unwrap(), $result);
}
)
}
test!(parse_1, "none", Paint::None);
test!(parse_2, " none ", Paint::None);
test!(parse_3, " inherit ", Paint::Inherit);
test!(parse_4, " currentColor ", Paint::CurrentColor);
test!(parse_5, " red ", Paint::Color(Color::red()));
test!(parse_6, " url(#qwe) ", Paint::FuncIRI("qwe", None));
test!(parse_7, " url(#qwe) none ", Paint::FuncIRI("qwe", Some(PaintFallback::None)));
test!(parse_8, " url(#qwe) currentColor ", Paint::FuncIRI("qwe", Some(PaintFallback::CurrentColor)));
test!(parse_9, " url(#qwe) red ", Paint::FuncIRI("qwe", Some(PaintFallback::Color(Color::red()))));
macro_rules! test_err {
($name:ident, $text:expr, $result:expr) => (
#[test]
fn $name() {
assert_eq!(Paint::from_str($text).unwrap_err().to_string(), $result);
}
)
}
test_err!(parse_err_1, "qwe", "invalid value");
test_err!(parse_err_2, "red icc-color(acmecmyk, 0.11, 0.48, 0.83, 0.00)", "invalid value");
}