#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use serde::de as ser_de;
use serde::{Deserialize, Serialize};
use ttv3::serde::ser::ValueSerializer;
use ttv3::size::ValueSizer;
use ttv3::Error;
pub mod ttv3;
pub enum Version {
V3,
}
pub fn from_reader<T, R>(mut r: R) -> Result<T, Error>
where
T: ser_de::DeserializeOwned,
R: std::io::Read,
{
if ttv3::read_byte(&mut r) != Some(3) {
return Err(Error::new("Invalid input, can only decode v3 using serde"));
}
let mut discard: [u8; 1] = Default::default();
r.read_exact(&mut discard)?;
let mut deserializer = ttv3::serde::de_read::Deserializer::from_reader(&mut r);
T::deserialize(&mut deserializer)
}
pub fn from_bytes<'a, T>(s: &'a [u8]) -> Result<T, Error>
where
T: Deserialize<'a>,
{
if s.len() < 2 {
return Err(Error::new("Invalid input, not long enough"));
}
if s[0] != 3 {
return Err(Error::new("Invalid input, can only decode v3 using serde"));
}
let mut deserializer = ttv3::serde::de::Deserializer::from_bytes(&s[2..]);
T::deserialize(&mut deserializer)
}
pub fn to_size<T>(value: &T) -> usize
where
T: Serialize,
{
let mut sizer = ValueSizer {
size: 1 + 1 + 1 + 1,
};
value.serialize(&mut sizer).unwrap();
sizer.size
}
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, ttv3::Error>
where
T: Serialize,
{
let len = to_size(value);
let mut vec: Vec<u8> = Vec::with_capacity(len);
vec.insert(0, 3);
vec.insert(1, 0);
let mut serializer = ValueSerializer::new(&mut vec, ttv3::serde::Empty {});
value.serialize(&mut serializer)?;
Ok(vec)
}
#[cfg(test)]
mod tt_tests {
use serde::{Deserialize, Serialize};
use crate::ttv3::Key;
use crate::ttv3::Value;
#[test]
fn enc_dec_string() {
let data = "hello world💖";
let bytes = crate::to_vec(&data).unwrap();
let res = crate::from_bytes::<&str>(&bytes);
assert_eq!(crate::to_size(&data), bytes.len());
match res {
Ok(s) => {
assert_eq!(s, data);
}
Err(err) => {
println!("{}", err);
assert!(1 != 1, err);
}
}
}
#[test]
fn enc_dec_hello_world() {
let mut map: std::collections::HashMap<&str, &str> = std::collections::HashMap::new();
map.insert(&"hello", &"world💖");
let data = crate::to_vec(&map).unwrap();
let resmap = crate::from_bytes::<std::collections::HashMap<&str, &str>>(&data);
assert_eq!(crate::to_size(&map), data.len());
match resmap {
Ok(m) => {
let res_sub_str = m.get("hello").unwrap();
assert_eq!(res_sub_str, &"world💖");
}
Err(err) => {
println!("{}", err);
assert!(1 != 1, err);
}
}
}
#[test]
fn enc_dec_worst_case() {
let mut map: std::collections::HashMap<&str, Value> = std::collections::HashMap::new();
map.insert(&"Da5ta", Value::String("n0thing".to_string()));
let mut submap: std::collections::HashMap<Key, Value> = std::collections::HashMap::new();
submap.insert(
Key::String("more".to_string()),
Value::String("d5ata89".to_string()),
);
map.insert(&"Data2", Value::Map(submap));
let vec: Vec<Value> = vec![
Value::String("hey".to_string()),
Value::String("jude".to_string()),
];
map.insert(&"Data4", Value::Vec(vec));
map.insert(&"1", Value::Bytes(vec![1, 2]));
map.insert(&"2", Value::F64(0.64));
map.insert(&"3", Value::I64(99));
map.insert(&"4", Value::Bool(true));
let data = crate::to_vec(&map).unwrap();
let resmap = crate::from_bytes::<std::collections::HashMap<&str, Value>>(&data);
assert_eq!(crate::to_size(&map), data.len());
match resmap {
Ok(m) => {
match m.get("Da5ta") {
Some(data2) => match data2 {
Value::String(s) => assert_eq!(s, "n0thing"),
_ => {
println!("wrong datatype for Da5ta");
assert!(1 != 1);
}
},
None => {
println!("Could not find key Da5ta!!!");
assert!(1 != 1);
}
};
match m.get("Data2") {
Some(data2) => match data2 {
Value::Map(m) => match m.get(&Key::String("more".to_string())) {
Some(s) => match s {
Value::String(s) => assert_eq!(s, &"d5ata89"),
_ => {
println!("wrong datatype for Da5ta");
assert!(1 != 1);
}
},
None => {
println!("Could not find key Data2.more!!!");
assert!(1 != 1);
}
},
_ => {
println!("wrong datatype for Data2");
assert!(1 != 1);
}
},
None => {
println!("Could not find key Data2!!!");
assert!(1 != 1);
}
};
match m.get("Data4") {
Some(data4) => match data4 {
Value::Vec(v) => match v.len() {
2 => {
match &v[0] {
Value::String(s) => assert_eq!(s, "hey"),
_ => {
println!("wrong datatype for Da5ta[0]");
assert!(1 != 1);
}
};
match &v[1] {
Value::String(s) => assert_eq!(s, "jude"),
_ => {
println!("wrong datatype for Da5ta[0]");
assert!(1 != 1);
}
};
}
_ => {
println!("wrong length of vec Data4");
assert!(1 != 1);
}
},
_ => {
println!("wrong datatype for Data4");
assert!(1 != 1);
}
},
None => {
println!("Could not find key Data4!!!");
assert!(1 != 1);
}
};
match m.get("1") {
Some(one) => match one {
Value::Bytes(bytes) => assert_eq!(bytes, &vec![1, 2]),
_ => {
println!("wrong datatype for 1!!!");
assert!(1 != 1);
}
},
None => {
println!("Could not find key 1!!!");
assert!(1 != 1);
}
}
match m.get("2") {
Some(one) => match one {
Value::F64(f) => assert_eq!(f, &0.64),
_ => {
println!("wrong datatype for 2!!!");
assert!(1 != 1);
}
},
None => {
println!("Could not find key 2!!!");
assert!(1 != 1);
}
}
match m.get("3") {
Some(one) => match one {
Value::I64(f) => assert_eq!(f, &99),
_ => {
println!("wrong datatype for 3!!!");
assert!(1 != 1);
}
},
None => {
println!("Could not find key 3!!!");
assert!(1 != 1);
}
}
match m.get("4") {
Some(one) => match one {
Value::Bool(f) => assert_eq!(f, &true),
_ => {
println!("wrong datatype for 4!!!");
assert!(1 != 1);
}
},
None => {
println!("Could not find key 4!!!");
assert!(1 != 1);
}
}
}
Err(err) => {
println!("{}", err);
assert!(1 != 1, err);
}
}
}
#[derive(Deserialize, Serialize, Debug)]
enum A {
A,
B(u8),
C(u8, u8),
D { a: u8, b: u8 },
}
#[test]
fn enc_dec_c_enum() {
let input = A::A;
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => {}
A::B(_) => panic!("wrong enum type: B expected: A"),
A::C(_, _) => panic!("wrong enum type: C expected: A"),
A::D { a: _, b: _ } => panic!("wrong enum type: D expected: A"),
}
}
#[test]
fn enc_dec_value_enum() {
let input = A::B(6);
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => panic!("wrong enum type: A expected: D"),
A::B(b) => match b {
6 => {}
_ => panic!("wrong value for A::B: {} expected: 6", b),
},
A::C(_, _) => panic!("wrong enum type: C expected: A"),
A::D { a: _, b: _ } => panic!("wrong enum type: D expected: A"),
}
}
#[test]
fn enc_dec_tuple_enum() {
let input = A::C(6, 8);
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => panic!("wrong enum type: A expected: D"),
A::B(_) => panic!("wrong enum type: B expected: A"),
A::C(h, j) => {
match h {
6 => {}
_ => panic!("wrong value for a: {} expected: 6", h),
};
match j {
8 => {}
_ => panic!("wrong value for b: {} expected: 8", h),
};
}
A::D { a: _, b: _ } => panic!("wrong enum type: D expected: A"),
}
}
#[test]
fn enc_dec_struct_enum() {
let input = A::D { a: 5, b: 8 };
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => panic!("wrong enum type: A expected: D"),
A::B(_) => panic!("wrong enum type: B expected: D"),
A::C(_, _) => panic!("wrong enum type: C expected: D"),
A::D { a: h, b: j } => {
match h {
5 => {}
_ => panic!("wrong value for a: {} expected: 5", h),
};
match j {
8 => {}
_ => panic!("wrong value for b: {} expected: 8", h),
}
}
}
}
#[test]
fn enc_dec_c_enum_read() {
let input = A::A;
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => {}
A::B(_) => panic!("wrong enum type: B expected: A"),
A::C(_, _) => panic!("wrong enum type: C expected: A"),
A::D { a: _, b: _ } => panic!("wrong enum type: D expected: A"),
}
}
#[test]
fn enc_dec_value_enum_read() {
let input = A::B(6);
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => panic!("wrong enum type: A expected: D"),
A::B(b) => match b {
6 => {}
_ => panic!("wrong value for A::B: {} expected: 6", b),
},
A::C(_, _) => panic!("wrong enum type: C expected: A"),
A::D { a: _, b: _ } => panic!("wrong enum type: D expected: A"),
}
}
#[test]
fn enc_dec_tuple_enum_read() {
let input = A::C(6, 8);
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_bytes(&data).unwrap();
match res {
A::A => panic!("wrong enum type: A expected: D"),
A::B(_) => panic!("wrong enum type: B expected: A"),
A::C(h, j) => {
match h {
6 => {}
_ => panic!("wrong value for a: {} expected: 6", h),
};
match j {
8 => {}
_ => panic!("wrong value for b: {} expected: 8", h),
};
}
A::D { a: _, b: _ } => panic!("wrong enum type: D expected: A"),
}
}
#[test]
fn enc_dec_struct_enum_read() {
let input = A::D { a: 5, b: 8 };
let data = crate::to_vec(&input).unwrap();
let res: A = crate::from_reader(&data as &[u8]).unwrap();
match res {
A::A => panic!("wrong enum type: A expected: D"),
A::B(_) => panic!("wrong enum type: B expected: D"),
A::C(_, _) => panic!("wrong enum type: C expected: D"),
A::D { a: h, b: j } => {
match h {
5 => {}
_ => panic!("wrong value for a: {} expected: 5", h),
};
match j {
8 => {}
_ => panic!("wrong value for b: {} expected: 8", h),
}
}
}
}
}