serde-xml-rs2 0.3.0

xml-rs based deserializer for Serde (compatible with 0.9+)
Documentation
use std::io::Read;

use serde::de;
use xml::reader::XmlEvent;

use de::Deserializer;
use error::{Error, ErrorKind, Result};

pub struct SeqAccess<'a, R: 'a + Read> {
    de: &'a mut Deserializer<R>,
    max_size: Option<usize>,
    expected_name: Option<String>,
}

impl<'a, R: 'a + Read> SeqAccess<'a, R> {
    pub fn new(de: &'a mut Deserializer<R>, max_size: Option<usize>) -> Result<Self> {
        let expected_name: Result<Option<String>> = if de.unset_map_value() {
            match de.peek() {
                Ok(&XmlEvent::StartElement { ref name, .. }) => Ok(Some(name.local_name.clone())),
                Ok(&XmlEvent::EndElement { .. }) => Ok(None),
                other => Err(
                    ErrorKind::Custom(format!(
                        "Expected StartElement or EndElement, found {:?}",
                        other
                    )).into(),
                ),
            }
        } else {
            Ok(None)
        };
        let expected_name = expected_name?;
        Ok(SeqAccess {
            de: de,
            max_size: max_size,
            expected_name: expected_name,
        })
    }
}

impl<'de, 'a, R: 'a + Read> de::SeqAccess<'de> for SeqAccess<'a, R> {
    type Error = Error;

    fn next_element_seed<T: de::DeserializeSeed<'de>>(
        &mut self,
        seed: T,
    ) -> Result<Option<T::Value>> {
        match self.max_size.as_mut() {
            Some(&mut 0) => {
                return Ok(None);
            },
            Some(max_size) => {
                *max_size -= 1;
            },
            None => {},
        }
        let more = match (self.de.peek()?, self.expected_name.as_ref()) {
            (&XmlEvent::StartElement { ref name, .. }, Some(expected_name)) => {
                &name.local_name == expected_name
            },
            (&XmlEvent::EndElement { .. }, None) |
            (_, Some(_)) |
            (&XmlEvent::EndDocument { .. }, _) => false,
            (_, None) => true,
        };
        if more {
            if self.expected_name.is_some() {
                self.de.set_map_value();
            }
            seed.deserialize(&mut *self.de).map(Some)
        } else {
            Ok(None)
        }
    }

    fn size_hint(&self) -> Option<usize> {
        self.max_size
    }
}