use std::fmt::{Debug, Display, Formatter};
use yad_core::constants::error::ErrorMessage;
use yad_core::constants::length::ByteLength;
use yad_core::constants::types::Type;
use yad_core::Value;
use crate::constants::{KEY_END_HEADER, KEY_NAME_HEADER, KEY_START_HEADER};
use crate::{encode_name, usize_from_slice_bytes};
use crate::error::{MALFORMED_KEY_NAME_VECTOR, MALFORMED_KEY_VECTOR};
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct Key {
pub name: String,
pub value: Value,
}
impl Key {
pub fn new<S: ToString>(name: S, value: Value) -> Self {
Self {
name: name.to_string(),
value,
}
}
pub fn set_value(&mut self, new_value: Value) -> () {
self.value = new_value;
}
fn byte_is_key_start_header(byte: u8) -> bool {
KEY_START_HEADER == byte
}
fn byte_is_key_end_header(byte: u8) -> bool {
KEY_END_HEADER == byte
}
fn byte_is_key_name_header(byte: u8) -> bool {
KEY_NAME_HEADER == (byte & 0xF0)
}
fn check_boundary_bytes(bytes: &Vec<u8>) -> bool {
let Some(first) = bytes.first() else {
return false;
};
let Some(last) = bytes.last() else {
return false;
};
Self::byte_is_key_start_header(*first) && Self::byte_is_key_end_header(*last)
}
fn find_and_decode_name_from_bytes(bytes: Vec<u8>) -> Option<String> {
if bytes.is_empty() {
return None;
}
let first = *bytes.get(0)?;
if !Self::byte_is_key_name_header(first) {
return None;
}
let byte_length = ByteLength::try_from(first).ok()?;
let be_length = usize_from_slice_bytes(&bytes[1..], byte_length)?;
let metadata_length = 1 + byte_length.as_byte_count() as usize;
if bytes.len() < metadata_length + be_length {
return None;
}
let string_bytes = &bytes[metadata_length..metadata_length + be_length];
String::from_utf8(string_bytes.to_vec()).ok()
}
pub fn serialize(&self) -> Result<Vec<u8>, ErrorMessage> {
let mut bytes: Vec<u8> = vec![KEY_START_HEADER];
bytes.extend_from_slice(encode_name(&self.name, KEY_NAME_HEADER)?.as_slice());
bytes.extend_from_slice(self.value.bytes.as_slice());
bytes.push(KEY_END_HEADER);
Ok(bytes)
}
pub fn deserialize(bytes: Vec<u8>) -> Result<Self, ErrorMessage> {
if !Self::check_boundary_bytes(&bytes) {
return Err(ErrorMessage(MALFORMED_KEY_VECTOR));
}
let name = Self::find_and_decode_name_from_bytes(bytes[1..].to_vec())
.ok_or_else(|| ErrorMessage(MALFORMED_KEY_NAME_VECTOR))?;
let name_metadata_length = 1 + ByteLength::One.as_byte_count() as usize + name.len();
if bytes.len() < name_metadata_length + 2 {
return Err(ErrorMessage(MALFORMED_KEY_VECTOR));
}
let value_bytes = &bytes[name_metadata_length + 1..bytes.len() - 1];
let value = Value::decode(value_bytes.to_vec())?;
Ok(Key { name, value })
}
}
impl Display for Key {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{} = {}", self.name, self.value)
}
}
impl Debug for Key {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let value_debug_format = match self.value.r#type {
Type::String | Type::Array => format!("{}", self.value),
Type::Bool | Type::True | Type::False => format!("{}", self.value),
Type::Float => format!("{}f{}", self.value, self.value.length.as_byte_count() * 8),
Type::Uint => format!("{}u{}", self.value, self.value.length.as_byte_count() * 8),
Type::Int => format!("{}i{}", self.value, self.value.length.as_byte_count() * 8),
};
write!(f, "{} = {}", self.name, value_debug_format)
}
}