use indexmap::IndexMap;
use jimtcl::{Interp, JimError, JimObject, JimResult, custom::JimExtensionType};
use super::TypedData;
pub fn td_null(_interp: &Interp) -> JimResult<TypedData> {
Ok(TypedData::Null)
}
pub fn td_boolean<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
Ok(TypedData::Bool(bool::try_from(obj)?))
}
pub fn td_integer<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
Ok(TypedData::Int(i64::try_from(obj)?))
}
pub fn td_float<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
Ok(TypedData::Float(f64::try_from(obj)?))
}
pub fn td_string<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
Ok(TypedData::Str(obj.to_string()))
}
pub fn td_list<'jim>(_interp: &'jim Interp, args: &[JimObject<'jim>]) -> JimResult<TypedData> {
let n = args.len() - 1;
let mut list = Vec::with_capacity(n);
for (i, val) in args[1..].iter().enumerate() {
let tval = TypedData::extract_ref(val).map_err(|e| {
JimError::from(format!(
"list element {} is not a valid TypedData ({})",
i, e
))
})?;
list.push(tval.clone().into());
}
Ok(TypedData::List(list.into()))
}
pub fn td_record<'jim>(_interp: &'jim Interp, args: &[JimObject<'jim>]) -> JimResult<TypedData> {
let n = args.len() - 1;
if !n.is_multiple_of(2) {
return Err(JimError::from("td dict muts have an even number of args"));
}
let n = n / 2;
let mut map = IndexMap::with_capacity(n);
for i in 0..n {
let key = &args[i * 2 + 1];
let val = &args[i * 2 + 2];
let tval = TypedData::extract_ref(val).map_err(|e| {
JimError::from(format!(
"dict element {} is not a valid TypedData ({})",
i, e
))
})?;
map.insert(key.to_string(), tval.clone().into());
}
Ok(TypedData::Record(map.into()))
}