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<'jim>(_interp: &'jim Interp) -> JimResult<String> {
let out = Uuid::new_v4();
Ok(out.to_string())
}
pub fn uuid_v7<'jim>(_interp: &'jim 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))
}