move builtin fns to outer scope to reduce nesting

This commit is contained in:
ConnorSkees 2020-04-30 19:36:34 -04:00
parent 170759239a
commit 0aed492123
9 changed files with 2759 additions and 2861 deletions

View File

@ -12,8 +12,7 @@ use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{Number, Value}; use crate::value::{Number, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn hsl(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn hsl(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
if args.is_empty() { if args.is_empty() {
return Err(("Missing argument $channels.", args.span()).into()); return Err(("Missing argument $channels.", args.span()).into());
} }
@ -217,9 +216,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
hue, saturation, lightness, alpha, hue, saturation, lightness, alpha,
)))) ))))
} }
} }
fn hsla(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn hsla(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
if args.is_empty() { if args.is_empty() {
return Err(("Missing argument $channels.", args.span()).into()); return Err(("Missing argument $channels.", args.span()).into());
} }
@ -423,9 +422,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
hue, saturation, lightness, alpha, hue, saturation, lightness, alpha,
)))) ))))
} }
} }
fn hue(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn hue(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.hue(), Unit::Deg)), Value::Color(c) => Ok(Value::Dimension(c.hue(), Unit::Deg)),
@ -435,13 +434,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn saturation( fn saturation(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.saturation(), Unit::Percent)), Value::Color(c) => Ok(Value::Dimension(c.saturation(), Unit::Percent)),
@ -451,13 +446,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn lightness( fn lightness(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.lightness(), Unit::Percent)), Value::Color(c) => Ok(Value::Dimension(c.lightness(), Unit::Percent)),
@ -467,13 +458,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn adjust_hue( fn adjust_hue(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -499,9 +486,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.adjust_hue(degrees)))) Ok(Value::Color(Box::new(color.adjust_hue(degrees))))
} }
fn lighten(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn lighten(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -527,9 +514,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.lighten(amount)))) Ok(Value::Color(Box::new(color.lighten(amount))))
} }
fn darken(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn darken(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -555,9 +542,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.darken(amount)))) Ok(Value::Color(Box::new(color.darken(amount))))
} }
fn saturate(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn saturate(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
if args.len() == 1 { if args.len() == 1 {
return Ok(Value::Ident( return Ok(Value::Ident(
@ -599,13 +586,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.saturate(amount)))) Ok(Value::Color(Box::new(color.saturate(amount))))
} }
fn desaturate( fn desaturate(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -631,13 +614,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.desaturate(amount)))) Ok(Value::Color(Box::new(color.desaturate(amount))))
} }
fn grayscale( fn grayscale(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -656,13 +635,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.desaturate(Number::one())))) Ok(Value::Color(Box::new(color.desaturate(Number::one()))))
} }
fn complement( fn complement(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -675,9 +650,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.complement()))) Ok(Value::Color(Box::new(color.complement())))
} }
fn invert(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn invert(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let weight = match arg!( let weight = match arg!(
args, args,
@ -714,8 +689,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("hsl", Builtin::new(hsl)); f.insert("hsl", Builtin::new(hsl));
f.insert("hsla", Builtin::new(hsla)); f.insert("hsla", Builtin::new(hsla));
f.insert("hue", Builtin::new(hue)); f.insert("hue", Builtin::new(hue));

View File

@ -10,8 +10,7 @@ use crate::unit::Unit;
use crate::value::Number; use crate::value::Number;
use crate::value::Value; use crate::value::Value;
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn alpha(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn alpha(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.alpha(), Unit::None)), Value::Color(c) => Ok(Value::Dimension(c.alpha(), Unit::None)),
@ -21,9 +20,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn opacity(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn opacity(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.alpha(), Unit::None)), Value::Color(c) => Ok(Value::Dimension(c.alpha(), Unit::None)),
@ -37,9 +36,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn opacify(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn opacify(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -65,9 +64,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.fade_in(amount)))) Ok(Value::Color(Box::new(color.fade_in(amount))))
} }
fn fade_in(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn fade_in(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -93,13 +92,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.fade_in(amount)))) Ok(Value::Color(Box::new(color.fade_in(amount))))
} }
fn transparentize( fn transparentize(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -125,9 +124,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.fade_out(amount)))) Ok(Value::Color(Box::new(color.fade_out(amount))))
} }
fn fade_out(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn fade_out(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -153,8 +152,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color.fade_out(amount)))) Ok(Value::Color(Box::new(color.fade_out(amount))))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("alpha", Builtin::new(alpha)); f.insert("alpha", Builtin::new(alpha));
f.insert("opacity", Builtin::new(opacity)); f.insert("opacity", Builtin::new(opacity));
f.insert("opacify", Builtin::new(opacify)); f.insert("opacify", Builtin::new(opacify));

