serde-xdr 0.6.0

XDR serialization and deserialization for Serde
Documentation
use {
    super::super::{
        errors::{CompatDeserializationError, DeserializationError, Result},
        Deserializer,
    },
    byteorder::ReadBytesExt,
    serde::de::{DeserializeSeed, SeqAccess},
};

pub struct SequenceDeserializer<'a, 'r, 's, R, S>
where
    'r: 'a,
    R: ReadBytesExt + 'r,
    S: ToString + 's,
{
    length: u32,
    type_name: &'s S,
    current_index: u32,
    deserializer: &'a mut Deserializer<'r, R>,
}

impl<'a, 'r, 's, R, S> SequenceDeserializer<'a, 'r, 's, R, S>
where
    'r: 'a,
    R: ReadBytesExt + 'r,
    S: ToString,
{
    pub fn new(
        length: u32,
        type_name: &'s S,
        deserializer: &'a mut Deserializer<'r, R>,
    ) -> Self {
        SequenceDeserializer {
            length,
            type_name,
            deserializer,
            current_index: 0,
        }
    }
}

impl<'a, 'de, 'r, 's, R, S> SeqAccess<'de>
    for SequenceDeserializer<'a, 'r, 's, R, S>
where
    'r: 'a,
    R: ReadBytesExt + 'r,
    S: ToString,
{
    type Error = CompatDeserializationError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        if self.current_index < self.length {
            let value =
                seed.deserialize(&mut *self.deserializer).map_err(|error| {
                    deserialize_error(self.type_name, self.current_index, error)
                })?;

            self.current_index += 1;

            Ok(Some(value))
        } else {
            Ok(None)
        }
    }

    fn size_hint(&self) -> Option<usize> {
        Some(self.length as usize)
    }
}

fn deserialize_error<S>(
    type_name: &S,
    index: u32,
    cause: CompatDeserializationError,
) -> DeserializationError
where
    S: ToString,
{
    DeserializationError::failure(
        format!("element {} of type {}", index, type_name.to_string()),
        cause,
    )
}

#[cfg(test)]
mod tests;