use crate::evaluator::RuntimeError;
use crate::value::Value;
pub fn keys(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
match &args[0] {
Value::Dict(dict) => {
let keys: Vec<Value> = dict.keys().map(|k| Value::String(k.clone())).collect();
Ok(Value::Array(keys))
}
_ => Err(RuntimeError::TypeErrorDetailed {
expected: "Dict".to_string(),
got: format!("{:?}", args[0]),
}),
}
}
pub fn values(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
match &args[0] {
Value::Dict(dict) => {
let vals: Vec<Value> = dict.values().cloned().collect();
Ok(Value::Array(vals))
}
_ => Err(RuntimeError::TypeErrorDetailed {
expected: "Dict".to_string(),
got: format!("{:?}", args[0]),
}),
}
}
pub fn has(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
match (&args[0], &args[1]) {
(Value::Dict(dict), Value::String(key)) => Ok(Value::Boolean(dict.contains_key(key))),
_ => Err(RuntimeError::TypeErrorDetailed {
expected: "Dict, String".to_string(),
got: format!("{:?}, {:?}", args[0], args[1]),
}),
}
}
pub fn merge(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
match (&args[0], &args[1]) {
(Value::Dict(dict1), Value::Dict(dict2)) => {
let mut result = dict1.clone();
for (k, v) in dict2 {
result.insert(k.clone(), v.clone());
}
Ok(Value::Dict(result))
}
_ => Err(RuntimeError::TypeErrorDetailed {
expected: "Dict, Dict".to_string(),
got: format!("{:?}, {:?}", args[0], args[1]),
}),
}
}