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()))
}