View File

@ -54,16 +54,13 @@ macro_rules! opt_hsl {
}; };
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn change_color(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn change_color(
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
if args.get_positional(1, scope, super_selector).is_some() { if args.get_positional(1, scope, super_selector).is_some() {
return Err( return Err((
("Only one positional argument is allowed. All other arguments must be passed by name.", args.span() "Only one positional argument is allowed. All other arguments must be passed by name.",
).into()); args.span(),
)
.into());
} }
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
@ -130,13 +127,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
color color
})) }))
} }
fn adjust_color( fn adjust_color(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
v => { v => {
@ -210,13 +203,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
color color
})) }))
} }
fn scale_color( fn scale_color(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
fn scale(val: Number, by: Number, max: Number) -> Number { fn scale(val: Number, by: Number, max: Number) -> Number {
if by.is_zero() { if by.is_zero() {
return val; return val;
@ -343,13 +332,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
color color
})) }))
} }
fn ie_hex_str( fn ie_hex_str(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -362,8 +347,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Ident(color.to_ie_hex_str(), QuoteKind::None)) Ok(Value::Ident(color.to_ie_hex_str(), QuoteKind::None))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("change-color", Builtin::new(change_color)); f.insert("change-color", Builtin::new(change_color));
f.insert("adjust-color", Builtin::new(adjust_color)); f.insert("adjust-color", Builtin::new(adjust_color));
f.insert("scale-color", Builtin::new(scale_color)); f.insert("scale-color", Builtin::new(scale_color));

View File

@ -12,8 +12,7 @@ use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{Number, Value}; use crate::value::{Number, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn rgb(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn rgb(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
if args.is_empty() { if args.is_empty() {
return Err(("Missing argument $channels.", args.span()).into()); return Err(("Missing argument $channels.", args.span()).into());
} }
@ -37,9 +36,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let blue = match channels.pop() { let blue = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n, Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => { Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
(n / Number::from(100)) * Number::from(255)
}
Some(v) if v.is_special_function() => { Some(v) if v.is_special_function() => {
let green = channels.pop().unwrap(); let green = channels.pop().unwrap();
let red = channels.pop().unwrap(); let red = channels.pop().unwrap();
@ -65,9 +62,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let green = match channels.pop() { let green = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n, Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => { Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
(n / Number::from(100)) * Number::from(255)
}
Some(v) if v.is_special_function() => { Some(v) if v.is_special_function() => {
let string = match channels.pop() { let string = match channels.pop() {
Some(red) => format!( Some(red) => format!(
@ -92,9 +87,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let red = match channels.pop() { let red = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n, Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => { Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
(n / Number::from(100)) * Number::from(255)
}
Some(v) if v.is_special_function() => { Some(v) if v.is_special_function() => {
return Ok(Value::Ident( return Ok(Value::Ident(
format!( format!(
@ -330,9 +323,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
red, green, blue, alpha, red, green, blue, alpha,
)))) ))))
} }
} }
fn rgba(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn rgba(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
if args.is_empty() { if args.is_empty() {
return Err(("Missing argument $channels.", args.span()).into()); return Err(("Missing argument $channels.", args.span()).into());
} }
@ -356,9 +349,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let blue = match channels.pop() { let blue = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n, Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => { Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
(n / Number::from(100)) * Number::from(255)
}
Some(v) if v.is_special_function() => { Some(v) if v.is_special_function() => {
let green = channels.pop().unwrap(); let green = channels.pop().unwrap();
let red = channels.pop().unwrap(); let red = channels.pop().unwrap();
@ -384,9 +375,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let green = match channels.pop() { let green = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n, Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => { Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
(n / Number::from(100)) * Number::from(255)
}
Some(v) if v.is_special_function() => { Some(v) if v.is_special_function() => {
let string = match channels.pop() { let string = match channels.pop() {
Some(red) => format!( Some(red) => format!(
@ -411,9 +400,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let red = match channels.pop() { let red = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n, Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => { Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
(n / Number::from(100)) * Number::from(255)
}
Some(v) if v.is_special_function() => { Some(v) if v.is_special_function() => {
return Ok(Value::Ident( return Ok(Value::Ident(
format!( format!(
@ -649,9 +636,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
red, green, blue, alpha, red, green, blue, alpha,
)))) ))))
} }
} }
fn red(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn red(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.red(), Unit::None)), Value::Color(c) => Ok(Value::Dimension(c.red(), Unit::None)),
@ -661,9 +648,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn green(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn green(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.green(), Unit::None)), Value::Color(c) => Ok(Value::Dimension(c.green(), Unit::None)),
@ -673,9 +660,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn blue(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn blue(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "color") { match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => Ok(Value::Dimension(c.blue(), Unit::None)), Value::Color(c) => Ok(Value::Dimension(c.blue(), Unit::None)),
@ -685,9 +672,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn mix(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn mix(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let color1 = match arg!(args, scope, super_selector, 0, "color1") { let color1 = match arg!(args, scope, super_selector, 0, "color1") {
Value::Color(c) => c, Value::Color(c) => c,
@ -731,8 +718,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Color(Box::new(color1.mix(&color2, weight)))) Ok(Value::Color(Box::new(color1.mix(&color2, weight))))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("rgb", Builtin::new(rgb)); f.insert("rgb", Builtin::new(rgb));
f.insert("rgba", Builtin::new(rgba)); f.insert("rgba", Builtin::new(rgba));
f.insert("red", Builtin::new(red)); f.insert("red", Builtin::new(red));

View File

@ -11,8 +11,7 @@ use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{Number, Value}; use crate::value::{Number, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn length(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn length(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let len = match arg!(args, scope, super_selector, 0, "list") { let len = match arg!(args, scope, super_selector, 0, "list") {
Value::List(v, ..) => Number::from(v.len()), Value::List(v, ..) => Number::from(v.len()),
@ -20,9 +19,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
_ => Number::one(), _ => Number::one(),
}; };
Ok(Value::Dimension(len, Unit::None)) Ok(Value::Dimension(len, Unit::None))
} }
fn nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let list = match arg!(args, scope, super_selector, 0, "list") { let list = match arg!(args, scope, super_selector, 0, "list") {
Value::List(v, ..) => v, Value::List(v, ..) => v,
@ -65,13 +64,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
Ok(list[list.len() - n.abs().to_integer().to_usize().unwrap()].clone()) Ok(list[list.len() - n.abs().to_integer().to_usize().unwrap()].clone())
} }
} }
fn list_separator( fn list_separator(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::Ident( Ok(Value::Ident(
match arg!(args, scope, super_selector, 0, "list") { match arg!(args, scope, super_selector, 0, "list") {
@ -81,9 +80,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
.to_owned(), .to_owned(),
QuoteKind::None, QuoteKind::None,
)) ))
} }
fn set_nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn set_nth(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (mut list, sep, brackets) = match arg!(args, scope, super_selector, 0, "list") { let (mut list, sep, brackets) = match arg!(args, scope, super_selector, 0, "list") {
Value::List(v, sep, b) => (v, sep, b), Value::List(v, sep, b) => (v, sep, b),
@ -128,9 +127,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
Ok(Value::List(list, sep, brackets)) Ok(Value::List(list, sep, brackets))
} }
fn append(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn append(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (mut list, sep, brackets) = match arg!(args, scope, super_selector, 0, "list") { let (mut list, sep, brackets) = match arg!(args, scope, super_selector, 0, "list") {
Value::List(v, sep, b) => (v, sep, b), Value::List(v, sep, b) => (v, sep, b),
@ -171,9 +170,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
list.push(val); list.push(val);
Ok(Value::List(list, sep, brackets)) Ok(Value::List(list, sep, brackets))
} }
fn join(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn join(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(4)?; args.max_args(4)?;
let (mut list1, sep1, brackets) = match arg!(args, scope, super_selector, 0, "list1") { let (mut list1, sep1, brackets) = match arg!(args, scope, super_selector, 0, "list1") {
Value::List(v, sep, brackets) => (v, sep, brackets), Value::List(v, sep, brackets) => (v, sep, brackets),
@ -245,13 +244,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
list1.extend(list2); list1.extend(list2);
Ok(Value::List(list1, sep, brackets)) Ok(Value::List(list1, sep, brackets))
} }
fn is_bracketed( fn is_bracketed(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::bool( Ok(Value::bool(
match arg!(args, scope, super_selector, 0, "list") { match arg!(args, scope, super_selector, 0, "list") {
@ -262,9 +257,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
_ => false, _ => false,
}, },
)) ))
} }
fn index(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn index(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let list = match arg!(args, scope, super_selector, 0, "list") { let list = match arg!(args, scope, super_selector, 0, "list") {
Value::List(v, ..) => v, Value::List(v, ..) => v,
@ -285,9 +280,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
None => return Ok(Value::Null), None => return Ok(Value::Null),
}; };
Ok(Value::Dimension(index, Unit::None)) Ok(Value::Dimension(index, Unit::None))
} }
fn zip(args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn zip(args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
let span = args.span(); let span = args.span();
let lists = args let lists = args
.get_variadic(scope, super_selector)? .get_variadic(scope, super_selector)?
@ -319,8 +314,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
.collect(); .collect();
Ok(Value::List(result, ListSeparator::Comma, Brackets::None)) Ok(Value::List(result, ListSeparator::Comma, Brackets::None))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("length", Builtin::new(length)); f.insert("length", Builtin::new(length));
f.insert("nth", Builtin::new(nth)); f.insert("nth", Builtin::new(nth));
f.insert("list-separator", Builtin::new(list_separator)); f.insert("list-separator", Builtin::new(list_separator));

View File

@ -8,8 +8,7 @@ use crate::scope::Scope;
use crate::selector::Selector; use crate::selector::Selector;
use crate::value::{SassMap, Value}; use crate::value::{SassMap, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn map_get(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn map_get(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let key = arg!(args, scope, super_selector, 1, "key"); let key = arg!(args, scope, super_selector, 1, "key");
let map = match arg!(args, scope, super_selector, 0, "map") { let map = match arg!(args, scope, super_selector, 0, "map") {
@ -24,13 +23,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(map.get(&key, args.span())?.unwrap_or(Value::Null)) Ok(map.get(&key, args.span())?.unwrap_or(Value::Null))
} }
fn map_has_key( fn map_has_key(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let key = arg!(args, scope, super_selector, 1, "key"); let key = arg!(args, scope, super_selector, 1, "key");
let map = match arg!(args, scope, super_selector, 0, "map") { let map = match arg!(args, scope, super_selector, 0, "map") {
@ -45,9 +40,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::bool(map.get(&key, args.span())?.is_some())) Ok(Value::bool(map.get(&key, args.span())?.is_some()))
} }
fn map_keys(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn map_keys(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let map = match arg!(args, scope, super_selector, 0, "map") { let map = match arg!(args, scope, super_selector, 0, "map") {
Value::Map(m) => m, Value::Map(m) => m,
@ -65,13 +60,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
ListSeparator::Comma, ListSeparator::Comma,
Brackets::None, Brackets::None,
)) ))
} }
fn map_values( fn map_values(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let map = match arg!(args, scope, super_selector, 0, "map") { let map = match arg!(args, scope, super_selector, 0, "map") {
Value::Map(m) => m, Value::Map(m) => m,
@ -89,13 +80,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
ListSeparator::Comma, ListSeparator::Comma,
Brackets::None, Brackets::None,
)) ))
} }
fn map_merge( fn map_merge(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let mut map1 = match arg!(args, scope, super_selector, 0, "map1") { let mut map1 = match arg!(args, scope, super_selector, 0, "map1") {
Value::Map(m) => m, Value::Map(m) => m,
@ -121,13 +108,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
}; };
map1.merge(map2); map1.merge(map2);
Ok(Value::Map(map1)) Ok(Value::Map(map1))
} }
fn map_remove( fn map_remove(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
let mut map = match arg!(args, scope, super_selector, 0, "map") { let mut map = match arg!(args, scope, super_selector, 0, "map") {
Value::Map(m) => m, Value::Map(m) => m,
Value::List(v, ..) if v.is_empty() => SassMap::new(), Value::List(v, ..) if v.is_empty() => SassMap::new(),
@ -144,8 +127,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
map.remove(&key); map.remove(&key);
} }
Ok(Value::Map(map)) Ok(Value::Map(map))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("map-get", Builtin::new(map_get)); f.insert("map-get", Builtin::new(map_get));
f.insert("map-has-key", Builtin::new(map_has_key)); f.insert("map-has-key", Builtin::new(map_has_key));
f.insert("map-keys", Builtin::new(map_keys)); f.insert("map-keys", Builtin::new(map_keys));

View File

@ -13,12 +13,7 @@ use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{Number, Value}; use crate::value::{Number, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn percentage(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn percentage(
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let num = match arg!(args, scope, super_selector, 0, "number") { let num = match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(n, Unit::None) => n * Number::from(100), Value::Dimension(n, Unit::None) => n * Number::from(100),
@ -44,9 +39,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Dimension(num, Unit::Percent)) Ok(Value::Dimension(num, Unit::Percent))
} }
fn round(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn round(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "number") { match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(n, u) => Ok(Value::Dimension(n.round(), u)), Value::Dimension(n, u) => Ok(Value::Dimension(n.round(), u)),
@ -59,9 +54,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn ceil(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn ceil(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "number") { match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(n, u) => Ok(Value::Dimension(n.ceil(), u)), Value::Dimension(n, u) => Ok(Value::Dimension(n.ceil(), u)),
@ -74,9 +69,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn floor(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn floor(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "number") { match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(n, u) => Ok(Value::Dimension(n.floor(), u)), Value::Dimension(n, u) => Ok(Value::Dimension(n.floor(), u)),
@ -89,9 +84,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn abs(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn abs(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "number") { match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(n, u) => Ok(Value::Dimension(n.abs(), u)), Value::Dimension(n, u) => Ok(Value::Dimension(n.abs(), u)),
@ -104,13 +99,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn comparable( fn comparable(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let unit1 = match arg!(args, scope, super_selector, 0, "number1") { let unit1 = match arg!(args, scope, super_selector, 0, "number1") {
Value::Dimension(_, u) => u, Value::Dimension(_, u) => u,
@ -140,11 +131,11 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
}; };
Ok(Value::bool(unit1.comparable(&unit2))) Ok(Value::bool(unit1.comparable(&unit2)))
} }
// TODO: write tests for this // TODO: write tests for this
#[cfg(feature = "random")] #[cfg(feature = "random")]
fn random(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn random(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let limit = match arg!(args, scope, super_selector, 0, "limit" = Value::Null) { let limit = match arg!(args, scope, super_selector, 0, "limit" = Value::Null) {
Value::Dimension(n, _) => n, Value::Dimension(n, _) => n,
@ -196,8 +187,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
Number::from(rng.gen_range(0, limit) + 1), Number::from(rng.gen_range(0, limit) + 1),
Unit::None, Unit::None,
)) ))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("percentage", Builtin::new(percentage)); f.insert("percentage", Builtin::new(percentage));
f.insert("round", Builtin::new(round)); f.insert("round", Builtin::new(round));
f.insert("ceil", Builtin::new(ceil)); f.insert("ceil", Builtin::new(ceil));

View File

@ -12,21 +12,20 @@ use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{SassFunction, Value}; use crate::value::{SassFunction, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn if_(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn if_(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
if arg!(args, scope, super_selector, 0, "condition").is_true(args.span())? { if arg!(args, scope, super_selector, 0, "condition").is_true(args.span())? {
Ok(arg!(args, scope, super_selector, 1, "if-true")) Ok(arg!(args, scope, super_selector, 1, "if-true"))
} else { } else {
Ok(arg!(args, scope, super_selector, 2, "if-false")) Ok(arg!(args, scope, super_selector, 2, "if-false"))
} }
} }
fn feature_exists( fn feature_exists(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "feature") { match arg!(args, scope, super_selector, 0, "feature") {
Value::Ident(s, _) => Ok(match s.as_str() { Value::Ident(s, _) => Ok(match s.as_str() {
@ -56,9 +55,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn unit(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn unit(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let unit = match arg!(args, scope, super_selector, 0, "number") { let unit = match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(_, u) => u.to_string(), Value::Dimension(_, u) => u.to_string(),
@ -74,38 +73,39 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Ident(unit, QuoteKind::Quoted)) Ok(Value::Ident(unit, QuoteKind::Quoted))
} }
fn type_of(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn type_of(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let value = arg!(args, scope, super_selector, 0, "value"); let value = arg!(args, scope, super_selector, 0, "value");
Ok(Value::Ident( Ok(Value::Ident(
value.kind(args.span())?.to_owned(), value.kind(args.span())?.to_owned(),
QuoteKind::None, QuoteKind::None,
)) ))
} }
fn unitless(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
fn unitless(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "number") { match arg!(args, scope, super_selector, 0, "number") {
Value::Dimension(_, Unit::None) => Ok(Value::True), Value::Dimension(_, Unit::None) => Ok(Value::True),
Value::Dimension(_, _) => Ok(Value::False), Value::Dimension(_, _) => Ok(Value::False),
_ => Ok(Value::True), _ => Ok(Value::True),
} }
} }
fn inspect(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn inspect(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
Ok(Value::Ident( Ok(Value::Ident(
arg!(args, scope, super_selector, 0, "value").inspect(args.span())?, arg!(args, scope, super_selector, 0, "value").inspect(args.span())?,
QuoteKind::None, QuoteKind::None,
)) ))
} }
fn variable_exists( fn variable_exists(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "name") { match arg!(args, scope, super_selector, 0, "name") {
Value::Ident(s, _) => Ok(Value::bool(scope.var_exists(&s))), Value::Ident(s, _) => Ok(Value::bool(scope.var_exists(&s))),
@ -115,13 +115,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn global_variable_exists( fn global_variable_exists(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "name") { match arg!(args, scope, super_selector, 0, "name") {
Value::Ident(s, _) => Ok(Value::bool(global_var_exists(&s))), Value::Ident(s, _) => Ok(Value::bool(global_var_exists(&s))),
@ -131,13 +131,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn mixin_exists( fn mixin_exists(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
match arg!(args, scope, super_selector, 0, "name") { match arg!(args, scope, super_selector, 0, "name") {
Value::Ident(s, _) => Ok(Value::bool(scope.mixin_exists(&s))), Value::Ident(s, _) => Ok(Value::bool(scope.mixin_exists(&s))),
@ -147,13 +143,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn function_exists( fn function_exists(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
match arg!(args, scope, super_selector, 0, "name") { match arg!(args, scope, super_selector, 0, "name") {
Value::Ident(s, _) => Ok(Value::bool( Value::Ident(s, _) => Ok(Value::bool(
@ -165,13 +161,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn get_function( fn get_function(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let name = match arg!(args, scope, super_selector, 0, "name") { let name = match arg!(args, scope, super_selector, 0, "name") {
Value::Ident(s, _) => s, Value::Ident(s, _) => s,
@ -183,8 +175,7 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
.into()) .into())
} }
}; };
let css = let css = arg!(args, scope, super_selector, 1, "css" = Value::False).is_true(args.span())?;
arg!(args, scope, super_selector, 1, "css" = Value::False).is_true(args.span())?;
let module = match arg!(args, scope, super_selector, 2, "module" = Value::Null) { let module = match arg!(args, scope, super_selector, 2, "module" = Value::Null) {
Value::Ident(s, ..) => Some(s), Value::Ident(s, ..) => Some(s),
Value::Null => None, Value::Null => None,
@ -220,9 +211,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
}; };
Ok(Value::Function(func)) Ok(Value::Function(func))
} }
fn call(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn call(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
let func = match arg!(args, scope, super_selector, 0, "function") { let func = match arg!(args, scope, super_selector, 0, "function") {
Value::Function(f) => f, Value::Function(f) => f,
v => { v => {
@ -237,8 +228,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
func.call(args.decrement(), scope, super_selector) func.call(args.decrement(), scope, super_selector)
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("if", Builtin::new(if_)); f.insert("if", Builtin::new(if_));
f.insert("feature-exists", Builtin::new(feature_exists)); f.insert("feature-exists", Builtin::new(feature_exists));
f.insert("unit", Builtin::new(unit)); f.insert("unit", Builtin::new(unit));

View File

@ -15,12 +15,11 @@ use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{Number, Value}; use crate::value::{Number, Value};
pub(crate) fn register(f: &mut GlobalFunctionMap) { fn to_upper_case(
fn to_upper_case(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "string") { match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(mut i, q) => { Value::Ident(mut i, q) => {
@ -36,13 +35,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn to_lower_case( fn to_lower_case(
mut args: CallArgs, mut args: CallArgs,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> SassResult<Value> { ) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "string") { match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(mut i, q) => { Value::Ident(mut i, q) => {
@ -58,13 +57,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn str_length( fn str_length(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "string") { match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(i, _) => Ok(Value::Dimension( Value::Ident(i, _) => Ok(Value::Dimension(
@ -80,9 +75,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn quote(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn quote(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "string") { match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(i, _) => Ok(Value::Ident(i, QuoteKind::Quoted)), Value::Ident(i, _) => Ok(Value::Ident(i, QuoteKind::Quoted)),
@ -95,9 +90,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn unquote(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> { fn unquote(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
match arg!(args, scope, super_selector, 0, "string") { match arg!(args, scope, super_selector, 0, "string") {
i @ Value::Ident(..) => Ok(i.unquote()), i @ Value::Ident(..) => Ok(i.unquote()),
@ -110,13 +105,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
) )
.into()), .into()),
} }
} }
fn str_slice( fn str_slice(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (string, quotes) = match arg!(args, scope, super_selector, 0, "string") { let (string, quotes) = match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(s, q) => (s, q), Value::Ident(s, q) => (s, q),
@ -216,13 +207,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
quotes, quotes,
)) ))
} }
} }
fn str_index( fn str_index(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(2)?; args.max_args(2)?;
let s1 = match arg!(args, scope, super_selector, 0, "string") { let s1 = match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(i, _) => i, Value::Ident(i, _) => i,
@ -256,13 +243,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
Some(v) => Value::Dimension(Number::from(v + 1), Unit::None), Some(v) => Value::Dimension(Number::from(v + 1), Unit::None),
None => Value::Null, None => Value::Null,
}) })
} }
fn str_insert( fn str_insert(mut args: CallArgs, scope: &Scope, super_selector: &Selector) -> SassResult<Value> {
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let (s1, quotes) = match arg!(args, scope, super_selector, 0, "string") { let (s1, quotes) = match arg!(args, scope, super_selector, 0, "string") {
Value::Ident(i, q) => (i, q), Value::Ident(i, q) => (i, q),
@ -361,10 +344,10 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
}; };
Ok(Value::Ident(string, quotes)) Ok(Value::Ident(string, quotes))
} }
#[cfg(feature = "random")] #[cfg(feature = "random")]
fn unique_id(args: CallArgs, _: &Scope, _: &Selector) -> SassResult<Value> { fn unique_id(args: CallArgs, _: &Scope, _: &Selector) -> SassResult<Value> {
args.max_args(0)?; args.max_args(0)?;
let mut rng = thread_rng(); let mut rng = thread_rng();
let string = std::iter::repeat(()) let string = std::iter::repeat(())
@ -372,8 +355,9 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
.take(7) .take(7)
.collect(); .collect();
Ok(Value::Ident(string, QuoteKind::None)) Ok(Value::Ident(string, QuoteKind::None))
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("to-upper-case", Builtin::new(to_upper_case)); f.insert("to-upper-case", Builtin::new(to_upper_case));
f.insert("to-lower-case", Builtin::new(to_lower_case)); f.insert("to-lower-case", Builtin::new(to_lower_case));
f.insert("str-length", Builtin::new(str_length)); f.insert("str-length", Builtin::new(str_length));