guartcl 0.5.0-beta3

Enhanced Jim Tcl.
Documentation
//! typedata creation commands
use indexmap::IndexMap;
use jimtcl::{Interp, JimError, JimObject, JimResult, custom::JimExtensionType};

use super::TypedData;

/// Create a null typed data structure
pub fn td_null(_interp: &Interp) -> JimResult<TypedData> {
    Ok(TypedData::Null)
}

/// Create a boolean typed data structure
pub fn td_boolean<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
    Ok(TypedData::Bool(bool::try_from(obj)?))
}

/// Create an integer typed data structure
pub fn td_integer<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
    Ok(TypedData::Int(i64::try_from(obj)?))
}

/// Create an float typed data structure
pub fn td_float<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
    Ok(TypedData::Float(f64::try_from(obj)?))
}

/// Create an string typed data structure
pub fn td_string<'jim>(_interp: &'jim Interp, obj: &JimObject<'jim>) -> JimResult<TypedData> {
    Ok(TypedData::Str(obj.to_string()))
}

/// Create an list from Tcl TypedData values.
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()))
}

/// Create an object from a Tcl dictionary.
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()))
}