update dependencies

This commit is contained in:
ConnorSkees 2020-06-26 08:03:43 -04:00
parent 6a6be73c5f
commit 41bfea3cea
5 changed files with 49 additions and 88 deletions

View File

@ -9,7 +9,7 @@ keywords = ["scss", "sass", "css", "web"]
repository = "https://github.com/connorskees/grass" repository = "https://github.com/connorskees/grass"
authors = ["ConnorSkees <39542938+ConnorSkees@users.noreply.github.com>"] authors = ["ConnorSkees <39542938+ConnorSkees@users.noreply.github.com>"]
edition = "2018" edition = "2018"
exclude = ["*.scss", "sass-spec", "tests", "Cargo.lock"] include = ["src", "Cargo.toml", "README.md", "CHANGELOG.md"]
default-run = "grass" default-run = "grass"
[[bin]] [[bin]]
@ -52,7 +52,7 @@ num-traits = "0.2.12"
once_cell = "1.4.0" once_cell = "1.4.0"
rand = { version = "0.7.3", optional = true } rand = { version = "0.7.3", optional = true }
codemap = "0.1.3" codemap = "0.1.3"
peekmore = "0.5.1" peekmore = "0.5.2"
wasm-bindgen = { version = "0.2.63", optional = true } wasm-bindgen = { version = "0.2.63", optional = true }
beef = "0.4.4" beef = "0.4.4"
# criterion is not a dev-dependency because it makes tests take too # criterion is not a dev-dependency because it makes tests take too
@ -77,7 +77,7 @@ bench = ["criterion"]
[dev-dependencies] [dev-dependencies]
tempfile = "3.1.0" tempfile = "3.1.0"
paste = "0.1.17" paste = "0.1.18"
[profile.release] [profile.release]
debug = true debug = true

View File

