arg methods are now inherent to CallArgs, rather than parser
This commit is contained in:
parent
3c756f661d
commit
5902ebd642
57
src/args.rs
57
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<Spanned<String>> {
|
||||
pub fn to_css_string(self) -> SassResult<Spanned<String>> {
|
||||
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<Spanned<Value>> {
|
||||
pub fn get_err(&mut self, position: usize, name: &'static str) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
Ok(match self.get(position, name) {
|
||||
Some(val) => val?.node,
|
||||
None => default,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn positional_arg(&mut self, position: usize) -> Option<SassResult<Spanned<Value>>> {
|
||||
self.get_positional(position)
|
||||
}
|
||||
|
||||
#[allow(dead_code, clippy::unused_self)]
|
||||
fn named_arg(&mut self, name: &'static str) -> Option<SassResult<Spanned<Value>>> {
|
||||
self.get_named(name)
|
||||
}
|
||||
|
||||
pub fn default_named_arg(&mut self, name: &'static str, default: Value) -> SassResult<Value> {
|
||||
Ok(match self.get_named(name) {
|
||||
Some(val) => val?.node,
|
||||
None => default,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_variadic(self) -> SassResult<Vec<Spanned<Value>>> {
|
||||
let mut vals = Vec::new();
|
||||
let mut args = match self
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|(a, v)| Ok((a.position()?, v)))
|
||||
.collect::<Result<Vec<(usize, SassResult<Spanned<Value>>)>, 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)
|
||||
}
|
||||
}
|
||||
|
@ -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<Value> {
|
||||
|
||||
fn hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn saturation(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn lightness(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn adjust_hue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
.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<Value>
|
||||
|
||||
fn lighten(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
|
||||
fn darken(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
|
||||
fn desaturate(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
.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<Value>
|
||||
|
||||
fn grayscale(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn complement(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn invert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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))
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
|
||||
fn alpha(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn opacity(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn opacify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
|
||||
fn fade_in(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
|
||||
fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Val
|
||||
.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((
|
||||
@ -110,7 +110,7 @@ fn transparentize(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
|
||||
|
||||
fn fade_out(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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((
|
||||
|
@ -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<Value> {
|
||||
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<Value
|
||||
.into());
|
||||
}
|
||||
|
||||
let color = match parser.arg(&mut args, 0, "color")? {
|
||||
let color = match args.get_err(0, "color")? {
|
||||
Value::Color(c) => c,
|
||||
v => {
|
||||
return Err((
|
||||
@ -66,10 +66,10 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
}
|
||||
};
|
||||
|
||||
opt_rgba!(args, alpha, "alpha", 0, 1, parser);
|
||||
opt_rgba!(args, red, "red", 0, 255, parser);
|
||||
opt_rgba!(args, green, "green", 0, 255, parser);
|
||||
opt_rgba!(args, blue, "blue", 0, 255, parser);
|
||||
opt_rgba!(args, alpha, "alpha", 0, 1);
|
||||
opt_rgba!(args, red, "red", 0, 255);
|
||||
opt_rgba!(args, green, "green", 0, 255);
|
||||
opt_rgba!(args, blue, "blue", 0, 255);
|
||||
|
||||
if red.is_some() || green.is_some() || blue.is_some() {
|
||||
return Ok(Value::Color(Box::new(Color::from_rgba(
|
||||
@ -80,7 +80,7 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
))));
|
||||
}
|
||||
|
||||
let hue = match parser.default_named_arg(&mut args, "hue", Value::Null)? {
|
||||
let hue = match args.default_named_arg("hue", Value::Null)? {
|
||||
Value::Dimension(n, ..) => Some(n),
|
||||
Value::Null => None,
|
||||
v => {
|
||||
@ -92,8 +92,8 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
}
|
||||
};
|
||||
|
||||
opt_hsl!(args, saturation, "saturation", 0, 100, parser);
|
||||
opt_hsl!(args, luminance, "lightness", 0, 100, parser);
|
||||
opt_hsl!(args, saturation, "saturation", 0, 100);
|
||||
opt_hsl!(args, luminance, "lightness", 0, 100);
|
||||
|
||||
if hue.is_some() || saturation.is_some() || luminance.is_some() {
|
||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||
@ -114,7 +114,7 @@ fn change_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
}
|
||||
|
||||
fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value
|
||||
}
|
||||
};
|
||||
|
||||
opt_rgba!(args, alpha, "alpha", -1, 1, parser);
|
||||
opt_rgba!(args, red, "red", -255, 255, parser);
|
||||
opt_rgba!(args, green, "green", -255, 255, parser);
|
||||
opt_rgba!(args, blue, "blue", -255, 255, parser);
|
||||
opt_rgba!(args, alpha, "alpha", -1, 1);
|
||||
opt_rgba!(args, red, "red", -255, 255);
|
||||
opt_rgba!(args, green, "green", -255, 255);
|
||||
opt_rgba!(args, blue, "blue", -255, 255);
|
||||
|
||||
if red.is_some() || green.is_some() || blue.is_some() {
|
||||
return Ok(Value::Color(Box::new(Color::from_rgba(
|
||||
@ -139,7 +139,7 @@ fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
))));
|
||||
}
|
||||
|
||||
let hue = match parser.default_named_arg(&mut args, "hue", Value::Null)? {
|
||||
let hue = match args.default_named_arg("hue", Value::Null)? {
|
||||
Value::Dimension(n, ..) => Some(n),
|
||||
Value::Null => None,
|
||||
v => {
|
||||
@ -151,8 +151,8 @@ fn adjust_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
}
|
||||
};
|
||||
|
||||
opt_hsl!(args, saturation, "saturation", -100, 100, parser);
|
||||
opt_hsl!(args, luminance, "lightness", -100, 100, parser);
|
||||
opt_hsl!(args, saturation, "saturation", -100, 100);
|
||||
opt_hsl!(args, luminance, "lightness", -100, 100);
|
||||
|
||||
if hue.is_some() || saturation.is_some() || luminance.is_some() {
|
||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||
@ -184,7 +184,7 @@ fn scale_color(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value>
|
||||
}
|
||||
|
||||
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<Value>
|
||||
};
|
||||
|
||||
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<Value>
|
||||
};
|
||||
}
|
||||
|
||||
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<Value>
|
||||
))));
|
||||
}
|
||||
|
||||
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<Value>
|
||||
|
||||
fn ie_hex_str(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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((
|
||||
|
@ -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<Value> {
|
||||
|
||||
fn red(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn green(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn blue(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn mix(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
}
|
||||
};
|
||||
|
||||
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<Value> {
|
||||
}
|
||||
};
|
||||
|
||||
let weight = match parser.default_arg(
|
||||
&mut args,
|
||||
let weight = match args.default_arg(
|
||||
2,
|
||||
"weight",
|
||||
Value::Dimension(Number::from(50), Unit::None, true),
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
fn length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
fn list_separator(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Val
|
||||
|
||||
fn set_nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn append(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn join(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
}
|
||||
};
|
||||
|
||||
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<Value> {
|
||||
|
||||
fn is_bracketed(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value
|
||||
|
||||
fn index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
}
|
||||
|
||||
fn zip(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
let lists = parser
|
||||
.variadic_args(args)?
|
||||
let lists = args
|
||||
.get_variadic()?
|
||||
.into_iter()
|
||||
.map(|x| x.node.as_list())
|
||||
.collect::<Vec<Vec<Value>>>();
|
||||
|
@ -10,8 +10,8 @@ use crate::{
|
||||
|
||||
fn map_get(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn map_has_key(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn map_keys(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn map_values(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn map_merge(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
}
|
||||
|
||||
fn map_remove(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
.into())
|
||||
}
|
||||
};
|
||||
let keys = parser.variadic_args(args)?;
|
||||
let keys = args.get_variadic()?;
|
||||
for key in keys {
|
||||
map.remove(&key);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
|
||||
fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
.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<Value>
|
||||
#[cfg(feature = "random")]
|
||||
fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
fn max(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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)),
|
||||
|
@ -13,16 +13,16 @@ use crate::{
|
||||
|
||||
fn if_(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
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<Val
|
||||
|
||||
fn unit(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn type_of(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
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<Value> {
|
||||
fn inspect(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
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<Va
|
||||
|
||||
fn global_variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
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<Value
|
||||
|
||||
fn function_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Va
|
||||
|
||||
fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value
|
||||
.into())
|
||||
}
|
||||
};
|
||||
let css = parser
|
||||
.default_arg(&mut args, 1, "css", Value::False)?
|
||||
.is_true();
|
||||
let module = match parser.default_arg(&mut args, 2, "module", Value::Null)? {
|
||||
let css = args.default_arg(1, "css", Value::False)?.is_true();
|
||||
let module = match args.default_arg(2, "module", Value::Null)? {
|
||||
Value::String(s, ..) => Some(s),
|
||||
Value::Null => None,
|
||||
v => {
|
||||
@ -199,7 +194,7 @@ fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
|
||||
}
|
||||
|
||||
fn call(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
let func = match parser.arg(&mut args, 0, "function")? {
|
||||
let func = match args.get_err(0, "function")? {
|
||||
Value::FunctionRef(f) => f,
|
||||
v => {
|
||||
return Err((
|
||||
|
@ -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},
|
||||
|
@ -11,12 +11,10 @@ use crate::{
|
||||
|
||||
fn is_superselector(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<V
|
||||
fn simple_selectors(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<V
|
||||
|
||||
fn selector_parse(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn selector_extend(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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,24 +155,22 @@ fn selector_extend(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
|
||||
|
||||
fn selector_replace(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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")?
|
||||
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<Value> {
|
||||
args.max_args(2)?;
|
||||
let selector1 =
|
||||
parser
|
||||
.arg(&mut args, 0, "selector1")?
|
||||
let selector1 = args
|
||||
.get_err(0, "selector1")?
|
||||
.to_selector(parser, "selector1", false)?;
|
||||
|
||||
if selector1.contains_parent_selector() {
|
||||
@ -185,9 +181,8 @@ fn selector_unify(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
|
||||
.into());
|
||||
}
|
||||
|
||||
let selector2 =
|
||||
parser
|
||||
.arg(&mut args, 1, "selector2")?
|
||||
let selector2 = args
|
||||
.get_err(1, "selector2")?
|
||||
.to_selector(parser, "selector2", false)?;
|
||||
|
||||
if selector2.contains_parent_selector() {
|
||||
|
@ -17,7 +17,7 @@ use crate::{
|
||||
|
||||
fn to_upper_case(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Valu
|
||||
|
||||
fn to_lower_case(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Valu
|
||||
|
||||
fn str_length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
|
||||
fn quote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn unquote(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
|
||||
fn str_slice(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
}
|
||||
};
|
||||
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<Value> {
|
||||
.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<Value> {
|
||||
|
||||
fn str_index(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value> {
|
||||
}
|
||||
};
|
||||
|
||||
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<Value> {
|
||||
|
||||
fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
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<Value>
|
||||
}
|
||||
};
|
||||
|
||||
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<Value>
|
||||
}
|
||||
};
|
||||
|
||||
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())
|
||||
}
|
||||
|
@ -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<Value> {
|
||||
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<Value> {
|
||||
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<SassResult<Spanned<Value>>> {
|
||||
args.get_positional(position)
|
||||
}
|
||||
|
||||
#[allow(dead_code, clippy::unused_self)]
|
||||
fn named_arg(
|
||||
&self,
|
||||
args: &mut CallArgs,
|
||||
name: &'static str,
|
||||
) -> Option<SassResult<Spanned<Value>>> {
|
||||
args.get_named(name)
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
pub fn default_named_arg(
|
||||
&self,
|
||||
args: &mut CallArgs,
|
||||
name: &'static str,
|
||||
default: Value,
|
||||
) -> SassResult<Value> {
|
||||
Ok(match args.get_named(name) {
|
||||
Some(val) => val?.node,
|
||||
None => default,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
pub fn variadic_args(&self, args: CallArgs) -> SassResult<Vec<Spanned<Value>>> {
|
||||
let mut vals = Vec::new();
|
||||
let mut args = match args
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|(a, v)| Ok((a.position()?, v)))
|
||||
.collect::<Result<Vec<(usize, SassResult<Spanned<Value>>)>, 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<Scope> {
|
||||
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 {
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user