diff --git a/src/args.rs b/src/args.rs index 04e3f1c..e25c4bb 100644 --- a/src/args.rs +++ b/src/args.rs @@ -339,12 +339,12 @@ pub(crate) fn eat_call_args>( let mut val: Vec = Vec::new(); let mut span = toks.peek().ok_or(("expected \")\".", span_before))?.pos(); loop { - match toks.peek().unwrap().kind { - '$' => { + match toks.peek() { + Some(Token { kind: '$', .. }) => { let Token { pos, .. } = toks.next().unwrap(); let v = eat_ident_no_interpolation(toks, false, pos)?; let whitespace = devour_whitespace_or_comment(toks)?; - if toks.peek().unwrap().kind == ':' { + if let Some(Token { kind: ':', .. }) = toks.peek() { toks.next(); name = v.node; } else { @@ -362,11 +362,11 @@ pub(crate) fn eat_call_args>( name.clear(); } } - ')' => { + Some(Token { kind: ')', .. }) => { toks.next(); return Ok(CallArgs(args, span)); } - _ => name.clear(), + Some(..) | None => name.clear(), } devour_whitespace_or_comment(toks)?; diff --git a/src/atrule/mod.rs b/src/atrule/mod.rs index e883c0c..097a811 100644 --- a/src/atrule/mod.rs +++ b/src/atrule/mod.rs @@ -88,7 +88,7 @@ impl AtRule { kind_span, )?; span.merge(kind_span); - if toks.peek().unwrap().kind == ';' { + if let Some(Token { kind: ';', .. }) = toks.peek() { kind_span.merge(toks.next().unwrap().pos()); } devour_whitespace(toks); @@ -111,7 +111,7 @@ impl AtRule { kind_span, )?; span.merge(kind_span); - if toks.peek().unwrap().kind == ';' { + if let Some(Token { kind: ';', .. }) = toks.peek() { kind_span.merge(toks.next().unwrap().pos()); } devour_whitespace(toks); @@ -143,7 +143,7 @@ impl AtRule { } AtRuleKind::Return => { let v = read_until_semicolon_or_closing_curly_brace(toks)?; - if toks.peek().unwrap().kind == ';' { + if let Some(Token { kind: ';', .. }) = toks.peek() { toks.next(); } devour_whitespace(toks); @@ -205,7 +205,7 @@ impl AtRule { } AtRuleKind::Charset => { read_until_semicolon_or_closing_curly_brace(toks)?; - if toks.peek().unwrap().kind == ';' { + if let Some(Token { kind: ';', .. }) = toks.peek() { toks.next(); } devour_whitespace(toks); diff --git a/src/builtin/list.rs b/src/builtin/list.rs index 16d1f59..b245256 100644 --- a/src/builtin/list.rs +++ b/src/builtin/list.rs @@ -22,7 +22,7 @@ fn length(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassR fn nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult { args.max_args(2)?; - let list = match arg!(args, scope, super_selector, 0, "list") { + let mut list = match arg!(args, scope, super_selector, 0, "list") { Value::List(v, ..) => v, Value::Map(m) => m.entries(), v => vec![v], @@ -58,11 +58,11 @@ fn nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResu return Err((format!("$n: {} is not an int.", n), args.span()).into()); } - if n.is_positive() { - Ok(list[n.to_integer().to_usize().unwrap() - 1].clone()) + Ok(list.remove(if n.is_positive() { + n.to_integer().to_usize().unwrap_or(std::usize::MAX) - 1 } else { - Ok(list[list.len() - n.abs().to_integer().to_usize().unwrap()].clone()) - } + list.len() - n.abs().to_integer().to_usize().unwrap_or(std::usize::MAX) + })) } fn list_separator( @@ -120,9 +120,9 @@ fn set_nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> Sass let val = arg!(args, scope, super_selector, 2, "value"); if n.is_positive() { - list[n.to_integer().to_usize().unwrap() - 1] = val; + list[n.to_integer().to_usize().unwrap_or(std::usize::MAX) - 1] = val; } else { - list[len - n.abs().to_integer().to_usize().unwrap()] = val; + list[len - n.abs().to_integer().to_usize().unwrap_or(std::usize::MAX)] = val; } Ok(Value::List(list, sep, brackets)) diff --git a/src/color/mod.rs b/src/color/mod.rs index 7dd8f15..2162383 100644 --- a/src/color/mod.rs +++ b/src/color/mod.rs @@ -488,7 +488,7 @@ fn repr(red: &Number, green: &Number, blue: &Number, alpha: &Number) -> String { } else if channel.is_negative() { 0_u8 } else { - channel.round().to_integer().to_u8().unwrap() + channel.round().to_integer().to_u8().unwrap_or(255) } } diff --git a/src/lib.rs b/src/lib.rs index 5fe7757..bb521f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -241,7 +241,7 @@ pub(crate) fn eat_expr>( if values.is_empty() { toks.next(); devour_whitespace(toks); - if toks.peek().is_some() && toks.peek().unwrap().kind == ';' { + if let Some(Token { kind: ';', .. }) = toks.peek() { toks.next(); } devour_whitespace(toks); diff --git a/src/utils/chars.rs b/src/utils/chars.rs index 483f484..6f5b3c8 100644 --- a/src/utils/chars.rs +++ b/src/utils/chars.rs @@ -40,7 +40,7 @@ pub(crate) fn hex_char_for(number: u32) -> char { } pub(crate) fn is_name(c: char) -> bool { - is_name_start(c) || c.is_digit(10) || c == '-' + is_name_start(c) || c.is_ascii_digit() || c == '-' } pub(crate) fn is_name_start(c: char) -> bool { diff --git a/src/utils/read_until.rs b/src/utils/read_until.rs index 55f855d..5d1b0be 100644 --- a/src/utils/read_until.rs +++ b/src/utils/read_until.rs @@ -75,12 +75,12 @@ pub(crate) fn read_until_closing_curly_brace>( } '/' => { let next = toks.next().unwrap(); - match toks.peek().unwrap().kind { - '/' => { + match toks.peek() { + Some(Token { kind: '/', .. }) => { read_until_newline(toks); devour_whitespace(toks); } - _ => t.push(next), + Some(..) | None => t.push(next), }; continue; } @@ -180,8 +180,8 @@ pub(crate) fn read_until_semicolon_or_closing_curly_brace { let next = toks.next().unwrap(); - match toks.peek().unwrap().kind { - '/' => { + match toks.peek() { + Some(Token { kind: '/', .. }) => { read_until_newline(toks); devour_whitespace(toks); } diff --git a/src/utils/strings.rs b/src/utils/strings.rs index de18938..f731e40 100644 --- a/src/utils/strings.rs +++ b/src/utils/strings.rs @@ -173,23 +173,25 @@ pub(crate) fn eat_ident>( super_selector: &Selector, span_before: Span, ) -> SassResult> { - let mut span = toks - .peek() - .ok_or(("Expected identifier.", span_before))? - .pos(); + let Token { + kind, + pos: mut span, + } = toks.peek().ok_or(("Expected identifier.", span_before))?; let mut text = String::new(); - if toks.peek().unwrap().kind == '-' { + if kind == &'-' { toks.next(); text.push('-'); - if toks.peek().is_none() { - return Ok(Spanned { node: text, span }); - } - if toks.peek().unwrap().kind == '-' { - toks.next(); - text.push('-'); - let body_span = interpolated_ident_body(toks, scope, super_selector, span, &mut text)?; - span = span.merge(body_span); - return Ok(Spanned { node: text, span }); + match toks.peek() { + Some(Token { kind: '-', .. }) => { + toks.next(); + text.push('-'); + let body_span = + interpolated_ident_body(toks, scope, super_selector, span, &mut text)?; + span = span.merge(body_span); + return Ok(Spanned { node: text, span }); + } + Some(..) => {} + None => return Ok(Spanned { node: text, span }), } } @@ -237,37 +239,38 @@ pub(crate) fn eat_ident_no_interpolation>( unit: bool, span_before: Span, ) -> SassResult> { - let mut span = toks - .peek() - .ok_or(("Expected identifier.", span_before))? - .pos(); + let Token { + kind, + pos: mut span, + } = toks.peek().ok_or(("Expected identifier.", span_before))?; let mut text = String::new(); - if toks.peek().unwrap().kind == '-' { + if kind == &'-' { toks.next(); text.push('-'); - if toks.peek().is_none() { - return Ok(Spanned { node: text, span }); - } - if toks.peek().unwrap().kind == '-' { - toks.next(); - text.push('-'); - text.push_str(&ident_body_no_interpolation(toks, unit, span)?.node); - return Ok(Spanned { node: text, span }); + + match toks.peek() { + Some(Token { kind: '-', .. }) => { + toks.next(); + text.push('-'); + text.push_str(&ident_body_no_interpolation(toks, unit, span)?.node); + return Ok(Spanned { node: text, span }); + } + Some(..) => {} + None => return Ok(Spanned { node: text, span }), } } - let first = match toks.peek() { + let first = match toks.next() { Some(v) => v, None => return Err(("Expected identifier.", span).into()), }; if is_name_start(first.kind) { - text.push(toks.next().unwrap().kind); + text.push(first.kind); } else if first.kind == '\\' { - toks.next(); text.push_str(&escape(toks, true)?); } else { - return Err(("Expected identifier.", first.pos()).into()); + return Err(("Expected identifier.", first.pos).into()); } let body = ident_body_no_interpolation(toks, unit, span)?; @@ -325,6 +328,7 @@ pub(crate) fn parse_quoted_string>( if first.kind.is_ascii_hexdigit() { let mut value = 0; for _ in 0..6 { + // todo: or patterns let next = match toks.peek() { Some(c) => c, None => break, diff --git a/src/utils/variables.rs b/src/utils/variables.rs index cbc7483..0981196 100644 --- a/src/utils/variables.rs +++ b/src/utils/variables.rs @@ -61,17 +61,17 @@ pub(crate) fn eat_variable_value>( } '#' => { val_toks.push(toks.next().unwrap()); - match toks.peek().unwrap().kind { - '{' => nesting += 1, - ';' => break, - '}' => { + match toks.peek() { + Some(Token { kind: '{', .. }) => nesting += 1, + Some(Token { kind: ';', .. }) => break, + Some(Token { kind: '}', .. }) => { if nesting == 0 { break; } else { nesting -= 1; } } - _ => {} + Some(..) | None => {} } val_toks.push(toks.next().unwrap()); } @@ -86,9 +86,9 @@ pub(crate) fn eat_variable_value>( } '/' => { let next = toks.next().unwrap(); - match toks.peek().unwrap().kind { - '/' => read_until_newline(toks), - _ => val_toks.push(next), + match toks.peek() { + Some(Token { kind: '/', .. }) => read_until_newline(toks), + Some(..) | None => val_toks.push(next), }; continue; } diff --git a/src/value/css_function.rs b/src/value/css_function.rs index d20e848..3b9dab6 100644 --- a/src/value/css_function.rs +++ b/src/value/css_function.rs @@ -28,7 +28,7 @@ pub(crate) fn eat_calc_args>( buf.push(' '); } '#' => { - if toks.peek().is_some() && toks.peek().unwrap().kind == '{' { + if let Some(Token { kind: '{', .. }) = toks.peek() { let span_before = toks.next().unwrap().pos(); let interpolation = parse_interpolation(toks, scope, super_selector, span_before)?;