From 74a81060ba94c561ec307f14b735bec50985448e Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 8 Feb 2020 13:16:53 -0500 Subject: [PATCH] Remove `Color` tokenkind --- src/builtin/color.rs | 22 ++++++++++++++++++++++ src/color/mod.rs | 12 ++++++++++++ src/lexer.rs | 5 ----- src/lib.rs | 3 --- src/value.rs | 23 ++++++++++++++++------- tests/color.rs | 5 +++++ 6 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/builtin/color.rs b/src/builtin/color.rs index c3ac2f3..e3493e1 100644 --- a/src/builtin/color.rs +++ b/src/builtin/color.rs @@ -1,9 +1,13 @@ use std::collections::BTreeMap; use std::convert::TryInto; +use num_rational::BigRational; +use num_bigint::BigInt; + use super::Builtin; use crate::color::Color; use crate::value::Value; +use crate::units::Unit; pub(crate) fn register(f: &mut BTreeMap) { decl!(f "rgb", |args| { @@ -17,4 +21,22 @@ pub(crate) fn register(f: &mut BTreeMap) { todo!("channels variable in `rgb`") } }); + decl!(f "red", |args| { + match arg!(args, 0, "red") { + Value::Color(c) => Some(Value::Dimension(BigRational::from_integer(BigInt::from(c.red())), Unit::None)), + _ => todo!("non-color given to builtin function `red()`") + } + }); + decl!(f "green", |args| { + match arg!(args, 0, "green") { + Value::Color(c) => Some(Value::Dimension(BigRational::from_integer(BigInt::from(c.green())), Unit::None)), + _ => todo!("non-color given to builtin function `green()`") + } + }); + decl!(f "blue", |args| { + match arg!(args, 0, "blue") { + Value::Color(c) => Some(Value::Dimension(BigRational::from_integer(BigInt::from(c.blue())), Unit::None)), + _ => todo!("non-color given to builtin function `blue()`") + } + }); } diff --git a/src/color/mod.rs b/src/color/mod.rs index 7107844..b591dd3 100644 --- a/src/color/mod.rs +++ b/src/color/mod.rs @@ -24,6 +24,18 @@ impl Color { } } + pub const fn red(&self) -> u16 { + self.red + } + + pub const fn blue(&self) -> u16 { + self.blue + } + + pub const fn green(&self) -> u16 { + self.green + } + pub fn from_values(red: u16, green: u16, blue: u16, alpha: u16) -> Self { let repr = if alpha >= 1 { format!("#{:0>2x}{:0>2x}{:0>2x}", red, green, blue) diff --git a/src/lexer.rs b/src/lexer.rs index a513c05..cfaf068 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -3,7 +3,6 @@ use std::iter::Peekable; use std::str::Chars; use crate::atrule::AtRuleKind; -use crate::color::ColorName; use crate::common::{Keyword, Op, Pos, Symbol}; use crate::selector::{Attribute, AttributeKind, CaseKind}; use crate::{Token, TokenKind, Whitespace}; @@ -414,10 +413,6 @@ impl<'a> Lexer<'a> { return TokenKind::Keyword(kw); } - if let Ok(c) = ColorName::try_from(string.as_ref()) { - return TokenKind::Color(c.into_color(string)); - } - if string == "-" { return TokenKind::Symbol(Symbol::Minus); } diff --git a/src/lib.rs b/src/lib.rs index d1551b1..0afb454 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,6 @@ use std::iter::{Iterator, Peekable}; use std::path::Path; use crate::atrule::{AtRule, AtRuleKind}; -use crate::color::Color; use crate::common::{Keyword, Op, Pos, Scope, Symbol, Whitespace}; use crate::css::Css; use crate::error::SassError; @@ -137,7 +136,6 @@ pub(crate) enum TokenKind { Attribute(Attribute), Op(Op), MultilineComment(String), - Color(Color), Interpolation, } @@ -148,7 +146,6 @@ impl Display for TokenKind { TokenKind::Ident(s) | TokenKind::Number(s) => write!(f, "{}", s), TokenKind::Symbol(s) => write!(f, "{}", s), TokenKind::AtRule(s) => write!(f, "{}", s), - TokenKind::Color(s) => write!(f, "{}", s), TokenKind::Op(s) => write!(f, "{}", s), TokenKind::Whitespace(s) => write!(f, "{}", s), TokenKind::Attribute(s) => write!(f, "{}", s), diff --git a/src/value.rs b/src/value.rs index 05e08ea..44f30b1 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,5 +1,5 @@ #![allow(dead_code, unused_variables)] -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use std::fmt::{self, Display}; use std::iter::{Iterator, Peekable}; use std::ops::{Add, Sub}; @@ -201,6 +201,7 @@ impl TryInto for Value { type Error = &'static str; fn try_into(self) -> Result { match self { + Self::BinaryOp(..) => self.eval().try_into(), Self::Dimension(n, Unit::Percent) => { todo!() } @@ -447,6 +448,15 @@ impl Value { _ => Some(Value::Ident(s, QuoteKind::None)), } } + // TokenKind::Interpolation => { + // Some(Value::Ident( + // parse_interpolation(toks, scope) + // .iter() + // .map(|x| x.kind.to_string()) + // .collect::(), + // QuoteKind::None + // )) + // } TokenKind::Ident(mut s) => { while let Some(tok) = toks.peek() { match tok.kind.clone() { @@ -463,10 +473,6 @@ impl Value { toks.next(); s.push_str(i) } - TokenKind::Color(c) => { - toks.next(); - s.push_str(&c.to_string()) - } _ => break, } } @@ -486,7 +492,11 @@ impl Value { }; Some(func.clone().args(&args).call()) } - _ => Some(Value::Ident(s, QuoteKind::None)), + _ => if let Ok(c) = crate::color::ColorName::try_from(s.as_ref()) { + Some(Value::Color(c.into_color(s))) + } else { + Some(Value::Ident(s, QuoteKind::None)) + } } } TokenKind::Symbol(Symbol::DoubleQuote) => { @@ -544,7 +554,6 @@ impl Value { } Some(Value::Ident(s, QuoteKind::None)) } - TokenKind::Color(c) => Some(Value::Color(c)), TokenKind::Keyword(Keyword::Important) => Some(Value::Important), TokenKind::Keyword(Keyword::True) => Some(Value::True), TokenKind::Keyword(Keyword::False) => Some(Value::False), diff --git a/tests/color.rs b/tests/color.rs index 7de5282..dbd4e63 100644 --- a/tests/color.rs +++ b/tests/color.rs @@ -31,6 +31,11 @@ test!(preserves_hex_3_val_ab2, "a {\n color: #ab2;\n}\n"); // "a {\n color: rgb(0, 0, 0);\n}\n", // "a {\n color: black;\n}\n" // ); +test!( + rgb_binop, + "a {\n color: rgb(1, 2, 1+2);\n}\n", + "a {\n color: #010203;\n}\n" +); test!( rgb_pads_0, "a {\n color: rgb(1, 2, 3);\n}\n",