guartcl 0.5.0-beta2

Enhanced Jim Tcl.
Documentation
use data_encoding::{BASE32, BASE64, Encoding, HEXLOWER, HEXLOWER_PERMISSIVE};
use jimtcl::{Interp, JimError, JimObject, JimResult, tcl_error};

pub fn bin_random<'jim>(_interp: &'jim Interp, len: &JimObject<'jim>) -> JimResult<Vec<u8>> {
    let len = usize::try_from(len)?;
    let mut bytes = vec![0u8; len];
    getrandom::fill(&mut bytes).map_err(JimError::wrap)?;
    Ok(bytes)
}

pub fn bin_encode_base64<'jim>(_interp: &'jim Interp, data: &JimObject<'jim>) -> JimResult<String> {
    encode(&BASE64, data)
}

pub fn bin_encode_base32<'jim>(_interp: &'jim Interp, data: &JimObject<'jim>) -> JimResult<String> {
    encode(&BASE32, data)
}

pub fn bin_encode_base58<'jim>(_interp: &'jim Interp, data: &JimObject<'jim>) -> JimResult<String> {
    let enc = bs58::encode(data.as_bytes());
    Ok(enc.into_string())
}

pub fn bin_encode_hex<'jim>(_interp: &'jim Interp, data: &JimObject<'jim>) -> JimResult<String> {
    encode(&HEXLOWER, data)
}

pub fn bin_decode_base64<'jim>(
    _interp: &'jim Interp,
    data: &JimObject<'jim>,
) -> JimResult<Vec<u8>> {
    decode("Base64", &BASE64, data)
}

pub fn bin_decode_base32<'jim>(
    _interp: &'jim Interp,
    data: &JimObject<'jim>,
) -> JimResult<Vec<u8>> {
    decode("Base32", &BASE32, data)
}

pub fn bin_decode_base58<'jim>(
    _interp: &'jim Interp,
    data: &JimObject<'jim>,
) -> JimResult<Vec<u8>> {
    let dec = bs58::decode(data.as_bytes());
    dec.into_vec()
        .map_err(|e| tcl_error!("Base58 decode failed: {}", e))
}

pub fn bin_decode_hex<'jim>(_interp: &'jim Interp, data: &JimObject<'jim>) -> JimResult<Vec<u8>> {
    decode("Hex", &HEXLOWER_PERMISSIVE, data)
}

fn decode<'jim>(name: &str, enc: &Encoding, data: &JimObject<'jim>) -> JimResult<Vec<u8>> {
    enc.decode(data.as_bytes())
        .map_err(|e| tcl_error!("{} decode failed: {}", name, e))
}

fn encode<'jim>(enc: &Encoding, data: &JimObject<'jim>) -> JimResult<String> {
    Ok(enc.encode(data.as_bytes()))
}