use core::fmt;
use core::convert::Infallible;
#[cfg(feature = "bytes")] use bytes::{Bytes, BytesMut};
#[cfg(feature = "std")] use std::borrow::Cow;
#[cfg(feature = "std")] use std::vec::Vec;
pub trait OctetsRef: AsRef<[u8]> + Copy + Sized {
type Range: AsRef<[u8]>;
fn range(self, start: usize, end: usize) -> Self::Range;
fn range_from(self, start: usize) -> Self::Range {
self.range(start, self.as_ref().len())
}
fn range_to(self, end: usize) -> Self::Range {
self.range(0, end)
}
fn range_all(self) -> Self::Range {
self.range(0, self.as_ref().len())
}
}
impl<'a, T: OctetsRef> OctetsRef for &'a T {
type Range = T::Range;
fn range(self, start: usize, end: usize) -> Self::Range {
(*self).range(start, end)
}
}
impl<'a> OctetsRef for &'a [u8] {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self[start..end]
}
}
#[cfg(feature = "std")]
impl<'a, 's> OctetsRef for &'a Cow<'s, [u8]> {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self.as_ref()[start..end]
}
}
#[cfg(feature = "std")]
impl<'a> OctetsRef for &'a Vec<u8> {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self[start..end]
}
}
#[cfg(feature = "bytes")]
impl<'a> OctetsRef for &'a Bytes {
type Range = Bytes;
fn range(self, start: usize, end: usize) -> Self::Range {
self.slice(start..end)
}
}
#[cfg(feature = "smallvec")]
impl<'a, A: smallvec::Array<Item = u8>>
OctetsRef for &'a smallvec::SmallVec<A>
{
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self.as_slice()[start..end]
}
}
pub trait Truncate {
fn truncate(&mut self, len: usize);
}
impl<'a> Truncate for &'a [u8] {
fn truncate(&mut self, len: usize) {
if len < self.len() {
*self = &self[..len]
}
}
}
#[cfg(feature = "std")]
impl<'a> Truncate for Cow<'a, [u8]> {
fn truncate(&mut self, len: usize) {
match *self {
Cow::Borrowed(ref mut slice) => *slice = &slice[..len],
Cow::Owned(ref mut vec) => vec.truncate(len),
}
}
}
#[cfg(feature = "std")]
impl Truncate for Vec<u8> {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
#[cfg(feature = "bytes")]
impl Truncate for Bytes {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
#[cfg(feature = "smallvec")]
impl<A: smallvec::Array<Item = u8>> Truncate for smallvec::SmallVec<A> {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
pub trait OctetsFrom<Source>: Sized {
type Error;
fn try_octets_from(source: Source) -> Result<Self, Self::Error>;
fn octets_from(source: Source) -> Self
where Self::Error: Into<Infallible> {
match Self::try_octets_from(source) {
Ok(ok) => ok,
Err(_) => unreachable!()
}
}
}
impl<'a, Source: AsRef<[u8]> + 'a> OctetsFrom<&'a Source> for &'a [u8] {
type Error = Infallible;
fn try_octets_from(source: &'a Source) -> Result<Self, Self::Error> {
Ok(source.as_ref())
}
}
#[cfg(feature = "std")]
impl<Source> OctetsFrom<Source> for Vec<u8>
where
Self: From<Source>,
{
type Error = Infallible;
fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
Ok(From::from(source))
}
}
#[cfg(feature = "bytes")]
impl<Source> OctetsFrom<Source> for Bytes
where
Self: From<Source>,
{
type Error = Infallible;
fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
Ok(From::from(source))
}
}
#[cfg(feature = "bytes")]
impl<Source> OctetsFrom<Source> for BytesMut
where
Self: From<Source>,
{
type Error = Infallible;
fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
Ok(From::from(source))
}
}
#[cfg(features = "smallvec")]
impl<Source, A> OctetsFrom<Source> for smallvec::SmallVec<A>
where
Source: AsRef<u8>,
A: Array<Item = u8>,
{
type Error = Infallible;
fn try_octets_from(source: Source) -> Result<Self, Self::Infallible> {
Ok(smallvec::ToSmallVec::to_smallvec(source.as_ref()))
}
}
pub trait OctetsInto<Target>: Sized {
type Error;
fn try_octets_into(self) -> Result<Target, Self::Error>;
fn octets_into(self) -> Target
where Self::Error: Into<Infallible> {
match self.try_octets_into() {
Ok(ok) => ok,
Err(_) => unreachable!()
}
}
}
impl<Source, Target: OctetsFrom<Source>> OctetsInto<Target> for Source {
type Error = <Target as OctetsFrom<Source>>::Error;
fn try_octets_into(self) -> Result<Target, Self::Error> {
Target::try_octets_from(self)
}
}
pub trait OctetsBuilder {
type Octets: AsRef<[u8]>;
type AppendError;
fn try_append_slice(
&mut self, slice: &[u8]
) -> Result<(), Self::AppendError>;
fn freeze(self) -> Self::Octets
where Self: Sized;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn append_slice(&mut self, slice: &[u8])
where Self::AppendError: Into<Infallible> {
let _ = self.try_append_slice(slice);
}
fn try_append_all<F>(&mut self, op: F) -> Result<(), Self::AppendError>
where
Self: Truncate,
F: FnOnce(&mut Self) -> Result<(), Self::AppendError>,
{
let pos = self.len();
match op(self) {
Ok(_) => Ok(()),
Err(err) => {
self.truncate(pos);
Err(err)
}
}
}
}
#[cfg(feature = "std")]
impl OctetsBuilder for Vec<u8> {
type Octets = Self;
type AppendError = Infallible;
fn try_append_slice(
&mut self, slice: &[u8]
) -> Result<(), Self::AppendError> {
self.extend_from_slice(slice);
Ok(())
}
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
fn freeze(self) -> Self::Octets {
self
}
}
#[cfg(feature = "std")]
impl<'a> OctetsBuilder for Cow<'a, [u8]> {
type Octets = Self;
type AppendError = Infallible;
fn try_append_slice(
&mut self, slice: &[u8]
) -> Result<(), Self::AppendError> {
if let Cow::Owned(ref mut vec) = *self {
vec.extend_from_slice(slice);
} else {
let mut vec = std::mem::replace(
self, Cow::Borrowed(b"")
).into_owned();
vec.extend_from_slice(slice);
*self = Cow::Owned(vec);
}
Ok(())
}
fn len(&self) -> usize {
self.as_ref().len()
}
fn is_empty(&self) -> bool {
self.as_ref().is_empty()
}
fn freeze(self) -> Self::Octets {
self
}
}
#[cfg(feature = "bytes")]
impl OctetsBuilder for BytesMut {
type Octets = Bytes;
type AppendError = Infallible;
fn try_append_slice(
&mut self, slice: &[u8]
) -> Result<(), Self::AppendError> {
self.extend_from_slice(slice);
Ok(())
}
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
fn freeze(self) -> Self::Octets {
self.freeze()
}
}
#[cfg(feature = "smallvec")]
impl<A: smallvec::Array<Item = u8>> OctetsBuilder for smallvec::SmallVec<A> {
type Octets = Self;
type AppendError = Infallible;
fn try_append_slice(
&mut self, slice: &[u8]
) -> Result<(), Self::AppendError> {
self.extend_from_slice(slice);
Ok(())
}
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
fn freeze(self) -> Self::Octets {
self
}
}
pub trait EmptyBuilder {
fn empty() -> Self;
fn with_capacity(capacity: usize) -> Self;
}
#[cfg(feature = "std")]
impl EmptyBuilder for Vec<u8> {
fn empty() -> Self {
Vec::new()
}
fn with_capacity(capacity: usize) -> Self {
Vec::with_capacity(capacity)
}
}
#[cfg(feature = "bytes")]
impl EmptyBuilder for BytesMut {
fn empty() -> Self {
BytesMut::new()
}
fn with_capacity(capacity: usize) -> Self {
BytesMut::with_capacity(capacity)
}
}
#[cfg(feature = "smallvec")]
impl<A: smallvec::Array<Item = u8>> EmptyBuilder for smallvec::SmallVec<A> {
fn empty() -> Self {
smallvec::SmallVec::new()
}
fn with_capacity(capacity: usize) -> Self {
smallvec::SmallVec::with_capacity(capacity)
}
}
pub trait IntoBuilder {
type Builder: OctetsBuilder;
fn into_builder(self) -> Self::Builder;
}
#[cfg(feature = "std")]
impl IntoBuilder for Vec<u8> {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
#[cfg(feature = "std")]
impl<'a> IntoBuilder for &'a [u8] {
type Builder = Vec<u8>;
fn into_builder(self) -> Self::Builder {
self.into()
}
}
#[cfg(feature = "std")]
impl<'a> IntoBuilder for Cow<'a, [u8]> {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
#[cfg(feature = "bytes")]
impl IntoBuilder for Bytes {
type Builder = BytesMut;
fn into_builder(self) -> Self::Builder {
BytesMut::from(self.as_ref())
}
}
#[cfg(feature = "smallvec")]
impl<A: smallvec::Array<Item = u8>> IntoBuilder for smallvec::SmallVec<A> {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
pub trait FromBuilder: AsRef<[u8]> + Sized {
type Builder: OctetsBuilder<Octets = Self>;
fn from_builder(builder: Self::Builder) -> Self;
}
#[cfg(feature = "std")]
impl FromBuilder for Vec<u8> {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
#[cfg(feature = "std")]
impl<'a> FromBuilder for Cow<'a, [u8]> {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
#[cfg(feature = "bytes")]
impl FromBuilder for Bytes {
type Builder = BytesMut;
fn from_builder(builder: Self::Builder) -> Self {
builder.freeze()
}
}
#[cfg(feature = "smallvec")]
impl<A: smallvec::Array<Item = u8>> FromBuilder for smallvec::SmallVec<A> {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ShortBuf;
impl fmt::Display for ShortBuf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("buffer size exceeded")
}
}
#[cfg(feature = "std")]
impl std::error::Error for ShortBuf {}
#[cfg(test)]
mod test {
}