1#[cfg(test)]
2#[path = "../../tests/bytes/static.rs"]
3mod tests;
4
5use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
6use std::hash::{Hash, Hasher};
7use std::sync::Arc;
8
9use crate::bytes::common::ByteBuffer;
10
11#[derive(Clone)]
15pub struct StaticByteBuffer {
16 data: Arc<[u8]>,
17}
18
19impl StaticByteBuffer {
20 #[inline]
22 pub fn from_slice(data: &[u8]) -> Self {
23 Self {
24 data: Arc::from(data),
25 }
26 }
27
28 #[inline]
30 pub fn from_array<const N: usize>(arr: &[u8; N]) -> Self {
31 Self::from_slice(arr.as_slice())
32 }
33
34 #[inline]
36 pub fn empty(size: usize) -> Self {
37 Self {
38 data: Arc::from(vec![0u8; size]),
39 }
40 }
41}
42
43unsafe impl Send for StaticByteBuffer {}
45unsafe impl Sync for StaticByteBuffer {}
46
47impl ByteBuffer for StaticByteBuffer {
48 #[inline]
49 fn len(&self) -> usize {
50 self.data.len()
51 }
52
53 #[inline]
54 fn get(&self, at: usize) -> &u8 {
55 assert!(at < self.len(), "index out of bounds: {} >= {}", at, self.len());
56 &self.data[at]
57 }
58
59 #[inline]
60 fn slice(&self) -> &[u8] {
61 &self.data
62 }
63
64 #[inline]
65 fn slice_start(&self, start: usize) -> &[u8] {
66 assert!(start <= self.len(), "start out of bounds");
67 &self.data[start..]
68 }
69
70 #[inline]
71 fn slice_end(&self, end: usize) -> &[u8] {
72 assert!(end <= self.len(), "end out of bounds");
73 &self.data[..end]
74 }
75
76 #[inline]
77 fn slice_both(&self, start: usize, end: usize) -> &[u8] {
78 assert!(start <= end && end <= self.len(), "invalid slice bounds");
79 &self.data[start..end]
80 }
81
82 #[inline]
83 fn split(&self, divide: usize) -> (&[u8], &[u8]) {
84 assert!(divide <= self.len(), "divide point out of bounds");
85 (&self.data[..divide], &self.data[divide..])
86 }
87}
88
89impl AsRef<[u8]> for StaticByteBuffer {
90 #[inline]
91 fn as_ref(&self) -> &[u8] {
92 &self.data
93 }
94}
95
96impl From<Vec<u8>> for StaticByteBuffer {
97 #[inline]
98 fn from(value: Vec<u8>) -> Self {
99 Self {
100 data: Arc::from(value),
101 }
102 }
103}
104
105impl From<&[u8]> for StaticByteBuffer {
106 #[inline]
107 fn from(value: &[u8]) -> Self {
108 Self::from_slice(value)
109 }
110}
111
112impl<const N: usize> From<&[u8; N]> for StaticByteBuffer {
113 #[inline]
114 fn from(value: &[u8; N]) -> Self {
115 Self::from_array(value)
116 }
117}
118
119impl<const N: usize> From<[u8; N]> for StaticByteBuffer {
120 #[inline]
121 fn from(value: [u8; N]) -> Self {
122 Self::from_array(&value)
123 }
124}
125
126impl From<StaticByteBuffer> for Vec<u8> {
127 #[inline]
128 fn from(val: StaticByteBuffer) -> Self {
129 val.data.to_vec()
130 }
131}
132
133impl From<&StaticByteBuffer> for Vec<u8> {
134 #[inline]
135 fn from(val: &StaticByteBuffer) -> Self {
136 val.data.to_vec()
137 }
138}
139
140impl<const N: usize> From<&StaticByteBuffer> for [u8; N] {
141 #[inline]
142 fn from(val: &StaticByteBuffer) -> Self {
143 match <[u8; N]>::try_from(&val.data[..]) {
144 Ok(res) => res,
145 Err(err) => panic!("error converting StaticByteBuffer to array [u8; {}], actual length {}: {}", N, val.len(), err),
146 }
147 }
148}
149
150impl PartialEq for StaticByteBuffer {
151 #[inline]
152 fn eq(&self, other: &Self) -> bool {
153 self.data == other.data
154 }
155}
156
157impl Eq for StaticByteBuffer {}
158
159impl Hash for StaticByteBuffer {
160 #[inline]
161 fn hash<H: Hasher>(&self, state: &mut H) {
162 self.data.hash(state);
163 }
164}
165
166impl Display for StaticByteBuffer {
167 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
168 for byte in self.data.iter() {
169 write!(f, "{byte:02x}")?;
170 }
171 Ok(())
172 }
173}
174
175impl Debug for StaticByteBuffer {
176 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
177 f.debug_struct("StaticByteBuffer").field("length", &self.len()).field("data", &self.data.as_ref()).finish()
178 }
179}