2020-03-30 15:43:15 -04:00
|
|
|
use std::collections::HashMap;
|
2020-02-02 21:09:29 -05:00
|
|
|
|
2020-03-30 15:43:15 -04:00
|
|
|
use super::Builtin;
|
|
|
|
use crate::common::{Brackets, ListSeparator};
|
2020-03-30 16:14:42 -04:00
|
|
|
use crate::value::{SassMap, Value};
|
2020-03-30 15:43:15 -04:00
|
|
|
|
|
|
|
pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
|
|
|
f.insert(
|
|
|
|
"map-get".to_owned(),
|
2020-04-04 18:17:04 -04:00
|
|
|
Builtin::new(|mut args, scope, super_selector| {
|
2020-04-22 06:17:52 -04:00
|
|
|
args.max_args(2)?;
|
2020-04-04 18:17:04 -04:00
|
|
|
let key = arg!(args, scope, super_selector, 1, "key");
|
|
|
|
let map = match arg!(args, scope, super_selector, 0, "map") {
|
2020-03-30 15:43:15 -04:00
|
|
|
Value::Map(m) => m,
|
2020-03-30 16:10:02 -04:00
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-03-30 15:43:15 -04:00
|
|
|
};
|
2020-04-12 19:37:12 -04:00
|
|
|
Ok(map.get(&key, args.span())?.unwrap_or(Value::Null))
|
2020-03-30 15:43:15 -04:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
f.insert(
|
|
|
|
"map-has-key".to_owned(),
|
2020-04-04 18:17:04 -04:00
|
|
|
Builtin::new(|mut args, scope, super_selector| {
|
2020-04-22 06:17:52 -04:00
|
|
|
args.max_args(2)?;
|
2020-04-04 18:17:04 -04:00
|
|
|
let key = arg!(args, scope, super_selector, 1, "key");
|
|
|
|
let map = match arg!(args, scope, super_selector, 0, "map") {
|
2020-03-30 15:43:15 -04:00
|
|
|
Value::Map(m) => m,
|
2020-03-30 16:10:02 -04:00
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-03-30 15:43:15 -04:00
|
|
|
};
|
2020-04-12 19:37:12 -04:00
|
|
|
Ok(Value::bool(map.get(&key, args.span())?.is_some()))
|
2020-03-30 15:43:15 -04:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
f.insert(
|
|
|
|
"map-keys".to_owned(),
|
2020-04-04 18:17:04 -04:00
|
|
|
Builtin::new(|mut args, scope, super_selector| {
|
2020-04-22 06:17:52 -04:00
|
|
|
args.max_args(1)?;
|
2020-04-04 18:17:04 -04:00
|
|
|
let map = match arg!(args, scope, super_selector, 0, "map") {
|
2020-03-30 15:43:15 -04:00
|
|
|
Value::Map(m) => m,
|
2020-03-30 16:10:02 -04:00
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-03-30 15:43:15 -04:00
|
|
|
};
|
|
|
|
Ok(Value::List(
|
|
|
|
map.keys(),
|
2020-03-30 16:14:42 -04:00
|
|
|
ListSeparator::Comma,
|
2020-03-30 15:43:15 -04:00
|
|
|
Brackets::None,
|
|
|
|
))
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
f.insert(
|
|
|
|
"map-values".to_owned(),
|
2020-04-04 18:17:04 -04:00
|
|
|
Builtin::new(|mut args, scope, super_selector| {
|
2020-04-22 06:17:52 -04:00
|
|
|
args.max_args(1)?;
|
2020-04-04 18:17:04 -04:00
|
|
|
let map = match arg!(args, scope, super_selector, 0, "map") {
|
2020-03-30 15:43:15 -04:00
|
|
|
Value::Map(m) => m,
|
2020-03-30 16:10:02 -04:00
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-03-30 15:43:15 -04:00
|
|
|
};
|
|
|
|
Ok(Value::List(
|
|
|
|
map.values(),
|
2020-03-30 16:21:00 -04:00
|
|
|
ListSeparator::Comma,
|
2020-03-30 15:43:15 -04:00
|
|
|
Brackets::None,
|
|
|
|
))
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
f.insert(
|
|
|
|
"map-merge".to_owned(),
|
2020-04-04 18:17:04 -04:00
|
|
|
Builtin::new(|mut args, scope, super_selector| {
|
2020-04-22 06:17:52 -04:00
|
|
|
args.max_args(2)?;
|
2020-04-04 18:17:04 -04:00
|
|
|
let mut map1 = match arg!(args, scope, super_selector, 0, "map1") {
|
2020-03-30 15:43:15 -04:00
|
|
|
Value::Map(m) => m,
|
2020-03-30 16:10:02 -04:00
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map1: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-03-30 15:43:15 -04:00
|
|
|
};
|
2020-04-04 18:17:04 -04:00
|
|
|
let map2 = match arg!(args, scope, super_selector, 1, "map2") {
|
2020-03-30 15:43:15 -04:00
|
|
|
Value::Map(m) => m,
|
2020-03-30 16:10:02 -04:00
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map2: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-03-30 15:43:15 -04:00
|
|
|
};
|
|
|
|
map1.merge(map2);
|
|
|
|
Ok(Value::Map(map1))
|
|
|
|
}),
|
|
|
|
);
|
2020-04-02 13:49:39 -04:00
|
|
|
f.insert(
|
|
|
|
"map-remove".to_owned(),
|
2020-04-04 18:17:04 -04:00
|
|
|
Builtin::new(|mut args, scope, super_selector| {
|
|
|
|
let mut map = match arg!(args, scope, super_selector, 0, "map") {
|
2020-04-02 13:49:39 -04:00
|
|
|
Value::Map(m) => m,
|
|
|
|
Value::List(v, ..) if v.is_empty() => SassMap::new(),
|
2020-04-12 19:37:12 -04:00
|
|
|
v => {
|
|
|
|
return Err((
|
|
|
|
format!("$map: {} is not a map.", v.to_css_string(args.span())?),
|
|
|
|
args.span(),
|
|
|
|
)
|
|
|
|
.into())
|
|
|
|
}
|
2020-04-02 13:49:39 -04:00
|
|
|
};
|
2020-04-04 18:17:04 -04:00
|
|
|
let keys = args.get_variadic(scope, super_selector)?;
|
2020-04-02 13:49:39 -04:00
|
|
|
for key in keys {
|
|
|
|
map.remove(&key);
|
|
|
|
}
|
|
|
|
Ok(Value::Map(map))
|
|
|
|
}),
|
|
|
|
);
|
2020-03-30 15:43:15 -04:00
|
|
|
}
|