use std::collections::HashMap;
use crate::nan_value::{Arena, NanValue};
use crate::value::{RuntimeError, Value};
pub fn register(global: &mut HashMap<String, Value>) {
let _ = global;
}
pub fn extra_members() -> Vec<(&'static str, String)> {
vec![
("withDefault", "Option.withDefault".to_string()),
("toResult", "Option.toResult".to_string()),
]
}
pub fn effects(_name: &str) -> &'static [&'static str] {
&[]
}
pub fn call(name: &str, args: &[Value]) -> Option<Result<Value, RuntimeError>> {
match name {
"Option.withDefault" => Some(with_default(args)),
"Option.toResult" => Some(to_result(args)),
_ => None,
}
}
fn with_default(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 2 {
return Err(RuntimeError::Error(format!(
"Option.withDefault() takes 2 arguments (option, default), got {}",
args.len()
)));
}
match &args[0] {
Value::Some(v) => Ok(*v.clone()),
Value::None => Ok(args[1].clone()),
_ => Err(RuntimeError::Error(
"Option.withDefault: first argument must be an Option".to_string(),
)),
}
}
fn to_result(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 2 {
return Err(RuntimeError::Error(format!(
"Option.toResult() takes 2 arguments (option, err), got {}",
args.len()
)));
}
match &args[0] {
Value::Some(v) => Ok(Value::Ok(v.clone())),
Value::None => Ok(Value::Err(Box::new(args[1].clone()))),
_ => Err(RuntimeError::Error(
"Option.toResult: first argument must be an Option".to_string(),
)),
}
}
pub fn call_nv(
name: &str,
args: &[NanValue],
arena: &mut Arena,
) -> Option<Result<NanValue, RuntimeError>> {
match name {
"Option.withDefault" => Some(with_default_nv(args, arena)),
"Option.toResult" => Some(to_result_nv(args, arena)),
_ => None,
}
}
fn with_default_nv(args: &[NanValue], arena: &mut Arena) -> Result<NanValue, RuntimeError> {
if args.len() != 2 {
return Err(RuntimeError::Error(format!(
"Option.withDefault() takes 2 arguments (option, default), got {}",
args.len()
)));
}
let v = args[0];
if v.is_some() {
Ok(v.wrapper_inner(arena))
} else if v.is_none() {
Ok(args[1])
} else {
Err(RuntimeError::Error(
"Option.withDefault: first argument must be an Option".to_string(),
))
}
}
fn to_result_nv(args: &[NanValue], arena: &mut Arena) -> Result<NanValue, RuntimeError> {
if args.len() != 2 {
return Err(RuntimeError::Error(format!(
"Option.toResult() takes 2 arguments (option, err), got {}",
args.len()
)));
}
let v = args[0];
if v.is_some() {
let inner = v.wrapper_inner(arena);
Ok(NanValue::new_ok_value(inner, arena))
} else if v.is_none() {
Ok(NanValue::new_err_value(args[1], arena))
} else {
Err(RuntimeError::Error(
"Option.toResult: first argument must be an Option".to_string(),
))
}
}