// SPDX-License-Identifier: AGPL-3.0-or-later //! This module contains the [Reader] trait which enables zero-copy deserialization over //! different input types. use crate::{error::MapError, Error, Result}; use std::{io::Read, ops::DerefMut}; pub trait Reader<'de> { /// Reads exactly enough bytes to fill the given buffer or returns an error. fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>; /// Returns true if the `borrow_bytes` method is supported by this instance. fn can_borrow() -> bool; /// Borrows the given number of bytes from this [Reader] starting at the current position. fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]>; } impl<'de, R: ?Sized + Reader<'de>, P: DerefMut> Reader<'de> for P { fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { self.deref_mut().read_exact(buf) } fn can_borrow() -> bool { R::can_borrow() } fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]> { self.deref_mut().borrow_bytes(len) } } /// An adapter over an implementation of the standard library [Read] trait. pub struct ReadAdapter(R); impl ReadAdapter { pub fn new(read: R) -> Self { Self(read) } } impl<'de, R: Read> Reader<'de> for ReadAdapter { fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { self.0.read_exact(buf).map_error() } fn can_borrow() -> bool { false } fn borrow_bytes(&mut self, _len: usize) -> Result<&'de [u8]> { Err(Error::NotSupported("borrowing from a ReadAdapter")) } } /// An adapter for reading out of a slice of bytes. pub struct SliceAdapter<'a>(&'a [u8]); impl<'a> SliceAdapter<'a> { pub fn new(slice: &'a [u8]) -> Self { Self(slice) } fn assert_longer_than(&self, buf_len: usize) -> Result<()> { if self.0.len() >= buf_len { Ok(()) } else { Err(Error::Eof) } } } impl<'de> Reader<'de> for SliceAdapter<'de> { fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { let buf_len = buf.len(); self.assert_longer_than(buf_len)?; buf.copy_from_slice(&self.0[..buf_len]); self.0 = &self.0[buf_len..]; Ok(()) } fn can_borrow() -> bool { true } fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]> { self.assert_longer_than(len)?; let borrow = &self.0[..len]; self.0 = &self.0[len..]; Ok(borrow) } }