use value::{Element, Content};
use error::{Error, ErrorCode};
use serde::de;
use std::{vec, mem};
use std::collections::btree_map;
pub struct Deserializer {
value: Option<Element>,
}
impl Deserializer {
pub fn new(value: Element) -> Deserializer {
Deserializer {
value: Some(value),
}
}
}
impl de::Deserializer for Deserializer {
type Error = Error;
#[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
use self::MapDeserializerState::*;
debug!("value::Deserializer::deserialize {:?}", self.value);
let el = match self.value.take() {
Some(value) => value,
None => { return Err(de::Error::end_of_stream()); }
};
match (el.attributes.is_empty(), el.members) {
(true, Content::Text(s)) => visitor.visit_string(s),
(true, Content::Nothing) => visitor.visit_unit(),
(_, m) => visitor.visit_map( MapDeserializer {
attributes: el.attributes
.into_iter()
.map(|(k, v)| (k, v.into_iter()))
.collect(),
state: Inner,
members: m,
}),
}
}
#[inline]
fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
debug!("value::Deserializer::deserialize_option");
if self.value.is_none() {
return Err(de::Error::end_of_stream());
};
if self.value == Some(Element::new_empty()) {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
#[inline]
fn deserialize_enum<V>(&mut self, _name: &str, _variants: &'static [&'static str], mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
debug!("value::Deserializer::deserialize_enum");
visitor.visit(VariantVisitor(self.value.take()))
}
#[inline]
fn deserialize_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
use self::MapDeserializerState::*;
debug!("value::Deserializer::deserialize_map {:?}", self.value);
let el = match self.value.take() {
Some(value) => value,
None => { return Err(de::Error::end_of_stream()); }
};
visitor.visit_map(MapDeserializer {
attributes: el.attributes
.into_iter()
.map(|(k, v)| (k, v.into_iter()))
.collect(),
state: Inner,
members: el.members,
})
}
}
struct VariantVisitor(Option<Element>);
impl de::VariantVisitor for VariantVisitor
{
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
where V: de::Deserialize
{
debug!("VariantVisitor::visit_variant");
if let Some(s) = self.0.as_mut().unwrap().attributes.remove("xsi:type") {
de::Deserialize::deserialize(&mut StringDeserializer(s.into_iter().next()))
} else {
return Err(Error::SyntaxError(ErrorCode::Expected("attribute xsi:type"), 0, 0));
}
}
fn visit_unit(&mut self) -> Result<(), Self::Error> {
Ok(())
}
fn visit_tuple<V>(&mut self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor
{
unimplemented!()
}
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
where T: de::Deserialize,
{
debug!("newtype deserialization");
let element = self.0.take().unwrap();
de::Deserialize::deserialize(&mut Deserializer::new(element))
}
fn visit_struct<V>(&mut self, _fields: &'static [&'static str], mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor
{
let element = self.0.take().unwrap();
visitor.visit_map(MapDeserializer {
attributes: element.attributes
.into_iter()
.map(|(k, v)| (k, v.into_iter()))
.collect(),
state: MapDeserializerState::Inner,
members: element.members,
})
}
}
struct SeqDeserializer<I: Iterator<Item=Element> + ExactSizeIterator>(I);
impl<I> de::Deserializer for SeqDeserializer<I>
where I: Iterator<Item=Element>,
I: ExactSizeIterator,
{
type Error = Error;
#[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
debug!("seqdeserializer::deserialize");
if let Some(el) = self.0.next() {
debug!("el");
de::Deserialize::deserialize(&mut Deserializer::new(el))
} else {
debug!("unit");
visitor.visit_unit()
}
}
#[inline]
fn deserialize_enum<V>(&mut self, _name: &str, _variants: &'static [&'static str], mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
debug!("value::Deserializer::deserialize_enum");
visitor.visit(VariantVisitor(self.0.next()))
}
#[inline]
fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
debug!("seqdeserializer::deserialize_seq");
visitor.visit_seq(self)
}
}
impl<I> de::SeqVisitor for SeqDeserializer<I>
where I: Iterator<Item=Element>,
I: ExactSizeIterator,
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize
{
debug!("SeqDeserializer::deserialize");
match self.0.next() {
Some(value) => {
debug!("value: {:?}", value);
de::Deserialize::deserialize(&mut Deserializer::new(value))
.map(|v| Some(v))
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), Error> {
debug!("SeqDeserializer::end");
if self.0.len() == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.0.len(), Some(self.0.len()))
}
}
struct StringDeserializer(Option<String>);
impl de::Deserializer for StringDeserializer {
type Error = Error;
#[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_string(self.0.take().unwrap())
}
}
#[derive(PartialEq, Debug)]
enum MapDeserializerState {
Inner,
Done,
}
struct MapDeserializer {
attributes: btree_map::BTreeMap<String, vec::IntoIter<String>>,
members: Content,
state: MapDeserializerState,
}
impl de::MapVisitor for MapDeserializer {
type Error = Error;
fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize
{
Ok(None)
}
fn visit_value<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize
{
unreachable!()
}
fn end(&mut self) -> Result<(), Error> {
debug!("value::MapDeserializer::end");
Ok(())
}
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Error>
where V: de::Deserialize,
{
use self::MapDeserializerState::*;
debug!("value::MapDeserializer::missing_field {:?} {}", self.state, field);
struct UnitDeserializer;
impl de::Deserializer for UnitDeserializer {
type Error = Error;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
}
fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_none()
}
}
match self.state {
Inner if field == "$value" => {
debug!("value");
self.state = Done;
match mem::replace(&mut self.members, Content::Nothing) {
Content::Text(s) =>
de::Deserialize::deserialize(&mut StringDeserializer(Some(s))),
Content::Nothing =>
de::Deserialize::deserialize(&mut UnitDeserializer),
Content::Members(_) => Err(Error::MissingFieldError("inner text")),
}
},
Inner => if let Some(v) = self.attributes.remove(field) {
debug!("attr");
de::Deserialize::deserialize(&mut SeqDeserializer(v.map(|s| Element::new_text(s))))
} else if let Content::Members(ref mut m) = self.members {
if let Some(el) = m.remove(field) {
debug!("el: {:?}", el);
de::Deserialize::deserialize(&mut SeqDeserializer(el.into_iter()))
} else {
de::Deserialize::deserialize(&mut UnitDeserializer)
}
} else {
de::Deserialize::deserialize(&mut UnitDeserializer)
},
Done => de::Deserialize::deserialize(&mut UnitDeserializer),
}
}
}
impl de::Deserializer for MapDeserializer {
type Error = Error;
#[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
debug!("MapDeserializer!");
visitor.visit_map(self)
}
}