use {
self::{deserializer::SequenceDeserializer, errors::Result},
byteorder::{BigEndian, ReadBytesExt},
serde::{de::Visitor, Deserialize},
std::io::{Cursor, Read},
};
pub use self::errors::{CompatDeserializationError, DeserializationError};
pub struct Deserializer<'r, R>
where
R: ReadBytesExt + 'r,
{
reader: &'r mut R,
}
impl<'r, R> Deserializer<'r, R>
where
R: ReadBytesExt + 'r,
{
pub fn new(reader: &'r mut R) -> Self {
Deserializer { reader }
}
fn deserialize_integer(&mut self, bits: u8) -> Result<i32> {
let value = self.reader.read_i32::<BigEndian>().map_err(|error| {
DeserializationError::io_error(
format!("signed {}-bit integer", bits),
error,
)
})?;
let most_significant_bit: u32 = 1 << (bits - 1);
let max_value = (most_significant_bit - 1) as i32;
let min_value = -max_value - 1;
if value >= min_value && value <= max_value {
Ok(value)
} else {
Err(DeserializationError::InvalidInteger { bits, value }.into())
}
}
fn deserialize_unsigned_integer(&mut self, bits: u8) -> Result<u32> {
let value = self.reader.read_u32::<BigEndian>().map_err(|error| {
DeserializationError::io_error(
format!("unsigned {}-bit integer", bits),
error,
)
})?;
let most_significant_bit: u64 = 1 << bits;
let max_value = (most_significant_bit - 1) as u32;
ensure!(
value <= max_value,
DeserializationError::InvalidUnsignedInteger { bits, value }
);
Ok(value)
}
fn deserialize_sequence<'de, V, S>(
&mut self,
visitor: V,
type_name: S,
length: u32,
) -> Result<V::Value>
where
V: Visitor<'de>,
S: AsRef<str>,
{
let type_name = type_name.as_ref();
let deserializer = SequenceDeserializer::new(length, &type_name, self);
Ok(visitor.visit_seq(deserializer)?)
}
fn deserialize_opaque(&mut self, type_name: &str) -> Result<Vec<u8>> {
let length = self.reader.read_u32::<BigEndian>().map_err(|error| {
DeserializationError::io_error(type_name, error)
})?;
let padding_size = 4 - (length + 3) % 4 - 1;
let buffer_length = length + padding_size;
let mut buffer = Vec::with_capacity(buffer_length as usize);
buffer.resize(buffer_length as usize, 0);
self.reader.read_exact(&mut buffer).map_err(|error| {
DeserializationError::io_error(type_name, error)
})?;
buffer.truncate(length as usize);
Ok(buffer)
}
}
pub fn from_reader<'de, 'r, R, T>(reader: &'r mut R) -> Result<T>
where
R: Read,
T: Deserialize<'de>,
{
let mut deserializer = Deserializer::new(reader);
Ok(T::deserialize(&mut deserializer)?)
}
pub fn from_bytes<'de, B, T>(bytes: B) -> Result<T>
where
B: AsRef<[u8]>,
T: Deserialize<'de>,
{
let mut reader = Cursor::new(bytes);
from_reader(&mut reader)
}
mod deserializer;
mod errors;