use crate::executor::Environment;
use crate::value::Value;
use indexmap::IndexMap;
pub fn register(env: &mut Environment) {
env.register_builtin("object.keys", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
Ok(Value::Array(
obj.keys().map(|k| Value::String(k.clone())).collect(),
))
} else {
Ok(Value::Array(Vec::new()))
}
});
env.register_builtin("object.values", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
Ok(Value::Array(obj.values().cloned().collect()))
} else {
Ok(Value::Array(Vec::new()))
}
});
env.register_builtin("object.entries", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
Ok(Value::Array(
obj.iter()
.map(|(k, v)| {
Value::Array(vec![Value::String(k.clone()), v.clone()])
})
.collect(),
))
} else {
Ok(Value::Array(Vec::new()))
}
});
env.register_builtin("object.merge", |args, _| {
let mut result = IndexMap::new();
for arg in args {
if let Value::Object(obj) = arg {
for (k, v) in obj {
result.insert(k.clone(), v.clone());
}
}
}
Ok(Value::Object(result))
});
env.register_builtin("object.clone", |args, _| {
args.first().cloned().ok_or_else(|| "object.clone: missing argument".to_string())
});
env.register_builtin("object.hasProperty", |args, _| {
match (args.first(), args.get(1)) {
(Some(Value::Object(obj)), Some(Value::String(key))) => {
Ok(Value::Bool(obj.contains_key(key)))
}
_ => Ok(Value::Bool(false)),
}
});
env.register_builtin("object.getProperty", |args, _| {
match (args.first(), args.get(1)) {
(Some(Value::Object(obj)), Some(Value::String(key))) => {
Ok(obj.get(key).cloned().unwrap_or(Value::Null))
}
_ => Ok(Value::Null),
}
});
env.register_builtin("keys", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
Ok(Value::Array(
obj.keys().map(|k| Value::String(k.clone())).collect(),
))
} else {
Ok(Value::Array(Vec::new()))
}
});
env.register_builtin("values", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
Ok(Value::Array(obj.values().cloned().collect()))
} else {
Ok(Value::Array(Vec::new()))
}
});
env.register_builtin("entries", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
Ok(Value::Array(
obj.iter()
.map(|(k, v)| Value::Array(vec![Value::String(k.clone()), v.clone()]))
.collect(),
))
} else {
Ok(Value::Array(Vec::new()))
}
});
env.register_builtin("merge", |args, _| {
let mut result = IndexMap::new();
for arg in args {
if let Value::Object(obj) = arg {
for (k, v) in obj {
result.insert(k.clone(), v.clone());
}
}
}
Ok(Value::Object(result))
});
env.register_builtin("clone", |args, _| {
args.first().cloned().ok_or_else(|| "clone: missing argument".to_string())
});
env.register_builtin("object.setProperty", |args, _| {
if let Some(Value::Object(obj)) = args.first() {
let mut new_obj = obj.clone();
if let (Some(Value::String(key)), Some(val)) = (args.get(1), args.get(2)) {
new_obj.insert(key.clone(), val.clone());
}
Ok(Value::Object(new_obj))
} else {
Ok(Value::Null)
}
});
}