use std::fmt;
use std::fmt::{Display};
use crate::constants::error::{ErrorMessage, MALFORMED_UTF8, NOT_AN_ARRAY, NOT_A_BOOL, NOT_A_FLOAT16, NOT_A_FLOAT32, NOT_A_FLOAT64, NOT_A_FLOAT8, NOT_A_INT16, NOT_A_INT32, NOT_A_INT64, NOT_A_INT8, NOT_A_NUMBER, NOT_A_STRING, NOT_A_UINT16, NOT_A_UINT32, NOT_A_UINT64, NOT_A_UINT8, NOT_ENOUGH_BYTES, STRING_MAX_LENGTH_EXCEEDED, STRING_OF_LENGTH_ZERO, VEC_MAX_LENGTH_EXCEEDED, VEC_OF_LENGTH_ZERO};
use crate::constants::length::ByteLength;
use crate::constants::types::{Type, FLOATING_POINT_TYPE};
use float8::F8E4M3;
use float16::f16;
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub struct Value {
pub r#type: Type,
pub length: ByteLength,
pub bytes: Vec<u8>,
}
impl Value {
pub fn decode(vec: Vec<u8>) -> Result<Self, ErrorMessage> {
if vec.len() < 1 {
Err(ErrorMessage(NOT_ENOUGH_BYTES))?
}
fn consumed_for_value(bytes: &[u8]) -> Result<usize, ErrorMessage> {
if bytes.is_empty() {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
let first = bytes[0];
let r#type = Type::try_from(first)?;
let bl = ByteLength::try_from(first)?;
let len_field_size = usize::from(bl);
if bytes.len() < 1 + len_field_size {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
match r#type {
Type::Uint | Type::Int | Type::Float => {
let total = 1 + len_field_size;
if bytes.len() < total {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
Ok(total)
}
Type::Bool | Type::True | Type::False => Ok(1),
Type::String => {
let str_len = match bl {
ByteLength::Zero => Err(ErrorMessage(STRING_OF_LENGTH_ZERO))?,
ByteLength::One => *bytes.get(1).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))? as usize,
ByteLength::Two => {
let s = bytes.get(1..=2).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u16::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Four => {
let s = bytes.get(1..=4).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u32::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Eight => {
let s = bytes.get(1..=8).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
let v = u64::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?);
if v as usize > usize::MAX { Err(ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))? }
v as usize
}
};
let total = 1 + len_field_size + str_len;
if bytes.len() < total {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
Ok(total)
}
Type::Array => {
let count = match bl {
ByteLength::Zero => Err(ErrorMessage(VEC_OF_LENGTH_ZERO))?,
ByteLength::One => *bytes.get(1).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))? as usize,
ByteLength::Two => {
let s = bytes.get(1..=2).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u16::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Four => {
let s = bytes.get(1..=4).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u32::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Eight => {
let s = bytes.get(1..=8).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
let v = u64::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?);
if v as usize > usize::MAX { Err(ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))? }
v as usize
}
};
let mut pos = 1 + len_field_size;
for _ in 0..count {
if pos >= bytes.len() {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
let consumed = consumed_for_value(&bytes[pos..])?;
pos = pos.checked_add(consumed).ok_or_else(|| ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))?;
}
if bytes.len() < pos {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
Ok(pos)
}
}
}
let first = *vec.get(0).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
let r#type = Type::try_from(first)?;
let bl = ByteLength::try_from(first)?;
let len_field_size = usize::from(bl);
match r#type {
Type::Uint | Type::Int | Type::Float => {
let total = 1 + len_field_size;
if vec.len() < total { Err(ErrorMessage(NOT_ENOUGH_BYTES))? }
let chunk = vec[..total].to_vec();
Self::from_number(chunk)
}
Type::String => {
let str_len = match bl {
ByteLength::Zero => Err(ErrorMessage(STRING_OF_LENGTH_ZERO))?,
ByteLength::One => *vec.get(1).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))? as usize,
ByteLength::Two => {
let s = vec.get(1..=2).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u16::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Four => {
let s = vec.get(1..=4).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u32::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Eight => {
let s = vec.get(1..=8).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
let v = u64::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?);
if v as usize > usize::MAX { Err(ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))? }
v as usize
}
};
let total = 1 + len_field_size + str_len;
if vec.len() < total { Err(ErrorMessage(NOT_ENOUGH_BYTES))? }
let payload = &vec[(1 + len_field_size)..total];
let s = String::from_bytes(payload)?;
Self::from_string(s)
}
Type::Array => {
let count = match bl {
ByteLength::Zero => Err(ErrorMessage(VEC_OF_LENGTH_ZERO))?,
ByteLength::One => *vec.get(1).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))? as usize,
ByteLength::Two => {
let s = vec.get(1..=2).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u16::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Four => {
let s = vec.get(1..=4).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
u32::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as usize
}
ByteLength::Eight => {
let s = vec.get(1..=8).ok_or(ErrorMessage(NOT_ENOUGH_BYTES))?;
let v = u64::from_be_bytes(s.try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?);
if v as usize > usize::MAX { Err(ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))? }
v as usize
}
};
let mut elements: Vec<Self> = Vec::with_capacity(count);
let mut pos = 1 + len_field_size;
for _ in 0..count {
if pos >= vec.len() { Err(ErrorMessage(NOT_ENOUGH_BYTES))? }
let consumed = consumed_for_value(&vec[pos..])?;
let chunk = vec[pos..pos + consumed].to_vec();
let element = Self::decode(chunk)?;
elements.push(element);
pos += consumed;
}
Self::from_vec(elements)
}
Type::Bool | Type::False | Type::True => {
Self::from_bool(r#type != Type::False)
}
}
}
pub fn from_number(mut vec: Vec<u8>) -> Result<Self, ErrorMessage> {
if vec.len() < 1 {
Err(ErrorMessage(NOT_ENOUGH_BYTES))?
}
let chunk_a = vec.remove(0);
if chunk_a & 0xF0 > FLOATING_POINT_TYPE {
Err(ErrorMessage(NOT_A_NUMBER))?;
}
let format = Type::try_from(chunk_a)?;
let byte_length = ByteLength::try_from(chunk_a)?;
if vec.len() < u8::from(byte_length) as usize {
Err(ErrorMessage(NOT_ENOUGH_BYTES))?
}
let mut bytes = Vec::with_capacity(1 + byte_length as usize);
bytes.push(chunk_a);
bytes.extend(vec.drain(0..byte_length as usize));
Ok(Self {
r#type: format,
length: byte_length,
bytes
})
}
pub fn isolate_value_bytes(&self) -> &[u8] {
let start = if self.r#type <= Type::Float {
1
} else {
(self.length as u8 + 1) as usize
};
&self.bytes[start..]
}
pub fn as_u8(&self) -> Result<u8, ErrorMessage> {
if self.r#type != Type::Uint || self.length != ByteLength::One {
Err(ErrorMessage(NOT_A_UINT8))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 1] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_UINT8))?;
Ok(u8::from_be_bytes(bytes))
}
pub fn from_u8(num: u8) -> Self {
let r#type = Type::Uint;
let length = ByteLength::One;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_i8(&self) -> Result<i8, ErrorMessage> {
if self.r#type != Type::Int || self.length != ByteLength::One {
Err(ErrorMessage(NOT_A_INT8))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 1] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_INT8))?;
Ok(i8::from_be_bytes(bytes))
}
pub fn from_i8(num: i8) -> Self {
let r#type = Type::Int;
let length = ByteLength::One;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_f8(&self) -> Result<F8E4M3, ErrorMessage> {
if self.r#type != Type::Float || self.length != ByteLength::One {
Err(ErrorMessage(NOT_A_FLOAT8))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 1] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_FLOAT8))?;
Ok(F8E4M3::from_bits(bytes[0]))
}
pub fn from_f8(num: F8E4M3) -> Self {
let r#type = Type::Float;
let length = ByteLength::One;
let num_as_be = num.to_bits();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.push(num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_u16(&self) -> Result<u16, ErrorMessage> {
if self.r#type != Type::Uint || self.length != ByteLength::Two {
Err(ErrorMessage(NOT_A_UINT16))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 2] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_UINT16))?;
Ok(u16::from_be_bytes(bytes))
}
pub fn from_u16(num: u16) -> Self {
let r#type = Type::Uint;
let length = ByteLength::Two;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_i16(&self) -> Result<i16, ErrorMessage> {
if self.r#type != Type::Int || self.length != ByteLength::Two {
Err(ErrorMessage(NOT_A_INT16))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 2] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_INT16))?;
Ok(i16::from_be_bytes(bytes))
}
pub fn from_i16(num: i16) -> Self {
let r#type = Type::Int;
let length = ByteLength::Two;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_f16(&self) -> Result<f16, ErrorMessage> {
if self.r#type != Type::Float || self.length != ByteLength::Two {
Err(ErrorMessage(NOT_A_FLOAT16))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 2] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_FLOAT16))?;
Ok(f16::from_be_bytes(bytes))
}
pub fn from_f16(num: f16) -> Self {
let r#type = Type::Float;
let length = ByteLength::Two;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_u32(&self) -> Result<u32, ErrorMessage> {
if self.r#type != Type::Uint || self.length != ByteLength::Four {
Err(ErrorMessage(NOT_A_UINT32))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 4] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_UINT32))?;
Ok(u32::from_be_bytes(bytes))
}
pub fn from_u32(num: u32) -> Self {
let r#type = Type::Uint;
let length = ByteLength::Four;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_i32(&self) -> Result<i32, ErrorMessage> {
if self.r#type != Type::Int || self.length != ByteLength::Four {
Err(ErrorMessage(NOT_A_INT32))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 4] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_INT32))?;
Ok(i32::from_be_bytes(bytes))
}
pub fn from_i32(num: i32) -> Self {
let r#type = Type::Int;
let length = ByteLength::Four;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_f32(&self) -> Result<f32, ErrorMessage> {
if self.r#type != Type::Float || self.length != ByteLength::Four {
Err(ErrorMessage(NOT_A_FLOAT32))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 4] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_FLOAT32))?;
Ok(f32::from_be_bytes(bytes))
}
pub fn from_f32(num: f32) -> Self {
let r#type = Type::Float;
let length = ByteLength::Four;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_u64(&self) -> Result<u64, ErrorMessage> {
if self.r#type != Type::Uint || self.length != ByteLength::Eight {
Err(ErrorMessage(NOT_A_UINT64))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 8] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_UINT64))?;
Ok(u64::from_be_bytes(bytes))
}
pub fn from_u64(num: u64) -> Self {
let r#type = Type::Uint;
let length = ByteLength::Eight;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_i64(&self) -> Result<i64, ErrorMessage> {
if self.r#type != Type::Int || self.length != ByteLength::Eight {
Err(ErrorMessage(NOT_A_INT64))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 8] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_INT64))?;
Ok(i64::from_be_bytes(bytes))
}
pub fn from_i64(num: i64) -> Self {
let r#type = Type::Int;
let length = ByteLength::Eight;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_f64(&self) -> Result<f64, ErrorMessage> {
if self.r#type != Type::Float || self.length != ByteLength::Eight {
Err(ErrorMessage(NOT_A_FLOAT64))?;
}
let bytes = self.isolate_value_bytes();
let bytes: [u8; 8] = bytes
.try_into()
.map_err(|_| ErrorMessage(NOT_A_FLOAT64))?;
Ok(f64::from_be_bytes(bytes))
}
pub fn from_f64(num: f64) -> Self {
let r#type = Type::Float;
let length = ByteLength::Eight;
let num_as_be = num.to_be_bytes();
let mut bytes = vec![u8::from(r#type) | u8::from(length)];
bytes.extend_from_slice(&num_as_be);
Self {
r#type,
length,
bytes
}
}
pub fn as_string(&self) -> Result<String, ErrorMessage> {
if self.r#type != Type::String {
Err(ErrorMessage(NOT_A_STRING))?;
}
let bytes = self.isolate_value_bytes();
Ok(String::from_bytes(bytes)?)
}
pub fn from_string(str: String) -> Result<Self, ErrorMessage> {
let r#type = Type::String;
let byte_length = match str.len() {
l if l == 0 => {
Err(ErrorMessage(STRING_OF_LENGTH_ZERO))?
}
l if l <= u8::MAX as usize => {
ByteLength::One
}
l if l <= u16::MAX as usize => {
ByteLength::Two
}
l if l <= u32::MAX as usize => {
ByteLength::Four
}
l if l <= u64::MAX as usize => {
ByteLength::Eight
}
_ => {
Err(ErrorMessage(STRING_MAX_LENGTH_EXCEEDED))?
}
};
let mut bytes = vec![u8::from(r#type) | u8::from(byte_length)];
match byte_length {
ByteLength::One => {
bytes.extend_from_slice(&(str.len() as u8).to_be_bytes());
}
ByteLength::Two => {
bytes.extend_from_slice(&(str.len() as u16).to_be_bytes());
}
ByteLength::Four => {
bytes.extend_from_slice(&(str.len() as u32).to_be_bytes());
}
ByteLength::Eight => {
bytes.extend_from_slice(&(str.len() as u64).to_be_bytes());
}
_ => {
Err(ErrorMessage(STRING_OF_LENGTH_ZERO))?
}
}
bytes.extend_from_slice(&str.as_bytes());
Ok(Self {
r#type,
length: byte_length,
bytes
})
}
pub fn as_bool(&self) -> Result<bool, ErrorMessage> {
if u8::from(self.r#type) | 0x0F != u8::from(Type::Bool) {
Err(ErrorMessage(NOT_A_BOOL))?;
}
Ok(self.r#type != Type::False)
}
pub fn from_bool(bool: bool) -> Result<Self, ErrorMessage> {
let r#type = if bool { Type::True } else { Type::False };
Ok(Self {
r#type,
length: ByteLength::Zero,
bytes: vec![u8::from(r#type)]
})
}
pub fn as_array(&self) -> Result<Vec<Self>, ErrorMessage> {
if self.r#type != Type::Array {
return Err(ErrorMessage(NOT_AN_ARRAY));
}
fn consumed_for_value(bytes: &[u8]) -> Result<usize, ErrorMessage> {
if bytes.is_empty() {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
let first = bytes[0];
let r#type = Type::try_from(first)?;
let len_field_size = usize::from(ByteLength::try_from(first)?);
if bytes.len() < 1 + len_field_size {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
match r#type {
Type::Uint | Type::Int | Type::Float => {
Ok(1 + len_field_size)
}
Type::Bool | Type::True | Type::False => {
Ok(1)
}
Type::String => {
let str_len = match ByteLength::try_from(len_field_size as u8)? {
ByteLength::Zero => Err(ErrorMessage(STRING_OF_LENGTH_ZERO))?,
ByteLength::One => bytes[1] as u64,
ByteLength::Two => u16::from_be_bytes(bytes[1..=2].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as u64,
ByteLength::Four => u32::from_be_bytes(bytes[1..=4].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as u64,
ByteLength::Eight => u64::from_be_bytes(bytes[1..=8].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?),
} as usize;
let total = 1 + len_field_size + str_len;
if bytes.len() < total {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
Ok(total)
}
Type::Array => {
let count = match ByteLength::try_from(len_field_size as u8)? {
ByteLength::Zero => Err(ErrorMessage(VEC_OF_LENGTH_ZERO))?,
ByteLength::One => bytes[1] as u64,
ByteLength::Two => u16::from_be_bytes(bytes[1..=2].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as u64,
ByteLength::Four => u32::from_be_bytes(bytes[1..=4].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as u64,
ByteLength::Eight => u64::from_be_bytes(bytes[1..=8].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?),
} as usize;
let mut pos = 1 + len_field_size;
for _ in 0..count {
if pos >= bytes.len() {
return Err(ErrorMessage(NOT_ENOUGH_BYTES));
}
let consumed = consumed_for_value(&bytes[pos..])?;
pos = pos.checked_add(consumed).ok_or_else(|| ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))?;
}
Ok(pos)
}
}
}
let mut vec: Vec<Self> = Vec::new();
let mut bytes = self.isolate_value_bytes().to_vec();
while !bytes.is_empty() {
let first = bytes[0];
let r#type = Type::try_from(first)?;
let byte_length = usize::from(ByteLength::try_from(first)?);
match r#type {
Type::Uint | Type::Int | Type::Float => {
let chunk = bytes[..=byte_length].to_vec();
bytes = bytes[(1 + byte_length)..].to_vec();
vec.push(Value::from_number(chunk)?);
}
Type::String => {
let length = match ByteLength::try_from(byte_length as u8)? {
ByteLength::Zero => Err(ErrorMessage(STRING_OF_LENGTH_ZERO))?,
ByteLength::One => bytes[1] as u64,
ByteLength::Two => u16::from_be_bytes(bytes[1..=2].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as u64,
ByteLength::Four => u32::from_be_bytes(bytes[1..=4].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?) as u64,
ByteLength::Eight => u64::from_be_bytes(bytes[1..=8].try_into().map_err(|_| ErrorMessage(NOT_ENOUGH_BYTES))?),
};
if (bytes.len() as u64) < length {
Err(ErrorMessage(NOT_ENOUGH_BYTES))?;
}
let string_bytes = &bytes.to_owned()[(1 + byte_length)..=1 + length as usize];
bytes = bytes[2 + length as usize..].to_vec();
vec.push(Value::from_string(String::from_bytes(string_bytes)?)?);
}
Type::Bool | Type::True | Type::False => {
vec.push(Value::from_bool(r#type != Type::False)?);
bytes = bytes[1..].to_vec();
}
Type::Array => {
let consumed = consumed_for_value(&bytes)?;
let chunk = bytes[..consumed].to_vec();
bytes = bytes[consumed..].to_vec();
vec.push(Self {
r#type: Type::Array,
length: ByteLength::try_from(first)?,
bytes: chunk,
});
}
}
}
Ok(vec)
}
pub fn from_vec(vec: Vec<Self>) -> Result<Self, ErrorMessage> {
let r#type = Type::Array;
let byte_length = match vec.len() {
l if l == 0 => {
Err(ErrorMessage(VEC_OF_LENGTH_ZERO))?
}
l if l <= u8::MAX as usize => {
ByteLength::One
}
l if l <= u16::MAX as usize => {
ByteLength::Two
}
l if l <= u32::MAX as usize => {
ByteLength::Four
}
l if l <= u64::MAX as usize => {
ByteLength::Eight
}
_ => {
Err(ErrorMessage(VEC_MAX_LENGTH_EXCEEDED))?
}
};
let mut bytes = vec![u8::from(r#type) | u8::from(byte_length)];
match byte_length {
ByteLength::One => {
bytes.extend_from_slice(&(vec.len() as u8).to_be_bytes());
}
ByteLength::Two => {
bytes.extend_from_slice(&(vec.len() as u16).to_be_bytes());
}
ByteLength::Four => {
bytes.extend_from_slice(&(vec.len() as u32).to_be_bytes());
}
ByteLength::Eight => {
bytes.extend_from_slice(&(vec.len() as u64).to_be_bytes());
}
_ => {
Err(ErrorMessage(VEC_OF_LENGTH_ZERO))?
}
}
for i in vec {
bytes.extend_from_slice(i.bytes.as_slice());
}
Ok(Self {
r#type,
length: byte_length,
bytes
})
}
}
pub trait FromYADNotation: Sized {
fn from_bytes(bytes: &[u8]) -> Result<Self, ErrorMessage>;
}
impl FromYADNotation for String {
fn from_bytes(bytes: &[u8]) -> Result<Self, ErrorMessage> {
if let Some(string) = String::from_utf8(Vec::from(bytes)).ok() {
Ok(string)
} else {
Err(ErrorMessage(MALFORMED_UTF8))
}
}
}
impl Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.r#type {
Type::Uint => match self.length {
ByteLength::One => write!(f, "{}", self.as_u8().ok().ok_or(fmt::Error)?),
ByteLength::Two => write!(f, "{}", self.as_u16().ok().ok_or(fmt::Error)?),
ByteLength::Four => write!(f, "{}", self.as_u32().ok().ok_or(fmt::Error)?),
ByteLength::Eight => write!(f, "{}", self.as_u64().ok().ok_or(fmt::Error)?),
_ => write!(f, "{:?}", self.bytes),
},
Type::Int => match self.length {
ByteLength::One => write!(f, "{}", self.as_i8().ok().ok_or(fmt::Error)?),
ByteLength::Two => write!(f, "{}", self.as_i16().ok().ok_or(fmt::Error)?),
ByteLength::Four => write!(f, "{}", self.as_i32().ok().ok_or(fmt::Error)?),
ByteLength::Eight => write!(f, "{}", self.as_i64().ok().ok_or(fmt::Error)?),
_ => write!(f, "{:?}", self.bytes),
},
Type::Float => match self.length {
ByteLength::One => write!(f, "{}", self.as_f8().ok().ok_or(fmt::Error)?),
ByteLength::Two => write!(f, "{}", self.as_f16().ok().ok_or(fmt::Error)?),
ByteLength::Four => write!(f, "{}", self.as_f32().ok().ok_or(fmt::Error)?),
ByteLength::Eight => write!(f, "{}", self.as_f64().ok().ok_or(fmt::Error)?),
_ => write!(f, "{:?}", self.bytes),
},
Type::String => write!(f, "{}", self.as_string().ok().ok_or(fmt::Error)?),
Type::Array => {
let array = self.as_array().ok().ok_or(fmt::Error)?;
let mut string = String::new();
string.push('[');
for (i, item) in array.iter().enumerate() {
string.push_str(format!("{}", item).as_str());
if i < array.len() - 1 {
string.push_str(", ");
}
}
string.push(']');
write!(f, "{}", string)
},
Type::Bool | Type::True | Type::False => write!(f, "{}", self.as_bool().ok().ok_or(fmt::Error)?),
}
}
}