lib: remove broken serde implementation

- The serde feature is very broken and incomplete.
- It was meant to be a sort of propterty list to structure interpreter, but it was not as fleshed out as equivalents in other languages are.
This commit is contained in:
Matt Bilker
2019-05-14 03:27:38 +00:00
parent b1b651aa11
commit cdb24d6dac
28 changed files with 0 additions and 3088 deletions

View File

@@ -8,7 +8,6 @@ edition = "2018"
[dependencies]
byteorder = "1.3.1"
bytes = "0.4.10"
cfg-if = "0.1"
encoding_rs = "0.8.6"
failure = "0.1.1"
indexmap = "1.0.1"
@@ -20,13 +19,9 @@ rustc-hex = "2.0.1"
clap = { version = "2.32.0", optional = true }
pretty_env_logger = { version = "0.3.0", optional = true }
serde = { version = "1.0.79", optional = true }
serde_bytes = { version = "0.11.1", optional = true }
serde_derive = { version = "1.0.79", optional = true }
[features]
build_binary = ["clap", "pretty_env_logger"]
serde-1 = ["serde", "serde_bytes", "serde_derive", "indexmap/serde-1"]
try_from = []
[profile.release]

View File

@@ -1,5 +1,3 @@
#[macro_use] extern crate cfg_if;
use std::fs::File;
use std::io::{self, Error as IoError, Read, Write};
@@ -11,42 +9,6 @@ use kbinxml::{NodeCollection, Options, Printer};
use minidom::Element;
use quick_xml::Reader;
cfg_if! {
if #[cfg(feature = "serde")] {
#[macro_use] extern crate serde_derive;
use std::net::Ipv4Addr;
use kbinxml::{ExtraNodes, Node};
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename = "test2")]
pub struct Testing2 {
hi: u16,
ho: i16,
vu: Vec<u8>,
opt: Option<u8>,
opt2: Option<u8>,
ip: Ipv4Addr,
#[serde(flatten)]
extra: ExtraNodes,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename = "test")]
pub struct Testing {
#[serde(rename = "attr_the_attr")] the_attr: String,
hi: u8,
ok: [u8; 3],
hhh: (u8, u8),
hhg: (u32, u32),
foo: String,
testing2: Testing2,
}
}
}
fn display_buf(buf: &[u8]) -> Result<(), IoError> {
io::stdout().write_all(&buf)?;
println!();
@@ -119,75 +81,6 @@ fn compare_slice(left: &[u8], right: &[u8]) {
}
}
#[cfg(feature = "serde")]
fn test_serde() -> std::io::Result<()> {
use kbinxml::{serde_from_bytes, serde_to_bytes};
let obj = Testing {
the_attr: "the_value".to_string(),
hi: 12,
ok: [12, 24, 48],
hhh: (55, 66),
hhg: (55, 66),
foo: "foobarbaz".to_string(),
testing2: Testing2 {
hi: 32423,
ho: 32000,
vu: vec![33, 255, 254],
opt: None,
opt2: Some(111),
ip: Ipv4Addr::new(127, 0, 0, 1),
extra: ExtraNodes::new(),
},
};
let bytes = serde_to_bytes(&obj).unwrap();
eprintln!("bytes: {:02x?}", bytes);
let mut file = File::create("testing.kbin")?;
file.write_all(&bytes)?;
let obj2 = serde_from_bytes::<Testing>(&bytes);
match &obj2 {
Ok(obj2) => eprintln!("obj2: {:#?}", obj2),
Err(e) => eprintln!("Unable to parse generated kbin back to struct: {:#?}", e),
};
let value = serde_from_bytes::<Node>(&bytes);
match &value {
Ok(obj2) => eprintln!("obj2: {:#?}", obj2),
Err(e) => eprintln!("Unable to parse generated kbin back to `Value`: {:#?}", e),
};
if obj2.is_ok() && value.is_ok() {
Printer::run(&bytes).unwrap();
}
Ok(())
}
#[cfg(not(feature = "serde"))]
fn test_serde() -> std::io::Result<()> {
Ok(())
}
#[cfg(feature = "serde")]
fn test_serde_node(contents: &[u8]) -> std::io::Result<()> {
let node = kbinxml::serde_from_bytes::<Node>(&contents);
match &node {
Ok(obj2) => {
eprintln!("obj2: {:#?}", obj2);
},
Err(e) => eprintln!("Unable to parse generated kbin back to `Node`: {:#?}", e),
};
Ok(())
}
#[cfg(not(feature = "serde"))]
fn test_serde_node(_contents: &[u8]) -> std::io::Result<()> {
Ok(())
}
fn run() -> Fallible<()> {
let matches = App::new("kbinxml")
.about(env!("CARGO_PKG_DESCRIPTION"))
@@ -199,8 +92,6 @@ fn run() -> Fallible<()> {
.arg(Arg::with_name("input")
.help("The file to convert")
.index(1))
.arg(Arg::with_name("serde")
.help("Test serialization and deserialization from kbin"))
.get_matches();
let printer_enabled = matches.is_present("printer");
@@ -232,8 +123,6 @@ fn run() -> Fallible<()> {
let options = Options::with_encoding(encoding_original);
let buf = kbinxml::to_binary_with_options(options, &element)?;
compare_slice(&buf, &contents);
test_serde_node(&contents)?;
} else {
let (collection, encoding) = kbinxml::from_text_xml(&contents)?;
@@ -253,8 +142,6 @@ fn run() -> Fallible<()> {
io::stdout().write_all(&buf)?;
}
} else if matches.is_present("serde") {
test_serde()?;
} else {
eprintln!("No input file specified!");
}

View File

@@ -1,251 +0,0 @@
use serde::de::{self, IntoDeserializer, Visitor};
use crate::de::custom::Custom;
use crate::de::definition::NodeDefinitionDeserializer;
use crate::de::node_contents::NodeContents;
use crate::de::seq::Seq;
use crate::de::structure::Struct;
use crate::error::{Error, KbinErrorKind};
use crate::node::{Marshal, NodeCollection};
use crate::node_types::StandardType;
fn warn_attributes(value: &NodeCollection) -> Result<(), Error> {
for attr in value.attributes() {
let key = attr.key()?.ok_or(KbinErrorKind::InvalidState)?;
let value = attr.value()?;
warn!("Ignoring Attribute {} = {}", key, value);
}
Ok(())
}
pub struct NodeCollectionDeserializer<'a> {
pub(crate) collection: &'a mut NodeCollection,
}
impl<'a> NodeCollectionDeserializer<'a> {
pub fn new(collection: &'a mut NodeCollection) -> Self {
trace!("NodeCollectionDeserializer::new() => attributes len: {}, children len: {}, base: {}",
collection.attributes().len(),
collection.children().len(),
collection.base());
Self { collection }
}
fn pop_node(&mut self) -> Result<NodeCollection, Error> {
self.collection.children_mut().pop_front().ok_or(KbinErrorKind::InvalidState.into())
}
fn pop_node_warn(&mut self) -> Result<NodeCollection, Error> {
let value = self.pop_node()?;
warn_attributes(&value)?;
Ok(value)
}
}
macro_rules! forward_to_definition_deserializer {
($($method:ident)*) => {
$(
#[inline]
fn $method<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!(concat!("NodeCollectionDeserializer::", stringify!($method), "()"));
let collection = self.pop_node()?;
NodeDefinitionDeserializer::new(collection.base()).$method(visitor)
}
)*
};
}
impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a> {
type Error = Error;
fn is_human_readable(&self) -> bool {
false
}
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
let mut collection = self.pop_node()?;
let (node_type, is_array) = collection.base().node_type_tuple();
if is_array {
warn_attributes(&collection)?;
trace!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array);
return visitor.visit_seq(Seq::new(&mut collection, true)?);
}
match node_type {
StandardType::NodeStart => {
debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => deserializing node", node_type, is_array);
let node = collection.as_node();
debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => node: {:?}", node_type, is_array, node);
let marshal = Marshal::with_node(StandardType::NodeStart, node?);
visitor.visit_newtype_struct(marshal.into_deserializer())
},
_ => {
warn_attributes(&collection)?;
let value = collection.base().value()?;
debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => value: {:?}", node_type, is_array, value);
let marshal = Marshal::with_value(node_type, value);
visitor.visit_newtype_struct(marshal.into_deserializer())
},
}
}
forward_to_deserialize_any! {
ignored_any
}
forward_to_definition_deserializer! {
deserialize_bool
deserialize_i8
deserialize_i16
deserialize_i32
deserialize_i64
deserialize_i128
deserialize_u8
deserialize_u16
deserialize_u32
deserialize_u64
deserialize_u128
deserialize_f32
deserialize_f64
deserialize_char
deserialize_str
deserialize_string
deserialize_bytes
deserialize_byte_buf
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_option()");
visitor.visit_some(self)
}
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_unit()");
Err(Error::StaticMessage("unit deserialization is not supported"))
}
fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_unit_struct(name: {:?})", name);
Err(Error::StaticMessage("unit struct deserialization is not supported"))
}
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_newtype_struct(name: {:?})", name);
Err(Error::StaticMessage("newtype struct deserialization is not supported"))
}
/// This will deserialize as a sequence of nodes if the first child node of
/// `self.collection` has `is_array == false`. Else, it will pop the first
/// child node and deserialize it as an array.
///
/// This is a compromise to allow struct sequences but also allow arrays of value.
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
let (node_type, is_array) = self.collection.children().front().ok_or(KbinErrorKind::InvalidState)?
.base()
.node_type_tuple();
debug!("NodeCollectionDeserializer::deserialize_seq(node_type: {:?}, is_array: {})", node_type, is_array);
if is_array {
let mut collection = self.pop_node_warn()?;
visitor.visit_seq(Seq::new(&mut collection, true)?)
} else {
visitor.visit_seq(Seq::new(&mut self.collection, false)?)
}
}
fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_tuple(len: {})", len);
let collection = self.pop_node_warn()?;
NodeDefinitionDeserializer::new(collection.base()).deserialize_tuple(len, visitor)
}
fn deserialize_tuple_struct<V>(mut self, name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len);
match name {
"__key" => {
let base = self.collection.base();
let node_type = base.node_type;
let key = base.key()?.ok_or(KbinErrorKind::InvalidState)?;
let de = key.into_deserializer();
visitor.visit_enum(Custom::new(de, node_type))
},
"__value" => {
let mut collection = self.pop_node()?;
visitor.visit_map(NodeContents::new(&mut collection))
},
_ => {
let collection = self.pop_node_warn()?;
NodeDefinitionDeserializer::new(collection.base()).deserialize_tuple_struct(name, len, visitor)
},
}
}
fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_map()");
let mut collection = self.pop_node()?;
visitor.visit_map(Struct::new(&mut collection))
}
fn deserialize_struct<V>(mut self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields);
let mut collection = self.pop_node()?;
let value = visitor.visit_map(Struct::new(&mut collection))?;
let keys: Vec<_> = self.collection.children().iter()
.filter_map(|x| x.base().key().ok())
.collect();
trace!("NodeCollectionDeserializer::deserialize_struct(name: {:?}) => end, keys: {:?}", name, keys);
Ok(value)
}
fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_enum(name: {:?}, variants: {:?})", name, variants);
Err(Error::StaticMessage("enum deserialization not supported"))
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeCollectionDeserializer::deserialize_identifier()");
// Delegate identifier deserialization to `NodeDefinitionDeserializer`
NodeDefinitionDeserializer::new(self.collection.base()).deserialize_identifier(visitor)
}
}

