update dependencies
This commit is contained in:
parent
6a6be73c5f
commit
41bfea3cea
@ -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
|
||||||
|
@ -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(())
|
||||||
|
@ -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();
|
||||||
|
@ -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> {
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user