don't clone in order to construct lexer

This commit is contained in:
Connor Skees 2021-07-24 20:10:10 -04:00
parent c7e3ff39cf
commit 3ab2aa961a
37 changed files with 193 additions and 187 deletions

View File

@ -7,7 +7,7 @@ use crate::{
Token, Token,
}; };
pub(crate) type BuiltinMixin = fn(CallArgs, &mut Parser<'_>) -> SassResult<Vec<Stmt>>; pub(crate) type BuiltinMixin = fn(CallArgs, &mut Parser) -> SassResult<Vec<Stmt>>;
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum Mixin { pub(crate) enum Mixin {

View File

@ -13,7 +13,7 @@ use crate::{
value::{Number, Value}, value::{Number, Value},
}; };
fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
if args.is_empty() { if args.is_empty() {
return Err(("Missing argument $channels.", args.span()).into()); return Err(("Missing argument $channels.", args.span()).into());
} }
@ -213,15 +213,15 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) ->
} }
} }
pub(crate) fn hsl(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn hsl(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
inner_hsl("hsl", args, parser) inner_hsl("hsl", args, parser)
} }
pub(crate) fn hsla(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn hsla(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
inner_hsl("hsla", args, parser) inner_hsl("hsla", args, parser)
} }
pub(crate) fn hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn hue(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.hue()), Unit::Deg, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.hue()), Unit::Deg, true)),
@ -233,7 +233,7 @@ pub(crate) fn hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
} }
} }
pub(crate) fn saturation(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn saturation(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.saturation()), Unit::Percent, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.saturation()), Unit::Percent, true)),
@ -245,7 +245,7 @@ pub(crate) fn saturation(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
} }
} }
pub(crate) fn lightness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn lightness(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.lightness()), Unit::Percent, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.lightness()), Unit::Percent, true)),
@ -257,7 +257,7 @@ pub(crate) fn lightness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
} }
} }
pub(crate) fn adjust_hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn adjust_hue(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -286,7 +286,7 @@ pub(crate) fn adjust_hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
Ok(Value::Color(Box::new(color.adjust_hue(degrees)))) Ok(Value::Color(Box::new(color.adjust_hue(degrees))))
} }
fn lighten(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn lighten(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -315,7 +315,7 @@ fn lighten(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
Ok(Value::Color(Box::new(color.lighten(amount)))) Ok(Value::Color(Box::new(color.lighten(amount))))
} }
fn darken(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn darken(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -344,7 +344,7 @@ fn darken(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
Ok(Value::Color(Box::new(color.darken(amount)))) Ok(Value::Color(Box::new(color.darken(amount))))
} }
fn saturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn saturate(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
if args.len() == 1 { if args.len() == 1 {
return Ok(Value::String( return Ok(Value::String(
@ -389,7 +389,7 @@ fn saturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
Ok(Value::Color(Box::new(color.saturate(amount)))) Ok(Value::Color(Box::new(color.saturate(amount))))
} }
fn desaturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn desaturate(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -418,7 +418,7 @@ fn desaturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value>
Ok(Value::Color(Box::new(color.desaturate(amount)))) Ok(Value::Color(Box::new(color.desaturate(amount))))
} }
pub(crate) fn grayscale(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn grayscale(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -439,7 +439,7 @@ pub(crate) fn grayscale(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
Ok(Value::Color(Box::new(color.desaturate(Number::one())))) Ok(Value::Color(Box::new(color.desaturate(Number::one()))))
} }
pub(crate) fn complement(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn complement(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -454,7 +454,7 @@ pub(crate) fn complement(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
Ok(Value::Color(Box::new(color.complement()))) Ok(Value::Color(Box::new(color.complement())))
} }
pub(crate) fn invert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn invert(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let weight = match args.get(1, "weight") { let weight = match args.get(1, "weight") {
Some(Err(e)) => return Err(e), Some(Err(e)) => return Err(e),

View File

@ -9,7 +9,7 @@ use crate::{
value::{Number, Value}, value::{Number, Value},
}; };
pub(crate) fn blackness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn blackness(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
@ -29,7 +29,7 @@ pub(crate) fn blackness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
Ok(Value::Dimension(Some(blackness * 100), Unit::Percent, true)) Ok(Value::Dimension(Some(blackness * 100), Unit::Percent, true))
} }
pub(crate) fn whiteness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn whiteness(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
@ -48,7 +48,7 @@ pub(crate) fn whiteness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
Ok(Value::Dimension(Some(whiteness * 100), Unit::Percent, true)) Ok(Value::Dimension(Some(whiteness * 100), Unit::Percent, true))
} }
pub(crate) fn hwb(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn hwb(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(4)?; args.max_args(4)?;
if args.is_empty() { if args.is_empty() {

View File

@ -35,7 +35,7 @@ mod test {
} }
} }
pub(crate) fn alpha(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn alpha(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
if args.len() <= 1 { if args.len() <= 1 {
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.alpha()), Unit::None, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.alpha()), Unit::None, true)),
@ -69,7 +69,7 @@ pub(crate) fn alpha(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
} }
} }
pub(crate) fn opacity(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn opacity(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.alpha()), Unit::None, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.alpha()), Unit::None, true)),
@ -87,7 +87,7 @@ pub(crate) fn opacity(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult
} }
// todo: unify `opacify` and `fade_in` // todo: unify `opacify` and `fade_in`
fn opacify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn opacify(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -113,7 +113,7 @@ fn opacify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
Ok(Value::Color(Box::new(color.fade_in(amount)))) Ok(Value::Color(Box::new(color.fade_in(amount))))
} }
fn fade_in(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn fade_in(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -140,7 +140,7 @@ fn fade_in(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
} }
// todo: unify with `fade_out` // todo: unify with `fade_out`
fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn transparentize(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
@ -166,7 +166,7 @@ fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
Ok(Value::Color(Box::new(color.fade_out(amount)))) Ok(Value::Color(Box::new(color.fade_out(amount))))
} }
fn fade_out(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn fade_out(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,

View File

@ -48,7 +48,7 @@ macro_rules! opt_hsl {
}; };
} }
pub(crate) fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn change_color(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
if args.positional_arg(1).is_some() { if args.positional_arg(1).is_some() {
return Err(( return Err((
"Only one positional argument is allowed. All other arguments must be passed by name.", "Only one positional argument is allowed. All other arguments must be passed by name.",
@ -116,7 +116,7 @@ pub(crate) fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
})) }))
} }
pub(crate) fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn adjust_color(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,
v => { v => {
@ -179,7 +179,7 @@ pub(crate) fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
// todo: refactor into rgb and hsl? // todo: refactor into rgb and hsl?
pub(crate) fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn scale_color(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
pub(crate) fn scale(val: Number, by: Number, max: Number) -> Number { pub(crate) fn scale(val: Number, by: Number, max: Number) -> Number {
if by.is_zero() { if by.is_zero() {
return val; return val;
@ -293,7 +293,7 @@ pub(crate) fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRe
})) }))
} }
pub(crate) fn ie_hex_str(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn ie_hex_str(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match args.get_err(0, "color")? { let color = match args.get_err(0, "color")? {
Value::Color(c) => c, Value::Color(c) => c,

View File

@ -15,7 +15,7 @@ use crate::{
/// name: Either `rgb` or `rgba` depending on the caller /// name: Either `rgb` or `rgba` depending on the caller
// todo: refactor into smaller functions // todo: refactor into smaller functions
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
if args.is_empty() { if args.is_empty() {
return Err(("Missing argument $channels.", args.span()).into()); return Err(("Missing argument $channels.", args.span()).into());
} }
@ -350,15 +350,15 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) ->
} }
} }
pub(crate) fn rgb(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn rgb(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
inner_rgb("rgb", args, parser) inner_rgb("rgb", args, parser)
} }
pub(crate) fn rgba(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn rgba(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
inner_rgb("rgba", args, parser) inner_rgb("rgba", args, parser)
} }
pub(crate) fn red(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn red(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.red()), Unit::None, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.red()), Unit::None, true)),
@ -370,7 +370,7 @@ pub(crate) fn red(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
} }
} }
pub(crate) fn green(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn green(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.green()), Unit::None, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.green()), Unit::None, true)),
@ -382,7 +382,7 @@ pub(crate) fn green(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
} }
} }
pub(crate) fn blue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn blue(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "color")? { match args.get_err(0, "color")? {
Value::Color(c) => Ok(Value::Dimension(Some(c.blue()), Unit::None, true)), Value::Color(c) => Ok(Value::Dimension(Some(c.blue()), Unit::None, true)),
@ -394,7 +394,7 @@ pub(crate) fn blue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
} }
} }
pub(crate) fn mix(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn mix(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let color1 = match args.get_err(0, "color1")? { let color1 = match args.get_err(0, "color1")? {
Value::Color(c) => c, Value::Color(c) => c,

View File

@ -11,7 +11,7 @@ use crate::{
value::{Number, Value}, value::{Number, Value},
}; };
pub(crate) fn length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn length(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::Dimension( Ok(Value::Dimension(
Some(Number::from(args.get_err(0, "list")?.as_list().len())), Some(Number::from(args.get_err(0, "list")?.as_list().len())),
@ -20,7 +20,7 @@ pub(crate) fn length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<
)) ))
} }
pub(crate) fn nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn nth(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let mut list = args.get_err(0, "list")?.as_list(); let mut list = args.get_err(0, "list")?.as_list();
let (n, unit) = match args.get_err(1, "n")? { let (n, unit) = match args.get_err(1, "n")? {
@ -65,7 +65,7 @@ pub(crate) fn nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
})) }))
} }
pub(crate) fn list_separator(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn list_separator(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::String( Ok(Value::String(
match args.get_err(0, "list")? { match args.get_err(0, "list")? {
@ -78,7 +78,7 @@ pub(crate) fn list_separator(mut args: CallArgs, parser: &mut Parser<'_>) -> Sas
)) ))
} }
pub(crate) fn set_nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn set_nth(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (mut list, sep, brackets) = match args.get_err(0, "list")? { let (mut list, sep, brackets) = match args.get_err(0, "list")? {
Value::List(v, sep, b) => (v, sep, b), Value::List(v, sep, b) => (v, sep, b),
@ -136,7 +136,7 @@ pub(crate) fn set_nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult
Ok(Value::List(list, sep, brackets)) Ok(Value::List(list, sep, brackets))
} }
pub(crate) fn append(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn append(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (mut list, sep, brackets) = match args.get_err(0, "list")? { let (mut list, sep, brackets) = match args.get_err(0, "list")? {
Value::List(v, sep, b) => (v, sep, b), Value::List(v, sep, b) => (v, sep, b),
@ -174,7 +174,7 @@ pub(crate) fn append(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<
Ok(Value::List(list, sep, brackets)) Ok(Value::List(list, sep, brackets))
} }
pub(crate) fn join(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn join(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(4)?; args.max_args(4)?;
let (mut list1, sep1, brackets) = match args.get_err(0, "list1")? { let (mut list1, sep1, brackets) = match args.get_err(0, "list1")? {
Value::List(v, sep, brackets) => (v, sep, brackets), Value::List(v, sep, brackets) => (v, sep, brackets),
@ -241,7 +241,7 @@ pub(crate) fn join(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
Ok(Value::List(list1, sep, brackets)) Ok(Value::List(list1, sep, brackets))
} }
pub(crate) fn is_bracketed(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn is_bracketed(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::bool(match args.get_err(0, "list")? { Ok(Value::bool(match args.get_err(0, "list")? {
Value::List(.., brackets) => match brackets { Value::List(.., brackets) => match brackets {
@ -252,7 +252,7 @@ pub(crate) fn is_bracketed(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
})) }))
} }
pub(crate) fn index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn index(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let list = args.get_err(0, "list")?.as_list(); let list = args.get_err(0, "list")?.as_list();
let value = args.get_err(1, "value")?; let value = args.get_err(1, "value")?;
@ -263,7 +263,7 @@ pub(crate) fn index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
Ok(Value::Dimension(Some(index), Unit::None, true)) Ok(Value::Dimension(Some(index), Unit::None, true))
} }
pub(crate) fn zip(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn zip(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let lists = args let lists = args
.get_variadic()? .get_variadic()?
.into_iter() .into_iter()

View File

@ -8,7 +8,7 @@ use crate::{
value::{SassMap, Value}, value::{SassMap, Value},
}; };
pub(crate) fn map_get(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_get(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let key = args.get_err(1, "key")?; let key = args.get_err(1, "key")?;
let map = match args.get_err(0, "map")? { let map = match args.get_err(0, "map")? {
@ -26,7 +26,7 @@ pub(crate) fn map_get(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult
Ok(map.get(&key).unwrap_or(Value::Null)) Ok(map.get(&key).unwrap_or(Value::Null))
} }
pub(crate) fn map_has_key(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_has_key(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let key = args.get_err(1, "key")?; let key = args.get_err(1, "key")?;
let map = match args.get_err(0, "map")? { let map = match args.get_err(0, "map")? {
@ -44,7 +44,7 @@ pub(crate) fn map_has_key(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRe
Ok(Value::bool(map.get(&key).is_some())) Ok(Value::bool(map.get(&key).is_some()))
} }
pub(crate) fn map_keys(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_keys(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let map = match args.get_err(0, "map")? { let map = match args.get_err(0, "map")? {
Value::Map(m) => m, Value::Map(m) => m,
@ -65,7 +65,7 @@ pub(crate) fn map_keys(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResul
)) ))
} }
pub(crate) fn map_values(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_values(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let map = match args.get_err(0, "map")? { let map = match args.get_err(0, "map")? {
Value::Map(m) => m, Value::Map(m) => m,
@ -86,7 +86,7 @@ pub(crate) fn map_values(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
)) ))
} }
pub(crate) fn map_merge(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_merge(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
if args.len() == 1 { if args.len() == 1 {
return Err(("Expected $args to contain a key.", args.span()).into()); return Err(("Expected $args to contain a key.", args.span()).into());
} }
@ -163,7 +163,7 @@ pub(crate) fn map_merge(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
Ok(Value::Map(map1)) Ok(Value::Map(map1))
} }
pub(crate) fn map_remove(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_remove(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let mut map = match args.get_err(0, "map")? { let mut map = match args.get_err(0, "map")? {
Value::Map(m) => m, Value::Map(m) => m,
Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::List(v, ..) if v.is_empty() => SassMap::new(),
@ -183,7 +183,7 @@ pub(crate) fn map_remove(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
Ok(Value::Map(map)) Ok(Value::Map(map))
} }
pub(crate) fn map_set(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn map_set(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let key_position = args.len().saturating_sub(2); let key_position = args.len().saturating_sub(2);
let value_position = args.len().saturating_sub(1); let value_position = args.len().saturating_sub(1);

View File

@ -14,7 +14,7 @@ use crate::{
value::{Number, Value}, value::{Number, Value},
}; };
pub(crate) fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn percentage(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let num = match args.get_err(0, "number")? { let num = match args.get_err(0, "number")? {
Value::Dimension(Some(n), Unit::None, _) => Some(n * Number::from(100)), Value::Dimension(Some(n), Unit::None, _) => Some(n * Number::from(100)),
@ -40,7 +40,7 @@ pub(crate) fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
Ok(Value::Dimension(num, Unit::Percent, true)) Ok(Value::Dimension(num, Unit::Percent, true))
} }
pub(crate) fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn round(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "number")? { match args.get_err(0, "number")? {
Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.round()), u, true)), Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.round()), u, true)),
@ -53,7 +53,7 @@ pub(crate) fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
} }
} }
pub(crate) fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn ceil(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "number")? { match args.get_err(0, "number")? {
Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.ceil()), u, true)), Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.ceil()), u, true)),
@ -66,7 +66,7 @@ pub(crate) fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
} }
} }
pub(crate) fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn floor(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "number")? { match args.get_err(0, "number")? {
Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.floor()), u, true)), Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.floor()), u, true)),
@ -79,7 +79,7 @@ pub(crate) fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
} }
} }
pub(crate) fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn abs(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "number")? { match args.get_err(0, "number")? {
Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.abs()), u, true)), Value::Dimension(Some(n), u, _) => Ok(Value::Dimension(Some(n.abs()), u, true)),
@ -92,7 +92,7 @@ pub(crate) fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
} }
} }
pub(crate) fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn comparable(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let unit1 = match args.get_err(0, "number1")? { let unit1 = match args.get_err(0, "number1")? {
Value::Dimension(_, u, _) => u, Value::Dimension(_, u, _) => u,
@ -120,7 +120,7 @@ pub(crate) fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
// TODO: write tests for this // TODO: write tests for this
#[cfg(feature = "random")] #[cfg(feature = "random")]
pub(crate) fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn random(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let limit = match args.default_arg(0, "limit", Value::Null)? { let limit = match args.default_arg(0, "limit", Value::Null)? {
Value::Dimension(Some(n), ..) => n, Value::Dimension(Some(n), ..) => n,
@ -179,7 +179,7 @@ pub(crate) fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<
)) ))
} }
pub(crate) fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn min(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.min_args(1)?; args.min_args(1)?;
let span = args.span(); let span = args.span();
let mut nums = args let mut nums = args
@ -225,7 +225,7 @@ pub(crate) fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value>
Ok(Value::Dimension(Some(min.0), min.1, true)) Ok(Value::Dimension(Some(min.0), min.1, true))
} }
pub(crate) fn max(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn max(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.min_args(1)?; args.min_args(1)?;
let span = args.span(); let span = args.span();
let mut nums = args let mut nums = args
@ -271,7 +271,7 @@ pub(crate) fn max(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value>
Ok(Value::Dimension(Some(max.0), max.1, true)) Ok(Value::Dimension(Some(max.0), max.1, true))
} }
pub(crate) fn divide(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn divide(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let number1 = args.get_err(0, "number1")?; let number1 = args.get_err(0, "number1")?;

View File

@ -11,7 +11,7 @@ use crate::{
value::{SassFunction, Value}, value::{SassFunction, Value},
}; };
fn if_(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn if_(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
if args.get_err(0, "condition")?.is_true() { if args.get_err(0, "condition")?.is_true() {
Ok(args.get_err(1, "if-true")?) Ok(args.get_err(1, "if-true")?)
@ -20,7 +20,7 @@ fn if_(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
} }
} }
pub(crate) fn feature_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn feature_exists(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "feature")? { match args.get_err(0, "feature")? {
#[allow(clippy::match_same_arms)] #[allow(clippy::match_same_arms)]
@ -50,7 +50,7 @@ pub(crate) fn feature_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> Sas
} }
} }
pub(crate) fn unit(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn unit(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let unit = match args.get_err(0, "number")? { let unit = match args.get_err(0, "number")? {
Value::Dimension(_, u, _) => u.to_string(), Value::Dimension(_, u, _) => u.to_string(),
@ -65,13 +65,13 @@ pub(crate) fn unit(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
Ok(Value::String(unit, QuoteKind::Quoted)) Ok(Value::String(unit, QuoteKind::Quoted))
} }
pub(crate) fn type_of(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn type_of(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let value = args.get_err(0, "value")?; let value = args.get_err(0, "value")?;
Ok(Value::String(value.kind().to_owned(), QuoteKind::None)) Ok(Value::String(value.kind().to_owned(), QuoteKind::None))
} }
pub(crate) fn unitless(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn unitless(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(match args.get_err(0, "number")? { Ok(match args.get_err(0, "number")? {
Value::Dimension(_, Unit::None, _) => Value::True, Value::Dimension(_, Unit::None, _) => Value::True,
@ -86,7 +86,7 @@ pub(crate) fn unitless(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResul
}) })
} }
pub(crate) fn inspect(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn inspect(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::String( Ok(Value::String(
args.get_err(0, "value")?.inspect(args.span())?.into_owned(), args.get_err(0, "value")?.inspect(args.span())?.into_owned(),
@ -94,7 +94,7 @@ pub(crate) fn inspect(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult
)) ))
} }
pub(crate) fn variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn variable_exists(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "name")? { match args.get_err(0, "name")? {
Value::String(s, _) => Ok(Value::bool( Value::String(s, _) => Ok(Value::bool(
@ -108,10 +108,7 @@ pub(crate) fn variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> Sa
} }
} }
pub(crate) fn global_variable_exists( pub(crate) fn global_variable_exists(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
mut args: CallArgs,
parser: &mut Parser<'_>,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let name: Identifier = match args.get_err(0, "name")? { let name: Identifier = match args.get_err(0, "name")? {
@ -147,7 +144,7 @@ pub(crate) fn global_variable_exists(
})) }))
} }
pub(crate) fn mixin_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn mixin_exists(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let name: Identifier = match args.get_err(0, "name")? { let name: Identifier = match args.get_err(0, "name")? {
Value::String(s, _) => s.into(), Value::String(s, _) => s.into(),
@ -182,7 +179,7 @@ pub(crate) fn mixin_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
})) }))
} }
pub(crate) fn function_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn function_exists(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let name: Identifier = match args.get_err(0, "name")? { let name: Identifier = match args.get_err(0, "name")? {
@ -218,7 +215,7 @@ pub(crate) fn function_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> Sa
})) }))
} }
pub(crate) fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn get_function(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let name: Identifier = match args.get_err(0, "name")? { let name: Identifier = match args.get_err(0, "name")? {
Value::String(s, _) => s.into(), Value::String(s, _) => s.into(),
@ -272,7 +269,7 @@ pub(crate) fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassR
Ok(Value::FunctionRef(func)) Ok(Value::FunctionRef(func))
} }
pub(crate) fn call(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn call(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let func = match args.get_err(0, "function")? { let func = match args.get_err(0, "function")? {
Value::FunctionRef(f) => f, Value::FunctionRef(f) => f,
v => { v => {
@ -290,7 +287,7 @@ pub(crate) fn call(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
} }
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub(crate) fn content_exists(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn content_exists(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(0)?; args.max_args(0)?;
if !parser.flags.in_mixin() { if !parser.flags.in_mixin() {
return Err(( return Err((
@ -305,7 +302,7 @@ pub(crate) fn content_exists(args: CallArgs, parser: &mut Parser<'_>) -> SassRes
} }
#[allow(unused_variables, clippy::needless_pass_by_value)] #[allow(unused_variables, clippy::needless_pass_by_value)]
pub(crate) fn keywords(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn keywords(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Err(( Err((

View File

@ -27,13 +27,10 @@ static FUNCTION_COUNT: AtomicUsize = AtomicUsize::new(0);
// TODO: impl Fn // TODO: impl Fn
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct Builtin( pub(crate) struct Builtin(pub fn(CallArgs, &mut Parser) -> SassResult<Value>, usize);
pub fn(CallArgs, &mut Parser<'_>) -> SassResult<Value>,
usize,
);
impl Builtin { impl Builtin {
pub fn new(body: fn(CallArgs, &mut Parser<'_>) -> SassResult<Value>) -> Builtin { pub fn new(body: fn(CallArgs, &mut Parser) -> SassResult<Value>) -> Builtin {
let count = FUNCTION_COUNT.fetch_add(1, Ordering::Relaxed); let count = FUNCTION_COUNT.fetch_add(1, Ordering::Relaxed);
Self(body, count) Self(body, count)
} }

View File

@ -9,7 +9,7 @@ use crate::{
value::Value, value::Value,
}; };
pub(crate) fn is_superselector(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn is_superselector(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let parent_selector = args let parent_selector = args
.get_err(0, "super")? .get_err(0, "super")?
@ -21,7 +21,7 @@ pub(crate) fn is_superselector(mut args: CallArgs, parser: &mut Parser<'_>) -> S
)) ))
} }
pub(crate) fn simple_selectors(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn simple_selectors(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
// todo: Value::to_compound_selector // todo: Value::to_compound_selector
let selector = args let selector = args
@ -51,7 +51,7 @@ pub(crate) fn simple_selectors(mut args: CallArgs, parser: &mut Parser<'_>) -> S
)) ))
} }
pub(crate) fn selector_parse(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn selector_parse(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(args Ok(args
.get_err(0, "selector")? .get_err(0, "selector")?
@ -60,7 +60,7 @@ pub(crate) fn selector_parse(mut args: CallArgs, parser: &mut Parser<'_>) -> Sas
.into_value()) .into_value())
} }
pub(crate) fn selector_nest(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn selector_nest(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let span = args.span(); let span = args.span();
let selectors = args.get_variadic()?; let selectors = args.get_variadic()?;
if selectors.is_empty() { if selectors.is_empty() {
@ -81,7 +81,7 @@ pub(crate) fn selector_nest(args: CallArgs, parser: &mut Parser<'_>) -> SassResu
.into_value()) .into_value())
} }
pub(crate) fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn selector_append(args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
let span = args.span(); let span = args.span();
let selectors = args.get_variadic()?; let selectors = args.get_variadic()?;
if selectors.is_empty() { if selectors.is_empty() {
@ -129,7 +129,7 @@ pub(crate) fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassRe
.into_value()) .into_value())
} }
pub(crate) fn selector_extend(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn selector_extend(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let selector = args let selector = args
.get_err(0, "selector")? .get_err(0, "selector")?
@ -144,7 +144,7 @@ pub(crate) fn selector_extend(mut args: CallArgs, parser: &mut Parser<'_>) -> Sa
Ok(Extender::extend(selector.0, source.0, target.0, args.span())?.to_sass_list()) Ok(Extender::extend(selector.0, source.0, target.0, args.span())?.to_sass_list())
} }
pub(crate) fn selector_replace(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn selector_replace(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let selector = args let selector = args
.get_err(0, "selector")? .get_err(0, "selector")?
@ -158,7 +158,7 @@ pub(crate) fn selector_replace(mut args: CallArgs, parser: &mut Parser<'_>) -> S
Ok(Extender::replace(selector.0, source.0, target.0, args.span())?.to_sass_list()) Ok(Extender::replace(selector.0, source.0, target.0, args.span())?.to_sass_list())
} }
pub(crate) fn selector_unify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn selector_unify(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let selector1 = args let selector1 = args
.get_err(0, "selector1")? .get_err(0, "selector1")?

View File

@ -15,7 +15,7 @@ use crate::{
value::{Number, Value}, value::{Number, Value},
}; };
pub(crate) fn to_upper_case(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn to_upper_case(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "string")? { match args.get_err(0, "string")? {
Value::String(mut i, q) => { Value::String(mut i, q) => {
@ -30,7 +30,7 @@ pub(crate) fn to_upper_case(mut args: CallArgs, parser: &mut Parser<'_>) -> Sass
} }
} }
pub(crate) fn to_lower_case(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn to_lower_case(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "string")? { match args.get_err(0, "string")? {
Value::String(mut i, q) => { Value::String(mut i, q) => {
@ -45,7 +45,7 @@ pub(crate) fn to_lower_case(mut args: CallArgs, parser: &mut Parser<'_>) -> Sass
} }
} }
pub(crate) fn str_length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn str_length(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "string")? { match args.get_err(0, "string")? {
Value::String(i, _) => Ok(Value::Dimension( Value::String(i, _) => Ok(Value::Dimension(
@ -61,7 +61,7 @@ pub(crate) fn str_length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
} }
} }
pub(crate) fn quote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn quote(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "string")? { match args.get_err(0, "string")? {
Value::String(i, _) => Ok(Value::String(i, QuoteKind::Quoted)), Value::String(i, _) => Ok(Value::String(i, QuoteKind::Quoted)),
@ -73,7 +73,7 @@ pub(crate) fn quote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
} }
} }
pub(crate) fn unquote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn unquote(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match args.get_err(0, "string")? { match args.get_err(0, "string")? {
i @ Value::String(..) => Ok(i.unquote()), i @ Value::String(..) => Ok(i.unquote()),
@ -85,7 +85,7 @@ pub(crate) fn unquote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult
} }
} }
pub(crate) fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn str_slice(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (string, quotes) = match args.get_err(0, "string")? { let (string, quotes) = match args.get_err(0, "string")? {
Value::String(s, q) => (s, q), Value::String(s, q) => (s, q),
@ -184,7 +184,7 @@ pub(crate) fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
} }
} }
pub(crate) fn str_index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn str_index(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let s1 = match args.get_err(0, "string")? { let s1 = match args.get_err(0, "string")? {
Value::String(i, _) => i, Value::String(i, _) => i,
@ -214,7 +214,7 @@ pub(crate) fn str_index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResu
}) })
} }
pub(crate) fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn str_insert(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (s1, quotes) = match args.get_err(0, "string")? { let (s1, quotes) = match args.get_err(0, "string")? {
Value::String(i, q) => (i, q), Value::String(i, q) => (i, q),
@ -314,7 +314,7 @@ pub(crate) fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
#[cfg(feature = "random")] #[cfg(feature = "random")]
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub(crate) fn unique_id(args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { pub(crate) fn unique_id(args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(0)?; args.max_args(0)?;
let mut rng = thread_rng(); let mut rng = thread_rng();
let string = std::iter::repeat(()) let string = std::iter::repeat(())

View File

@ -19,7 +19,7 @@ use crate::{
#[cfg(feature = "random")] #[cfg(feature = "random")]
use crate::builtin::math::random; use crate::builtin::math::random;
fn clamp(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn clamp(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let span = args.span(); let span = args.span();
@ -101,7 +101,7 @@ fn clamp(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
Ok(number) Ok(number)
} }
fn hypot(args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn hypot(args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.min_args(1)?; args.min_args(1)?;
let span = args.span(); let span = args.span();
@ -172,7 +172,7 @@ fn hypot(args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
Ok(Value::Dimension(sum.sqrt(), first.1, true)) Ok(Value::Dimension(sum.sqrt(), first.1, true))
} }
fn log(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn log(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let number = match args.get_err(0, "number")? { let number = match args.get_err(0, "number")? {
@ -239,7 +239,7 @@ fn log(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
)) ))
} }
fn pow(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn pow(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let base = match args.get_err(0, "base")? { let base = match args.get_err(0, "base")? {
@ -289,7 +289,7 @@ fn pow(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
Ok(Value::Dimension(base.pow(exponent), Unit::None, true)) Ok(Value::Dimension(base.pow(exponent), Unit::None, true))
} }
fn sqrt(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn sqrt(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let number = args.get_err(0, "number")?; let number = args.get_err(0, "number")?;
@ -318,7 +318,7 @@ fn sqrt(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
macro_rules! trig_fn { macro_rules! trig_fn {
($name:ident, $name_deg:ident) => { ($name:ident, $name_deg:ident) => {
fn $name(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn $name(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let number = args.get_err(0, "number")?; let number = args.get_err(0, "number")?;
@ -357,7 +357,7 @@ trig_fn!(cos, cos_deg);
trig_fn!(sin, sin_deg); trig_fn!(sin, sin_deg);
trig_fn!(tan, tan_deg); trig_fn!(tan, tan_deg);
fn acos(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn acos(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let number = args.get_err(0, "number")?; let number = args.get_err(0, "number")?;
@ -394,7 +394,7 @@ fn acos(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
}) })
} }
fn asin(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn asin(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let number = args.get_err(0, "number")?; let number = args.get_err(0, "number")?;
@ -429,7 +429,7 @@ fn asin(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
}) })
} }
fn atan(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn atan(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let number = args.get_err(0, "number")?; let number = args.get_err(0, "number")?;
@ -462,7 +462,7 @@ fn atan(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> {
}) })
} }
fn atan2(mut args: CallArgs, _: &mut Parser<'_>) -> SassResult<Value> { fn atan2(mut args: CallArgs, _: &mut Parser) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let (y_num, y_unit) = match args.get_err(0, "y")? { let (y_num, y_unit) = match args.get_err(0, "y")? {
Value::Dimension(n, u, ..) => (n, u), Value::Dimension(n, u, ..) => (n, u),

View File

@ -14,7 +14,7 @@ use crate::{
value::Value, value::Value,
}; };
fn load_css(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Vec<Stmt>> { fn load_css(mut args: CallArgs, parser: &mut Parser) -> SassResult<Vec<Stmt>> {
args.max_args(2)?; args.max_args(2)?;
let span = args.span(); let span = args.span();
@ -69,7 +69,7 @@ fn load_css(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Vec<Stmt>
} }
} }
fn module_functions(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn module_functions(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let module = match args.get_err(0, "module")? { let module = match args.get_err(0, "module")? {
@ -88,7 +88,7 @@ fn module_functions(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<V
)) ))
} }
fn module_variables(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn module_variables(mut args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let module = match args.get_err(0, "module")? { let module = match args.get_err(0, "module")? {

View File

@ -198,7 +198,7 @@ impl Module {
pub fn insert_builtin( pub fn insert_builtin(
&mut self, &mut self,
name: &'static str, name: &'static str,
function: fn(CallArgs, &mut Parser<'_>) -> SassResult<Value>, function: fn(CallArgs, &mut Parser) -> SassResult<Value>,
) { ) {
let ident = name.into(); let ident = name.into();
self.scope self.scope

View File

@ -1,4 +1,4 @@
use std::{iter::Peekable, str::Chars, sync::Arc}; use std::{borrow::Cow, iter::Peekable, str::Chars, sync::Arc};
use codemap::File; use codemap::File;
@ -7,13 +7,13 @@ use crate::Token;
const FORM_FEED: char = '\x0C'; const FORM_FEED: char = '\x0C';
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct Lexer { pub(crate) struct Lexer<'a> {
buf: Vec<Token>, buf: Cow<'a, [Token]>,
cursor: usize, cursor: usize,
amt_peeked: usize, amt_peeked: usize,
} }
impl Lexer { impl<'a> Lexer<'a> {
fn peek_cursor(&self) -> usize { fn peek_cursor(&self) -> usize {
self.cursor + self.amt_peeked self.cursor + self.amt_peeked
} }
@ -64,7 +64,7 @@ impl Lexer {
} }
} }
impl Iterator for Lexer { impl<'a> Iterator for Lexer<'a> {
type Item = Token; type Item = Token;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -106,7 +106,7 @@ impl<'a> Iterator for TokenLexer<'a> {
} }
} }
impl Lexer { impl<'a> Lexer<'a> {
pub fn new_from_file(file: &Arc<File>) -> Self { pub fn new_from_file(file: &Arc<File>) -> Self {
let buf = TokenLexer { let buf = TokenLexer {
file: Arc::clone(file), file: Arc::clone(file),
@ -118,9 +118,17 @@ impl Lexer {
Self::new(buf) Self::new(buf)
} }
pub fn new(buf: Vec<Token>) -> Lexer { pub fn new(buf: Vec<Token>) -> Self {
Lexer { Lexer {
buf, buf: Cow::Owned(buf),
cursor: 0,
amt_peeked: 0,
}
}
pub fn new_ref(buf: &'a [Token]) -> Lexer<'a> {
Lexer {
buf: Cow::Borrowed(buf),
cursor: 0, cursor: 0,
amt_peeked: 0, amt_peeked: 0,
} }

View File

@ -14,7 +14,7 @@ use crate::{
use super::Parser; use super::Parser;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn parse_func_args(&mut self) -> SassResult<FuncArgs> { pub(super) fn parse_func_args(&mut self) -> SassResult<FuncArgs> {
let mut args: Vec<FuncArg> = Vec::new(); let mut args: Vec<FuncArg> = Vec::new();
let mut close_paren_span: Span = match self.toks.peek() { let mut close_paren_span: Span = match self.toks.peek() {
@ -350,8 +350,12 @@ impl<'a> Parser<'a> {
} }
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn eval_args(&mut self, fn_args: FuncArgs, mut args: CallArgs) -> SassResult<Scope> { pub(super) fn eval_args(
&mut self,
fn_args: &FuncArgs,
mut args: CallArgs,
) -> SassResult<Scope> {
let mut scope = Scope::new(); let mut scope = Scope::new();
if fn_args.0.is_empty() { if fn_args.0.is_empty() {
args.max_args(0)?; args.max_args(0)?;
@ -363,7 +367,7 @@ impl<'a> Parser<'a> {
} }
self.scopes.enter_new_scope(); self.scopes.enter_new_scope();
for (idx, mut arg) in fn_args.0.into_iter().enumerate() { for (idx, arg) in fn_args.0.iter().enumerate() {
if arg.is_variadic { if arg.is_variadic {
let arg_list = Value::ArgList(args.get_variadic()?); let arg_list = Value::ArgList(args.get_variadic()?);
scope.insert_var(arg.name, arg_list); scope.insert_var(arg.name, arg_list);
@ -372,8 +376,8 @@ impl<'a> Parser<'a> {
let val = match args.get(idx, arg.name) { let val = match args.get(idx, arg.name) {
Some(v) => v, Some(v) => v,
None => match arg.default.as_mut() { None => match arg.default.as_ref() {
Some(v) => self.parse_value_from_vec(mem::take(v), true), Some(v) => self.parse_value_from_vec(v, true),
None => { None => {
return Err( return Err(
(format!("Missing argument ${}.", &arg.name), args.span()).into() (format!("Missing argument ${}.", &arg.name), args.span()).into()

View File

@ -12,7 +12,7 @@ use crate::{
Token, Token,
}; };
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn parse_if(&mut self) -> SassResult<Vec<Stmt>> { pub(super) fn parse_if(&mut self) -> SassResult<Vec<Stmt>> {
self.whitespace_or_comment(); self.whitespace_or_comment();
@ -271,7 +271,7 @@ impl<'a> Parser<'a> {
); );
if self.flags.in_function() { if self.flags.in_function() {
let these_stmts = Parser { let these_stmts = Parser {
toks: &mut Lexer::new(body.clone()), toks: &mut Lexer::new_ref(&body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,
@ -295,7 +295,7 @@ impl<'a> Parser<'a> {
} else { } else {
stmts.append( stmts.append(
&mut Parser { &mut Parser {
toks: &mut Lexer::new(body.clone()), toks: &mut Lexer::new_ref(&body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,
@ -343,12 +343,12 @@ impl<'a> Parser<'a> {
}); });
let mut stmts = Vec::new(); let mut stmts = Vec::new();
let mut val = self.parse_value_from_vec(cond.clone(), true)?; let mut val = self.parse_value_from_vec(&cond, true)?;
self.scopes.enter_new_scope(); self.scopes.enter_new_scope();
while val.node.is_true() { while val.node.is_true() {
if self.flags.in_function() { if self.flags.in_function() {
let these_stmts = Parser { let these_stmts = Parser {
toks: &mut Lexer::new(body.clone()), toks: &mut Lexer::new_ref(&body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,
@ -372,7 +372,7 @@ impl<'a> Parser<'a> {
} else { } else {
stmts.append( stmts.append(
&mut Parser { &mut Parser {
toks: &mut Lexer::new(body.clone()), toks: &mut Lexer::new_ref(&body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,
@ -392,7 +392,7 @@ impl<'a> Parser<'a> {
.parse_stmt()?, .parse_stmt()?,
); );
} }
val = self.parse_value_from_vec(cond.clone(), true)?; val = self.parse_value_from_vec(&cond, true)?;
} }
self.scopes.exit_scope(); self.scopes.exit_scope();
@ -429,7 +429,7 @@ impl<'a> Parser<'a> {
self.whitespace_or_comment(); self.whitespace_or_comment();
let iter_val_toks = read_until_open_curly_brace(self.toks)?; let iter_val_toks = read_until_open_curly_brace(self.toks)?;
let iter = self let iter = self
.parse_value_from_vec(iter_val_toks, true)? .parse_value_from_vec(&iter_val_toks, true)?
.node .node
.as_list(); .as_list();
self.toks.next(); self.toks.next();
@ -460,7 +460,7 @@ impl<'a> Parser<'a> {
if self.flags.in_function() { if self.flags.in_function() {
let these_stmts = Parser { let these_stmts = Parser {
toks: &mut Lexer::new(body.clone()), toks: &mut Lexer::new_ref(&body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,
@ -484,7 +484,7 @@ impl<'a> Parser<'a> {
} else { } else {
stmts.append( stmts.append(
&mut Parser { &mut Parser {
toks: &mut Lexer::new(body.clone()), toks: &mut Lexer::new_ref(&body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,

View File

@ -17,7 +17,7 @@ use super::{common::ContextFlags, Parser, Stmt};
const RESERVED_IDENTIFIERS: [&str; 7] = const RESERVED_IDENTIFIERS: [&str; 7] =
["calc", "element", "expression", "url", "and", "or", "not"]; ["calc", "element", "expression", "url", "and", "or", "not"];
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn parse_function(&mut self) -> SassResult<()> { pub(super) fn parse_function(&mut self) -> SassResult<()> {
self.whitespace_or_comment(); self.whitespace_or_comment();
let Spanned { node: name, span } = self.parse_identifier()?; let Spanned { node: name, span } = self.parse_identifier()?;
@ -86,7 +86,7 @@ impl<'a> Parser<'a> {
.. ..
} = function; } = function;
let scope = self.eval_args(fn_args, args)?; let scope = self.eval_args(&fn_args, args)?;
let mut new_scope = Scopes::new(); let mut new_scope = Scopes::new();
let mut entered_scope = false; let mut entered_scope = false;

View File

@ -12,7 +12,7 @@ use crate::{
use super::Parser; use super::Parser;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn ident_body_no_interpolation(&mut self, unit: bool) -> SassResult<Spanned<String>> { fn ident_body_no_interpolation(&mut self, unit: bool) -> SassResult<Spanned<String>> {
let mut text = String::new(); let mut text = String::new();
while let Some(tok) = self.toks.peek() { while let Some(tok) = self.toks.peek() {

View File

@ -26,7 +26,7 @@ fn is_plain_css_import(url: &str) -> bool {
|| lower.starts_with("//") || lower.starts_with("//")
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
/// Searches the current directory of the file then searches in `load_paths` directories /// Searches the current directory of the file then searches in `load_paths` directories
/// if the import has not yet been found. /// if the import has not yet been found.
/// ///

View File

@ -20,12 +20,12 @@ impl fmt::Display for KeyframesSelector {
} }
} }
struct KeyframesSelectorParser<'a, 'b> { struct KeyframesSelectorParser<'a, 'b, 'c> {
parser: &'a mut Parser<'b>, parser: &'a mut Parser<'b, 'c>,
} }
impl<'a, 'b> KeyframesSelectorParser<'a, 'b> { impl<'a, 'b, 'c> KeyframesSelectorParser<'a, 'b, 'c> {
pub fn new(parser: &'a mut Parser<'b>) -> Self { pub fn new(parser: &'a mut Parser<'b, 'c>) -> Self {
Self { parser } Self { parser }
} }
@ -81,7 +81,7 @@ impl<'a, 'b> KeyframesSelectorParser<'a, 'b> {
} }
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn parse_keyframes_name(&mut self) -> SassResult<String> { fn parse_keyframes_name(&mut self) -> SassResult<String> {
let mut name = String::new(); let mut name = String::new();
self.whitespace_or_comment(); self.whitespace_or_comment();

View File

@ -6,7 +6,7 @@ use crate::{
use super::Parser; use super::Parser;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
/// Peeks to see if the `ident` is at the current position. If it is, /// Peeks to see if the `ident` is at the current position. If it is,
/// consume the identifier /// consume the identifier
pub fn scan_identifier(&mut self, ident: &'static str, case_insensitive: bool) -> bool { pub fn scan_identifier(&mut self, ident: &'static str, case_insensitive: bool) -> bool {

View File

@ -14,7 +14,7 @@ use crate::{
use super::{common::ContextFlags, Parser, Stmt}; use super::{common::ContextFlags, Parser, Stmt};
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn parse_mixin(&mut self) -> SassResult<()> { pub(super) fn parse_mixin(&mut self) -> SassResult<()> {
self.whitespace(); self.whitespace();
let Spanned { node: name, span } = self.parse_identifier_no_interpolation(false)?; let Spanned { node: name, span } = self.parse_identifier_no_interpolation(false)?;
@ -142,7 +142,7 @@ impl<'a> Parser<'a> {
} }
}; };
let scope = self.eval_args(fn_args, args)?; let scope = self.eval_args(&fn_args, args)?;
let scope_len = self.scopes.len(); let scope_len = self.scopes.len();
@ -218,16 +218,16 @@ impl<'a> Parser<'a> {
if let Some(ref content_args) = content.content_args { if let Some(ref content_args) = content.content_args {
call_args.max_args(content_args.len())?; call_args.max_args(content_args.len())?;
let scope = self.eval_args(content_args.clone(), call_args)?; let scope = self.eval_args(&content_args, call_args)?;
scope_at_decl.enter_scope(scope); scope_at_decl.enter_scope(scope);
entered_scope = true; entered_scope = true;
} else { } else {
call_args.max_args(0)?; call_args.max_args(0)?;
} }
let stmts = if let Some(body) = content.content.clone() { let stmts = if let Some(body) = &content.content {
Parser { Parser {
toks: &mut Lexer::new(body), toks: &mut Lexer::new_ref(body),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: &mut scope_at_decl, scopes: &mut scope_at_decl,

View File

@ -64,8 +64,8 @@ pub(crate) enum Stmt {
} }
// todo: merge at_root and at_root_has_selector into an enum // todo: merge at_root and at_root_has_selector into an enum
pub(crate) struct Parser<'a> { pub(crate) struct Parser<'a, 'b> {
pub toks: &'a mut Lexer, pub toks: &'a mut Lexer<'b>,
pub map: &'a mut CodeMap, pub map: &'a mut CodeMap,
pub path: &'a Path, pub path: &'a Path,
pub global_scope: &'a mut Scope, pub global_scope: &'a mut Scope,
@ -89,7 +89,7 @@ pub(crate) struct Parser<'a> {
pub module_config: &'a mut ModuleConfig, pub module_config: &'a mut ModuleConfig,
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub fn parse(&mut self) -> SassResult<Vec<Stmt>> { pub fn parse(&mut self) -> SassResult<Vec<Stmt>> {
let mut stmts = Vec::new(); let mut stmts = Vec::new();
@ -610,7 +610,7 @@ impl<'a> Parser<'a> {
} }
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn parse_unknown_at_rule(&mut self, name: String) -> SassResult<Stmt> { fn parse_unknown_at_rule(&mut self, name: String) -> SassResult<Stmt> {
if self.flags.in_function() { if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into()); return Err(("This at-rule is not allowed here.", self.span_before).into());
@ -947,7 +947,7 @@ impl<'a> Parser<'a> {
} }
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn debug(&self, message: &Spanned<Cow<'a, str>>) { fn debug(&self, message: &Spanned<Cow<'a, str>>) {
if self.options.quiet { if self.options.quiet {
return; return;

View File

@ -16,7 +16,7 @@ use crate::{
Token, Token,
}; };
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn parse_module_alias(&mut self) -> SassResult<Option<String>> { fn parse_module_alias(&mut self) -> SassResult<Option<String>> {
if !matches!( if !matches!(
self.toks.peek(), self.toks.peek(),

View File

@ -13,7 +13,7 @@ use super::common::SelectorOrStyle;
use super::Parser; use super::Parser;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn parse_style_value_when_no_space_after_semicolon(&mut self) -> Option<Vec<Token>> { fn parse_style_value_when_no_space_after_semicolon(&mut self) -> Option<Vec<Token>> {
let mut toks = Vec::new(); let mut toks = Vec::new();
while let Some(tok) = self.toks.peek() { while let Some(tok) = self.toks.peek() {
@ -128,7 +128,7 @@ impl<'a> Parser<'a> {
self.parse_style_value_when_no_space_after_semicolon() self.parse_style_value_when_no_space_after_semicolon()
{ {
let len = toks.len(); let len = toks.len();
if let Ok(val) = self.parse_value_from_vec(toks, false) { if let Ok(val) = self.parse_value_from_vec(&toks, false) {
self.toks.take(len).for_each(drop); self.toks.take(len).for_each(drop);
return Ok(SelectorOrStyle::Style( return Ok(SelectorOrStyle::Style(
InternedString::get_or_intern(property), InternedString::get_or_intern(property),

View File

@ -4,7 +4,7 @@ use crate::{error::SassResult, Token};
use super::Parser; use super::Parser;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn throw_away_until_newline(&mut self) { pub(super) fn throw_away_until_newline(&mut self) {
for tok in &mut self.toks { for tok in &mut self.toks {
if tok.kind == '\n' { if tok.kind == '\n' {

View File

@ -4,7 +4,7 @@ use crate::{error::SassResult, parse::common::Comment, utils::IsWhitespace, valu
use super::super::Parser; use super::super::Parser;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn parse_calc_args(&mut self, buf: &mut String) -> SassResult<()> { pub(super) fn parse_calc_args(&mut self, buf: &mut String) -> SassResult<()> {
buf.reserve(2); buf.reserve(2);
buf.push('('); buf.push('(');

View File

@ -30,19 +30,19 @@ impl HigherIntermediateValue {
} }
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
fn call_function(&mut self, function: SassFunction, args: CallArgs) -> SassResult<Value> { fn call_function(&mut self, function: SassFunction, args: CallArgs) -> SassResult<Value> {
function.call(args, self) function.call(args, self)
} }
} }
pub(crate) struct ValueVisitor<'a, 'b: 'a> { pub(crate) struct ValueVisitor<'a, 'b: 'a, 'c> {
parser: &'a mut Parser<'b>, parser: &'a mut Parser<'b, 'c>,
span: Span, span: Span,
} }
impl<'a, 'b: 'a> ValueVisitor<'a, 'b> { impl<'a, 'b: 'a, 'c> ValueVisitor<'a, 'b, 'c> {
pub fn new(parser: &'a mut Parser<'b>, span: Span) -> Self { pub fn new(parser: &'a mut Parser<'b, 'c>, span: Span) -> Self {
Self { parser, span } Self { parser, span }
} }

View File

@ -46,9 +46,9 @@ impl IsWhitespace for IntermediateValue {
} }
/// We parse a value until the predicate returns true /// We parse a value until the predicate returns true
type Predicate<'a> = &'a dyn Fn(&mut Parser<'_>) -> bool; type Predicate<'a> = &'a dyn Fn(&mut Parser<'_, '_>) -> bool;
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
/// Parse a value from a stream of tokens /// Parse a value from a stream of tokens
/// ///
/// This function will cease parsing if the predicate returns true. /// This function will cease parsing if the predicate returns true.
@ -171,11 +171,11 @@ impl<'a> Parser<'a> {
pub(crate) fn parse_value_from_vec( pub(crate) fn parse_value_from_vec(
&mut self, &mut self,
toks: Vec<Token>, toks: &[Token],
in_paren: bool, in_paren: bool,
) -> SassResult<Spanned<Value>> { ) -> SassResult<Spanned<Value>> {
Parser { Parser {
toks: &mut Lexer::new(toks), toks: &mut Lexer::new_ref(toks),
map: self.map, map: self.map,
path: self.path, path: self.path,
scopes: self.scopes, scopes: self.scopes,
@ -1063,13 +1063,13 @@ impl<'a> Parser<'a> {
} }
} }
struct IntermediateValueIterator<'a, 'b: 'a> { struct IntermediateValueIterator<'a, 'b: 'a, 'c> {
parser: &'a mut Parser<'b>, parser: &'a mut Parser<'b, 'c>,
peek: Option<SassResult<Spanned<IntermediateValue>>>, peek: Option<SassResult<Spanned<IntermediateValue>>>,
predicate: Predicate<'a>, predicate: Predicate<'a>,
} }
impl<'a, 'b: 'a> Iterator for IntermediateValueIterator<'a, 'b> { impl<'a, 'b: 'a, 'c> Iterator for IntermediateValueIterator<'a, 'b, 'c> {
type Item = SassResult<Spanned<IntermediateValue>>; type Item = SassResult<Spanned<IntermediateValue>>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.peek.is_some() { if self.peek.is_some() {
@ -1080,8 +1080,8 @@ impl<'a, 'b: 'a> Iterator for IntermediateValueIterator<'a, 'b> {
} }
} }
impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> { impl<'a, 'b: 'a, 'c> IntermediateValueIterator<'a, 'b, 'c> {
pub fn new(parser: &'a mut Parser<'b>, predicate: Predicate<'a>) -> Self { pub fn new(parser: &'a mut Parser<'b, 'c>, predicate: Predicate<'a>) -> Self {
Self { Self {
parser, parser,
peek: None, peek: None,

View File

@ -21,7 +21,7 @@ impl VariableValue {
} }
} }
impl<'a> Parser<'a> { impl<'a, 'b> Parser<'a, 'b> {
pub(super) fn parse_variable_declaration(&mut self) -> SassResult<()> { pub(super) fn parse_variable_declaration(&mut self) -> SassResult<()> {
let next = self.toks.next(); let next = self.toks.next();
assert!(matches!(next, Some(Token { kind: '$', .. }))); assert!(matches!(next, Some(Token { kind: '$', .. })));

View File

@ -40,7 +40,7 @@ impl Hash for Attribute {
} }
} }
fn attribute_name(parser: &mut Parser<'_>, start: Span) -> SassResult<QualifiedName> { fn attribute_name(parser: &mut Parser, start: Span) -> SassResult<QualifiedName> {
let next = parser.toks.peek().ok_or(("Expected identifier.", start))?; let next = parser.toks.peek().ok_or(("Expected identifier.", start))?;
if next.kind == '*' { if next.kind == '*' {
parser.toks.next(); parser.toks.next();
@ -85,7 +85,7 @@ fn attribute_name(parser: &mut Parser<'_>, start: Span) -> SassResult<QualifiedN
}) })
} }
fn attribute_operator(parser: &mut Parser<'_>) -> SassResult<AttributeOp> { fn attribute_operator(parser: &mut Parser) -> SassResult<AttributeOp> {
let op = match parser.toks.next() { let op = match parser.toks.next() {
Some(Token { kind: '=', .. }) => return Ok(AttributeOp::Equals), Some(Token { kind: '=', .. }) => return Ok(AttributeOp::Equals),
Some(Token { kind: '~', .. }) => AttributeOp::Include, Some(Token { kind: '~', .. }) => AttributeOp::Include,
@ -101,7 +101,7 @@ fn attribute_operator(parser: &mut Parser<'_>) -> SassResult<AttributeOp> {
Ok(op) Ok(op)
} }
impl Attribute { impl Attribute {
pub fn from_tokens(parser: &mut Parser<'_>) -> SassResult<Attribute> { pub fn from_tokens(parser: &mut Parser) -> SassResult<Attribute> {
let start = parser.span_before; let start = parser.span_before;
parser.whitespace(); parser.whitespace();
let attr = attribute_name(parser, start)?; let attr = attribute_name(parser, start)?;

View File

@ -44,21 +44,21 @@ const SELECTOR_PSEUDO_CLASSES: [&str; 8] = [
/// Pseudo-element selectors that take unadorned selectors as arguments. /// Pseudo-element selectors that take unadorned selectors as arguments.
const SELECTOR_PSEUDO_ELEMENTS: [&str; 1] = ["slotted"]; const SELECTOR_PSEUDO_ELEMENTS: [&str; 1] = ["slotted"];
pub(crate) struct SelectorParser<'a, 'b> { pub(crate) struct SelectorParser<'a, 'b, 'c> {
/// Whether this parser allows the parent selector `&`. /// Whether this parser allows the parent selector `&`.
allows_parent: bool, allows_parent: bool,
/// Whether this parser allows placeholder selectors beginning with `%`. /// Whether this parser allows placeholder selectors beginning with `%`.
allows_placeholder: bool, allows_placeholder: bool,
parser: &'a mut Parser<'b>, parser: &'a mut Parser<'b, 'c>,
span: Span, span: Span,
} }
impl<'a, 'b> SelectorParser<'a, 'b> { impl<'a, 'b, 'c> SelectorParser<'a, 'b, 'c> {
pub fn new( pub fn new(
parser: &'a mut Parser<'b>, parser: &'a mut Parser<'b, 'c>,
allows_parent: bool, allows_parent: bool,
allows_placeholder: bool, allows_placeholder: bool,
span: Span, span: Span,

View File

@ -511,7 +511,7 @@ impl Value {
/// `name` is the argument name. It's used for error reporting. /// `name` is the argument name. It's used for error reporting.
pub fn to_selector( pub fn to_selector(
self, self,
parser: &mut Parser<'_>, parser: &mut Parser,
name: &str, name: &str,
allows_parent: bool, allows_parent: bool,
) -> SassResult<Selector> { ) -> SassResult<Selector> {

View File

@ -48,7 +48,7 @@ impl SassFunction {
} }
} }
pub fn call(self, args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { pub fn call(self, args: CallArgs, parser: &mut Parser) -> SassResult<Value> {
match self { match self {
Self::Builtin(f, ..) => f.0(args, parser), Self::Builtin(f, ..) => f.0(args, parser),
Self::UserDefined(f, ..) => parser.eval_function(*f, args), Self::UserDefined(f, ..) => parser.eval_function(*f, args),