View File

@@ -1,90 +0,0 @@
use serde::de::{Deserializer, DeserializeSeed, EnumAccess, Error, IntoDeserializer, VariantAccess, Visitor};
use crate::node_types::StandardType;
pub struct Custom<D> {
de: D,
node_type: StandardType,
}
impl<D> Custom<D> {
pub fn new(de: D, node_type: StandardType) -> Self {
trace!("Custom::new(node_type: {:?})", node_type);
Self { de, node_type }
}
}
impl<'de, D> EnumAccess<'de> for Custom<D>
where D: Deserializer<'de>
{
type Error = D::Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), D::Error>
where V: DeserializeSeed<'de>
{
trace!("<Custom as EnumAccess>::variant_seed(node_type: {:?})", self.node_type);
let variant = self.node_type.id.into_deserializer();
seed.deserialize(variant).map(|s| (s, self))
}
}
impl<'de, D> VariantAccess<'de> for Custom<D>
where D: Deserializer<'de>
{
type Error = D::Error;
fn unit_variant(self) -> Result<(), D::Error> {
Err(D::Error::custom("unit variant not supported"))
}
// Used to get the value the `Visitor` wants through the `DeserializeSeed`
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, D::Error>
where T: DeserializeSeed<'de>
{
trace!("<Custom as VariantAccess>::newtype_variant_seed()");
seed.deserialize(self.de)
}
fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, D::Error>
where V: Visitor<'de>
{
Err(D::Error::custom("tuple variant not supported"))
}
fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value, D::Error>
where V: Visitor<'de>
{
Err(D::Error::custom("struct variant not supported"))
}
}
impl<'de, D> Deserializer<'de> for Custom<D>
where D: Deserializer<'de>
{
type Error = D::Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, D::Error>
where V: Visitor<'de>
{
trace!("<Custom as Deserializer>::deserialize_any(node_type: {:?})", self.node_type);
visitor.visit_enum(self)
}
/// Passthrough identifier deserialization so regular deserialization still works
#[inline]
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, D::Error>
where V: Visitor<'de>
{
trace!("<Custom as Deserializer>::deserialize_identifier(node_type: {:?})", self.node_type);
self.de.deserialize_identifier(visitor)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct map struct enum ignored_any
}
}

View File

@@ -1,228 +0,0 @@
use serde::de::{self, IntoDeserializer, Visitor};
use crate::de::custom::Custom;
use crate::de::seq::Seq;
use crate::error::{Error, KbinErrorKind};
use crate::node::{Marshal, NodeCollection, NodeDefinition};
use crate::node_types::StandardType;
use crate::value::Value;
pub struct NodeDefinitionDeserializer<'a> {
definition: &'a NodeDefinition,
}
impl<'a> NodeDefinitionDeserializer<'a> {
pub fn new(definition: &'a NodeDefinition) -> Self {
trace!("NodeDefinitionDeserializer::new(definition: {})", definition);
Self { definition }
}
}
macro_rules! auto_deserialize {
($($method:ident $konst:ident $visit_method:ident)*) => {
$(
#[inline]
fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!(concat!("NodeDefinitionDeserializer::", stringify!($method), "()"));
match self.definition.value() {
Ok(Value::$konst(value)) => visitor.$visit_method(value),
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
Err(e) => Err(e.into()),
}
}
)*
};
}
impl<'de, 'a> de::Deserializer<'de> for NodeDefinitionDeserializer<'a> {
type Error = Error;
fn is_human_readable(&self) -> bool {
false
}
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
let node_type = self.definition.node_type;
let is_array = self.definition.is_array;
trace!("NodeDefinitionDeserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array);
// Construct a shim `NodeCollection` for `Seq` if we are deserializing an
// array value
if is_array {
let mut collection = NodeCollection::new(self.definition.clone());
return visitor.visit_seq(Seq::new(&mut collection, true)?);
}
let value = match node_type {
StandardType::NodeStart => {
debug!("NodeDefinitionDeserializer::deserialize_any(unode_type: {:?}, is_array: {})", node_type, is_array);
Err(KbinErrorKind::InvalidNodeType(node_type).into())
},
_ => {
let value = self.definition.value()?;
debug!("NodeDefinitionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => value: {:?}", node_type, is_array, value);
let marshal = Marshal::with_value(node_type, value);
visitor.visit_newtype_struct(marshal.into_deserializer())
},
};
value
}
forward_to_deserialize_any! {
i128 u128 char str
seq
map struct enum ignored_any
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_bool()");
match self.definition.value() {
Ok(Value::Boolean(b)) => visitor.visit_bool(b),
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
Err(e) => Err(e.into()),
}
}
auto_deserialize! {
deserialize_i8 S8 visit_i8
deserialize_i16 S16 visit_i16
deserialize_i32 S32 visit_i32
deserialize_i64 S64 visit_i64
deserialize_u8 U8 visit_u8
deserialize_u16 U16 visit_u16
deserialize_u32 U32 visit_u32
deserialize_u64 U64 visit_u64
deserialize_f32 Float visit_f32
deserialize_f64 Double visit_f64
deserialize_byte_buf Binary visit_byte_buf
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_string()");
match self.definition.value() {
Ok(Value::String(s)) |
Ok(Value::Attribute(s)) => visitor.visit_string(s),
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
Err(e) => Err(e.into()),
}
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_bytes()");
if self.definition.node_type == StandardType::Binary {
match self.definition.value_bytes() {
Some(data) => visitor.visit_bytes(data),
None => Err(KbinErrorKind::InvalidState.into()),
}
} else {
Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into())
}
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_option()");
visitor.visit_some(self)
}
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_unit()");
Err(Error::StaticMessage("unit deserialization is not supported"))
}
fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_unit_struct(name: {:?})", name);
Err(Error::StaticMessage("unit struct deserialization is not supported"))
}
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_newtype_struct(name: {:?})", name);
Err(Error::StaticMessage("newtype struct deserialization is not supported"))
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len);
let node_type = self.definition.node_type;
match name {
"__key" => {
let key = self.definition.key()?.ok_or(KbinErrorKind::InvalidState)?;
let de = key.into_deserializer();
visitor.visit_enum(Custom::new(de, node_type))
},
"__value" => {
debug!("NodeDefinitionDeserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type);
self.deserialize_any(visitor)
},
_ => {
Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into())
},
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserialize::deserialize_tuple(len: {})", len);
macro_rules! tuple {
($($konst:ident),*) => {
match self.definition.value() {
$(
Ok(value @ Value::$konst(_)) |
)*
Ok(value @ Value::Ip4(_)) => value.into_deserializer().deserialize_any(visitor),
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
Err(e) => Err(e.into()),
}
};
}
tuple! {
S8_2, U8_2, S16_2, U16_2, S32_2, U32_2, S64_2, U64_2, Float2, Double2, Boolean2,
S8_3, U8_3, S16_3, U16_3, S32_3, U32_3, S64_3, U64_3, Float3, Double3, Boolean3,
S8_4, U8_4, S16_4, U16_4, S32_4, U32_4, S64_4, U64_4, Float4, Double4, Boolean4,
Vs16, Vu16,
Vs8, Vu8, Vb
}
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDefinitionDeserializer::deserialize_identifier()");
let key = self.definition.key()?.ok_or(KbinErrorKind::InvalidState)?;
let key = match self.definition.node_type {
StandardType::Attribute => format!("attr_{}", key),
_ => key,
};
visitor.visit_string(key)
}
}

View File

@@ -1,97 +0,0 @@
use std::result::Result as StdResult;
use bytes::Bytes;
use serde::de::{self, Deserialize, Visitor};
use crate::error::{Error, KbinErrorKind};
use crate::node::NodeCollection;
use crate::reader::Reader;
mod collection;
mod custom;
mod definition;
mod node_contents;
mod seq;
mod structure;
use self::custom::Custom;
use self::structure::Struct;
pub type Result<T> = StdResult<T, Error>;
pub struct Deserializer {
collection: NodeCollection,
}
pub fn from_bytes<'a, T>(input: &'a [u8]) -> Result<T>
where T: Deserialize<'a>
{
let mut deserializer = Deserializer::new(input)?;
let t = T::deserialize(&mut deserializer)?;
Ok(t)
}
impl Deserializer {
pub fn new(input: &[u8]) -> Result<Self> {
let mut reader = Reader::new(Bytes::from(input))?;
let collection = NodeCollection::from_iter(&mut reader).ok_or(KbinErrorKind::InvalidState)?;
Ok(Self { collection })
}
}
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
type Error = Error;
fn is_human_readable(&self) -> bool {
false
}
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_any()");
self.deserialize_map(visitor)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct enum identifier
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_map()");
let value = visitor.visit_map(Struct::new(&mut self.collection))?;
let keys: Vec<_> = self.collection.children().iter()
.filter_map(|x| x.base().key().ok())
.collect();
trace!("Deserializer::deserialize_map() => end, keys: {:?}", keys);
Ok(value)
}
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields);
let value = visitor.visit_map(Struct::new(&mut self.collection))?;
let keys: Vec<_> = self.collection.children().iter()
.filter_map(|x| x.base().key().ok())
.collect();
trace!("Deserializer::deserialize_struct(name: {:?}) => end, keys: {:?}", name, keys);
Ok(value)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_ignored_any()");
self.deserialize_any(visitor)
}
}

View File

