ab_core_primitives/pieces/
cow_bytes.rs

1use bytes::{Bytes, BytesMut};
2use core::hash::{Hash, Hasher};
3use core::{fmt, mem};
4
5pub(super) enum CowBytes {
6    Shared(Bytes),
7    Owned(BytesMut),
8}
9
10impl fmt::Debug for CowBytes {
11    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12        for byte in self.as_ref() {
13            write!(f, "{byte:02x}")?;
14        }
15        Ok(())
16    }
17}
18
19impl PartialEq for CowBytes {
20    fn eq(&self, other: &Self) -> bool {
21        self.as_ref().eq(other.as_ref())
22    }
23}
24
25impl Eq for CowBytes {}
26
27impl Hash for CowBytes {
28    fn hash<H: Hasher>(&self, state: &mut H) {
29        self.as_ref().hash(state)
30    }
31}
32
33impl Clone for CowBytes {
34    fn clone(&self) -> Self {
35        match self {
36            Self::Shared(bytes) => Self::Shared(bytes.clone()),
37            // Always return shared clone
38            Self::Owned(bytes) => Self::Shared(Bytes::copy_from_slice(bytes)),
39        }
40    }
41}
42
43impl AsRef<[u8]> for CowBytes {
44    fn as_ref(&self) -> &[u8] {
45        match self {
46            CowBytes::Shared(bytes) => bytes.as_ref(),
47            CowBytes::Owned(bytes) => bytes.as_ref(),
48        }
49    }
50}
51
52impl AsMut<[u8]> for CowBytes {
53    #[inline]
54    fn as_mut(&mut self) -> &mut [u8] {
55        match self {
56            CowBytes::Shared(bytes) => {
57                *self = CowBytes::Owned(BytesMut::from(mem::take(bytes)));
58
59                let CowBytes::Owned(bytes) = self else {
60                    unreachable!("Just replaced; qed");
61                };
62
63                bytes.as_mut()
64            }
65            CowBytes::Owned(bytes) => bytes.as_mut(),
66        }
67    }
68}