use std::collections::HashSet;
use tan::{
context::Context,
error::Error,
expr::{expr_clone, Expr},
util::module_util::require_module,
};
pub fn set_new(_args: &[Expr]) -> Result<Expr, Error> {
let set: HashSet<Expr> = HashSet::new();
Ok(Expr::set(set))
}
pub fn set_put(args: &[Expr]) -> Result<Expr, Error> {
let [this, value] = args else {
return Err(Error::invalid_arguments(
"requires `this` and `value` arguments",
None,
));
};
let Some(mut items) = this.as_set_mut() else {
return Err(Error::invalid_arguments(
"`this` argument should be a Set",
this.range(),
));
};
items.insert(expr_clone(value.unpack()));
Ok(Expr::None)
}
pub fn set_values(args: &[Expr]) -> Result<Expr, Error> {
let [this] = args else {
return Err(Error::invalid_arguments("requires `this` argument", None));
};
let Some(items) = this.as_set_mut() else {
return Err(Error::invalid_arguments(
"`this` argument should be a Set",
this.range(),
));
};
let values: Vec<_> = items.iter().map(expr_clone).collect();
Ok(Expr::array(values))
}
pub fn import_lib_set(context: &mut Context) {
let module = require_module("set", context);
module.insert_invocable("Set", Expr::foreign_func(&set_new));
module.insert_invocable("put$$Set$$Int", Expr::foreign_func(&set_put));
module.insert_invocable("put$$Set$$Float", Expr::foreign_func(&set_put));
module.insert_invocable("put$$Set$$String", Expr::foreign_func(&set_put));
module.insert_invocable("values-of", Expr::foreign_func(&set_values));
module.insert_invocable("values-of$$Set", Expr::foreign_func(&set_values));
}