use std::io::Cursor;
use bufsize::SizeCounter;
use bytes::buf::Chain;
use bytes::Buf;
use bytes::BufMut;
use bytes::Bytes;
use bytes::BytesMut;
use crate::varint;
pub trait BufExt: Buf {
fn copy_or_reuse_bytes(&mut self, len: usize) -> Bytes {
self.copy_to_bytes(len)
}
}
impl BufExt for Bytes {}
impl BufExt for Cursor<Bytes> {
fn copy_or_reuse_bytes(&mut self, len: usize) -> Bytes {
let pos = self.position() as usize;
let end = pos + len;
let bytes = self.get_ref().slice(pos..end);
self.set_position(end as u64);
bytes
}
}
impl<T: AsRef<[u8]> + ?Sized> BufExt for Cursor<&T> {}
impl<T: BufExt, U: BufExt> BufExt for Chain<T, U> {}
pub trait BufMutExt: BufMut {
type Final: Send + 'static;
fn put_varint_u64(&mut self, v: u64)
where
Self: Sized,
{
varint::write_u64(self, v)
}
fn put_varint_i64(&mut self, v: i64)
where
Self: Sized,
{
varint::write_u64(self, varint::zigzag(v))
}
fn finalize(self) -> Self::Final;
}
impl BufMutExt for BytesMut {
type Final = Bytes;
fn finalize(self) -> Self::Final {
self.freeze()
}
}
impl BufMutExt for SizeCounter {
type Final = usize;
#[inline]
fn put_varint_u64(&mut self, v: u64) {
self.put_uint(v, varint::u64_len(v));
}
#[inline]
fn put_varint_i64(&mut self, v: i64) {
self.put_int(v, varint::u64_len(varint::zigzag(v)));
}
#[inline]
fn finalize(self) -> Self::Final {
self.size()
}
}
pub struct DeserializeSource<B: BufExt>(pub(crate) B);
impl<B: BufExt> DeserializeSource<B> {
pub fn new(b: B) -> Self {
DeserializeSource(b)
}
}
macro_rules! impl_deser_as_ref_u8 {
( $($t:ty),* ) => {
$(
impl<'a> From<&'a $t> for DeserializeSource<Cursor<&'a [u8]>> {
fn from(from: &'a $t) -> Self {
let data: &[u8] = from.as_ref();
Self(Cursor::new(data))
}
}
)*
}
}
impl_deser_as_ref_u8!([u8], Vec<u8>, String, str);
macro_rules! impl_deser_into_bytes {
( $($t:ty),* ) => {
$(
impl From<$t> for DeserializeSource<Cursor<Bytes>> {
fn from(from: $t) -> Self {
Self(Cursor::new(from.into()))
}
}
)*
}
}
impl_deser_into_bytes!(Bytes, Vec<u8>, String);
impl From<&Bytes> for DeserializeSource<Cursor<Bytes>> {
fn from(from: &Bytes) -> Self {
Self(Cursor::new(from.clone()))
}
}