# and [`Deserialize`](::serde::Deserialize)."
)]
#![cfg_attr(
not(feature = "serde"),
doc = "- `serde` — implements `Serialize` and `Deserialize`."
)]
#![doc = " Add `#[serde(borrow)]` to struct fields holding `CowBytes<'a>` to allow"]
#![doc = " zero-copy deserialization from input data."]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
mod buf;
mod cmp;
mod convert;
mod iter;
#[cfg(feature = "serde")]
mod serde;
use alloc::vec::Vec;
use core::borrow::Borrow;
use core::ops::{Deref, RangeBounds};
use bytes::Bytes;
#[derive(Clone, Debug)]
pub enum CowBytes<'a> {
Borrowed(&'a [u8]),
Shared(Bytes),
}
impl CowBytes<'_> {
#[must_use]
#[inline]
pub const fn new() -> Self {
Self::Borrowed(&[])
}
#[must_use]
#[inline]
pub const fn from_static(bytes: &'static [u8]) -> Self {
Self::Shared(Bytes::from_static(bytes))
}
#[must_use]
#[inline]
pub fn as_slice(&self) -> &[u8] {
match self {
Self::Borrowed(bytes) => bytes,
Self::Shared(bytes) => bytes,
}
}
#[must_use]
#[inline]
pub fn len(&self) -> usize {
self.as_slice().len()
}
#[must_use]
#[inline]
pub fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
#[must_use]
#[inline]
pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
let range = (range.start_bound().cloned(), range.end_bound().cloned());
match self {
Self::Borrowed(bytes) => Self::Borrowed(&bytes[range]),
Self::Shared(bytes) => Self::Shared(bytes.slice(range)),
}
}
#[must_use = "use `truncate` to discard the bytes beyond `at`"]
#[inline]
pub fn split_off(&mut self, at: usize) -> Self {
match self {
Self::Borrowed(bytes) => {
let (head, tail) = bytes.split_at(at);
*bytes = head;
Self::Borrowed(tail)
}
Self::Shared(bytes) => Self::Shared(bytes.split_off(at)),
}
}
#[must_use = "use `advance` from `Buf` to discard the bytes before `at`"]
#[inline]
pub fn split_to(&mut self, at: usize) -> Self {
match self {
Self::Borrowed(bytes) => {
let (head, tail) = bytes.split_at(at);
*bytes = tail;
Self::Borrowed(head)
}
Self::Shared(bytes) => Self::Shared(bytes.split_to(at)),
}
}
#[inline]
pub fn truncate(&mut self, len: usize) {
match self {
Self::Borrowed(bytes) => {
if len < bytes.len() {
*bytes = &bytes[..len];
}
}
Self::Shared(bytes) => bytes.truncate(len),
}
}
#[inline]
pub fn clear(&mut self) {
self.truncate(0);
}
#[inline]
pub fn with_mut<R>(&mut self, f: impl FnOnce(&mut [u8]) -> R) -> R {
let mut bytes = core::mem::replace(self, Self::Borrowed(&[])).into_vec();
let result = f(&mut bytes);
*self = Self::Shared(Bytes::from(bytes));
result
}
#[must_use]
#[inline]
pub fn into_bytes(self) -> Bytes {
Bytes::from(self)
}
#[must_use]
#[inline]
pub fn into_static(self) -> CowBytes<'static> {
match self {
Self::Borrowed(bytes) => CowBytes::Shared(Bytes::copy_from_slice(bytes)),
Self::Shared(bytes) => CowBytes::Shared(bytes),
}
}
#[must_use]
#[inline]
pub fn into_vec(self) -> Vec<u8> {
match self {
Self::Borrowed(bytes) => bytes.to_vec(),
Self::Shared(bytes) => bytes
.try_into_mut()
.map_or_else(|bytes| bytes.to_vec(), Into::into),
}
}
}
impl Default for CowBytes<'_> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl Deref for CowBytes<'_> {
type Target = [u8];
#[inline]
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl AsRef<[u8]> for CowBytes<'_> {
#[inline]
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl Borrow<[u8]> for CowBytes<'_> {
#[inline]
fn borrow(&self) -> &[u8] {
self.as_slice()
}
}
#[cfg(all(doctest, feature = "std"))]
#[doc = include_str!("../README.md")]
struct ReadmeDoctests;