@@ -1,88 +0,0 @@
use serde::de::{DeserializeSeed, IntoDeserializer, MapAccess};
use crate::de::{Custom, Result};
use crate::de::definition::NodeDefinitionDeserializer;
use crate::error::{Error, KbinErrorKind};
use crate::node::NodeCollection;
#[derive(Debug)]
enum ReadState {
Value,
Attributes,
}
pub struct NodeContents<'a> {
collection: &'a mut NodeCollection,
state: ReadState,
}
impl<'a> NodeContents<'a> {
pub fn new(collection: &'a mut NodeCollection) -> Self {
trace!("--> NodeContents::new(node_type: {:?})", collection.base().node_type);
Self {
collection,
state: ReadState::Value,
}
}
}
impl<'de, 'a> MapAccess<'de> for NodeContents<'a> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where K: DeserializeSeed<'de>
{
trace!("--> <NodeContents as MapAccess>::next_key_seed(state: {:?})", self.state);
match self.state {
ReadState::Value => {
let base = self.collection.base();
let de = "__value".into_deserializer();
seed.deserialize(Custom::new(de, base.node_type)).map(Some)
},
ReadState::Attributes => {
if let Some(attribute) = self.collection.attributes().front() {
let key = attribute.key()?.ok_or(KbinErrorKind::InvalidState)?;
debug!("<NodeContents as MapAccess>::next_key_seed(state: {:?}) => attribute: {:?}, key: {:?}", self.state, attribute, key);
let de = NodeDefinitionDeserializer::new(attribute);
seed.deserialize(de).map(Some)
} else {
debug!("<-- <NodeContents as MapAccess>::next_key_seed(state: {:?}) => end of map", self.state);
Ok(None)
}
},
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where V: DeserializeSeed<'de>
{
trace!("--> <NodeContents as MapAccess>::next_value_seed(state: {:?})", self.state);
match self.state {
ReadState::Value => {
let base = self.collection.base();
let de = NodeDefinitionDeserializer::new(base);
let value = seed.deserialize(de)?;
self.state = ReadState::Attributes;
Ok(value)
},
ReadState::Attributes => {
if let Some(attribute) = self.collection.attributes_mut().pop_front() {
let node_type = attribute.node_type;
let value = attribute.value()?;
debug!("<NodeContents as MapAccess>::next_value_seed() => attribute: {:?}, value: {:?}", attribute, value);
let de = value.into_deserializer();
seed.deserialize(Custom::new(de, node_type))
} else {
Err(KbinErrorKind::InvalidState.into())
}
},
}
}
}

View File

@@ -1,124 +0,0 @@
use std::collections::VecDeque;
use serde::de::{DeserializeSeed, IntoDeserializer, SeqAccess};
use crate::de::collection::NodeCollectionDeserializer;
use crate::error::{Error, KbinErrorKind};
use crate::node::NodeCollection;
use crate::node_types::StandardType;
use crate::value::Value;
enum SequenceMode {
Struct {
known_identifier: String,
},
Value {
values: VecDeque<Value>,
},
}
pub struct Seq<'a> {
collection: &'a mut NodeCollection,
index: usize,
seq_mode: SequenceMode,
}
impl<'a> Seq<'a> {
pub fn new(collection: &'a mut NodeCollection, is_array: bool) -> Result<Self, Error> {
trace!("Seq::new(is_array: {})", is_array);
let seq_mode = if is_array {
let base = collection.base();
let value = base.value()?;
let values = if let Value::Array(node_type, values) = value {
debug!("Seq::new(is_array: {}) => len: {}", is_array, values.len());
if node_type != base.node_type {
return Err(KbinErrorKind::TypeMismatch(base.node_type, node_type).into());
}
VecDeque::from(values)
} else {
return Err(KbinErrorKind::InvalidState.into());
};
SequenceMode::Value { values }
} else {
let child = collection.children().front().ok_or(KbinErrorKind::InvalidState)?;
let known_identifier = child.base().key()?.ok_or(KbinErrorKind::InvalidState)?;
debug!("Seq::new(is_array: {}) => known identifier: {:?}", is_array, known_identifier);
SequenceMode::Struct { known_identifier }
};
Ok(Self {
collection,
index: 0,
seq_mode,
})
}
}
impl<'de, 'a> SeqAccess<'de> for Seq<'a> {
type Error = Error;
// A len of `None` indicates that the sequence ends when `NodeEnd` is reached
// or a different type node is reached.
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: DeserializeSeed<'de>
{
trace!("--> Seq::next_element_seed()");
match self.seq_mode {
SequenceMode::Struct { ref known_identifier } => {
{
let base = match self.collection.children().front() {
Some(child) => child.base(),
None => {
debug!("<-- Seq::next_element_seed(mode: Struct) => end of sequence (by `collection.children.front() == None`)");
return Ok(None);
},
};
let node_type = base.node_type;
debug!("Seq::next_element_seed(mode: Struct) => peeked type: {:?}", node_type);
if self.index > 0 {
// The struct sequence ends when the node identifier has a different name
// and the current node type is not `NodeStart` or `NodeEnd` and the last
// node was not a `NodeStart` event.
//
// The should not trigger for struct subfields because those would be
// deserialized by the struct deserializer.
if node_type != StandardType::NodeStart &&
node_type != StandardType::NodeEnd
{
let node_identifier = base.key()?.ok_or(KbinErrorKind::InvalidState)?;
if node_identifier.as_str() != known_identifier {
debug!("<-- Seq::next_element_seed(mode: Struct) => peeked identifier does not equal known identifier: {:?}", known_identifier);
return Ok(None);
}
}
}
self.index += 1;
}
let de = NodeCollectionDeserializer::new(&mut self.collection);
seed.deserialize(de).map(Some)
},
SequenceMode::Value { ref mut values } => {
let value = match values.pop_front() {
Some(v) => v,
None => {
debug!("<-- Seq::next_element_seed(mode: Value) => out of bounds read, returning None");
return Ok(None);
},
};
let de = value.into_deserializer();
seed.deserialize(de).map(Some)
},
}
}
}

View File

@@ -1,87 +0,0 @@
use serde::de::{DeserializeSeed, IntoDeserializer, MapAccess};
use crate::de::Custom;
use crate::de::collection::NodeCollectionDeserializer;
use crate::de::definition::NodeDefinitionDeserializer;
use crate::error::Error;
use crate::node::NodeCollection;
use crate::node_types::StandardType;
pub struct Struct<'a> {
collection: &'a mut NodeCollection,
key: Option<String>,
}
impl<'a> Struct<'a> {
pub fn new(collection: &'a mut NodeCollection) -> Self {
let key = collection.base().key().ok().and_then(|v| v);
trace!("--> Struct::new() => attributes len: {}, children len: {}, base: {}",
collection.attributes().len(),
collection.children().len(),
collection.base());
Self {
collection,
key,
}
}
}
impl<'de, 'a> MapAccess<'de> for Struct<'a> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where K: DeserializeSeed<'de>
{
debug!("--> <Struct as MapAccess>::next_key_seed()");
// First, if the key field is still present, emit the `__node_key` first
if self.key.is_some() {
let de = "__node_key".into_deserializer();
return seed.deserialize(Custom::new(de, StandardType::String)).map(Some);
}
// Then if there are attributes left, deserialize them first
if let Some(attribute) = self.collection.attributes().front() {
let de = NodeDefinitionDeserializer::new(attribute);
return seed.deserialize(de).map(Some);
}
// Else, deserialize the child nodes
let mut node = match self.collection.children_mut().front_mut() {
Some(v) => v,
None => {
debug!("<-- <Struct as MapAccess>::next_key_seed() => end of map");
return Ok(None);
},
};
let de = NodeCollectionDeserializer::new(&mut node);
seed.deserialize(de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where V: DeserializeSeed<'de>
{
debug!("--> <Struct as MapAccess>::next_value_seed()");
// First, if the key field is still present, emit the `__node_key` value
if let Some(key) = self.key.take() {
let de = key.into_deserializer();
return seed.deserialize(de);
}
// Then if there are attributes left, deserialize them first
if let Some(attribute) = self.collection.attributes_mut().pop_front() {
let de = NodeDefinitionDeserializer::new(&attribute);
return seed.deserialize(de);
}
// Else, deserialize the child nodes. Delegate popping nodes off the
// children queue by the deserialize methods else handling `Struct`
// sequences will break.
let de = NodeCollectionDeserializer::new(&mut self.collection);
seed.deserialize(de)
}
}

View File

@@ -170,67 +170,3 @@ impl From<QuickXmlError> for KbinError {
}
}
}
cfg_if! {
if #[cfg(feature = "serde")] {
use std::error::Error as StdError;
use std::fmt::Display;
use failure::Compat;
use serde::{de, ser};
#[derive(Debug)]
pub enum Error {
Message(String),
StaticMessage(&'static str),
Wrapped(Compat<KbinError>),
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(StdError::description(self))
}
}
impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::Message(ref msg) => msg,
Error::StaticMessage(ref msg) => msg,
Error::Wrapped(ref err) => err.description(),
}
}
}
impl From<KbinError> for Error {
fn from(inner: KbinError) -> Self {
Error::Wrapped(inner.compat())
}
}
impl From<KbinErrorKind> for Error {
fn from(inner: KbinErrorKind) -> Self {
Error::Wrapped(KbinError::from(inner).compat())
}
}
impl From<Context<KbinErrorKind>> for Error {
fn from(inner: Context<KbinErrorKind>) -> Self {
Error::Wrapped(KbinError::from(inner).compat())
}
}
}
}

View File

@@ -1,15 +1,6 @@
#![cfg_attr(test, feature(test))]
#![cfg_attr(feature = "try_from", feature(try_from))]
extern crate byteorder;
extern crate bytes;
extern crate encoding_rs;
extern crate indexmap;
extern crate minidom;
extern crate quick_xml;
extern crate rustc_hex;
#[macro_use] extern crate cfg_if;
#[macro_use] extern crate failure;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
@@ -53,21 +44,6 @@ pub use crate::to_text_xml::ToTextXml;
pub use crate::value::Value;
pub use crate::writer::{Writer, Writeable};
cfg_if! {
if #[cfg(feature = "serde")] {
extern crate serde_bytes;
#[macro_use] extern crate serde;
mod de;
mod ser;
pub use crate::de::from_bytes as serde_from_bytes;
pub use crate::node::ExtraNodes;
pub use crate::ser::to_bytes as serde_to_bytes;
}
}
const SIGNATURE: u8 = 0xA0;
const SIG_COMPRESSED: u8 = 0x42;

View File

