guartcl 0.5.0-beta3

Enhanced Jim Tcl.
Documentation
use jimtcl::{Interp, JimObject, JimResult, object::IntoJimObj, tcl_error};
use uuid::Uuid;

pub fn uuid_v3<'jim>(
    _interp: &'jim Interp,
    ns: &JimObject<'jim>,
    data: &JimObject<'jim>,
) -> JimResult<String> {
    let ns_uuid = namespace_uuid(ns.as_str()?)?;
    let name = data.as_bytes();
    let out = Uuid::new_v3(&ns_uuid, name);
    Ok(out.to_string())
}

pub fn uuid_v5<'jim>(
    _interp: &'jim Interp,
    ns: &JimObject<'jim>,
    data: &JimObject<'jim>,
) -> JimResult<String> {
    let ns_uuid = namespace_uuid(ns.as_str()?)?;
    let name = data.as_bytes();
    let out = Uuid::new_v5(&ns_uuid, name);
    Ok(out.to_string())
}

pub fn uuid_v4(_interp: &Interp) -> JimResult<String> {
    let out = Uuid::new_v4();
    Ok(out.to_string())
}

pub fn uuid_v7(_interp: &Interp) -> JimResult<String> {
    let out = Uuid::now_v7();
    Ok(out.to_string())
}

pub fn uuid_version<'jim>(_interp: &'jim Interp, uuid: &JimObject<'jim>) -> JimResult<usize> {
    Ok(parse_uuid(uuid)?.get_version_num())
}

pub fn uuid_timestamp<'jim>(_interp: &'jim Interp, uuid: &JimObject<'jim>) -> JimResult<f64> {
    let uuid = parse_uuid(uuid)?;
    if let Some(ts) = uuid.get_timestamp() {
        let (secs, nanos) = ts.to_unix();
        Ok(secs as f64 + (nanos as f64 * 1_000_000_000.0))
    } else {
        Err(tcl_error!("uuid does not have a timestamp"))
    }
}

pub fn uuid_binary<'jim>(
    interp: &'jim Interp,
    uuid: &JimObject<'jim>,
) -> JimResult<JimObject<'jim>> {
    let uuid = parse_uuid(uuid)?;
    Ok(uuid.as_bytes().to_jim(interp))
}

fn namespace_uuid(uuid: &str) -> JimResult<Uuid> {
    match uuid {
        "oid" => Ok(Uuid::NAMESPACE_OID),
        "url" => Ok(Uuid::NAMESPACE_URL),
        "dns" => Ok(Uuid::NAMESPACE_DNS),
        "x500" => Ok(Uuid::NAMESPACE_X500),
        _ => Uuid::try_parse(uuid).map_err(|e| tcl_error!("invalid UUID: {}", e)),
    }
}

fn parse_uuid<'jim>(uuid: &JimObject<'jim>) -> JimResult<Uuid> {
    Uuid::try_parse(uuid.as_str()?).map_err(|e| tcl_error!("invalid UUID: {}", e))
}