use crate::error::DecodeError;
use std::fmt::{Debug, Display, Write};
pub struct Tagged {
pub tag: Tag,
pub ty: TdfType,
}
#[derive(Debug, PartialEq, Eq)]
pub struct Tag(pub [u8; 4]);
impl PartialEq<[u8]> for Tag {
fn eq(&self, other: &[u8]) -> bool {
let len = other.len();
for i in 0..4 {
let key_byte = self.0[i];
if i >= len && key_byte != 0 {
return false;
}
let input_byte = other[i];
if key_byte != input_byte {
return false;
}
}
true
}
}
impl From<&[u8]> for Tag {
fn from(value: &[u8]) -> Self {
let mut out = [0u8; 4];
for i in 0..value.len() {
out[i] = value[i];
}
Self(out)
}
}
impl From<&[u8; 4]> for Tag {
fn from(value: &[u8; 4]) -> Self {
Self(*value)
}
}
impl Display for Tag {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for byte in self.0 {
if byte != 0 {
f.write_char(byte as char)?;
}
}
Ok(())
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u8)]
pub enum TdfType {
VarInt = 0x0,
String = 0x1,
Blob = 0x2,
Group = 0x3,
List = 0x4,
Map = 0x5,
Union = 0x6,
VarIntList = 0x7,
Pair = 0x8,
Triple = 0x9,
Float = 0xA,
}
impl TryFrom<u8> for TdfType {
type Error = DecodeError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(match value {
0x0 => TdfType::VarInt,
0x1 => TdfType::String,
0x2 => TdfType::Blob,
0x3 => TdfType::Group,
0x4 => TdfType::List,
0x5 => TdfType::Map,
0x6 => TdfType::Union,
0x7 => TdfType::VarIntList,
0x8 => TdfType::Pair,
0x9 => TdfType::Triple,
0xA => TdfType::Float,
ty => return Err(DecodeError::UnknownType { ty }),
})
}
}