@@ -1,290 +0,0 @@
use std::fmt;
use std::marker::PhantomData;
use serde::de::{self, Deserialize, DeserializeSeed, Error, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::de::value::{MapDeserializer, SeqDeserializer};
use crate::node::Node;
use crate::node_types::StandardType;
use crate::value::Value;
pub(crate) struct NodeVisitor {
key: Option<String>,
}
impl<'de> NodeVisitor {
fn map_to_node<A>(node_type: StandardType, key: &str, map: &mut A) -> Result<Node, A::Error>
where A: MapAccess<'de>
{
trace!("NodeVisitor::map_to_node(node_type: {:?})", node_type);
match node_type {
StandardType::Attribute => Err(A::Error::custom("`Attribute` nodes must be handled elsewhere")),
StandardType::NodeStart => {
let value = map.next_value_seed(NodeValueSeed(key.to_owned()))?;
debug!("NodeVisitor::map_to_node(node_type: {:?}) => value: {:?}", node_type, value);
Ok(value)
},
// Rolling up the `NodeStart` handling and other value types is not going
// to happen as `NodeStart` nodes do not have a value
node_type => {
let node = map.next_value_seed(NodeWithValueSeed(key.to_owned()))?;
debug!("NodeVisitor::map_to_node(node_type: {:?}) => node: {:?}", node_type, node);
Ok(node)
},
}
}
}
impl<'de> Visitor<'de> for NodeVisitor {
type Value = Node;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid kbin node (for NodeVisitor)")
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where A: MapAccess<'de>
{
trace!("NodeVisitor::visit_map()");
let mut node = Node::new(self.key.unwrap_or_else(|| "".to_owned()));
while let Some(NodeStart { key, node_type }) = map.next_key()? {
debug!("NodeVisitor::visit_map() => node_type: {:?}, key: {:?}", node_type, key);
if key == "__value" {
trace!("NodeVisitor::visit_map() => got __value, getting node value");
let node_value = map.next_value()?;
debug!("NodeVisitor::visit_map() => node value: {:?}", node_value);
node.set_value(Some(node_value));
} else if key == "__node_key" {
trace!("NodeVisitor::visit_map() => got __node_key, getting node key");
let node_key: String = map.next_value()?;
debug!("NodeVisitor::visit_map() => node key: {:?}", node_key);
node.set_key(node_key);
} else {
match node_type {
StandardType::Attribute => {
let value = map.next_value();
debug!("NodeVisitor::visit_map() => value: {:?}", value);
if let Value::Attribute(s) = value? {
//let key = String::from(&key["attr_".len()..]);
node.set_attr(key, s);
} else {
return Err(A::Error::custom("`Attribute` node must have `Value::Attribute` value"));
}
},
_ => {
let new_node = NodeVisitor::map_to_node(node_type, &key, &mut map)?;
debug!("NodeVisitor::visit_map() => node: {:?}", node);
node.append_child(new_node);
},
};
}
}
Ok(node)
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where A: SeqAccess<'de>
{
trace!("NodeVisitor::visit_seq()");
let key = seq.next_element()?.ok_or_else(|| A::Error::custom("first element must be `key`"))?;
let attributes = seq.next_element()?.ok_or_else(|| A::Error::custom("second element must be `attributes`"))?;
let children = seq.next_element()?.ok_or_else(|| A::Error::custom("third element must be `children`"))?;
let value = seq.next_element()?.ok_or_else(|| A::Error::custom("fourth element must be `value`"))?;
Ok(Node {
key,
attributes,
children,
value,
})
}
}
impl<'de> Deserialize<'de> for Node {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
deserializer.deserialize_map(NodeVisitor { key: None })
}
}
/// A `DeserializeSeed` holder to deserialize a `Node` from `NodeDeserializer`
pub(crate) struct NodeSeed;
impl<'de> DeserializeSeed<'de> for NodeSeed {
type Value = Node;
#[inline]
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: de::Deserializer<'de>
{
// `key` will be fixed in `deserialize_seq`
deserializer.deserialize_seq(NodeVisitor { key: None })
}
}
struct NodeValueSeed(String);
impl<'de> DeserializeSeed<'de> for NodeValueSeed {
type Value = Node;
#[inline]
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: de::Deserializer<'de>
{
trace!("NodeValueSeed(key: {:?})::deserialize()", self.0);
deserializer.deserialize_map(NodeVisitor { key: Some(self.0) })
}
}
#[derive(Debug)]
pub(crate) struct NodeWithValueSeed(String);
impl<'de> DeserializeSeed<'de> for NodeWithValueSeed {
type Value = Node;
#[inline]
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: de::Deserializer<'de>
{
trace!("NodeWithValueSeed(key: {:?})::deserialize()", self.0);
deserializer.deserialize_tuple_struct("__value", 0, NodeVisitor { key: Some(self.0) })
}
}
pub struct NodeDeserializer<E> {
node: Node,
marker: PhantomData<E>,
index: usize,
}
impl<'de, E: Error> de::Deserializer<'de> for NodeDeserializer<E> {
type Error = E;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("NodeDeserializer::deserialize_any(key: {:?})", self.node.key);
visitor.visit_seq(self)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct map struct enum identifier ignored_any
}
}
impl<'de, E: Error> SeqAccess<'de> for NodeDeserializer<E> {
type Error = E;
/// "Deserializes" the key, attributes as (key, string), children as
/// (key, node), and value as itself
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: DeserializeSeed<'de>
{
macro_rules! make_deserializer {
($value:expr, $deserializer:ident) => {
match $value.take() {
Some(value) => {
let deserializer = $deserializer::new(value.into_iter());
seed.deserialize(deserializer).map(Some)
},
None => seed.deserialize(().into_deserializer()).map(Some),
}
};
}
trace!("--> <NodeDeserializer as SeqAccess>::next_element_seed(index: {})", self.index);
let value = match self.index {
0 => seed.deserialize(self.node.key.as_str().into_deserializer()).map(Some),
1 => make_deserializer!(self.node.attributes, MapDeserializer),
2 => make_deserializer!(self.node.children, SeqDeserializer),
3 => match self.node.value.take() {
Some(value) => seed.deserialize(value.into_deserializer()).map(Some),
None => seed.deserialize(().into_deserializer()).map(Some),
},
_ => Ok(None),
};
self.index += 1;
value
}
}
impl<'de, E: Error> IntoDeserializer<'de, E> for Node {
type Deserializer = NodeDeserializer<E>;
#[inline]
fn into_deserializer(self) -> Self::Deserializer {
NodeDeserializer {
node: self,
marker: PhantomData,
index: 0,
}
}
}
/// Node classifier that gets the key name and the type of the node before the
/// main `Node` object handles getting the value based on the type and the
/// attributes.
#[derive(Debug)]
pub(crate) struct NodeStart {
pub(crate) key: String,
pub(crate) node_type: StandardType,
}
impl<'de> Deserialize<'de> for NodeStart {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
trace!("NodeStart::deserialize()");
struct NodeVisitor;
impl<'de> Visitor<'de> for NodeVisitor {
type Value = NodeStart;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("enum input of a node (for NodeStart)")
}
#[inline]
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where A: EnumAccess<'de>
{
trace!("NodeVisitor::visit_enum()");
let (id, variant): (u8, _) = data.variant()?;
let node_type = StandardType::from_u8(id);
debug!("NodeVisitor::visit_enum() => id: {}, node_type: {:?}", id, node_type);
let key: String = variant.newtype_variant_seed(PhantomData)?;
debug!("NodeVisitor::visit_enum() => key: {:?}", key);
Ok(NodeStart { key, node_type })
}
}
deserializer.deserialize_tuple_struct("__key", 0, NodeVisitor)
}
}

View File

@@ -1,86 +0,0 @@
use std::fmt;
use serde::de::{self, Deserialize, Error, MapAccess, Visitor};
use crate::node::Node;
use crate::node::extra::ExtraNodes;
use crate::node::marshal::{Marshal, MarshalValue};
use crate::value::Value;
impl<'de> Deserialize<'de> for ExtraNodes {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
struct ExtraNodesVisitor;
impl<'de> Visitor<'de> for ExtraNodesVisitor {
type Value = ExtraNodes;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid map of kbin nodes (for ExtraNodes)")
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where A: MapAccess<'de>
{
trace!("ExtraNodesVisitor::visit_map()");
let mut extra = ExtraNodes::new();
while let Some(key) = map.next_key::<String>()? {
debug!("ExtraNodesVisitor::visit_map() => key: {:?}", key);
if key == "__node_key" {
debug!("ExtraNodesVisitor::visit_map() => got __node_key, getting node key");
let node_key: String = map.next_value()?;
debug!("ExtraNodesVisitor::visit_map() => node key: {:?}", node_key);
extra.set_parent_key(node_key);
continue;
}
let marshal: Marshal = map.next_value()?;
debug!("ExtraNodesVisitor::visit_map() => marshal: {:?}", marshal);
let value = marshal.into_inner();
if key.starts_with("attr_") {
let key = String::from(&key["attr_".len()..]);
debug!("ExtraNodesVisitor::visit_map() => found attribute, key: {:?}, value: {:?}", key, value);
if let Some(value) = value.as_value() {
if let Value::Attribute(s) = value {
extra.set_attr(key, s);
} else {
return Err(A::Error::custom("`Attribute` node must have `Value::Attribute` value"));
}
} else {
return Err(A::Error::custom("`Marshal` must contain `Value` for attribute"));
}
} else {
match value {
MarshalValue::Node(mut node) => {
node.key = key.clone();
extra.insert(key, node)
},
MarshalValue::Value(value) => match value {
Value::Node(mut node) => {
node.key = key.clone();
extra.insert(key, *node)
},
value => extra.insert(key.clone(), Node::with_value(key, value)),
},
};
}
}
Ok(extra)
}
}
deserializer.deserialize_map(ExtraNodesVisitor)
}
}

View File

@@ -1,54 +0,0 @@
use std::mem;
use indexmap::IndexMap;
use crate::node::Node;
mod de;
mod ser;
/// Container for extra `Node` and `Attribute` objects that are not part of a
/// parent object
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExtraNodes {
parent_key: String,
attributes: IndexMap<String, String>,
nodes: IndexMap<String, Node>,
}
impl ExtraNodes {
pub fn new() -> Self {
Self {
parent_key: String::with_capacity(0),
attributes: IndexMap::new(),
nodes: IndexMap::new(),
}
}
#[inline]
pub fn parent_key(&self) -> &str {
&self.parent_key
}
#[inline]
pub fn attributes(&self) -> &IndexMap<String, String> {
&self.attributes
}
#[inline]
pub fn nodes(&self) -> &IndexMap<String, Node> {
&self.nodes
}
pub fn set_parent_key(&mut self, key: String) -> String {
mem::replace(&mut self.parent_key, key)
}
pub fn set_attr(&mut self, key: String, value: String) -> Option<String> {
self.attributes.insert(key, value)
}
pub fn insert(&mut self, key: String, value: Node) -> Option<Node> {
self.nodes.insert(key, value)
}
}

View File

@@ -1,24 +0,0 @@
use serde::ser::{Serialize, SerializeMap};
use crate::node::ExtraNodes;
impl Serialize for ExtraNodes {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ::serde::Serializer
{
trace!("<ExtraNodes as Serialize>::serialize()");
let len = self.attributes.len() + self.nodes.len();
let mut map = serializer.serialize_map(Some(len))?;
for (k, v) in &self.attributes {
map.serialize_entry(k, v)?;
}
for (k, v) in &self.nodes {
map.serialize_entry(k, v)?;
}
map.end()
}
}

View File

