ser/de support including enums
This commit is contained in:
parent
53e3c568a8
commit
3a8b622ae7
150
src/de.rs
150
src/de.rs
@ -1,7 +1,5 @@
|
|||||||
use serde::de::{
|
use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor};
|
||||||
self, DeserializeSeed, MapAccess, SeqAccess,
|
use serde::de::value::U32Deserializer;
|
||||||
Visitor,
|
|
||||||
};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::bipack_source::{BipackSource, VecSource};
|
use crate::bipack_source::{BipackSource, VecSource};
|
||||||
@ -13,11 +11,13 @@ pub struct Deserializer {
|
|||||||
input: VecSource,
|
input: VecSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bytes<'de,T: Deserialize<'de>>(source: Vec<u8>) -> Result<T> {
|
pub fn from_bytes<'de, T: Deserialize<'de>>(source: &[u8]) -> Result<T> {
|
||||||
let mut des = Deserializer { input: VecSource::from(source)};
|
let mut des = Deserializer { input: VecSource::from(source.to_vec()) };
|
||||||
T::deserialize(&mut des)
|
T::deserialize(&mut des)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deserializer {}
|
||||||
|
|
||||||
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_bool<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_bool<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
visitor.visit_bool(if self.input.get_u8()? == 0 { false } else { true } )
|
visitor.visit_bool(if self.input.get_u8()? == 0 { false } else { true })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i8<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_i8<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
@ -73,14 +73,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
|||||||
let ch = self.input.get_str()?;
|
let ch = self.input.get_str()?;
|
||||||
if ch.len() != 1 {
|
if ch.len() != 1 {
|
||||||
Err(Error::BadFormat(format!("Char length is {}, should be 1 {:?}", ch.len(), ch)))
|
Err(Error::BadFormat(format!("Char length is {}, should be 1 {:?}", ch.len(), ch)))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
visitor.visit_char(ch.chars().next().unwrap())
|
visitor.visit_char(ch.chars().next().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
visitor.visit_string( self.input.get_str()?)
|
visitor.visit_string(self.input.get_str()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_string<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_string<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
@ -131,15 +130,24 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
|||||||
|
|
||||||
fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
let size = self.input.get_unsigned()?;
|
let size = self.input.get_unsigned()?;
|
||||||
visitor.visit_map(SimpleMap { de: self, size: size as usize} )
|
visitor.visit_map(SimpleMap { de: self, size: size as usize })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
visitor.visit_seq(SimpleSeq::new(self, fields.len() ))
|
visitor.visit_seq(SimpleSeq::new(self, fields.len()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
#[inline]
|
||||||
todo!()
|
fn deserialize_enum<V>(
|
||||||
|
self,
|
||||||
|
_name: &'static str,
|
||||||
|
_variants: &'static [&'static str],
|
||||||
|
visitor: V,
|
||||||
|
) -> Result<V::Value>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_enum(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_identifier<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
fn deserialize_identifier<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
|
||||||
@ -155,13 +163,56 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, 'a> serde::de::EnumAccess<'de> for &'a mut Deserializer {
|
||||||
|
type Error = Error;
|
||||||
|
type Variant = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self)> {
|
||||||
|
let varint: u32 = self.input.get_unsigned()? as u32;
|
||||||
|
let v = DeserializeSeed::deserialize::<U32Deserializer<Error>>(
|
||||||
|
seed,
|
||||||
|
varint.into_deserializer())?;
|
||||||
|
Ok((v, self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, 'a> serde::de::VariantAccess<'de> for &'a mut Deserializer {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn unit_variant(self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn newtype_variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<V::Value> {
|
||||||
|
DeserializeSeed::deserialize(seed, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn tuple_variant<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
|
||||||
|
serde::de::Deserializer::deserialize_tuple(self, len, visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn struct_variant<V: Visitor<'de>>(
|
||||||
|
self,
|
||||||
|
fields: &'static [&'static str],
|
||||||
|
visitor: V,
|
||||||
|
) -> Result<V::Value> {
|
||||||
|
serde::de::Deserializer::deserialize_tuple(self, fields.len(), visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct SimpleSeq<'a> {
|
struct SimpleSeq<'a> {
|
||||||
de: &'a mut Deserializer,
|
de: &'a mut Deserializer,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SimpleSeq<'a> {
|
impl<'a> SimpleSeq<'a> {
|
||||||
fn new(de: &'a mut Deserializer,size: usize) -> Self {
|
fn new(de: &'a mut Deserializer, size: usize) -> Self {
|
||||||
SimpleSeq {
|
SimpleSeq {
|
||||||
de,
|
de,
|
||||||
size: size,
|
size: size,
|
||||||
@ -198,8 +249,7 @@ impl<'de, 'a> MapAccess<'de> for SimpleMap<'a> {
|
|||||||
fn next_key_seed<K>(&mut self, seed: K) -> std::result::Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de> {
|
fn next_key_seed<K>(&mut self, seed: K) -> std::result::Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de> {
|
||||||
if self.size < 1 {
|
if self.size < 1 {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
self.size -= 1;
|
self.size -= 1;
|
||||||
seed.deserialize(&mut *self.de).map(Some)
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
@ -210,9 +260,19 @@ impl<'de, 'a> MapAccess<'de> for SimpleMap<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod tests {
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[test]
|
use serde::{Deserialize, Serialize};
|
||||||
fn test_ints() -> Result<()> {
|
|
||||||
|
use crate::de::from_bytes;
|
||||||
|
use crate::error::Result;
|
||||||
|
use crate::ser::to_bytes;
|
||||||
|
use crate::tools::to_dump;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ints() -> Result<()> {
|
||||||
// #[derive(Deserialize, PartialEq, Debug)]
|
// #[derive(Deserialize, PartialEq, Debug)]
|
||||||
// struct Test {
|
// struct Test {
|
||||||
// int: u32,
|
// int: u32,
|
||||||
@ -220,7 +280,7 @@ fn test_ints() -> Result<()> {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
let b = vec![7];
|
let b = vec![7];
|
||||||
assert_eq!( 7u8, from_bytes(vec![7u8])?);
|
assert_eq!(7u8, from_bytes(&vec![7u8])?);
|
||||||
|
|
||||||
|
|
||||||
// let j = r#"{"int":1,"seq":["a","b"]}"#;
|
// let j = r#"{"int":1,"seq":["a","b"]}"#;
|
||||||
@ -230,17 +290,7 @@ fn test_ints() -> Result<()> {
|
|||||||
// };
|
// };
|
||||||
// assert_eq!(expected, from_str(j).unwrap());
|
// assert_eq!(expected, from_str(j).unwrap());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
mod tests {
|
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::de::from_bytes;
|
|
||||||
use crate::error::Result;
|
|
||||||
use crate::ser::to_bytes;
|
|
||||||
use crate::tools::to_dump;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_struct() -> Result<()> {
|
fn test_struct() -> Result<()> {
|
||||||
@ -256,7 +306,7 @@ mod tests {
|
|||||||
|
|
||||||
let packed = to_bytes(&expected)?;
|
let packed = to_bytes(&expected)?;
|
||||||
println!("::{}", to_dump(&packed));
|
println!("::{}", to_dump(&packed));
|
||||||
let unpacked: Test = from_bytes(packed)?;
|
let unpacked: Test = from_bytes(&packed)?;
|
||||||
println!("::{:?}", unpacked);
|
println!("::{:?}", unpacked);
|
||||||
assert_eq!(&expected, &unpacked);
|
assert_eq!(&expected, &unpacked);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -275,7 +325,7 @@ mod tests {
|
|||||||
let packed = to_bytes(&src)?;
|
let packed = to_bytes(&src)?;
|
||||||
println!("{}", to_dump(&packed));
|
println!("{}", to_dump(&packed));
|
||||||
|
|
||||||
let restored: HashMap<String, i32> = from_bytes(packed)?;
|
let restored: HashMap<String, i32> = from_bytes(&packed)?;
|
||||||
println!("{:?}", restored);
|
println!("{:?}", restored);
|
||||||
assert_eq!(src, restored);
|
assert_eq!(src, restored);
|
||||||
|
|
||||||
@ -288,10 +338,42 @@ mod tests {
|
|||||||
let packed = to_bytes(&src)?;
|
let packed = to_bytes(&src)?;
|
||||||
println!("{}", to_dump(&packed));
|
println!("{}", to_dump(&packed));
|
||||||
|
|
||||||
let restored: HashSet<String> = from_bytes(packed)?;
|
let restored: HashSet<String> = from_bytes(&packed)?;
|
||||||
println!("{:?}", restored);
|
println!("{:?}", restored);
|
||||||
assert_eq!(src, restored);
|
assert_eq!(src, restored);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn testeq<'a, T: Serialize + Deserialize<'a> + PartialEq + Debug>(x: & 'a T) {
|
||||||
|
let packed = to_bytes(x).unwrap();
|
||||||
|
println!("packed {:?}:\n{}", x, to_dump(&packed) );
|
||||||
|
assert_eq!(*x, from_bytes(&packed).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enum() -> Result<()> {
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
|
enum E {
|
||||||
|
Unit,
|
||||||
|
Unit2,
|
||||||
|
Newtype(u32),
|
||||||
|
Tuple(u32, u32),
|
||||||
|
Struct { a: u32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
let packed = to_bytes(&E::Newtype(7))?;
|
||||||
|
println!("{}", to_dump(&packed));
|
||||||
|
let r: E = from_bytes(&packed)?;
|
||||||
|
println!("{:?}", r);
|
||||||
|
|
||||||
|
testeq(&E::Unit);
|
||||||
|
testeq(&E::Unit2);
|
||||||
|
testeq(&E::Newtype(101));
|
||||||
|
testeq(&E::Tuple(17, 42));
|
||||||
|
testeq(&E::Struct {a: 19} );
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
@ -134,6 +134,7 @@ impl<'a> ser::Serializer for &'a mut Serializer {
|
|||||||
where
|
where
|
||||||
T: ?Sized + Serialize,
|
T: ?Sized + Serialize,
|
||||||
{
|
{
|
||||||
|
|
||||||
value.serialize(self)
|
value.serialize(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +201,7 @@ impl<'a> ser::Serializer for &'a mut Serializer {
|
|||||||
variant: &'static str,
|
variant: &'static str,
|
||||||
_len: usize,
|
_len: usize,
|
||||||
) -> Result<Self::SerializeStructVariant> {
|
) -> Result<Self::SerializeStructVariant> {
|
||||||
variant.serialize(&mut *self)?;
|
self.output.put_unsigned(_variant_index);
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,6 +388,9 @@ fn test_enum() -> std::result::Result<(), FromUtf8Error> {
|
|||||||
let t = E::Tuple(7,17);
|
let t = E::Tuple(7,17);
|
||||||
println!("u:{}",to_dump(to_bytes(&t).unwrap().as_slice()));
|
println!("u:{}",to_dump(to_bytes(&t).unwrap().as_slice()));
|
||||||
assert_eq!("0c 1c 44",to_hex(to_bytes(&t).unwrap())?);
|
assert_eq!("0c 1c 44",to_hex(to_bytes(&t).unwrap())?);
|
||||||
|
let t = E::Struct { a: 17 };
|
||||||
|
println!("u:{}",to_dump(to_bytes(&t).unwrap().as_slice()));
|
||||||
|
assert_eq!("10 44",to_hex(to_bytes(&t).unwrap())?);
|
||||||
// let expected = r#""Unit""#;
|
// let expected = r#""Unit""#;
|
||||||
// assert_eq!(to_string(&u).unwrap(), expected);
|
// assert_eq!(to_string(&u).unwrap(), expected);
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user