@ -9,7 +9,7 @@ Spec progress as of 2020-06-22:
## Use as library ## Use as library
``` ```
fn main() -> Result<(), grass::Error> { fn main() -> Result<(), Box<grass::Error>> {
let sass = grass::from_string("a { b { color: &; } }".to_string())?; let sass = grass::from_string("a { b { color: &; } }".to_string())?;
assert_eq!(sass, "a b {\n color: a b;\n}\n"); assert_eq!(sass, "a b {\n color: a b;\n}\n");
Ok(()) Ok(())

View File

@ -14,8 +14,8 @@ impl<'a> Parser<'a> {
Err(..) => return Ok(false), Err(..) => return Ok(false),
}; };
if peeked_identifier == ident { if peeked_identifier == ident {
self.toks.take(ident.chars().count()).for_each(drop); self.toks.truncate_iterator_to_cursor();
self.toks.reset_cursor(); self.toks.next();
return Ok(true); return Ok(true);
} }
self.toks.reset_cursor(); self.toks.reset_cursor();

View File

@ -186,8 +186,9 @@ impl<'a> Parser<'a> {
if lower == "min" { if lower == "min" {
match self.try_parse_min_max("min", true)? { match self.try_parse_min_max("min", true)? {
Some((val, len)) => { Some(val) => {
self.toks.take(len).for_each(drop); self.toks.truncate_iterator_to_cursor();
self.toks.next();
return Ok( return Ok(
IntermediateValue::Value(Value::String(val, QuoteKind::None)) IntermediateValue::Value(Value::String(val, QuoteKind::None))
.span(span), .span(span),
@ -199,8 +200,9 @@ impl<'a> Parser<'a> {
} }
} else if lower == "max" { } else if lower == "max" {
match self.try_parse_min_max("max", true)? { match self.try_parse_min_max("max", true)? {
Some((val, len)) => { Some(val) => {
self.toks.take(len).for_each(drop); self.toks.truncate_iterator_to_cursor();
self.toks.next();
return Ok( return Ok(
IntermediateValue::Value(Value::String(val, QuoteKind::None)) IntermediateValue::Value(Value::String(val, QuoteKind::None))
.span(span), .span(span),
@ -691,12 +693,10 @@ impl<'a> Parser<'a> {
fn try_eat_url(&mut self) -> SassResult<Option<String>> { fn try_eat_url(&mut self) -> SassResult<Option<String>> {
let mut buf = String::from("url("); let mut buf = String::from("url(");
let mut peek_counter = 0; peek_whitespace(self.toks);
peek_counter += peek_whitespace(self.toks);
while let Some(tok) = self.toks.peek() { while let Some(tok) = self.toks.peek() {
let kind = tok.kind; let kind = tok.kind;
self.toks.advance_cursor(); self.toks.advance_cursor();
peek_counter += 1;
if kind == '!' if kind == '!'
|| kind == '%' || kind == '%'
|| kind == '&' || kind == '&'
@ -709,9 +709,7 @@ impl<'a> Parser<'a> {
} else if kind == '#' { } else if kind == '#' {
if let Some(Token { kind: '{', .. }) = self.toks.peek() { if let Some(Token { kind: '{', .. }) = self.toks.peek() {
self.toks.advance_cursor(); self.toks.advance_cursor();
peek_counter += 1; let interpolation = self.peek_interpolation()?;
let (interpolation, count) = self.peek_interpolation()?;
peek_counter += count;
match interpolation.node { match interpolation.node {
Value::String(ref s, ..) => buf.push_str(s), Value::String(ref s, ..) => buf.push_str(s),
v => buf.push_str(v.to_css_string(interpolation.span)?.borrow()), v => buf.push_str(v.to_css_string(interpolation.span)?.borrow()),
@ -721,17 +719,19 @@ impl<'a> Parser<'a> {
} }
} else if kind == ')' { } else if kind == ')' {
buf.push(')'); buf.push(')');
self.toks.take(peek_counter).for_each(drop); self.toks.truncate_iterator_to_cursor();
self.toks.next();
return Ok(Some(buf)); return Ok(Some(buf));
} else if kind.is_whitespace() { } else if kind.is_whitespace() {
peek_counter += peek_whitespace(self.toks); peek_whitespace(self.toks);
let next = match self.toks.peek() { let next = match self.toks.peek() {
Some(v) => v, Some(v) => v,
None => break, None => break,
}; };
if next.kind == ')' { if next.kind == ')' {
buf.push(')'); buf.push(')');
self.toks.take(peek_counter + 1).for_each(drop); self.toks.truncate_iterator_to_cursor();
self.toks.next();
return Ok(Some(buf)); return Ok(Some(buf));
} else { } else {
break; break;
@ -744,23 +744,20 @@ impl<'a> Parser<'a> {
Ok(None) Ok(None)
} }
fn peek_number(&mut self) -> SassResult<Option<(String, usize)>> { fn peek_number(&mut self) -> SassResult<Option<String>> {
let mut buf = String::new(); let mut buf = String::new();
let mut peek_counter = 0;
let (num, count) = self.peek_whole_number(); let num = self.peek_whole_number();
peek_counter += count;
buf.push_str(&num); buf.push_str(&num);
self.toks.advance_cursor(); self.toks.advance_cursor();
if let Some(Token { kind: '.', .. }) = self.toks.peek() { if let Some(Token { kind: '.', .. }) = self.toks.peek() {
self.toks.advance_cursor(); self.toks.advance_cursor();
let (num, count) = self.peek_whole_number(); let num = self.peek_whole_number();
if count == 0 { if num.is_empty() {
return Ok(None); return Ok(None);
} }
peek_counter += count;
buf.push_str(&num); buf.push_str(&num);
} else { } else {
self.toks.move_cursor_back().unwrap(); self.toks.move_cursor_back().unwrap();
@ -768,7 +765,7 @@ impl<'a> Parser<'a> {
let next = match self.toks.peek() { let next = match self.toks.peek() {
Some(tok) => tok, Some(tok) => tok,
None => return Ok(Some((buf, peek_counter))), None => return Ok(Some(buf)),
}; };
match next.kind { match next.kind {
@ -776,56 +773,49 @@ impl<'a> Parser<'a> {
let unit = peek_ident_no_interpolation(self.toks, true, self.span_before)?.node; let unit = peek_ident_no_interpolation(self.toks, true, self.span_before)?.node;
buf.push_str(&unit); buf.push_str(&unit);
peek_counter += unit.chars().count();
} }
'%' => { '%' => {
self.toks.advance_cursor(); self.toks.advance_cursor();
peek_counter += 1;
buf.push('%'); buf.push('%');
} }
_ => {} _ => {}
} }
Ok(Some((buf, peek_counter))) Ok(Some(buf))
} }
fn peek_whole_number(&mut self) -> (String, usize) { fn peek_whole_number(&mut self) -> String {
let mut buf = String::new(); let mut buf = String::new();
let mut peek_counter = 0;
while let Some(tok) = self.toks.peek() { while let Some(tok) = self.toks.peek() {
if tok.kind.is_ascii_digit() { if tok.kind.is_ascii_digit() {
buf.push(tok.kind); buf.push(tok.kind);
peek_counter += 1;
self.toks.advance_cursor(); self.toks.advance_cursor();
} else { } else {
return (buf, peek_counter); return buf;
} }
} }
(buf, peek_counter) buf
} }
fn try_parse_min_max( fn try_parse_min_max(
&mut self, &mut self,
fn_name: &str, fn_name: &str,
allow_comma: bool, allow_comma: bool,
) -> SassResult<Option<(String, usize)>> { ) -> SassResult<Option<String>> {
let mut buf = if allow_comma { let mut buf = if allow_comma {
format!("{}(", fn_name) format!("{}(", fn_name)
} else { } else {
String::new() String::new()
}; };
let mut peek_counter = 0; peek_whitespace(self.toks);
peek_counter += peek_whitespace(self.toks);
while let Some(tok) = self.toks.peek() { while let Some(tok) = self.toks.peek() {
let kind = tok.kind; let kind = tok.kind;
peek_counter += 1;
match kind { match kind {
'+' | '-' | '0'..='9' => { '+' | '-' | '0'..='9' => {
self.toks.advance_cursor(); self.toks.advance_cursor();
if let Some((number, count)) = self.peek_number()? { if let Some(number) = self.peek_number()? {
buf.push(kind); buf.push(kind);
buf.push_str(&number); buf.push_str(&number);
peek_counter += count;
} else { } else {
return Ok(None); return Ok(None);
} }
@ -834,9 +824,7 @@ impl<'a> Parser<'a> {
self.toks.advance_cursor(); self.toks.advance_cursor();
if let Some(Token { kind: '{', .. }) = self.toks.peek() { if let Some(Token { kind: '{', .. }) = self.toks.peek() {
self.toks.advance_cursor(); self.toks.advance_cursor();
peek_counter += 1; let interpolation = self.peek_interpolation()?;
let (interpolation, count) = self.peek_interpolation()?;
peek_counter += count;
match interpolation.node { match interpolation.node {
Value::String(ref s, ..) => buf.push_str(s), Value::String(ref s, ..) => buf.push_str(s),
v => buf.push_str(v.to_css_string(interpolation.span)?.borrow()), v => buf.push_str(v.to_css_string(interpolation.span)?.borrow()),
@ -846,30 +834,21 @@ impl<'a> Parser<'a> {
} }
} }
'c' | 'C' => { 'c' | 'C' => {
if let Some((name, additional_peek_count)) = if let Some(name) = self.try_parse_min_max_function("calc")? {
self.try_parse_min_max_function("calc")?
{
peek_counter += additional_peek_count;
buf.push_str(&name); buf.push_str(&name);
} else { } else {
return Ok(None); return Ok(None);
} }
} }
'e' | 'E' => { 'e' | 'E' => {
if let Some((name, additional_peek_count)) = if let Some(name) = self.try_parse_min_max_function("env")? {
self.try_parse_min_max_function("env")?
{
peek_counter += additional_peek_count;
buf.push_str(&name); buf.push_str(&name);
} else { } else {
return Ok(None); return Ok(None);
} }
} }
'v' | 'V' => { 'v' | 'V' => {
if let Some((name, additional_peek_count)) = if let Some(name) = self.try_parse_min_max_function("var")? {
self.try_parse_min_max_function("var")?
{
peek_counter += additional_peek_count;
buf.push_str(&name); buf.push_str(&name);
} else { } else {
return Ok(None); return Ok(None);
@ -878,9 +857,8 @@ impl<'a> Parser<'a> {
'(' => { '(' => {
self.toks.advance_cursor(); self.toks.advance_cursor();
buf.push('('); buf.push('(');
if let Some((val, len)) = self.try_parse_min_max(fn_name, false)? { if let Some(val) = self.try_parse_min_max(fn_name, false)? {
buf.push_str(&val); buf.push_str(&val);
peek_counter += len;
} else { } else {
return Ok(None); return Ok(None);
} }
@ -912,11 +890,9 @@ impl<'a> Parser<'a> {
if !matches!(self.toks.peek(), Some(Token { kind: '(', .. })) { if !matches!(self.toks.peek(), Some(Token { kind: '(', .. })) {
return Ok(None); return Ok(None);
} }
peek_counter += 1;
if let Some((val, len)) = self.try_parse_min_max(fn_name, false)? { if let Some(val) = self.try_parse_min_max(fn_name, false)? {
buf.push_str(&val); buf.push_str(&val);
peek_counter += len;
} else { } else {
return Ok(None); return Ok(None);
} }
@ -924,7 +900,7 @@ impl<'a> Parser<'a> {
_ => return Ok(None), _ => return Ok(None),
} }
peek_counter += peek_whitespace(self.toks); peek_whitespace(self.toks);
let next = match self.toks.peek() { let next = match self.toks.peek() {
Some(tok) => tok, Some(tok) => tok,
@ -933,10 +909,9 @@ impl<'a> Parser<'a> {
match next.kind { match next.kind {
')' => { ')' => {
peek_counter += 1;
self.toks.advance_cursor(); self.toks.advance_cursor();
buf.push(')'); buf.push(')');
return Ok(Some((buf, peek_counter))); return Ok(Some(buf));
} }
'+' | '-' | '*' | '/' => { '+' | '-' | '*' | '/' => {
buf.push(' '); buf.push(' ');
@ -955,19 +930,15 @@ impl<'a> Parser<'a> {
_ => return Ok(None), _ => return Ok(None),
} }
peek_counter += peek_whitespace(self.toks); peek_whitespace(self.toks);
} }
Ok(Some((buf, peek_counter))) Ok(Some(buf))
} }
#[allow(dead_code, unused_mut, unused_variables, unused_assignments)] #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
fn try_parse_min_max_function( fn try_parse_min_max_function(&mut self, fn_name: &'static str) -> SassResult<Option<String>> {
&mut self,
fn_name: &'static str,
) -> SassResult<Option<(String, usize)>> {
let mut ident = peek_ident_no_interpolation(self.toks, false, self.span_before)?.node; let mut ident = peek_ident_no_interpolation(self.toks, false, self.span_before)?.node;
let mut peek_counter = ident.chars().count();
ident.make_ascii_lowercase(); ident.make_ascii_lowercase();
if ident != fn_name { if ident != fn_name {
return Ok(None); return Ok(None);
@ -977,22 +948,17 @@ impl<'a> Parser<'a> {
} }
self.toks.advance_cursor(); self.toks.advance_cursor();
ident.push('('); ident.push('(');
peek_counter += 1;
todo!("special functions inside `min()` or `max()`") todo!("special functions inside `min()` or `max()`")
} }
fn peek_interpolation(&mut self) -> SassResult<(Spanned<Value>, usize)> { fn peek_interpolation(&mut self) -> SassResult<Spanned<Value>> {
let vec = peek_until_closing_curly_brace(self.toks)?; let vec = peek_until_closing_curly_brace(self.toks)?;
let peek_counter = vec.len();
self.toks.advance_cursor(); self.toks.advance_cursor();
let val = self.parse_value_from_vec(vec)?; let val = self.parse_value_from_vec(vec)?;
Ok(( Ok(Spanned {
Spanned { node: val.node.eval(val.span)?.node.unquote(),
node: val.node.eval(val.span)?.node.unquote(), span: val.span,
span: val.span, })
},
peek_counter,
))
} }
fn peek_escape(&mut self) -> SassResult<String> { fn peek_escape(&mut self) -> SassResult<String> {

View File

@ -26,18 +26,13 @@ pub(crate) fn devour_whitespace<I: Iterator<Item = W>, W: IsWhitespace>(
found_whitespace found_whitespace
} }
pub(crate) fn peek_whitespace<I: Iterator<Item = W>, W: IsWhitespace>( pub(crate) fn peek_whitespace<I: Iterator<Item = W>, W: IsWhitespace>(s: &mut PeekMoreIterator<I>) {
s: &mut PeekMoreIterator<I>,
) -> usize {
let mut peek_counter = 0;
while let Some(w) = s.peek() { while let Some(w) = s.peek() {
if !w.is_whitespace() { if !w.is_whitespace() {
break; break;
} }
peek_counter += 1; s.advance_cursor();
s.peek_forward(1);
} }
peek_counter
} }
/// Eat tokens until a newline /// Eat tokens until a newline