diff --git a/src/builtin/modules/meta.rs b/src/builtin/modules/meta.rs index be4a626..fb14935 100644 --- a/src/builtin/modules/meta.rs +++ b/src/builtin/modules/meta.rs @@ -18,25 +18,48 @@ fn load_css(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { } fn module_functions(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(2)?; - todo!() + args.max_args(1)?; + + let module = match args.get_err(0, "module")? { + Value::String(s, ..) => s, + v => { + return Err(( + format!("$module: {} is not a string.", v.inspect(args.span())?), + args.span(), + ) + .into()) + } + }; + + Ok(Value::Map( + parser + .modules + .get(&module) + .ok_or(( + format!("There is no module with the namespace \"{}\".", module), + args.span(), + ))? + .functions(), + )) } fn module_variables(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(2)?; + args.max_args(1)?; todo!() } pub(crate) fn declare(f: &mut Module) { - f.insert_builtin("call", call); - f.insert_builtin("content-exists", content_exists); f.insert_builtin("feature-exists", feature_exists); - f.insert_builtin("function-exists", function_exists); - f.insert_builtin("get-function", get_function); - f.insert_builtin("global-variable-exists", global_variable_exists); f.insert_builtin("inspect", inspect); - f.insert_builtin("keywords", keywords); - f.insert_builtin("mixin-exists", mixin_exists); f.insert_builtin("type-of", type_of); + f.insert_builtin("keywords", keywords); + f.insert_builtin("global-variable-exists", global_variable_exists); f.insert_builtin("variable-exists", variable_exists); + f.insert_builtin("function-exists", function_exists); + f.insert_builtin("mixin-exists", mixin_exists); + f.insert_builtin("content-exists", content_exists); + f.insert_builtin("module-variables", module_variables); + f.insert_builtin("module-functions", module_functions); + f.insert_builtin("get-function", get_function); + f.insert_builtin("call", call); } diff --git a/src/builtin/modules/mod.rs b/src/builtin/modules/mod.rs index f32917f..34bf783 100644 --- a/src/builtin/modules/mod.rs +++ b/src/builtin/modules/mod.rs @@ -8,10 +8,10 @@ use crate::{ args::CallArgs, atrule::Mixin, builtin::Builtin, - common::Identifier, + common::{Identifier, QuoteKind}, error::SassResult, parse::Parser, - value::{SassFunction, Value}, + value::{SassFunction, SassMap, Value}, }; mod color; @@ -54,6 +54,20 @@ impl Module { self.functions .insert(ident, SassFunction::Builtin(Builtin::new(function), ident)); } + + pub fn functions(&self) -> SassMap { + SassMap::new_with( + self.functions + .iter() + .map(|(key, value)| { + ( + Value::String(key.to_string(), QuoteKind::Quoted), + Value::FunctionRef(value.clone()), + ) + }) + .collect::>(), + ) + } } pub(crate) fn declare_module_color() -> Module { diff --git a/src/value/map.rs b/src/value/map.rs index e5071c6..fc2c3f9 100644 --- a/src/value/map.rs +++ b/src/value/map.rs @@ -34,6 +34,10 @@ impl SassMap { SassMap(Vec::new()) } + pub const fn new_with(elements: Vec<(Value, Value)>) -> SassMap { + SassMap(elements) + } + /// We take by value here (consuming the map) in order to /// save a clone of the value, since the only place this /// should be called is in a builtin function, which throws