use core::{
fmt::{Debug, Formatter},
hash::Hash,
marker::PhantomData,
ops::{Deref, DerefMut},
};
use crate::Format;
#[cfg(feature = "proptest")]
mod proptest;
mod serde;
pub struct Bytes<F: Format> {
inner: Vec<u8>,
_marker: PhantomData<F>,
}
impl<F: Format> Debug for Bytes<F> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Bytes")
.field("inner", &self.inner)
.finish_non_exhaustive()
}
}
impl<F: Format> Clone for Bytes<F> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
_marker: PhantomData,
}
}
}
impl<F: Format, G: Format> PartialEq<Bytes<F>> for Bytes<G> {
fn eq(&self, other: &Bytes<F>) -> bool {
self.inner.eq(&other.inner)
}
}
impl<F: Format> Eq for Bytes<F> {}
impl<F: Format> PartialEq<[u8]> for Bytes<F> {
fn eq(&self, other: &[u8]) -> bool {
self.inner.eq(other)
}
}
impl<F: Format, const N: usize> PartialEq<[u8; N]> for Bytes<F> {
fn eq(&self, other: &[u8; N]) -> bool {
self.inner.eq(other)
}
}
impl<F: Format> PartialEq<Vec<u8>> for Bytes<F> {
fn eq(&self, other: &Vec<u8>) -> bool {
self.inner.eq(other)
}
}
impl<F: Format> From<Vec<u8>> for Bytes<F> {
#[inline]
fn from(inner: Vec<u8>) -> Self {
Self {
inner,
_marker: PhantomData,
}
}
}
impl<F: Format> From<Bytes<F>> for Vec<u8> {
#[inline]
fn from(bytes: Bytes<F>) -> Self {
bytes.inner
}
}
impl<F: Format> FromIterator<u8> for Bytes<F> {
#[inline]
fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
Vec::<u8>::from_iter(iter).into()
}
}
impl<F: Format> IntoIterator for Bytes<F> {
type Item = u8;
type IntoIter = std::vec::IntoIter<u8>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<F: Format> AsRef<[u8]> for Bytes<F> {
#[inline]
fn as_ref(&self) -> &[u8] {
self.inner.as_ref()
}
}
impl<F: Format> AsMut<[u8]> for Bytes<F> {
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
self.inner.as_mut()
}
}
impl<F: Format> AsRef<Vec<u8>> for Bytes<F> {
#[inline]
fn as_ref(&self) -> &Vec<u8> {
&self.inner
}
}
impl<F: Format> AsMut<Vec<u8>> for Bytes<F> {
#[inline]
fn as_mut(&mut self) -> &mut Vec<u8> {
&mut self.inner
}
}
impl<F: Format> Deref for Bytes<F> {
type Target = [u8];
#[inline]
fn deref(&self) -> &Self::Target {
self.inner.deref()
}
}
impl<F: Format> DerefMut for Bytes<F> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner.deref_mut()
}
}
impl<F: Format> PartialOrd for Bytes<F> {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Vec::<u8>::partial_cmp(&self.inner, &other.inner)
}
}
impl<F: Format> Ord for Bytes<F> {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
Vec::<u8>::cmp(&self.inner, &other.inner)
}
}
impl<F: Format> Hash for Bytes<F> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
Vec::<u8>::hash(&self.inner, state)
}
}
impl<F: Format> Default for Bytes<F> {
fn default() -> Self {
Self::new()
}
}
impl<F: Format> Bytes<F> {
#[inline]
pub fn new() -> Self {
Vec::<u8>::new().into()
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Vec::<u8>::with_capacity(capacity).into()
}
#[inline]
pub fn into_inner(self) -> Vec<u8> {
self.inner
}
pub fn convert<G: Format>(self) -> Bytes<G> {
Bytes {
inner: self.inner,
_marker: PhantomData,
}
}
}
#[cfg(test)]
mod tests {
use crate::Plain;
use super::*;
static_assertions::assert_impl_all!(Bytes<Plain>: Debug, Clone, PartialEq, Eq);
}