use crate::alloc_prelude::*;
use nano_leb128::ULEB128;
#[repr(u64)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum KnownType {
Reserved0 = 0,
CompositeDict = 1,
CompositeList = 2,
Bytes = 3,
UTF8 = 4,
Boolean = 5,
Int64 = 6,
UVarInt = 7,
SVarInt = 8,
Float64 = 9,
Decimal = 10,
Reserved11 = 11,
Stamp64 = 12,
Sched = 13,
Reserved14 = 14,
ExtendedType = 15,
}
impl From<u64> for KnownType {
fn from(i: u64) -> Self {
match i {
0 => Self::Reserved0,
1 => Self::CompositeDict,
2 => Self::CompositeList,
3 => Self::Bytes,
4 => Self::UTF8,
5 => Self::Boolean,
6 => Self::Int64,
7 => Self::UVarInt,
8 => Self::SVarInt,
9 => Self::Float64,
10 => Self::Decimal,
11 => Self::Reserved11,
12 => Self::Stamp64,
13 => Self::Sched,
14 => Self::Reserved14,
_ => Self::ExtendedType,
}
}
}
#[repr(u64)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum KnownExtendedType {
Unknown = 0,
Complex = 16,
}
impl From<u64> for KnownExtendedType {
fn from(i: u64) -> Self {
match i {
16 => Self::Complex,
_ => Self::Unknown,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DataType {
Null,
StandardType(KnownType),
StandardExtendedType(KnownExtendedType),
UserExtendedType(u64),
}
impl DataType {
pub fn encode(&self) -> Result<(u8, Vec<u8>), crate::Error> {
let mut out: Vec<u8> = Vec::new();
let mut len_bytes = [0u8; 10];
match self {
Self::Null => {
return Ok((0, out));
}
Self::StandardType(t) => {
return Ok(((*t as u8) & 0x0F, out));
}
Self::StandardExtendedType(t) => {
let count = ULEB128::from(*t as u64).write_into(&mut len_bytes)?;
out.extend(&len_bytes[0..count]);
}
Self::UserExtendedType(t) => {
let count = ULEB128::from(*t).write_into(&mut len_bytes)?;
out.extend(&len_bytes[0..count]);
}
}
Ok((0x0Fu8, out))
}
}
impl From<KnownType> for DataType {
fn from(t: KnownType) -> Self {
Self::StandardType(t)
}
}
impl From<KnownExtendedType> for DataType {
fn from(t: KnownExtendedType) -> Self {
Self::StandardExtendedType(t)
}
}
impl From<u64> for DataType {
fn from(i: u64) -> Self {
if i < 15 {
Self::StandardType(KnownType::from(i))
} else if i < 96 {
Self::StandardExtendedType(KnownExtendedType::from(i))
} else {
Self::UserExtendedType(i)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encode_type_standard() {
let ty = DataType::StandardType(KnownType::CompositeDict);
let (base, ext) = ty.encode().unwrap();
assert_eq!(base, 0x01);
assert_eq!(ext.len(), 0);
let ty = DataType::StandardType(KnownType::Float64);
let (base, ext) = ty.encode().unwrap();
assert_eq!(base, 0x09);
assert_eq!(ext.len(), 0);
}
#[test]
fn encode_type_standard_extended() {
let ty = DataType::StandardExtendedType(KnownExtendedType::Complex);
let (base, ext) = ty.encode().unwrap();
assert_eq!(base, 0x0F);
assert_eq!(ext, vec![0x10]);
}
#[test]
fn encode_type_user_extended() {
let ty = DataType::UserExtendedType(624485);
let (base, ext) = ty.encode().unwrap();
assert_eq!(base, 0x0F);
assert_eq!(ext, vec![0xE5, 0x8E, 0x26]);
}
}