@@ -1,171 +0,0 @@
use std::fmt;
use std::marker::PhantomData;
use serde::de::{self, Deserialize, DeserializeSeed, IntoDeserializer, SeqAccess, Visitor};
use crate::node::Node;
use crate::node::de::NodeSeed;
use crate::node_types::StandardType;
use crate::value::Value;
#[derive(Debug)]
pub enum MarshalValue {
Node(Node),
Value(Value),
}
#[derive(Debug)]
pub struct Marshal {
node_type: StandardType,
value: MarshalValue,
}
impl MarshalValue {
/*
pub fn as_node(self) -> Option<Node> {
match self {
MarshalValue::Node(node) => Some(node),
MarshalValue::Value(_) => None,
}
}
*/
pub fn as_value(self) -> Option<Value> {
match self {
MarshalValue::Node(_) => None,
MarshalValue::Value(value) => Some(value),
}
}
}
impl Marshal {
pub fn with_node(node_type: StandardType, node: Node) -> Self {
Self {
node_type,
value: MarshalValue::Node(node),
}
}
pub fn with_value(node_type: StandardType, value: Value) -> Self {
Self {
node_type,
value: MarshalValue::Value(value),
}
}
pub fn into_inner(self) -> MarshalValue {
self.value
}
}
impl<'de> Deserialize<'de> for Marshal {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
struct MarshalVisitor;
impl<'de> Visitor<'de> for MarshalVisitor {
type Value = Marshal;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("the components of `Marshal`")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where A: SeqAccess<'de>
{
let node_type = StandardType::from_u8(seq.next_element()?.unwrap());
trace!("NodeMarshalVisitor::visit_seq() => node_type: {:?}", node_type);
let value = if node_type == StandardType::NodeStart {
let node = seq.next_element_seed(NodeSeed)?.unwrap();
debug!("NodeMarshalVisitor::visit_seq() => node: {:?}", node);
MarshalValue::Node(node)
} else {
let value = seq.next_element_seed(node_type)?.unwrap();
debug!("NodeMarshalVisitor::visit_seq() => value: {:?}", value);
MarshalValue::Value(value)
};
Ok(Marshal { node_type, value })
}
/// An alternate entrypoint
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: de::Deserializer<'de>
{
trace!("NodeMarshalVisitor::visit_newtype_struct()");
Marshal::deserialize(deserializer)
}
}
deserializer.deserialize_any(MarshalVisitor)
}
}
pub struct MarshalDeserializer<E> {
node_type: StandardType,
value: Option<MarshalValue>,
index: usize,
marker: PhantomData<E>,
}
impl<'de, E> de::Deserializer<'de> for MarshalDeserializer<E>
where E: de::Error
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("MarshalDeserializer::deserialize_any(node_type: {:?}, value: {:?})", self.node_type, self.value);
visitor.visit_seq(self)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct map struct enum identifier ignored_any
}
}
impl<'de, E> SeqAccess<'de> for MarshalDeserializer<E>
where E: de::Error
{
type Error = E;
/// Deserialize `Marshal` as a tuple
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: DeserializeSeed<'de>
{
trace!("<MarshalDeserializer as SeqAccess>::next_element_seed(node_type: {:?}, value: {:?}, index: {})", self.node_type, self.value, self.index);
let result = match self.index {
0 => seed.deserialize(self.node_type.id.into_deserializer()).map(Some),
1 => match self.value.take() {
Some(MarshalValue::Node(node)) => seed.deserialize(node.into_deserializer()).map(Some),
Some(MarshalValue::Value(value)) => seed.deserialize(value.into_deserializer()).map(Some),
None => Err(E::custom("`value` for `MarshalDeserializer` should not be `None` at `next_element_seed` at index 1")),
},
_ => Ok(None),
};
self.index += 1;
result
}
}
impl<'de, E> IntoDeserializer<'de, E> for Marshal
where E: de::Error
{
type Deserializer = MarshalDeserializer<E>;
fn into_deserializer(self) -> Self::Deserializer {
MarshalDeserializer {
node_type: self.node_type,
value: Some(self.value),
index: 0,
marker: PhantomData,
}
}
}

View File

@@ -12,18 +12,6 @@ mod definition;
pub use self::collection::NodeCollection;
pub use self::definition::{Key, NodeData, NodeDefinition};
cfg_if! {
if #[cfg(feature = "serde")] {
pub(crate) mod de;
mod extra;
mod marshal;
mod ser;
pub use self::marshal::{Marshal, MarshalDeserializer};
pub use self::extra::ExtraNodes;
}
}
// The attributes argument is very hard to generalize
fn convert_attributes(attrs: &[(&str, &str)]) -> IndexMap<String, String> {
attrs.iter()

View File

@@ -1,12 +0,0 @@
use serde::ser::Serialize;
use crate::node::Node;
impl Serialize for Node {
#[inline]
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where S: ::serde::Serializer
{
unimplemented!();
}
}

View File

@@ -1,174 +0,0 @@
use byteorder::{BigEndian, WriteBytesExt};
use failure::ResultExt;
use serde::ser::{self, Impossible, Serialize};
use crate::error::{Error, KbinErrorKind};
use crate::node_types::StandardType;
pub struct BufferSerializer {
buffer: Vec<u8>,
}
impl BufferSerializer {
pub fn new() -> Self {
Self {
buffer: Vec::new(),
}
}
#[inline]
pub fn get_ref(&self) -> &[u8] {
&self.buffer
}
#[inline]
pub fn into_inner(self) -> Vec<u8> {
self.buffer
}
}
macro_rules! ser_type {
(byte; $inner_type:ident, $method:ident, $standard_type:ident $($cast:tt)*) => {
fn $method(self, value: $inner_type) -> Result<Self::Ok, Self::Error> {
let node_type = StandardType::$standard_type;
trace!("BufferSerializer::{}(node_type: {}, value: {})", stringify!($method), stringify!($standard_type), value);
self.buffer.write_u8(value $($cast)*).context(KbinErrorKind::DataWrite(node_type.name))?;
Ok(node_type)
}
};
(large; $inner_type:ident, $method:ident, $write_method:ident, $standard_type:ident $($cast:tt)*) => {
fn $method(self, value: $inner_type) -> Result<Self::Ok, Self::Error> {
trace!(concat!("BufferSerializer::{}(node_type: {}, value: {})"), stringify!($method), stringify!($standard_type), value);
//self.buffer.push(Value::$standard_type(value));
let node_type = StandardType::$standard_type;
self.buffer.$write_method::<BigEndian>(value $($cast)*).context(KbinErrorKind::DataWrite(node_type.name))?;
Ok(node_type)
}
}
}
impl<'a> ser::Serializer for &'a mut BufferSerializer {
type Ok = StandardType;
type Error = Error;
type SerializeSeq = Impossible<Self::Ok, Self::Error>;
type SerializeTuple = Impossible<Self::Ok, Self::Error>;
type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
type SerializeMap = Impossible<Self::Ok, Self::Error>;
type SerializeStruct = Impossible<Self::Ok, Self::Error>;
type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
fn is_human_readable(&self) -> bool {
false
}
ser_type!(byte; bool, serialize_bool, Boolean as u8);
ser_type!(byte; u8, serialize_u8, U8);
ser_type!(byte; i8, serialize_i8, S8 as u8);
ser_type!(large; u16, serialize_u16, write_u16, U16);
ser_type!(large; i16, serialize_i16, write_i16, S16);
ser_type!(large; u32, serialize_u32, write_u32, U32);
ser_type!(large; i32, serialize_i32, write_i32, S32);
ser_type!(large; u64, serialize_u64, write_u64, U64);
ser_type!(large; i64, serialize_i64, write_i64, S64);
ser_type!(large; f32, serialize_f32, write_f32, Float);
ser_type!(large; f64, serialize_f64, write_f64, Double);
fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_char(value: {})", value);
Err(Error::StaticMessage("char not supported"))
}
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_str(value: {})", value);
Err(Error::StaticMessage("str not supported"))
}
// Binary data is handled separately from other array types.
// Binary data should also be the only element of its node.
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_bytes(value: {:02x?})", value);
Err(Error::StaticMessage("bytes not supported"))
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_none()");
Err(Error::StaticMessage("option not supported"))
}
fn serialize_some<T>(self, _v: &T) -> Result<Self::Ok, Self::Error>
where T: ?Sized + Serialize
{
trace!("BufferSerializer::serialize_some()");
Err(Error::StaticMessage("option not supported"))
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_unit()");
Err(Error::StaticMessage("unit not supported"))
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_unit_struct(name: {})", name);
Err(Error::StaticMessage("unit struct not supported"))
}
fn serialize_unit_variant(self, name: &'static str, variant_index: u32, variant: &'static str) -> Result<Self::Ok, Self::Error> {
trace!("BufferSerializer::serialize_unit_variant(name: {}, variant_index: {}, variant: {})", name, variant_index, variant);
Err(Error::StaticMessage("unit variant not supported"))
}
fn serialize_newtype_struct<T>(self, name: &'static str, _value: &T) -> Result<Self::Ok, Self::Error>
where T: ?Sized + Serialize
{
trace!("BufferSerializer::serialize_newtype_struct(name: {})", name);
Err(Error::StaticMessage("newtype struct not supported"))
}
fn serialize_newtype_variant<T>(self, name: &'static str, variant_index: u32, variant: &'static str, _value: &T) -> Result<Self::Ok, Self::Error>
where T: ?Sized + Serialize
{
trace!("BufferSerializer::serialize_newtype_variant(name: {}, variant_index: {}, variant: {})", name, variant_index, variant);
Err(Error::StaticMessage("newtype variant not supported"))
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
trace!("BufferSerializer::serialize_seq(len: {:?})", len);
Err(Error::StaticMessage("sequences not supported"))
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
trace!("BufferSerializer::serialize_tuple(len: {})", len);
Err(Error::StaticMessage("tuple not supported"))
}
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> {
trace!("BufferSerializer::serialize_tuple_struct(name: {}, len: {})", name, len);
Err(Error::StaticMessage("tuple struct not supported"))
}
fn serialize_tuple_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Self::SerializeTupleVariant, Self::Error> {
trace!("BufferSerializer::serialize_tuple_variant(name: {}, variant_index: {}, variant: {}, len: {})", name, variant_index, variant, len);
Err(Error::StaticMessage("tuple variant not supported"))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
trace!("BufferSerializer::serialize_map(len: {:?})", len);
Err(Error::StaticMessage("map not supported"))
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
trace!("BufferSerializer::serialize_struct(name: {}, len: {})", name, len);
Err(Error::StaticMessage("struct not supported"))
}
fn serialize_struct_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Self::SerializeStructVariant, Self::Error> {
trace!("BufferSerializer::serialize_struct_variant(name: {}, variant_index: {}, variant: {}, len: {})", name, variant_index, variant, len);
Err(Error::StaticMessage("struct variant not supported"))
}
}

View File

@@ -1,55 +0,0 @@
use serde::ser::{Serialize, SerializeTupleStruct};
use crate::error::KbinErrorKind;
use crate::node_types::StandardType;
use crate::ser::{Error, Result, Serializer, TypeHint, WriteMode};
pub struct Custom<'a> {
ser: &'a mut Serializer,
node_type: StandardType,
}
impl<'a> Custom<'a> {
pub fn new(ser: &'a mut Serializer, name: &'static str, len: usize) -> Result<Self> {
let node_type = StandardType::from_name(name);
// Custom node type handler
//
// Sets the serializer to output a specific format for wrapper types
match node_type {
StandardType::Ip4 => ser.write_mode = WriteMode::Array,
_ => {},
};
// TODO: Fix check for types that have a count above 1
let node_size = node_type.size as usize;
if node_size != len {
return Err(KbinErrorKind::SizeMismatch(*node_type, node_size, len).into());
}
Ok(Self { ser, node_type })
}
}
impl<'a> SerializeTupleStruct for Custom<'a> {
type Ok = Option<TypeHint>;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
trace!("Custom::serialize_field()");
value.serialize(&mut *self.ser)?;
Ok(())
}
fn end(self) -> Result<Self::Ok> {
trace!("Custom::end()");
self.ser.write_mode = WriteMode::Single;
Ok(Some(TypeHint::from_type(self.node_type)))
}
}

