1use std::collections::HashSet;
2
3use tan::{
4 context::Context,
5 error::Error,
6 expr::{expr_clone, Expr},
7 util::module_util::require_module,
8};
9
10pub fn set_new(_args: &[Expr]) -> Result<Expr, Error> {
13 let set: HashSet<Expr> = HashSet::new();
15 Ok(Expr::set(set))
16}
17
18pub fn set_put(args: &[Expr]) -> Result<Expr, Error> {
19 let [this, value] = args else {
20 return Err(Error::invalid_arguments(
21 "requires `this` and `value` arguments",
22 None,
23 ));
24 };
25
26 let Some(mut items) = this.as_set_mut() else {
27 return Err(Error::invalid_arguments(
28 "`this` argument should be a Set",
29 this.range(),
30 ));
31 };
32
33 items.insert(expr_clone(value.unpack()));
37
38 Ok(Expr::None)
40}
41
42pub fn set_values(args: &[Expr]) -> Result<Expr, Error> {
45 let [this] = args else {
46 return Err(Error::invalid_arguments("requires `this` argument", None));
47 };
48
49 let Some(items) = this.as_set_mut() else {
50 return Err(Error::invalid_arguments(
51 "`this` argument should be a Set",
52 this.range(),
53 ));
54 };
55
56 let values: Vec<_> = items.iter().map(expr_clone).collect();
57 Ok(Expr::array(values))
58}
59
60pub fn import_lib_set(context: &mut Context) {
61 let module = require_module("set", context);
63
64 module.insert_invocable("Set", Expr::foreign_func(&set_new));
65
66 module.insert_invocable("put$$Set$$Int", Expr::foreign_func(&set_put));
69 module.insert_invocable("put$$Set$$Float", Expr::foreign_func(&set_put));
70 module.insert_invocable("put$$Set$$String", Expr::foreign_func(&set_put));
71 module.insert_invocable("values-of", Expr::foreign_func(&set_values));
74 module.insert_invocable("values-of$$Set", Expr::foreign_func(&set_values));
75}