diff --git a/src/args.rs b/src/args.rs index aa3ba0a..9da248b 100644 --- a/src/args.rs +++ b/src/args.rs @@ -5,7 +5,6 @@ use codemap::{Span, Spanned}; use crate::{ common::Identifier, error::SassResult, - parse::Parser, value::Value, {Cow, Token}, }; @@ -65,7 +64,7 @@ impl CallArgs { CallArgs(HashMap::new(), span) } - pub fn to_css_string(self, parser: &mut Parser<'_>) -> SassResult> { + pub fn to_css_string(self) -> SassResult> { let mut string = String::with_capacity(2 + self.len() * 10); string.push('('); let mut span = self.1; @@ -77,7 +76,7 @@ impl CallArgs { }); } - let args = match parser.variadic_args(self) { + let args = match self.get_variadic() { Ok(v) => v, Err(..) => { return Err(("Plain CSS functions don't support keyword arguments.", span).into()) @@ -123,11 +122,11 @@ impl CallArgs { } } - pub fn get_err(&mut self, position: usize, name: &'static str) -> SassResult> { + pub fn get_err(&mut self, position: usize, name: &'static str) -> SassResult { match self.get_named(name) { - Some(v) => v, + Some(v) => Ok(v?.node), None => match self.get_positional(position) { - Some(v) => v, + Some(v) => Ok(v?.node), None => Err((format!("Missing argument ${}.", name), self.span()).into()), }, } @@ -190,4 +189,50 @@ impl CallArgs { } Ok(()) } + + pub fn default_arg( + &mut self, + position: usize, + name: &'static str, + default: Value, + ) -> SassResult { + Ok(match self.get(position, name) { + Some(val) => val?.node, + None => default, + }) + } + + pub fn positional_arg(&mut self, position: usize) -> Option>> { + self.get_positional(position) + } + + #[allow(dead_code, clippy::unused_self)] + fn named_arg(&mut self, name: &'static str) -> Option>> { + self.get_named(name) + } + + pub fn default_named_arg(&mut self, name: &'static str, default: Value) -> SassResult { + Ok(match self.get_named(name) { + Some(val) => val?.node, + None => default, + }) + } + + pub fn get_variadic(self) -> SassResult>> { + let mut vals = Vec::new(); + let mut args = match self + .0 + .into_iter() + .map(|(a, v)| Ok((a.position()?, v))) + .collect::>)>, String>>() + { + Ok(v) => v, + Err(e) => return Err((format!("No argument named ${}.", e), self.1).into()), + }; + args.sort_by(|(a1, _), (a2, _)| a1.cmp(a2)); + for arg in args { + vals.push(arg.1?); + } + Ok(vals) + } } diff --git a/src/builtin/color/hsl.rs b/src/builtin/color/hsl.rs index 4792524..64c07a6 100644 --- a/src/builtin/color/hsl.rs +++ b/src/builtin/color/hsl.rs @@ -18,7 +18,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> } if args.len() == 1 { - let mut channels = match parser.arg(&mut args, 0, "channels")? { + let mut channels = match args.get_err(0, "channels")? { Value::List(v, ..) => v, _ => return Err(("Missing argument $channels.", args.span()).into()), }; @@ -77,11 +77,11 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> Number::one(), )))) } else { - let hue = match parser.arg(&mut args, 0, "hue")? { + let hue = match args.get_err(0, "hue")? { Value::Dimension(n, ..) => n, v if v.is_special_function() => { - let saturation = parser.arg(&mut args, 1, "saturation")?; - let lightness = parser.arg(&mut args, 2, "lightness")?; + let saturation = args.get_err(1, "saturation")?; + let lightness = args.get_err(2, "lightness")?; let mut string = format!( "{}({}, {}, {}", name, @@ -91,11 +91,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> ); if !args.is_empty() { string.push_str(", "); - string.push_str( - &parser - .arg(&mut args, 3, "alpha")? - .to_css_string(args.span())?, - ); + string.push_str(&args.get_err(3, "alpha")?.to_css_string(args.span())?); } string.push(')'); return Ok(Value::String(string, QuoteKind::None)); @@ -108,10 +104,10 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let saturation = match parser.arg(&mut args, 1, "saturation")? { + let saturation = match args.get_err(1, "saturation")? { Value::Dimension(n, ..) => n / Number::from(100), v if v.is_special_function() => { - let lightness = parser.arg(&mut args, 2, "lightness")?; + let lightness = args.get_err(2, "lightness")?; let mut string = format!( "{}({}, {}, {}", name, @@ -121,11 +117,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> ); if !args.is_empty() { string.push_str(", "); - string.push_str( - &parser - .arg(&mut args, 3, "alpha")? - .to_css_string(args.span())?, - ); + string.push_str(&args.get_err(3, "alpha")?.to_css_string(args.span())?); } string.push(')'); return Ok(Value::String(string, QuoteKind::None)); @@ -141,7 +133,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let lightness = match parser.arg(&mut args, 2, "lightness")? { + let lightness = match args.get_err(2, "lightness")? { Value::Dimension(n, ..) => n / Number::from(100), v if v.is_special_function() => { let mut string = format!( @@ -153,11 +145,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> ); if !args.is_empty() { string.push_str(", "); - string.push_str( - &parser - .arg(&mut args, 3, "alpha")? - .to_css_string(args.span())?, - ); + string.push_str(&args.get_err(3, "alpha")?.to_css_string(args.span())?); } string.push(')'); return Ok(Value::String(string, QuoteKind::None)); @@ -173,8 +161,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let alpha = match parser.default_arg( - &mut args, + let alpha = match args.default_arg( 3, "alpha", Value::Dimension(Number::one(), Unit::None, true), @@ -228,7 +215,7 @@ fn hsla(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.hue(), Unit::Deg, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -240,7 +227,7 @@ fn hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn saturation(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.saturation(), Unit::Percent, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -252,7 +239,7 @@ fn saturation(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn lightness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.lightness(), Unit::Percent, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -264,7 +251,7 @@ fn lightness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn adjust_hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -274,7 +261,7 @@ fn adjust_hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult .into()) } }; - let degrees = match parser.arg(&mut args, 1, "degrees")? { + let degrees = match args.get_err(1, "degrees")? { Value::Dimension(n, ..) => n, v => { return Err(( @@ -292,7 +279,7 @@ fn adjust_hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn lighten(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -302,7 +289,7 @@ fn lighten(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 100) / Number::from(100), v => { return Err(( @@ -320,7 +307,7 @@ fn lighten(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn darken(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -330,7 +317,7 @@ fn darken(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 100) / Number::from(100), v => { return Err(( @@ -352,15 +339,13 @@ fn saturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { return Ok(Value::String( format!( "saturate({})", - parser - .arg(&mut args, 0, "amount")? - .to_css_string(args.span())? + args.get_err(0, "amount")?.to_css_string(args.span())? ), QuoteKind::None, )); } - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 100) / Number::from(100), v => { return Err(( @@ -373,7 +358,7 @@ fn saturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, Value::Dimension(n, u, _) => { return Ok(Value::String( @@ -394,7 +379,7 @@ fn saturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn desaturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -404,7 +389,7 @@ fn desaturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult .into()) } }; - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 100) / Number::from(100), v => { return Err(( @@ -422,7 +407,7 @@ fn desaturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn grayscale(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, Value::Dimension(n, u, _) => { return Ok(Value::String( @@ -443,7 +428,7 @@ fn grayscale(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn complement(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -458,8 +443,7 @@ fn complement(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn invert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let weight = match parser.default_arg( - &mut args, + let weight = match args.default_arg( 1, "weight", Value::Dimension(Number::from(100), Unit::Percent, true), @@ -476,7 +460,7 @@ fn invert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Color(Box::new(c.invert(weight)))), Value::Dimension(n, Unit::Percent, _) => { Ok(Value::String(format!("invert({}%)", n), QuoteKind::None)) diff --git a/src/builtin/color/opacity.rs b/src/builtin/color/opacity.rs index 46e84c6..f73b52b 100644 --- a/src/builtin/color/opacity.rs +++ b/src/builtin/color/opacity.rs @@ -7,7 +7,7 @@ use crate::{ fn alpha(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.alpha(), Unit::None, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -19,7 +19,7 @@ fn alpha(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn opacity(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.alpha(), Unit::None, true)), Value::Dimension(num, unit, _) => Ok(Value::String( format!("opacity({}{})", num, unit), @@ -35,7 +35,7 @@ fn opacity(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn opacify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -45,7 +45,7 @@ fn opacify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 1), v => { return Err(( @@ -60,7 +60,7 @@ fn opacify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn fade_in(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -70,7 +70,7 @@ fn fade_in(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 1), v => { return Err(( @@ -85,7 +85,7 @@ fn fade_in(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -95,7 +95,7 @@ fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult bound!(args, "amount", n, u, 0, 1), v => { return Err(( @@ -110,7 +110,7 @@ fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(2)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -120,7 +120,7 @@ fn fade_out(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let amount = match parser.arg(&mut args, 1, "amount")? { + let amount = match args.get_err(1, "amount")? { Value::Dimension(n, u, _) => bound!(args, "amount", n, u, 0, 1), v => { return Err(( diff --git a/src/builtin/color/other.rs b/src/builtin/color/other.rs index 00bc92f..af1367d 100644 --- a/src/builtin/color/other.rs +++ b/src/builtin/color/other.rs @@ -13,8 +13,8 @@ use crate::{ }; macro_rules! opt_rgba { - ($args:ident, $name:ident, $arg:literal, $low:literal, $high:literal, $parser:ident) => { - let $name = match $parser.default_named_arg(&mut $args, $arg, Value::Null)? { + ($args:ident, $name:ident, $arg:literal, $low:literal, $high:literal) => { + let $name = match $args.default_named_arg($arg, Value::Null)? { Value::Dimension(n, u, _) => Some(bound!($args, $arg, n, u, $low, $high)), Value::Null => None, v => { @@ -29,8 +29,8 @@ macro_rules! opt_rgba { } macro_rules! opt_hsl { - ($args:ident, $name:ident, $arg:literal, $low:literal, $high:literal, $parser:ident) => { - let $name = match $parser.default_named_arg(&mut $args, $arg, Value::Null)? { + ($args:ident, $name:ident, $arg:literal, $low:literal, $high:literal) => { + let $name = match $args.default_named_arg($arg, Value::Null)? { Value::Dimension(n, u, _) => { Some(bound!($args, $arg, n, u, $low, $high) / Number::from(100)) } @@ -47,7 +47,7 @@ macro_rules! opt_hsl { } fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - if parser.positional_arg(&mut args, 1).is_some() { + if args.positional_arg(1).is_some() { return Err(( "Only one positional argument is allowed. All other arguments must be passed by name.", args.span(), @@ -55,7 +55,7 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult c, v => { return Err(( @@ -66,10 +66,10 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult Some(n), Value::Null => None, v => { @@ -92,8 +92,8 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult) -> SassResult { - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -125,10 +125,10 @@ fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult Some(n), Value::Null => None, v => { @@ -151,8 +151,8 @@ fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult } let span = args.span(); - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( @@ -196,8 +196,8 @@ fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult }; macro_rules! opt_scale_arg { - ($args:ident, $name:ident, $arg:literal, $low:literal, $high:literal, $parser:ident) => { - let $name = match $parser.default_named_arg(&mut $args, $arg, Value::Null)? { + ($args:ident, $name:ident, $arg:literal, $low:literal, $high:literal) => { + let $name = match $args.default_named_arg($arg, Value::Null)? { Value::Dimension(n, Unit::Percent, _) => { Some(bound!($args, $arg, n, Unit::Percent, $low, $high) / Number::from(100)) } @@ -224,10 +224,10 @@ fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult }; } - opt_scale_arg!(args, alpha, "alpha", -100, 100, parser); - opt_scale_arg!(args, red, "red", -100, 100, parser); - opt_scale_arg!(args, green, "green", -100, 100, parser); - opt_scale_arg!(args, blue, "blue", -100, 100, parser); + opt_scale_arg!(args, alpha, "alpha", -100, 100); + opt_scale_arg!(args, red, "red", -100, 100); + opt_scale_arg!(args, green, "green", -100, 100); + opt_scale_arg!(args, blue, "blue", -100, 100); if red.is_some() || green.is_some() || blue.is_some() { return Ok(Value::Color(Box::new(Color::from_rgba( @@ -254,8 +254,8 @@ fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult )))); } - opt_scale_arg!(args, saturation, "saturation", -100, 100, parser); - opt_scale_arg!(args, luminance, "lightness", -100, 100, parser); + opt_scale_arg!(args, saturation, "saturation", -100, 100); + opt_scale_arg!(args, luminance, "lightness", -100, 100); if saturation.is_some() || luminance.is_some() { // Color::as_hsla() returns more exact values than Color::hue(), etc. @@ -290,7 +290,7 @@ fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn ie_hex_str(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v => { return Err(( diff --git a/src/builtin/color/rgb.rs b/src/builtin/color/rgb.rs index 86dfeb1..3249f44 100644 --- a/src/builtin/color/rgb.rs +++ b/src/builtin/color/rgb.rs @@ -21,7 +21,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> } if args.len() == 1 { - let mut channels = match parser.arg(&mut args, 0, "channels")? { + let mut channels = match args.get_err(0, "channels")? { Value::List(v, ..) => v, _ => return Err(("Missing argument $channels.", args.span()).into()), }; @@ -125,10 +125,10 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> Ok(Value::Color(Box::new(color))) } else if args.len() == 2 { - let color = match parser.arg(&mut args, 0, "color")? { + let color = match args.get_err(0, "color")? { Value::Color(c) => c, v if v.is_special_function() => { - let alpha = parser.arg(&mut args, 1, "alpha")?; + let alpha = args.get_err(1, "alpha")?; return Ok(Value::String( format!( "{}({}, {})", @@ -147,7 +147,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let alpha = match parser.arg(&mut args, 1, "alpha")? { + let alpha = match args.get_err(1, "alpha")? { Value::Dimension(n, Unit::None, _) => n, Value::Dimension(n, Unit::Percent, _) => n / Number::from(100), v @ Value::Dimension(..) => { @@ -183,7 +183,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> }; Ok(Value::Color(Box::new(color.with_alpha(alpha)))) } else { - let red = match parser.arg(&mut args, 0, "red")? { + let red = match args.get_err(0, "red")? { Value::Dimension(n, Unit::None, _) => n, Value::Dimension(n, Unit::Percent, _) => (n / Number::from(100)) * Number::from(255), v @ Value::Dimension(..) => { @@ -197,8 +197,8 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } v if v.is_special_function() => { - let green = parser.arg(&mut args, 1, "green")?; - let blue = parser.arg(&mut args, 2, "blue")?; + let green = args.get_err(1, "green")?; + let blue = args.get_err(2, "blue")?; let mut string = format!( "{}({}, {}, {}", name, @@ -208,11 +208,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> ); if !args.is_empty() { string.push_str(", "); - string.push_str( - &parser - .arg(&mut args, 3, "alpha")? - .to_css_string(args.span())?, - ); + string.push_str(&args.get_err(3, "alpha")?.to_css_string(args.span())?); } string.push(')'); return Ok(Value::String(string, QuoteKind::None)); @@ -225,7 +221,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let green = match parser.arg(&mut args, 1, "green")? { + let green = match args.get_err(1, "green")? { Value::Dimension(n, Unit::None, _) => n, Value::Dimension(n, Unit::Percent, _) => (n / Number::from(100)) * Number::from(255), v @ Value::Dimension(..) => { @@ -239,7 +235,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } v if v.is_special_function() => { - let blue = parser.arg(&mut args, 2, "blue")?; + let blue = args.get_err(2, "blue")?; let mut string = format!( "{}({}, {}, {}", name, @@ -249,11 +245,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> ); if !args.is_empty() { string.push_str(", "); - string.push_str( - &parser - .arg(&mut args, 3, "alpha")? - .to_css_string(args.span())?, - ); + string.push_str(&args.get_err(3, "alpha")?.to_css_string(args.span())?); } string.push(')'); return Ok(Value::String(string, QuoteKind::None)); @@ -266,7 +258,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let blue = match parser.arg(&mut args, 2, "blue")? { + let blue = match args.get_err(2, "blue")? { Value::Dimension(n, Unit::None, _) => n, Value::Dimension(n, Unit::Percent, _) => (n / Number::from(100)) * Number::from(255), v @ Value::Dimension(..) => { @@ -289,11 +281,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> ); if !args.is_empty() { string.push_str(", "); - string.push_str( - &parser - .arg(&mut args, 3, "alpha")? - .to_css_string(args.span())?, - ); + string.push_str(&args.get_err(3, "alpha")?.to_css_string(args.span())?); } string.push(')'); return Ok(Value::String(string, QuoteKind::None)); @@ -306,8 +294,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser<'_>) -> .into()) } }; - let alpha = match parser.default_arg( - &mut args, + let alpha = match args.default_arg( 3, "alpha", Value::Dimension(Number::one(), Unit::None, true), @@ -359,7 +346,7 @@ fn rgba(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn red(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.red(), Unit::None, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -371,7 +358,7 @@ fn red(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn green(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.green(), Unit::None, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -383,7 +370,7 @@ fn green(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn blue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "color")? { + match args.get_err(0, "color")? { Value::Color(c) => Ok(Value::Dimension(c.blue(), Unit::None, true)), v => Err(( format!("$color: {} is not a color.", v.inspect(args.span())?), @@ -395,7 +382,7 @@ fn blue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn mix(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(3)?; - let color1 = match parser.arg(&mut args, 0, "color1")? { + let color1 = match args.get_err(0, "color1")? { Value::Color(c) => c, v => { return Err(( @@ -406,7 +393,7 @@ fn mix(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } }; - let color2 = match parser.arg(&mut args, 1, "color2")? { + let color2 = match args.get_err(1, "color2")? { Value::Color(c) => c, v => { return Err(( @@ -417,8 +404,7 @@ fn mix(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } }; - let weight = match parser.default_arg( - &mut args, + let weight = match args.default_arg( 2, "weight", Value::Dimension(Number::from(50), Unit::None, true), diff --git a/src/builtin/list.rs b/src/builtin/list.rs index 0474e32..11599b6 100644 --- a/src/builtin/list.rs +++ b/src/builtin/list.rs @@ -14,7 +14,7 @@ use crate::{ fn length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; Ok(Value::Dimension( - Number::from(parser.arg(&mut args, 0, "list")?.as_list().len()), + Number::from(args.get_err(0, "list")?.as_list().len()), Unit::None, true, )) @@ -22,8 +22,8 @@ fn length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let mut list = parser.arg(&mut args, 0, "list")?.as_list(); - let n = match parser.arg(&mut args, 1, "n")? { + let mut list = args.get_err(0, "list")?.as_list(); + let n = match args.get_err(1, "n")? { Value::Dimension(num, ..) => num, v => { return Err(( @@ -64,7 +64,7 @@ fn nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn list_separator(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; Ok(Value::String( - match parser.arg(&mut args, 0, "list")? { + match args.get_err(0, "list")? { Value::List(_, sep, ..) => sep.name(), _ => ListSeparator::Space.name(), } @@ -75,12 +75,12 @@ fn list_separator(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(3)?; - let (mut list, sep, brackets) = match parser.arg(&mut args, 0, "list")? { + let (mut list, sep, brackets) = match args.get_err(0, "list")? { Value::List(v, sep, b) => (v, sep, b), Value::Map(m) => (m.as_list(), ListSeparator::Comma, Brackets::None), v => (vec![v], ListSeparator::Space, Brackets::None), }; - let n = match parser.arg(&mut args, 1, "n")? { + let n = match args.get_err(1, "n")? { Value::Dimension(num, ..) => num, v => { return Err(( @@ -109,7 +109,7 @@ fn set_nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { return Err((format!("$n: {} is not an int.", n), args.span()).into()); } - let val = parser.arg(&mut args, 2, "value")?; + let val = args.get_err(2, "value")?; if n.is_positive() { list[n.to_integer().to_usize().unwrap_or(std::usize::MAX) - 1] = val; @@ -122,13 +122,12 @@ fn set_nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn append(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(3)?; - let (mut list, sep, brackets) = match parser.arg(&mut args, 0, "list")? { + let (mut list, sep, brackets) = match args.get_err(0, "list")? { Value::List(v, sep, b) => (v, sep, b), v => (vec![v], ListSeparator::Space, Brackets::None), }; - let val = parser.arg(&mut args, 1, "val")?; - let sep = match parser.default_arg( - &mut args, + let val = args.get_err(1, "val")?; + let sep = match args.default_arg( 2, "separator", Value::String("auto".to_owned(), QuoteKind::None), @@ -161,18 +160,17 @@ fn append(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn join(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(4)?; - let (mut list1, sep1, brackets) = match parser.arg(&mut args, 0, "list1")? { + let (mut list1, sep1, brackets) = match args.get_err(0, "list1")? { Value::List(v, sep, brackets) => (v, sep, brackets), Value::Map(m) => (m.as_list(), ListSeparator::Comma, Brackets::None), v => (vec![v], ListSeparator::Space, Brackets::None), }; - let (list2, sep2) = match parser.arg(&mut args, 1, "list2")? { + let (list2, sep2) = match args.get_err(1, "list2")? { Value::List(v, sep, ..) => (v, sep), Value::Map(m) => (m.as_list(), ListSeparator::Comma), v => (vec![v], ListSeparator::Space), }; - let sep = match parser.default_arg( - &mut args, + let sep = match args.default_arg( 2, "separator", Value::String("auto".to_owned(), QuoteKind::None), @@ -204,8 +202,7 @@ fn join(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } }; - let brackets = match parser.default_arg( - &mut args, + let brackets = match args.default_arg( 3, "bracketed", Value::String("auto".to_owned(), QuoteKind::None), @@ -230,7 +227,7 @@ fn join(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn is_bracketed(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - Ok(Value::bool(match parser.arg(&mut args, 0, "list")? { + Ok(Value::bool(match args.get_err(0, "list")? { Value::List(.., brackets) => match brackets { Brackets::Bracketed => true, Brackets::None => false, @@ -241,8 +238,8 @@ fn is_bracketed(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(2)?; - let list = parser.arg(&mut args, 0, "list")?.as_list(); - let value = parser.arg(&mut args, 1, "value")?; + let list = args.get_err(0, "list")?.as_list(); + let value = args.get_err(1, "value")?; // TODO: find a way to propagate any errors here // Potential input to fuzz: index(1px 1in 1cm, 96px + 1rem) let index = match list.into_iter().position(|v| v == value) { @@ -253,8 +250,8 @@ fn index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } fn zip(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - let lists = parser - .variadic_args(args)? + let lists = args + .get_variadic()? .into_iter() .map(|x| x.node.as_list()) .collect::>>(); diff --git a/src/builtin/map.rs b/src/builtin/map.rs index 7a0fd35..068d4af 100644 --- a/src/builtin/map.rs +++ b/src/builtin/map.rs @@ -10,8 +10,8 @@ use crate::{ fn map_get(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let key = parser.arg(&mut args, 1, "key")?; - let map = match parser.arg(&mut args, 0, "map")? { + let key = args.get_err(1, "key")?; + let map = match args.get_err(0, "map")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -28,8 +28,8 @@ fn map_get(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn map_has_key(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let key = parser.arg(&mut args, 1, "key")?; - let map = match parser.arg(&mut args, 0, "map")? { + let key = args.get_err(1, "key")?; + let map = match args.get_err(0, "map")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -46,7 +46,7 @@ fn map_has_key(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn map_keys(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let map = match parser.arg(&mut args, 0, "map")? { + let map = match args.get_err(0, "map")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -67,7 +67,7 @@ fn map_keys(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn map_values(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let map = match parser.arg(&mut args, 0, "map")? { + let map = match args.get_err(0, "map")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -88,7 +88,7 @@ fn map_values(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn map_merge(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let mut map1 = match parser.arg(&mut args, 0, "map1")? { + let mut map1 = match args.get_err(0, "map1")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -100,7 +100,7 @@ fn map_merge(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let map2 = match parser.arg(&mut args, 1, "map2")? { + let map2 = match args.get_err(1, "map2")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -117,7 +117,7 @@ fn map_merge(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } fn map_remove(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - let mut map = match parser.arg(&mut args, 0, "map")? { + let mut map = match args.get_err(0, "map")? { Value::Map(m) => m, Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::ArgList(v) if v.is_empty() => SassMap::new(), @@ -129,7 +129,7 @@ fn map_remove(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult .into()) } }; - let keys = parser.variadic_args(args)?; + let keys = args.get_variadic()?; for key in keys { map.remove(&key); } diff --git a/src/builtin/math.rs b/src/builtin/math.rs index 0c83db8..94104ec 100644 --- a/src/builtin/math.rs +++ b/src/builtin/math.rs @@ -15,7 +15,7 @@ use crate::{ fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let num = match parser.arg(&mut args, 0, "number")? { + let num = match args.get_err(0, "number")? { Value::Dimension(n, Unit::None, _) => n * Number::from(100), v @ Value::Dimension(..) => { return Err(( @@ -40,7 +40,7 @@ fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "number")? { + match args.get_err(0, "number")? { Value::Dimension(n, u, _) => Ok(Value::Dimension(n.round(), u, true)), v => Err(( format!("$number: {} is not a number.", v.inspect(args.span())?), @@ -52,7 +52,7 @@ fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "number")? { + match args.get_err(0, "number")? { Value::Dimension(n, u, _) => Ok(Value::Dimension(n.ceil(), u, true)), v => Err(( format!("$number: {} is not a number.", v.inspect(args.span())?), @@ -64,7 +64,7 @@ fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "number")? { + match args.get_err(0, "number")? { Value::Dimension(n, u, _) => Ok(Value::Dimension(n.floor(), u, true)), v => Err(( format!("$number: {} is not a number.", v.inspect(args.span())?), @@ -76,7 +76,7 @@ fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "number")? { + match args.get_err(0, "number")? { Value::Dimension(n, u, _) => Ok(Value::Dimension(n.abs(), u, true)), v => Err(( format!("$number: {} is not a number.", v.inspect(args.span())?), @@ -88,7 +88,7 @@ fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let unit1 = match parser.arg(&mut args, 0, "number1")? { + let unit1 = match args.get_err(0, "number1")? { Value::Dimension(_, u, _) => u, v => { return Err(( @@ -98,7 +98,7 @@ fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult .into()) } }; - let unit2 = match parser.arg(&mut args, 1, "number2")? { + let unit2 = match args.get_err(1, "number2")? { Value::Dimension(_, u, _) => u, v => { return Err(( @@ -116,7 +116,7 @@ fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult #[cfg(feature = "random")] fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let limit = match parser.default_arg(&mut args, 0, "limit", Value::Null)? { + let limit = match args.default_arg(0, "limit", Value::Null)? { Value::Dimension(n, ..) => n, Value::Null => { let mut rng = rand::thread_rng(); @@ -173,8 +173,8 @@ fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.min_args(1)?; let span = args.span(); - let mut nums = parser - .variadic_args(args)? + let mut nums = args + .get_variadic()? .into_iter() .map(|val| match val.node { Value::Dimension(number, unit, _) => Ok((number, unit)), @@ -211,8 +211,8 @@ fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn max(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.min_args(1)?; let span = args.span(); - let mut nums = parser - .variadic_args(args)? + let mut nums = args + .get_variadic()? .into_iter() .map(|val| match val.node { Value::Dimension(number, unit, _) => Ok((number, unit)), diff --git a/src/builtin/meta.rs b/src/builtin/meta.rs index 73f0215..9255de7 100644 --- a/src/builtin/meta.rs +++ b/src/builtin/meta.rs @@ -13,16 +13,16 @@ use crate::{ fn if_(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(3)?; - if parser.arg(&mut args, 0, "condition")?.is_true() { - Ok(parser.arg(&mut args, 1, "if-true")?) + if args.get_err(0, "condition")?.is_true() { + Ok(args.get_err(1, "if-true")?) } else { - Ok(parser.arg(&mut args, 2, "if-false")?) + Ok(args.get_err(2, "if-false")?) } } fn feature_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "feature")? { + match args.get_err(0, "feature")? { #[allow(clippy::match_same_arms)] Value::String(s, _) => Ok(match s.as_str() { // A local variable will shadow a global variable unless @@ -52,7 +52,7 @@ fn feature_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; - let unit = match parser.arg(&mut args, 0, "number")? { + let unit = match args.get_err(0, "number")? { Value::Dimension(_, u, _) => u.to_string(), v => { return Err(( @@ -67,14 +67,14 @@ fn unit(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn type_of(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let value = parser.arg(&mut args, 0, "value")?; + let value = args.get_err(0, "value")?; Ok(Value::String(value.kind().to_owned(), QuoteKind::None)) } fn unitless(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; #[allow(clippy::match_same_arms)] - Ok(match parser.arg(&mut args, 0, "number")? { + Ok(match args.get_err(0, "number")? { Value::Dimension(_, Unit::None, _) => Value::True, Value::Dimension(..) => Value::False, _ => Value::True, @@ -84,17 +84,14 @@ fn unitless(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn inspect(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; Ok(Value::String( - parser - .arg(&mut args, 0, "value")? - .inspect(args.span())? - .into_owned(), + args.get_err(0, "value")?.inspect(args.span())?.into_owned(), QuoteKind::None, )) } fn variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "name")? { + match args.get_err(0, "name")? { Value::String(s, _) => Ok(Value::bool( parser.scopes.var_exists(s.into(), parser.global_scope), )), @@ -108,7 +105,7 @@ fn variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "name")? { + match args.get_err(0, "name")? { Value::String(s, _) => Ok(Value::bool(parser.global_scope.var_exists(s.into()))), v => Err(( format!("$name: {} is not a string.", v.inspect(args.span())?), @@ -120,7 +117,7 @@ fn global_variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRe fn mixin_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - match parser.arg(&mut args, 0, "name")? { + match args.get_err(0, "name")? { Value::String(s, _) => Ok(Value::bool( parser.scopes.mixin_exists(s.into(), parser.global_scope), )), @@ -134,7 +131,7 @@ fn mixin_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(2)?; - match parser.arg(&mut args, 0, "name")? { + match args.get_err(0, "name")? { Value::String(s, _) => Ok(Value::bool( parser.scopes.fn_exists(s.into(), parser.global_scope), )), @@ -148,7 +145,7 @@ fn function_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(3)?; - let name: Identifier = match parser.arg(&mut args, 0, "name")? { + let name: Identifier = match args.get_err(0, "name")? { Value::String(s, _) => s.into(), v => { return Err(( @@ -158,10 +155,8 @@ fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult Some(s), Value::Null => None, v => { @@ -199,7 +194,7 @@ fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { - let func = match parser.arg(&mut args, 0, "function")? { + let func = match args.get_err(0, "function")? { Value::FunctionRef(f) => f, v => { return Err(( diff --git a/src/builtin/mod.rs b/src/builtin/mod.rs index 8d78dea..4ec4354 100644 --- a/src/builtin/mod.rs +++ b/src/builtin/mod.rs @@ -1,3 +1,6 @@ +// A reference to the parser is only necessary for some functions +#![allow(unused_variables)] + use std::{ collections::HashMap, sync::atomic::{AtomicUsize, Ordering}, diff --git a/src/builtin/selector.rs b/src/builtin/selector.rs index 28d0520..4015796 100644 --- a/src/builtin/selector.rs +++ b/src/builtin/selector.rs @@ -11,12 +11,10 @@ use crate::{ fn is_superselector(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let parent_selector = parser - .arg(&mut args, 0, "super")? + let parent_selector = args + .get_err(0, "super")? .to_selector(parser, "super", false)?; - let child_selector = parser - .arg(&mut args, 1, "sub")? - .to_selector(parser, "sub", false)?; + let child_selector = args.get_err(1, "sub")?.to_selector(parser, "sub", false)?; Ok(Value::bool( parent_selector.is_super_selector(&child_selector), @@ -26,8 +24,8 @@ fn is_superselector(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; // todo: Value::to_compound_selector - let selector = parser - .arg(&mut args, 0, "selector")? + let selector = args + .get_err(0, "selector")? .to_selector(parser, "selector", false)?; if selector.0.components.len() != 1 { @@ -55,15 +53,15 @@ fn simple_selectors(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; - Ok(parser - .arg(&mut args, 0, "selector")? + Ok(args + .get_err(0, "selector")? .to_selector(parser, "selector", false)? .into_value()) } fn selector_nest(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { let span = args.span(); - let selectors = parser.variadic_args(args)?; + let selectors = args.get_variadic()?; if selectors.is_empty() { return Err(("$selectors: At least one selector must be passed.", span).into()); } @@ -84,7 +82,7 @@ fn selector_nest(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassResult { let span = args.span(); - let selectors = parser.variadic_args(args)?; + let selectors = args.get_variadic()?; if selectors.is_empty() { return Err(("$selectors: At least one selector must be passed.", span).into()); } @@ -142,14 +140,14 @@ fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn selector_extend(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(3)?; - let selector = parser - .arg(&mut args, 0, "selector")? + let selector = args + .get_err(0, "selector")? .to_selector(parser, "selector", false)?; - let target = parser - .arg(&mut args, 1, "extendee")? + let target = args + .get_err(1, "extendee")? .to_selector(parser, "extendee", false)?; - let source = parser - .arg(&mut args, 2, "extender")? + let source = args + .get_err(2, "extender")? .to_selector(parser, "extender", false)?; Ok(Extender::extend(selector.0, source.0, target.0, args.span())?.to_sass_list()) @@ -157,25 +155,23 @@ fn selector_extend(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(3)?; - let selector = parser - .arg(&mut args, 0, "selector")? + let selector = args + .get_err(0, "selector")? .to_selector(parser, "selector", false)?; - let target = parser - .arg(&mut args, 1, "original")? + let target = args + .get_err(1, "original")? .to_selector(parser, "original", false)?; - let source = - parser - .arg(&mut args, 2, "replacement")? - .to_selector(parser, "replacement", false)?; + let source = args + .get_err(2, "replacement")? + .to_selector(parser, "replacement", false)?; Ok(Extender::replace(selector.0, source.0, target.0, args.span())?.to_sass_list()) } fn selector_unify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let selector1 = - parser - .arg(&mut args, 0, "selector1")? - .to_selector(parser, "selector1", false)?; + let selector1 = args + .get_err(0, "selector1")? + .to_selector(parser, "selector1", false)?; if selector1.contains_parent_selector() { return Err(( @@ -185,10 +181,9 @@ fn selector_unify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "string")? { + match args.get_err(0, "string")? { Value::String(mut i, q) => { i.make_ascii_uppercase(); Ok(Value::String(i, q)) @@ -32,7 +32,7 @@ fn to_upper_case(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "string")? { + match args.get_err(0, "string")? { Value::String(mut i, q) => { i.make_ascii_lowercase(); Ok(Value::String(i, q)) @@ -47,7 +47,7 @@ fn to_lower_case(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "string")? { + match args.get_err(0, "string")? { Value::String(i, _) => Ok(Value::Dimension( Number::from(i.chars().count()), Unit::None, @@ -63,7 +63,7 @@ fn str_length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult fn quote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "string")? { + match args.get_err(0, "string")? { Value::String(i, _) => Ok(Value::String(i, QuoteKind::Quoted)), v => Err(( format!("$string: {} is not a string.", v.inspect(args.span())?), @@ -75,7 +75,7 @@ fn quote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn unquote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - match parser.arg(&mut args, 0, "string")? { + match args.get_err(0, "string")? { i @ Value::String(..) => Ok(i.unquote()), v => Err(( format!("$string: {} is not a string.", v.inspect(args.span())?), @@ -87,7 +87,7 @@ fn unquote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(3)?; - let (string, quotes) = match parser.arg(&mut args, 0, "string")? { + let (string, quotes) = match args.get_err(0, "string")? { Value::String(s, q) => (s, q), v => { return Err(( @@ -98,7 +98,7 @@ fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } }; let str_len = string.chars().count(); - let start = match parser.arg(&mut args, 1, "start-at")? { + let start = match args.get_err(1, "start-at")? { Value::Dimension(n, Unit::None, _) if n.is_decimal() => { return Err((format!("{} is not an int.", n), args.span()).into()) } @@ -128,7 +128,7 @@ fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { .into()) } }; - let mut end = match parser.default_arg(&mut args, 2, "end-at", Value::Null)? { + let mut end = match args.default_arg(2, "end-at", Value::Null)? { Value::Dimension(n, Unit::None, _) if n.is_decimal() => { return Err((format!("{} is not an int.", n), args.span()).into()) } @@ -180,7 +180,7 @@ fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn str_index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; - let s1 = match parser.arg(&mut args, 0, "string")? { + let s1 = match args.get_err(0, "string")? { Value::String(i, _) => i, v => { return Err(( @@ -191,7 +191,7 @@ fn str_index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } }; - let substr = match parser.arg(&mut args, 1, "substring")? { + let substr = match args.get_err(1, "substring")? { Value::String(i, _) => i, v => { return Err(( @@ -210,7 +210,7 @@ fn str_index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(3)?; - let (s1, quotes) = match parser.arg(&mut args, 0, "string")? { + let (s1, quotes) = match args.get_err(0, "string")? { Value::String(i, q) => (i, q), v => { return Err(( @@ -221,7 +221,7 @@ fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult } }; - let substr = match parser.arg(&mut args, 1, "insert")? { + let substr = match args.get_err(1, "insert")? { Value::String(i, _) => i, v => { return Err(( @@ -232,7 +232,7 @@ fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult } }; - let index = match parser.arg(&mut args, 2, "index")? { + let index = match args.get_err(2, "index")? { Value::Dimension(n, Unit::None, _) if n.is_decimal() => { return Err((format!("$index: {} is not an int.", n), args.span()).into()) } diff --git a/src/parse/args.rs b/src/parse/args.rs index c4b00d7..5664882 100644 --- a/src/parse/args.rs +++ b/src/parse/args.rs @@ -277,80 +277,6 @@ impl<'a> Parser<'a> { } impl<'a> Parser<'a> { - #[allow(clippy::unused_self)] - pub fn arg( - &self, - args: &mut CallArgs, - position: usize, - name: &'static str, - ) -> SassResult { - Ok(args.get_err(position, name)?.node) - } - - #[allow(clippy::unused_self)] - pub fn default_arg( - &self, - args: &mut CallArgs, - position: usize, - name: &'static str, - default: Value, - ) -> SassResult { - Ok(match args.get(position, name) { - Some(val) => val?.node, - None => default, - }) - } - - #[allow(clippy::unused_self)] - pub fn positional_arg( - &self, - args: &mut CallArgs, - position: usize, - ) -> Option>> { - args.get_positional(position) - } - - #[allow(dead_code, clippy::unused_self)] - fn named_arg( - &self, - args: &mut CallArgs, - name: &'static str, - ) -> Option>> { - args.get_named(name) - } - - #[allow(clippy::unused_self)] - pub fn default_named_arg( - &self, - args: &mut CallArgs, - name: &'static str, - default: Value, - ) -> SassResult { - Ok(match args.get_named(name) { - Some(val) => val?.node, - None => default, - }) - } - - #[allow(clippy::unused_self)] - pub fn variadic_args(&self, args: CallArgs) -> SassResult>> { - let mut vals = Vec::new(); - let mut args = match args - .0 - .into_iter() - .map(|(a, v)| Ok((a.position()?, v))) - .collect::>)>, String>>() - { - Ok(v) => v, - Err(e) => return Err((format!("No argument named ${}.", e), args.1).into()), - }; - args.sort_by(|(a1, _), (a2, _)| a1.cmp(a2)); - for arg in args { - vals.push(arg.1?); - } - Ok(vals) - } - pub(super) fn eval_args(&mut self, fn_args: FuncArgs, mut args: CallArgs) -> SassResult { let mut scope = Scope::new(); if fn_args.0.is_empty() { @@ -361,7 +287,7 @@ impl<'a> Parser<'a> { for (idx, mut arg) in fn_args.0.into_iter().enumerate() { if arg.is_variadic { let span = args.span(); - let arg_list = Value::ArgList(self.variadic_args(args)?); + let arg_list = Value::ArgList(args.get_variadic()?); scope.insert_var( arg.name, Spanned { diff --git a/src/parse/value/parse.rs b/src/parse/value/parse.rs index 4651911..4d1ba33 100644 --- a/src/parse/value/parse.rs +++ b/src/parse/value/parse.rs @@ -284,9 +284,9 @@ impl<'a> Parser<'a> { } "url" => match self.try_parse_url()? { Some(val) => s = val, - None => s.push_str(&self.parse_call_args()?.to_css_string(self)?), + None => s.push_str(&self.parse_call_args()?.to_css_string()?), }, - _ => s.push_str(&self.parse_call_args()?.to_css_string(self)?), + _ => s.push_str(&self.parse_call_args()?.to_css_string()?), } return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(