View File

@@ -1,99 +0,0 @@
use byteorder::WriteBytesExt;
use failure::ResultExt;
use serde::ser::{Serialize, SerializeMap};
use crate::error::{Error, KbinErrorKind};
use crate::node_types::StandardType;
use crate::ser::{Result, Serializer, TypeHint, WriteMode, ARRAY_MASK};
use crate::sixbit::Sixbit;
pub struct Map<'a> {
ser: &'a mut Serializer,
}
impl<'a> Map<'a> {
pub fn new(ser: &'a mut Serializer) -> Result<Self> {
debug!("Map::new()");
// Restrict bounds of immutable borrow from `hierarchy` Vec
{
// The key name would have been pushed to the stack in
// `<Struct as SerializeStruct>::serialize_field` before calling
// `serialize` on the value
let name = if let Some(key) = ser.hierarchy.last() {
trace!("Map::new() => found key name: {}", key);
key
} else {
return Err(KbinErrorKind::InvalidState.into());
};
let node_type = StandardType::NodeStart;
ser.node_buf.write_u8(node_type.id).context(KbinErrorKind::DataWrite(node_type.name))?;
Sixbit::pack(&mut *ser.node_buf, name)?;
}
Ok(Self { ser })
}
}
impl<'a> SerializeMap for Map<'a> {
type Ok = Option<TypeHint>;
type Error = Error;
fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
where K: ?Sized + Serialize,
V: ?Sized + Serialize
{
trace!("--> <Map as SerializeMap>::serialize_entry()");
// Serialize methods that return `None` will not be written
if let Some(hint) = value.serialize(&mut *self.ser)? {
let node_type = hint.node_type;
debug!("SerializeMap::serialize_entry() => hint: {:?}", hint);
// Struct handler outputs `NodeStart` event by itself. Avoid repeating it.
if node_type != StandardType::NodeStart {
self.ser.write_node(hint)?;
self.serialize_key(key)?;
if node_type != StandardType::Attribute {
self.ser.node_buf.write_u8(StandardType::NodeEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("node end"))?;
}
}
}
Ok(())
}
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where T: ?Sized + Serialize
{
trace!("--> <Map as SerializeMap>::serialize_key()");
self.ser.write_mode = WriteMode::Identifier;
let hint = key.serialize(&mut *self.ser)?.ok_or(KbinErrorKind::MissingTypeHint)?;
debug!("<Map as SerializeMap>::serialize_key() => hint: {:?}", hint);
self.ser.write_mode = WriteMode::Single;
match hint.node_type {
StandardType::Attribute |
StandardType::String => Ok(()),
node_type => Err(KbinErrorKind::TypeMismatch(StandardType::String, node_type).into()),
}
}
fn serialize_value<T>(&mut self, _value: &T) -> Result<()>
where T: ?Sized + Serialize
{
trace!("--> <Map as SerializeMap>::serialize_value()");
unimplemented!();
}
fn end(self) -> Result<Self::Ok> {
trace!("<Map as SerializeMap>::end()");
self.ser.node_buf.write_u8(StandardType::NodeEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("node end"))?;
Ok(Some(TypeHint::from_type(StandardType::NodeStart)))
}
}

View File

@@ -1,322 +0,0 @@
use std::io::{Cursor, Write};
use std::result::Result as StdResult;
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use failure::ResultExt;
use serde::ser::{self, Impossible, Serialize};
use crate::byte_buffer::ByteBufferWrite;
use crate::encoding_type::EncodingType;
use crate::node_types::StandardType;
use crate::error::{Error, KbinError, KbinErrorKind};
use crate::sixbit::Sixbit;
use super::{ARRAY_MASK, SIGNATURE, SIG_COMPRESSED};
mod buffer;
mod custom;
mod map;
mod structure;
mod seq;
mod tuple;
use self::custom::Custom;
use self::map::Map;
use self::structure::Struct;
use self::seq::Seq;
use self::tuple::Tuple;
pub type Result<T> = StdResult<T, Error>;
// Writing arrays should not be aligned after each write. Buffer realignment
// should be performed after Writing a single value.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum WriteMode {
Single,
Array,
Identifier,
}
pub struct Serializer {
encoding: EncodingType,
hierarchy: Vec<&'static str>,
write_mode: WriteMode,
node_buf: ByteBufferWrite,
data_buf: ByteBufferWrite,
}
#[derive(Debug)]
pub struct TypeHint {
node_type: StandardType,
is_array: bool,
count: usize,
}
impl TypeHint {
fn from_type(node_type: StandardType) -> Self {
Self {
node_type,
is_array: false,
count: 1,
}
}
}
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where T: Serialize
{
let mut serializer = Serializer {
encoding: EncodingType::SHIFT_JIS,
hierarchy: Vec::new(),
write_mode: WriteMode::Single,
node_buf: ByteBufferWrite::new(Vec::new()),
data_buf: ByteBufferWrite::new(Vec::new()),
};
value.serialize(&mut serializer)?;
let output = serializer.finalize()?;
Ok(output)
}
impl Serializer {
fn finalize(mut self) -> StdResult<Vec<u8>, KbinError> {
let mut header = Cursor::new(Vec::with_capacity(8));
header.write_u8(SIGNATURE).context(KbinErrorKind::HeaderWrite("signature"))?;
header.write_u8(SIG_COMPRESSED).context(KbinErrorKind::HeaderWrite("compression"))?;
let encoding = self.encoding.to_byte();
header.write_u8(encoding).context(KbinErrorKind::HeaderWrite("encoding"))?;
header.write_u8(0xFF ^ encoding).context(KbinErrorKind::HeaderWrite("encoding negation"))?;
self.node_buf.write_u8(StandardType::FileEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("file end"))?;
self.node_buf.realign_writes(None)?;
let mut output = header.into_inner();
let node_buf = self.node_buf.into_inner();
output.write_u32::<BigEndian>(node_buf.len() as u32).context(KbinErrorKind::HeaderWrite("node buffer length"))?;
output.extend_from_slice(&node_buf);
let data_buf = self.data_buf.into_inner();
output.write_u32::<BigEndian>(data_buf.len() as u32).context(KbinErrorKind::HeaderWrite("data buffer length"))?;
output.extend_from_slice(&data_buf);
Ok(output)
}
fn write_node(&mut self, hint: TypeHint) -> Result<()> {
let node_type = hint.node_type;
let array_mask = if hint.is_array { ARRAY_MASK } else { 0 };
self.node_buf.write_u8(node_type.id | array_mask).context(KbinErrorKind::DataWrite(node_type.name))?;
Ok(())
}
fn write_identifier(&mut self, key: &str) -> Result<()> {
Sixbit::pack(&mut *self.node_buf, key)?;
Ok(())
}
}
// `straight_impl` passes a single element array to `write_aligned` where
// `ser_type` will use `BigEndian` to populate a multi-element array for
// `write_aligned`
macro_rules! ser_type {
(byte; $inner_type:ident, $method:ident, $standard_type:ident $($cast:tt)*) => {
fn $method(self, value: $inner_type) -> Result<Self::Ok> {
trace!(concat!("Serializer::", stringify!($method), "(value: {})"), value);
let node_type = StandardType::$standard_type;
match self.write_mode {
WriteMode::Single => {
let value = value $($cast)*;
self.data_buf.write_aligned(*node_type, &[value])?;
},
WriteMode::Array => {
self.data_buf.write_u8(value $($cast)*).context(KbinErrorKind::DataWrite(node_type.name))?;
},
WriteMode::Identifier => return Err(KbinErrorKind::InvalidState.into()),
};
Ok(Some(TypeHint::from_type(node_type)))
}
};
(large; $inner_type:ident, $method:ident, $write_method:ident, $standard_type:ident $($cast:tt)*) => {
fn $method(self, value: $inner_type) -> Result<Self::Ok> {
trace!(concat!("Serializer::", stringify!($method), "(value: {})"), value);
let node_type = StandardType::$standard_type;
match self.write_mode {
WriteMode::Single => {
let mut buf = [0; ::std::mem::size_of::<$inner_type>()];
BigEndian::$write_method(&mut buf, value);
self.data_buf.write_aligned(*node_type, &buf)?;
},
WriteMode::Array => {
self.data_buf.$write_method::<BigEndian>(value $($cast)*).context(KbinErrorKind::DataWrite(node_type.name))?;
},
WriteMode::Identifier => return Err(KbinErrorKind::InvalidState.into()),
};
Ok(Some(TypeHint::from_type(node_type)))
}
}
}
impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = Option<TypeHint>;
type Error = Error;
type SerializeSeq = Seq<'a>;
type SerializeTuple = Tuple<'a>;
type SerializeTupleStruct = Custom<'a>;
type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
type SerializeMap = Map<'a>;
type SerializeStruct = Struct<'a>;
type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
fn is_human_readable(&self) -> bool {
false
}
ser_type!(byte; bool, serialize_bool, Boolean as u8);
ser_type!(byte; u8, serialize_u8, U8);
ser_type!(byte; i8, serialize_i8, S8 as u8);
ser_type!(large; u16, serialize_u16, write_u16, U16);
ser_type!(large; i16, serialize_i16, write_i16, S16);
ser_type!(large; u32, serialize_u32, write_u32, U32);
ser_type!(large; i32, serialize_i32, write_i32, S32);
ser_type!(large; u64, serialize_u64, write_u64, U64);
ser_type!(large; i64, serialize_i64, write_i64, S64);
ser_type!(large; f32, serialize_f32, write_f32, Float);
ser_type!(large; f64, serialize_f64, write_f64, Double);
fn serialize_char(self, value: char) -> Result<Self::Ok> {
trace!("Serializer::serialize_char(value: {})", value);
self.data_buf.write_str(self.encoding, &value.to_string())?;
Ok(Some(TypeHint::from_type(StandardType::String)))
}
fn serialize_str(self, value: &str) -> Result<Self::Ok> {
trace!("Serializer::serialize_str(value: {})", value);
let hint = if value.starts_with("attr_") {
let key = &value["attr_".len()..];
debug!("Serializer::serialize_str(key: {}) => writing as attribute", key);
self.write_identifier(key)?;
Some(TypeHint::from_type(StandardType::Attribute))
} else if self.write_mode == WriteMode::Identifier {
debug!("Serializer::serialize_str(identifier: {}) => writing as identifier", value);
self.write_identifier(value)?;
Some(TypeHint::from_type(StandardType::String))
} else {
self.data_buf.write_str(self.encoding, value)?;
Some(TypeHint::from_type(StandardType::String))
};
Ok(hint)
}
// Binary data is handled separately from other array types.
// Binary data should also be the only element of its node.
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
trace!("Serializer::serialize_bytes(value: {:02x?})", value);
let node_type = StandardType::Binary;
let size = (value.len() as u32) * (node_type.size as u32);
self.data_buf.write_u32::<BigEndian>(size).context(KbinErrorKind::DataWrite("binary node size"))?;
self.data_buf.write_all(value).context(KbinErrorKind::DataWrite("binary"))?;
self.data_buf.realign_writes(None)?;
Ok(Some(TypeHint::from_type(node_type)))
}
// TODO: Figure out a good way to serialize this
fn serialize_none(self) -> Result<Self::Ok> {
trace!("Serializer::serialize_none()");
Ok(None)
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize
{
trace!("Serializer::serialize_some()");
value.serialize(&mut *self)
}
// TODO: Figure out a good way to serialize this
fn serialize_unit(self) -> Result<Self::Ok> {
trace!("Serializer::serialize_unit()");
Err(Error::StaticMessage("unit not supported"))
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
trace!("Serializer::serialize_unit_struct(name: {})", name);
name.serialize(&mut *self)
}
fn serialize_unit_variant(self, name: &'static str, variant_index: u32, variant: &'static str) -> Result<Self::Ok> {
trace!("Serializer::serialize_unit_variant(name: {}, variant_index: {}, variant: {})", name, variant_index, variant);
variant.serialize(&mut *self)
}
fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize
{
trace!("Serializer::serialize_newtype_struct(name: {})", name);
value.serialize(&mut *self)
}
fn serialize_newtype_variant<T>(self, name: &'static str, variant_index: u32, variant: &'static str, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize
{
trace!("Serializer::serialize_newtype_variant(name: {}, variant_index: {}, variant: {})", name, variant_index, variant);
variant.serialize(&mut *self)?;
let hint = value.serialize(&mut *self)?.map(|mut hint| {
hint.is_array = false;
hint
});
Ok(hint)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
trace!("Serializer::serialize_seq(len: {:?})", len);
let len = len.ok_or(Error::StaticMessage("unsized sequences not supported"))?;
Seq::new(self, len)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
trace!("Serializer::serialize_tuple(len: {})", len);
Ok(Tuple::new(self, len))
}
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct> {
trace!("Serializer::serialize_tuple_struct(name: {}, len: {})", name, len);
Custom::new(self, name, len)
}
fn serialize_tuple_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Self::SerializeTupleVariant> {
trace!("Serializer::serialize_tuple_variant(name: {}, variant_index: {}, variant: {}, len: {})", name, variant_index, variant, len);
Err(Error::StaticMessage("tuple variant not supported"))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
trace!("Serializer::serialize_map(len: {:?})", len);
Map::new(self)
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
trace!("Serializer::serialize_struct(name: {}, len: {})", name, len);
Struct::new(self, name, len)
}
fn serialize_struct_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Self::SerializeStructVariant> {
trace!("Serializer::serialize_struct_variant(name: {}, variant_index: {}, variant: {}, len: {})", name, variant_index, variant, len);
Err(Error::StaticMessage("struct variant not supported"))
}
}

View File

@@ -1,84 +0,0 @@
use std::io::{Seek, SeekFrom};
use byteorder::{BigEndian, WriteBytesExt};
use failure::ResultExt;
use serde::ser::{Serialize, SerializeSeq};
use crate::error::KbinErrorKind;
use crate::node_types::StandardType;
use crate::ser::{Error, Result, Serializer, TypeHint, WriteMode};
pub struct Seq<'a> {
ser: &'a mut Serializer,
size_index: u64,
node_type: Option<StandardType>,
len: usize,
}
impl<'a> Seq<'a> {
pub fn new(ser: &'a mut Serializer, len: usize) -> Result<Self> {
trace!("Tuple::new(len: {})", len);
ser.write_mode = WriteMode::Array;
// Estimate u32 for the total size of the tuple
let size_index = ser.data_buf.position();
ser.data_buf.write_u32::<BigEndian>(len as u32).context(KbinErrorKind::DataWrite("size placeholder"))?;
Ok(Self {
ser,
size_index,
node_type: None,
len,
})
}
}
impl<'a> SerializeSeq for Seq<'a> {
type Ok = Option<TypeHint>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
trace!("--> <Seq as SerializeSeq>::serialize_element()");
let hint = value.serialize(&mut *self.ser)?.ok_or(KbinErrorKind::MissingTypeHint)?;
debug!("<-- <Seq as SerializeSeq>::serialize_element() => hint: {:?}", hint);
// Rust tuple types can have different types per element, this is not
// permitted by kbin
if let Some(node_type) = self.node_type {
if node_type != hint.node_type {
return Err(KbinErrorKind::TypeMismatch(node_type, hint.node_type).into());
}
} else {
self.node_type = Some(hint.node_type);
}
Ok(())
}
fn end(self) -> Result<Self::Ok> {
trace!("<-- <Seq as SerializeSeq>::end()");
self.ser.write_mode = WriteMode::Single;
self.ser.data_buf.realign_writes(None)?;
let node_type = self.node_type.ok_or(KbinErrorKind::InvalidState)?;
let size = (self.len as u32) * (node_type.size as u32);
// Update the size estimate from the constructor
if size as usize != self.len {
debug!("<Seq as SerializeSeq>::end() => size correction: {}", size);
let current_pos = self.ser.data_buf.position();
self.ser.data_buf.seek(SeekFrom::Start(self.size_index)).context(KbinErrorKind::Seek)?;
self.ser.data_buf.write_u32::<BigEndian>(size).context(KbinErrorKind::DataWrite("node size"))?;
self.ser.data_buf.seek(SeekFrom::Start(current_pos)).context(KbinErrorKind::Seek)?;
}
Ok(Some(TypeHint { node_type, is_array: true, count: self.len }))
}
}

