value(de): fix deserialization of the Binary type

This commit is contained in:
Matt Bilker
2018-08-31 01:04:31 -04:00
parent b3586cbed7
commit 7ba2293151
6 changed files with 55 additions and 21 deletions

View File

@@ -16,4 +16,5 @@ pretty_env_logger = "0.2.3"
quick-xml = "0.12.1"
rustc-hex = "2.0.1"
serde = "1.0.69"
serde_bytes = "0.10.4"
serde_derive = "1.0.69"

View File

@@ -119,17 +119,6 @@ macro_rules! de_type {
}
}
macro_rules! implement_type {
($method:ident) => {
fn $method<V>(self, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::{}()", stringify!($method));
unimplemented!();
}
}
}
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = Error;
@@ -240,8 +229,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
de_type!(large; deserialize_i64, visit_i64, read_i64, S64);
de_type!(large; deserialize_f32, visit_f32, read_f32, Float);
de_type!(large; deserialize_f64, visit_f64, read_f64, Double);
implement_type!(deserialize_char);
implement_type!(deserialize_str);
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_char()");
Err(Error::StaticMessage("char deserialization is not supported"))
}
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_str()");
Err(Error::StaticMessage("borrowed string deserialization is not supported"))
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
@@ -257,7 +258,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_bytes()");
visitor.visit_bytes(self.reader.read_bytes()?)
visitor.visit_borrowed_bytes(self.reader.read_bytes()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
@@ -276,20 +277,25 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
visitor.visit_some(self)
}
implement_type!(deserialize_unit);
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_unit()");
Err(Error::StaticMessage("unit deserialization is not supported"))
}
fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_unit_struct(name: {:?})", name);
unimplemented!();
Err(Error::StaticMessage("unit struct deserialization is not supported"))
}
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_newtype_struct(name: {:?})", name);
unimplemented!();
Err(Error::StaticMessage("newtype struct deserialization is not supported"))
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
@@ -304,6 +310,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
// collecting a list of structs
StandardType::NodeStart => visitor.visit_seq(Seq::new(self, None)?)?,
// Bytes should be deserialized by `deserialize_bytes`
StandardType::Binary => self.deserialize_bytes(visitor)?,
_ => {
// TODO: add size check against len
let node_size = node_type.size * node_type.count;

View File

@@ -6,6 +6,7 @@ extern crate indexmap;
extern crate minidom;
extern crate num;
extern crate rustc_hex;
extern crate serde_bytes;
#[macro_use] extern crate failure;
#[macro_use] extern crate lazy_static;

View File

@@ -66,7 +66,7 @@ impl KbinType {
}
},
count if count > 1 => self.parse_array::<T>(&mut result, input, arr_count)?,
_ => unimplemented!(),
_ => return Err(KbinErrorKind::InvalidState.into()),
};
Ok(result)
@@ -107,7 +107,7 @@ impl KbinType {
};
},
count if count > 1 => self.to_array::<T>(&mut output, input, arr_count)?,
_ => unimplemented!(),
_ => return Err(KbinErrorKind::InvalidState.into()),
};
Ok(output)

View File

@@ -70,6 +70,14 @@ impl<'de> Deserialize<'de> for Value {
self.visit_byte_buf(value.to_vec())
}
#[inline]
fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> Result<Self::Value, E>
where E: de::Error
{
trace!("ValueVisitor::visit_borrowed_bytes(value: 0x{:02x?})", value);
self.visit_byte_buf(value.to_vec())
}
#[inline]
fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E> {
trace!("ValueVisitor::visit_byte_buf(value: 0x{:02x?})", value);
@@ -206,7 +214,7 @@ impl<'de, E> de::Deserializer<'de> for ValueDeserializer<E>
Value::Attribute(s) => visitor.visit_string(s),
Value::Array(_, v) => SeqDeserializer::new(v.into_iter()).deserialize_any(visitor),
Value::Node(_) => unimplemented!(),
Value::Node(node) => node.into_deserializer().deserialize_any(visitor),
}
};
}

View File

@@ -2,6 +2,7 @@ use std::fmt;
use std::net::Ipv4Addr;
use serde::de::{Deserialize, Deserializer, DeserializeSeed};
use serde_bytes::ByteBuf;
use node::Node;
use node_types::StandardType;
@@ -20,6 +21,7 @@ macro_rules! construct_types {
$(
$konst($($value_type)*),
)+
Binary(Vec<u8>),
Time(u32),
Attribute(String),
@@ -41,6 +43,7 @@ macro_rules! construct_types {
$(
Value::$konst(_) => StandardType::$konst,
)+
Value::Binary(_) => StandardType::Binary,
Value::Time(_) => StandardType::Time,
Value::Attribute(_) => StandardType::Attribute,
Value::Array(node_type, _) => node_type,
@@ -74,6 +77,7 @@ macro_rules! construct_types {
$(
StandardType::$konst => <$($value_type)*>::deserialize(deserializer).map(Value::$konst),
)+
StandardType::Binary => ByteBuf::deserialize(deserializer).map(Vec::from).map(Value::Binary),
StandardType::Time => u32::deserialize(deserializer).map(Value::Time),
StandardType::Attribute => String::deserialize(deserializer).map(Value::Attribute),
StandardType::NodeStart => Node::deserialize(deserializer).map(Box::new).map(Value::Node),
@@ -85,6 +89,17 @@ macro_rules! construct_types {
}
}
impl From<Vec<u8>> for Value {
fn from(value: Vec<u8>) -> Value {
Value::Binary(value)
}
}
impl From<ByteBuf> for Value {
fn from(value: ByteBuf) -> Value {
Value::Binary(value.into())
}
}
impl fmt::Debug for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -149,7 +164,7 @@ construct_types! {
(U32, u32);
(S64, i64);
(U64, u64);
(Binary, Vec<u8>);
//(Binary, Vec<u8>);
(String, String);
(Ip4, Ipv4Addr);
//(Time, u32);