grass/src/builtin/meta.rs

93 lines
3.5 KiB
Rust
Raw Normal View History

2020-02-02 22:33:04 -05:00
use std::collections::BTreeMap;
2020-02-02 21:09:29 -05:00
use super::{Builtin, GLOBAL_FUNCTIONS};
2020-02-03 07:35:04 -05:00
use crate::common::QuoteKind;
2020-02-03 08:10:55 -05:00
use crate::units::Unit;
2020-02-02 22:33:04 -05:00
use crate::value::Value;
pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
decl!(f "if", |args, _| {
2020-02-16 18:18:57 -05:00
max_args!(args, 3);
2020-02-16 18:15:56 -05:00
if arg!(args, 0, "condition").is_true() {
Ok(arg!(args, 1, "if-true"))
2020-02-03 07:11:35 -05:00
} else {
Ok(arg!(args, 2, "if-false"))
2020-02-03 07:11:35 -05:00
}
});
decl!(f "feature-exists", |args, _| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
match arg!(args, 0, "feature").unquote().to_string().as_str() {
2020-02-03 07:22:20 -05:00
// A local variable will shadow a global variable unless
// `!global` is used.
"global-variable-shadowing" => Ok(Value::False),
2020-02-03 07:22:20 -05:00
// the @extend rule will affect selectors nested in pseudo-classes
// like :not()
"extend-selector-pseudoclass" => Ok(Value::False),
2020-02-03 07:22:20 -05:00
// Full support for unit arithmetic using units defined in the
// [Values and Units Level 3][] spec.
"units-level-3" => Ok(Value::False),
2020-02-03 07:22:20 -05:00
// The Sass `@error` directive is supported.
"at-error" => Ok(Value::True),
2020-02-03 07:22:20 -05:00
// The "Custom Properties Level 1" spec is supported. This means
// that custom properties are parsed statically, with only
// interpolation treated as SassScript.
"custom-property" => Ok(Value::False),
_ => Ok(Value::False),
2020-02-03 07:22:20 -05:00
}
});
decl!(f "unit", |args, _| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
2020-02-16 18:15:56 -05:00
let unit = match arg!(args, 0, "number") {
2020-02-03 07:35:04 -05:00
Value::Dimension(_, u) => u.to_string(),
_ => String::new()
};
Ok(Value::Ident(unit, QuoteKind::Double))
2020-02-03 07:35:04 -05:00
});
decl!(f "type-of", |args, _| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
let value = arg!(args, 0, "value");
Ok(Value::Ident(value.kind().to_owned(), QuoteKind::None))
2020-02-03 07:56:21 -05:00
});
decl!(f "unitless", |args, _| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
2020-02-16 18:15:56 -05:00
match arg!(args, 0, "number") {
Value::Dimension(_, Unit::None) => Ok(Value::True),
Value::Dimension(_, _) => Ok(Value::False),
_ => Ok(Value::True)
2020-02-03 08:10:55 -05:00
}
});
decl!(f "inspect", |args, _| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
2020-02-08 17:03:43 -05:00
let value = arg!(args, 0, "value");
Ok(Value::Ident(value.to_string(), QuoteKind::None))
2020-02-03 15:18:12 -05:00
});
decl!(f "variable-exists", |args, scope| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
let value = arg!(args, 0, "name");
Ok(Value::bool(scope.var_exists(&value.to_string())))
});
decl!(f "mixin-exists", |args, scope| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
let value = arg!(args, 0, "name");
Ok(Value::bool(scope.mixin_exists(&value.to_string())))
});
decl!(f "function-exists", |args, scope| {
2020-02-16 18:18:57 -05:00
max_args!(args, 1);
let value = arg!(args, 0, "name");
let s = value.unquote().to_string();
Ok(Value::bool(scope.fn_exists(&s) || GLOBAL_FUNCTIONS.contains_key(&s)))
});
decl!(f "call", |_args, _scope| {
todo!("builtin function `call()` is blocked on refactoring how call args are stored and parsed")
// let func = arg!(args, 0, "function").to_string();
// let func = match scope.get_fn(&func) {
// Ok(f) => f,
// Err(_) => match GLOBAL_FUNCTIONS.get(&func) {
// Some(f) => return f(&args, scope),
// None => todo!("called undefined function"),
// },
// };
// Some(func.clone().args(&args).call())
});
2020-02-07 00:10:43 -05:00
}