View File

@@ -1,107 +0,0 @@
use byteorder::WriteBytesExt;
use failure::ResultExt;
use serde::ser::{Serialize, SerializeStruct};
use crate::error::{Error, KbinErrorKind};
use crate::node_types::StandardType;
use crate::ser::{Result, Serializer, TypeHint, ARRAY_MASK};
pub struct Struct<'a> {
ser: &'a mut Serializer,
name: &'static str,
}
impl<'a> Struct<'a> {
pub fn new(ser: &'a mut Serializer, name: &'static str, len: usize) -> Result<Self> {
debug!("Struct::new(name: {}, len: {}) => hierarchy: {:?}", name, len, ser.hierarchy);
// Restrict bounds of immutable borrow from `hierarchy` Vec
{
// The key name would have been pushed to the stack in `serialize_field`
// before calling `serialize` on the value
let name = if let Some(key) = ser.hierarchy.last() {
trace!("Struct::new(name: {}) => found key name: {}", name, key);
key
} else {
name
};
let node_type = StandardType::NodeStart;
ser.node_buf.write_u8(node_type.id).context(KbinErrorKind::DataWrite(node_type.name))?;
ser.write_identifier(name)?;
}
// The `Vec` cannot be borrowed as mutable in an `else` condition because
// of the immutable borrow made in the previous if statement, so this is a
// workaround
ser.hierarchy.push(name);
trace!("Struct::new(name: {}) => hierarchy: {:?}", name, ser.hierarchy);
Ok(Self {
ser,
name,
})
}
}
impl<'a> SerializeStruct for Struct<'a> {
type Ok = Option<TypeHint>;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
// Push key name onto stack so if the value is a struct, it will pick up
// the correct name
self.ser.hierarchy.push(key);
debug!("SerializeStruct(name: {})::serialize_field(key: {}) => hierarchy: {:?}", self.name, key, self.ser.hierarchy);
// Serialize methods that return `None` will not be written
if let Some(hint) = value.serialize(&mut *self.ser)? {
let node_type = hint.node_type;
let array_mask = if hint.is_array { ARRAY_MASK } else { 0 };
debug!("SerializeStruct(name: {})::serialize_field(key: {}) => hint: {:?}", self.name, key, hint);
// Struct handler outputs the `NodeStart` event by itself. Avoid repeating it.
if node_type != StandardType::NodeStart {
// Serialize fields that start with "attr_" as Attribute nodes
let (node_type, key) = if key.starts_with("attr_") {
let key = &key["attr_".len()..];
debug!("SerializeStruct(name: {})::serialize_field(key: {}) => writing as attribute", self.name, key);
// Attribute nodes are always strings
if node_type != StandardType::String {
return Err(KbinErrorKind::TypeMismatch(StandardType::String, node_type).into());
}
(StandardType::Attribute, key)
} else {
(node_type, key)
};
self.ser.node_buf.write_u8(node_type.id | array_mask).context(KbinErrorKind::DataWrite(node_type.name))?;
self.ser.write_identifier(key)?;
if node_type != StandardType::Attribute {
self.ser.node_buf.write_u8(StandardType::NodeEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("node end"))?;
}
}
}
// Pop the name off the stack that was added earlier
let val = self.ser.hierarchy.pop();
debug!("SerializeStruct(name: {})::serialize_field() => popped: {:?}", self.name, val);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
debug!("SerializeStruct(name: {})::end()", self.name);
self.ser.node_buf.write_u8(StandardType::NodeEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("node end"))?;
let val = self.ser.hierarchy.pop();
trace!("SerializeStruct(name: {})::end() => popped: {:?}, hierarchy: {:?}, node_buf: {:02x?}", self.name, val, self.ser.hierarchy, self.ser.node_buf.get_ref());
Ok(Some(TypeHint::from_type(StandardType::NodeStart)))
}
}

View File

@@ -1,79 +0,0 @@
use serde::ser::{Serialize, SerializeTuple};
use crate::error::KbinErrorKind;
use crate::node_types::StandardType;
use crate::ser::{Error, Result, Serializer, TypeHint};
use crate::ser::buffer::BufferSerializer;
/// Tuple handler for serialization.
///
/// Kbin tuple types are monotype (all tuple elements have the same type)
/// which differs from Rust's tuples that can have different types for each
/// element.
///
/// This key difference is what makes it harder to seralize tuples, which is
/// why the `BufferSerializer` is used to serialize tuple elements to an
/// intermediate byte array before running the write logic. Kbin's write logic
/// depends on the size of the type, which is taken care of by
/// `ByteBuffer::write_aligned`.
pub struct Tuple<'a> {
ser: &'a mut Serializer,
buffer: BufferSerializer,
node_type: Option<StandardType>,
len: usize,
}
impl<'a> Tuple<'a> {
pub fn new(ser: &'a mut Serializer, len: usize) -> Self {
trace!("Tuple::new(len: {})", len);
Self {
ser,
buffer: BufferSerializer::new(),
node_type: None,
len,
}
}
fn find_standard_type(&self) -> Result<StandardType> {
let base = self.node_type.ok_or(KbinErrorKind::MissingBaseType)?;
let combined = StandardType::find_type(base, self.len);
debug!("find_standard_type => StandardType::find_type(base: {:?}, len: {}) = {:?}", base, self.len, combined);
Ok(combined)
}
}
impl<'a> SerializeTuple for Tuple<'a> {
type Ok = Option<TypeHint>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
let node_type = value.serialize(&mut self.buffer)?;
// Rust tuple types can have different types per element, this is not
// permitted by kbin
if let Some(known) = self.node_type {
if known != node_type {
return Err(KbinErrorKind::TypeMismatch(known, node_type).into());
}
} else {
self.node_type = Some(node_type);
}
Ok(())
}
fn end(self) -> Result<Self::Ok> {
let node_type = self.find_standard_type()?;
let buffer = self.buffer.into_inner();
debug!("<Tuple as SerializeTuple>::end() => buffer: {:?}, node_type: {:?}", buffer, node_type);
self.ser.data_buf.write_aligned(*node_type, &buffer)?;
Ok(Some(TypeHint::from_type(node_type)))
}
}

