use std::error::Error;
use std::str;
use std::convert::TryInto;
use std::num::ParseIntError;
pub fn as_u8(val: &str) -> Result<u8, Box<dyn Error>> {
let res = u8::from_le_bytes(decode_hex(val)?[..].try_into().unwrap());
Ok(res)
}
pub fn as_u16(val: &str) -> Result<u16, Box<dyn Error>> {
let res = u16::from_le_bytes(decode_hex(val)?[..].try_into().unwrap());
Ok(res)
}
pub fn as_u32(val: &str) -> Result<u32, Box<dyn Error>> {
let res = u32::from_le_bytes(decode_hex(val)?[..].try_into().unwrap());
Ok(res)
}
pub fn as_u64(val: &str) -> Result<u64, Box<dyn Error>> {
let res = u64::from_le_bytes(decode_hex(val)?[..].try_into().unwrap());
Ok(res)
}
pub fn as_u128(val: &str) -> Result<u128, Box<dyn Error>> {
let res = u128::from_le_bytes(decode_hex(val)?[..].try_into().unwrap());
Ok(res)
}
pub fn as_bytes(val: &str) -> Result<Vec<u8>, Box<dyn Error>> {
let res = decode_hex(val)?;
Ok(res)
}
pub fn as_list(val: &str) -> Result<Vec<String>, Box<dyn Error>> {
let bytes = as_bytes(val)?;
let mut list: Vec<String> = Vec::new();
let mut i = 0;
while i < bytes.len() {
let item_length_size: usize = u8::from_le_bytes([bytes[i]; 1]) as usize;
i += 1;
match item_length_size {
1 => {
let item_length: usize = u8::from_le_bytes([bytes[i]; 1]) as usize;
i += 1;
let item_string: String = str::from_utf8(&bytes[i..i + item_length])?.to_string();
i += item_length;
list.push(item_string)
},
2 => {
let item_length: usize = u16::from_le_bytes([bytes[i], bytes[i + 1]]) as usize;
i += 2;
let item_string: String = str::from_utf8(&bytes[i..i + item_length])?.to_string();
i += item_length;
list.push(item_string)
},
4 => {
let item_length: usize = u32::from_le_bytes([bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3]]) as usize;
i += 4;
let item_string: String = str::from_utf8(&bytes[i..i + item_length])?.to_string();
i += item_length;
list.push(item_string)
},
8 => {
let value_length: usize = u64::from_le_bytes([bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3], bytes[i + 4], bytes[i + 5], bytes[i + 6], bytes[i + 7]]) as usize;
i += 8;
let item_string: String = str::from_utf8(&bytes[i..i + value_length])?.to_string();
i += value_length;
list.push(item_string)
},
_ => ()
}
}
Ok(list)
}
fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
(2..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16))
.collect()
}