#[cfg(feature = "json")]
use super::Result;
use std::io;
use std::result::Result as StdResult;
#[cfg(feature = "fs")]
use std::path::Path;
use bytes::{
Offset, Cursor, Bytes, BytesRead, BytesReadRef, BytesWrite, BytesSeek
};
#[cfg(feature = "json")]
use serde::{Serialize, de::DeserializeOwned};
#[cfg(feature = "fs")]
use tokio::fs::{self, File};
#[cfg(feature = "fs")]
use tokio::io::AsyncReadExt;
pub struct BodyBytes<'a> {
inner: Bytes<'a>
}
impl<'a> BodyBytes<'a> {
pub fn new(slice: &'a [u8]) -> Self {
Self { inner: slice.into() }
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn inner(&self) -> &'a [u8] {
self.inner.inner()
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub fn deserialize<D>(&self) -> Result<D>
where D: DeserializeOwned {
serde_json::from_slice(self.inner.as_slice())
.map_err(|e| e.into())
}
#[cfg(feature = "fs")]
#[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
pub async fn to_file<P>(&mut self, path: P) -> Result<()>
where P: AsRef<Path> {
fs::write(path, self.as_slice()).await
.map_err(|e| e.into())
}
}
impl BytesRead for BodyBytes<'_> {
#[inline]
fn as_slice(&self) -> &[u8] {
self.inner.as_slice()
}
#[inline]
fn remaining(&self) -> &[u8] {
self.inner.remaining()
}
#[inline]
fn try_read(&mut self, len: usize) -> StdResult<&[u8], bytes::ReadError> {
self.inner.try_read(len)
}
#[inline]
fn peek(&self, len: usize) -> Option<&[u8]> {
self.inner.peek(len)
}
}
impl<'a> BytesReadRef<'a> for BodyBytes<'a> {
#[inline]
fn as_slice_ref(&self) -> &'a [u8] {
self.inner.as_slice_ref()
}
#[inline]
fn remaining_ref(&self) -> &'a [u8] {
self.inner.remaining_ref()
}
#[inline]
fn try_read_ref(
&mut self,
len: usize
) -> StdResult<&'a [u8], bytes::ReadError> {
self.inner.try_read_ref(len)
}
#[inline]
fn peek_ref(&self, len: usize) -> Option<&'a [u8]> {
self.inner.peek_ref(len)
}
}
impl BytesSeek for BodyBytes<'_> {
fn position(&self) -> usize {
self.inner.position()
}
fn try_seek(&mut self, pos: usize) -> StdResult<(), bytes::SeekError> {
self.inner.try_seek(pos)
}
}
pub struct BodyBytesMut<'a> {
inner: Offset<Cursor<&'a mut Vec<u8>>>
}
impl<'a> BodyBytesMut<'a> {
pub fn new(offset: usize, buffer: &'a mut Vec<u8>) -> Self {
Self {
inner: Offset::new(Cursor::new(buffer), offset)
}
}
pub fn resize(&mut self, len: usize) {
let offset = self.inner.offset();
unsafe {
self.as_mut_vec().resize(offset + len, 0);
}
}
pub fn reserve(&mut self, len: usize) {
let offset = self.inner.offset();
unsafe {
self.as_mut_vec().reserve(offset + len);
}
}
pub fn len(&self) -> usize {
self.inner.len()
}
#[cfg(feature = "json")]
pub fn serialize<S: ?Sized>(&mut self, value: &S) -> Result<()>
where S: Serialize {
serde_json::to_writer(self, value)
.map_err(|e| e.into())
}
#[cfg(feature = "fs")]
pub async fn from_file<P>(&mut self, path: P) -> Result<()>
where P: AsRef<Path> {
let mut file = File::open(path).await?;
let buf_size = file.metadata().await
.map(|m| m.len() as usize + 1)
.unwrap_or(0);
self.reserve(buf_size);
unsafe {
let v = self.as_mut_vec();
file.read_to_end(v).await?;
}
Ok(())
}
#[doc(hidden)]
pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
self.inner.inner_mut().inner_mut()
}
}
impl BytesWrite for BodyBytesMut<'_> {
fn as_mut(&mut self) -> &mut [u8] {
self.inner.as_mut()
}
fn as_bytes(&self) -> Bytes<'_> {
self.inner.as_bytes()
}
fn remaining_mut(&mut self) -> &mut [u8] {
self.inner.remaining_mut()
}
fn try_write(
&mut self,
slice: impl AsRef<[u8]>
) -> StdResult<(), bytes::WriteError> {
self.inner.try_write(slice)
}
}
impl BytesSeek for BodyBytesMut<'_> {
fn position(&self) -> usize {
self.inner.position()
}
fn try_seek(&mut self, pos: usize) -> StdResult<(), bytes::SeekError> {
self.inner.try_seek(pos)
}
}
impl io::Write for BodyBytesMut<'_> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}