View File

@@ -12,18 +12,6 @@ use crate::error::{KbinError, KbinErrorKind};
use crate::node::Node;
use crate::node_types::{self, StandardType};
cfg_if! {
if #[cfg(feature = "serde")] {
use serde::de::{Deserialize, Deserializer, DeserializeSeed};
use serde_bytes::ByteBuf;
pub(crate) mod de;
mod ser;
use crate::node::de::NodeSeed;
}
}
macro_rules! tuple {
(
byte: [
@@ -454,28 +442,6 @@ macro_rules! construct_types {
}
}
}
#[cfg(feature = "serde")]
impl<'de> DeserializeSeed<'de> for StandardType {
type Value = Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: Deserializer<'de>
{
trace!("<StandardType as DeserializeSeed>::deserialize(self: {:?})", self);
match self {
$(
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 => NodeSeed.deserialize(deserializer).map(Box::new).map(Value::Node),
StandardType::NodeEnd |
StandardType::FileEnd => unimplemented!(),
}
}
}
}
}
@@ -677,13 +643,6 @@ impl From<Vec<u8>> for Value {
}
}
#[cfg(feature = "serde")]
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 {
macro_rules! field {

View File

@@ -1,249 +0,0 @@
use std::fmt;
use std::marker::PhantomData;
use serde::de::{Deserialize, Deserializer, EnumAccess, Error, IntoDeserializer, SeqAccess, VariantAccess, Visitor};
use serde::de::value::SeqDeserializer;
use crate::node::Marshal;
use crate::node_types::StandardType;
use crate::value::Value;
impl<'de> Deserialize<'de> for Value {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
trace!("<Value as Deserialize>::deserialize()");
struct ValueVisitor;
macro_rules! visit_rule {
($($method:ident $type:tt $konst:ident),*) => {
$(
#[inline]
fn $method<E>(self, value: $type) -> Result<Self::Value, E> {
trace!("ValueVisitor::{}(value: {:?})", stringify!($method), value);
Ok(Value::$konst(value))
}
)*
};
}
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid kbin value (for Value)")
}
#[inline]
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where E: Error
{
trace!("ValueVisitor::visit_string(value: {:?})", value);
if value.starts_with("attr_") {
Ok(Value::Attribute(String::from(&value["attr_".len()..])))
} else {
Ok(Value::String(value))
}
}
#[inline]
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where E: Error
{
trace!("ValueVisitor::visit_str(value: {:?})", value);
if value.starts_with("attr_") {
Ok(Value::Attribute(String::from(&value["attr_".len()..])))
} else {
Ok(Value::String(String::from(value)))
}
}
#[inline]
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where E: Error
{
trace!("ValueVisitor::visit_bytes(value: 0x{:02x?})", value);
self.visit_byte_buf(value.to_vec())
}
#[inline]
fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> Result<Self::Value, E>
where E: 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);
Ok(Value::Binary(value))
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: Deserializer<'de>
{
trace!("ValueVisitor::visit_some()");
Deserialize::deserialize(deserializer)
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where A: SeqAccess<'de>
{
trace!("ValueVisitor::visit_seq()");
let mut vec = Vec::new();
let mut array_node_type = None;
while let Some(elem) = seq.next_element()? {
let elem: Value = elem;
let node_type = elem.standard_type();
// Ensure that all elements in the `Vec` are of the same `Value` variant
if let Some(array_node_type) = array_node_type {
if array_node_type != node_type {
return Err(A::Error::custom("All values in `Value::Array` must be the same node type"));
}
} else {
array_node_type = Some(node_type);
}
debug!("ValueVisitor::visit_seq() => node_type: {:?}, elem: {:?}", node_type, elem);
vec.push(elem);
}
let array_node_type = array_node_type.ok_or_else(|| A::Error::custom("`Value::Array` must have node type"))?;
Ok(Value::Array(array_node_type, vec))
}
#[inline]
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: Deserializer<'de>
{
trace!("ValueVisitor::visit_newtype_struct()");
let marshal: Marshal = Marshal::deserialize(deserializer)?;
debug!("ValueVisitor::visit_newtype_struct() => marshal: {:?}", marshal);
marshal.into_inner().as_value().ok_or_else(|| D::Error::custom("`Marshal` must contain `Value` not `Node`"))
}
#[inline]
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where A: EnumAccess<'de>
{
trace!("ValueVisitor::visit_enum()");
let (id, access): (u8, _) = data.variant()?;
let node_type = StandardType::from_u8(id);
debug!("ValueVisitor::visit_enum() => id: {}, node_type: {:?}", id, node_type);
let value = access.newtype_variant_seed(node_type)?;
debug!("ValueVisitor::visit_enum() => value: {:?}", value);
Ok(value)
}
visit_rule! {
visit_bool bool Boolean,
visit_i8 i8 S8,
visit_i16 i16 S16,
visit_i32 i32 S32,
visit_i64 i64 S64,
visit_u8 u8 U8,
visit_u16 u16 U16,
visit_u32 u32 U32,
visit_u64 u64 U64,
visit_f32 f32 Float,
visit_f64 f64 Double
}
}
deserializer.deserialize_any(ValueVisitor)
}
}
pub struct ValueDeserializer<E> {
value: Value,
marker: PhantomData<E>,
}
impl<'de, E> Deserializer<'de> for ValueDeserializer<E>
where E: Error
{
type Error = E;
/// Trigger `Ipv4Addr`'s deserializer to use octets rather than a string for
/// deserialization
fn is_human_readable(&self) -> bool {
false
}
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
trace!("ValueDeserializer::deserialize_any(value: {:?})", self.value);
macro_rules! tuple {
($($type:ident),*) => {
match self.value {
Value::S8(n) => visitor.visit_i8(n),
Value::U8(n) => visitor.visit_u8(n),
Value::S16(n) => visitor.visit_i16(n),
Value::U16(n) => visitor.visit_u16(n),
Value::S32(n) => visitor.visit_i32(n),
Value::U32(n) => visitor.visit_u32(n),
Value::S64(n) => visitor.visit_i64(n),
Value::U64(n) => visitor.visit_u64(n),
Value::Binary(buf) => visitor.visit_byte_buf(buf),
Value::String(s) => visitor.visit_string(s),
Value::Ip4(n) => SeqDeserializer::new(n.octets().into_iter().cloned()).deserialize_any(visitor),
Value::Float(n) => visitor.visit_f32(n),
Value::Double(n) => visitor.visit_f64(n),
Value::Boolean(n) => visitor.visit_bool(n),
$(
Value::$type(n) => SeqDeserializer::new(n.into_iter().cloned()).deserialize_any(visitor),
)*
Value::Time(n) => visitor.visit_u32(n),
Value::Attribute(s) => visitor.visit_string(s),
Value::Array(_, v) => SeqDeserializer::new(v.into_iter()).deserialize_any(visitor),
Value::Node(node) => node.into_deserializer().deserialize_any(visitor),
}
};
}
tuple! {
S8_2, U8_2, S16_2, U16_2, S32_2, U32_2, S64_2, U64_2, Float2, Double2, Boolean2,
S8_3, U8_3, S16_3, U16_3, S32_3, U32_3, S64_3, U64_3, Float3, Double3, Boolean3,
S8_4, U8_4, S16_4, U16_4, S32_4, U32_4, S64_4, U64_4, Float4, Double4, Boolean4,
Vs16, Vu16,
Vs8, Vu8, Vb
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct map struct enum identifier ignored_any
}
}
impl<'de, E> IntoDeserializer<'de, E> for Value
where E: Error
{
type Deserializer = ValueDeserializer<E>;
fn into_deserializer(self) -> Self::Deserializer {
ValueDeserializer {
value: self,
marker: PhantomData,
}
}
}

View File

@@ -1,58 +0,0 @@
use serde::ser::{Serialize, SerializeTupleStruct};
use crate::value::Value;
impl Serialize for Value {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ::serde::Serializer
{
trace!("<Value as Serialize>::serialize()");
macro_rules! tuple {
($($type:ident),*) => {
match *self {
Value::S8(ref n) => n.serialize(serializer),
Value::U8(ref n) => n.serialize(serializer),
Value::S16(ref n) => n.serialize(serializer),
Value::U16(ref n) => n.serialize(serializer),
Value::S32(ref n) => n.serialize(serializer),
Value::U32(ref n) => n.serialize(serializer),
Value::S64(ref n) => n.serialize(serializer),
Value::U64(ref n) => n.serialize(serializer),
Value::Binary(ref buf) => buf.serialize(serializer),
Value::String(ref s) => serializer.serialize_str(s),
Value::Ip4(ref v) => {
let mut custom = serializer.serialize_tuple_struct("ip4", 4)?;
custom.serialize_field(v)?;
custom.end()
},
Value::Time(ref n) => {
let mut custom = serializer.serialize_tuple_struct("time", 4)?;
custom.serialize_field(n)?;
custom.end()
},
Value::Float(f) => serializer.serialize_f32(f),
Value::Double(d) => serializer.serialize_f64(d),
Value::Boolean(b) => serializer.serialize_bool(b),
$(
Value::$type(ref v) => v.serialize(serializer),
)*
Value::Attribute(ref s) => serializer.serialize_str(&format!("attr_{}", s)),
Value::Array(_, ref a) => a.serialize(serializer),
Value::Node(ref n) => n.serialize(serializer),
}
};
}
tuple! {
S8_2, U8_2, S16_2, U16_2, S32_2, U32_2, S64_2, U64_2, Float2, Double2, Boolean2,
S8_3, U8_3, S16_3, U16_3, S32_3, U32_3, S64_3, U64_3, Float3, Double3, Boolean3,
S8_4, U8_4, S16_4, U16_4, S32_4, U32_4, S64_4, U64_4, Float4, Double4, Boolean4,
Vs16, Vu16,
Vs8, Vu8, Vb
}
}
}