diff --git a/Cargo.toml b/Cargo.toml index d778791..4e23745 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/de/mod.rs b/src/de/mod.rs index 369e328..638ae21 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -119,17 +119,6 @@ macro_rules! de_type { } } -macro_rules! implement_type { - ($method:ident) => { - fn $method(self, _visitor: V) -> Result - 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(self, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("Deserializer::deserialize_char()"); + Err(Error::StaticMessage("char deserialization is not supported")) + } + + fn deserialize_str(self, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("Deserializer::deserialize_str()"); + Err(Error::StaticMessage("borrowed string deserialization is not supported")) + } fn deserialize_string(self, visitor: V) -> Result 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(self, visitor: V) -> Result @@ -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(self, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("Deserializer::deserialize_unit()"); + Err(Error::StaticMessage("unit deserialization is not supported")) + } fn deserialize_unit_struct(self, name: &'static str, _visitor: V) -> Result 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(self, name: &'static str, _visitor: V) -> Result where V: Visitor<'de> { trace!("Deserializer::deserialize_newtype_struct(name: {:?})", name); - unimplemented!(); + Err(Error::StaticMessage("newtype struct deserialization is not supported")) } fn deserialize_seq(self, visitor: V) -> Result @@ -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; diff --git a/src/lib.rs b/src/lib.rs index ee577bf..8598527 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; diff --git a/src/node_types.rs b/src/node_types.rs index 666309a..faa916c 100644 --- a/src/node_types.rs +++ b/src/node_types.rs @@ -66,7 +66,7 @@ impl KbinType { } }, count if count > 1 => self.parse_array::(&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::(&mut output, input, arr_count)?, - _ => unimplemented!(), + _ => return Err(KbinErrorKind::InvalidState.into()), }; Ok(output) diff --git a/src/value/de.rs b/src/value/de.rs index b2c36ea..00a0d85 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -70,6 +70,14 @@ impl<'de> Deserialize<'de> for Value { self.visit_byte_buf(value.to_vec()) } + #[inline] + fn visit_borrowed_bytes(self, value: &'de [u8]) -> Result + 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(self, value: Vec) -> Result { trace!("ValueVisitor::visit_byte_buf(value: 0x{:02x?})", value); @@ -206,7 +214,7 @@ impl<'de, E> de::Deserializer<'de> for ValueDeserializer 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), } }; } diff --git a/src/value/mod.rs b/src/value/mod.rs index 90ace8d..0730ae3 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -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), 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> for Value { + fn from(value: Vec) -> Value { + Value::Binary(value) + } +} + +impl From 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); + //(Binary, Vec); (String, String); (Ip4, Ipv4Addr); //(Time, u32);