stellar-notation 0.9.18

Rust library for encoding and decoding objects in Stellar Notation format.
Documentation

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