1use std::any::Any;
9use std::ops::Range;
10use std::ops::RangeBounds;
11use std::sync::Arc;
12use std::sync::Weak;
13
14pub type Bytes = AbstractBytes<[u8]>;
15pub trait BytesOwner: AsRef<[u8]> + Send + Sync + 'static {}
16
17pub type WeakBytes = Weak<dyn AbstractOwner<[u8]>>;
18
19pub struct AbstractBytes<T: ?Sized> {
21 pub(crate) ptr: *const u8,
22 pub(crate) len: usize,
23
24 pub(crate) owner: Option<Arc<dyn AbstractOwner<T>>>,
26}
27
28pub trait AbstractOwner<T: ?Sized>: AsRef<T> + Send + Sync + 'static {
30 fn as_any_mut(&mut self) -> &mut dyn Any;
31}
32
33impl<T: BytesOwner> AbstractOwner<[u8]> for T {
34 fn as_any_mut(&mut self) -> &mut dyn Any {
35 self
36 }
37}
38
39unsafe impl<T: ?Sized> Send for AbstractBytes<T> {}
41unsafe impl<T: ?Sized> Sync for AbstractBytes<T> {}
42
43impl<T: ?Sized> Clone for AbstractBytes<T> {
46 fn clone(&self) -> Self {
47 Self {
48 ptr: self.ptr,
49 len: self.len,
50 owner: self.owner.clone(),
51 }
52 }
53}
54
55impl<T> AbstractBytes<T>
57where
58 T: SliceLike + ?Sized,
59 T::Owned: AbstractOwner<T>,
60{
61 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
64 use std::ops::Bound;
65 let start = match range.start_bound() {
66 Bound::Included(&n) => n,
67 Bound::Excluded(&n) => n + 1,
68 Bound::Unbounded => 0,
69 };
70 let end = match range.end_bound() {
71 Bound::Included(&n) => n + 1,
72 Bound::Excluded(&n) => n,
73 Bound::Unbounded => self.len,
74 };
75 assert!(start <= end, "invalid slice {}..{}", start, end);
76 assert!(end <= self.len, "{} exceeds Bytes length {}", end, self.len);
77 if start == end {
78 Self::new()
79 } else {
80 T::check_slice_bytes(self.as_bytes(), start, end);
81 Self {
82 ptr: unsafe { self.ptr.add(start) },
83 len: end - start,
84 owner: self.owner.clone(),
85 }
86 }
87 }
88
89 pub fn slice_to_bytes(&self, slice: &T) -> Self {
95 match self.range_of_slice(slice) {
96 Some(range) => self.slice(range),
97 None => Self::copy_from_slice(slice),
98 }
99 }
100
101 pub fn range_of_slice(&self, slice: &T) -> Option<Range<usize>> {
109 let slice_start = slice.as_ptr() as usize;
110 let slice_end = slice_start + slice.len();
111 let bytes_start = self.ptr as usize;
112 let bytes_end = bytes_start + self.len;
113 if slice_start >= bytes_start && slice_end <= bytes_end {
114 let start = slice_start - bytes_start;
115 Some(start..start + slice.len())
116 } else {
117 None
118 }
119 }
120
121 #[inline]
123 pub fn new() -> Self {
124 let empty = T::EMPTY.as_bytes();
125 Self {
126 ptr: empty.as_ptr(),
127 len: empty.len(),
128 owner: None,
129 }
130 }
131
132 pub fn from_owner(value: impl AbstractOwner<T>) -> Self {
134 let slice: &T = value.as_ref();
135 let bytes = slice.as_bytes();
136 Self {
137 ptr: bytes.as_ptr(),
138 len: bytes.len(),
139 owner: Some(Arc::new(value)),
140 }
141 }
142
143 pub fn copy_from_slice(data: &T) -> Self {
145 Self::from_owner(data.to_owned())
146 }
147
148 #[inline]
149 pub(crate) fn as_bytes(&self) -> &[u8] {
150 unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
151 }
152
153 pub fn downgrade(&self) -> Option<Weak<dyn AbstractOwner<T>>> {
156 self.owner.as_ref().map(Arc::downgrade)
157 }
158
159 pub fn upgrade(weak: &Weak<dyn AbstractOwner<T>>) -> Option<Self> {
162 let arc = weak.upgrade()?;
163 let slice_like: &T = arc.as_ref().as_ref();
164 Some(Self {
165 ptr: slice_like.as_ptr(),
166 len: slice_like.len(),
167 owner: Some(arc),
168 })
169 }
170}
171
172impl Bytes {
173 #[inline]
174 pub(crate) fn as_slice(&self) -> &[u8] {
175 self.as_bytes()
176 }
177
178 pub const fn from_static(slice: &'static [u8]) -> Self {
180 Self {
181 ptr: slice.as_ptr(),
182 len: slice.len(),
183 owner: None,
184 }
185 }
186
187 pub fn into_vec(mut self) -> Vec<u8> {
189 let len = self.len();
190
191 'zero_copy: {
192 let arc_owner = match self.owner.as_mut() {
193 None => break 'zero_copy,
194 Some(owner) => owner,
195 };
196 let owner = match Arc::get_mut(arc_owner) {
197 None => break 'zero_copy,
198 Some(owner) => owner,
199 };
200 let any = owner.as_any_mut();
201 let mut maybe_vec = any.downcast_mut::<Vec<u8>>();
202 match maybe_vec {
203 Some(ref mut owner) if owner.len() == len => {
204 let mut result: Vec<u8> = Vec::new();
205 std::mem::swap(&mut result, owner);
206 return result;
207 }
208 _ => break 'zero_copy,
209 }
210 }
211
212 self.as_slice().to_vec()
213 }
214}
215
216#[cfg(feature = "non-zerocopy-into")]
217impl From<Bytes> for Vec<u8> {
218 fn from(value: Bytes) -> Vec<u8> {
219 value.into_vec()
220 }
221}
222
223pub trait SliceLike: 'static {
224 type Owned;
225 const EMPTY: &'static Self;
226
227 fn as_bytes(&self) -> &[u8];
228 fn to_owned(&self) -> Self::Owned;
229
230 #[inline]
231 fn check_slice_bytes(bytes: &[u8], start: usize, end: usize) {
232 let _ = (bytes, start, end);
233 }
234
235 #[inline]
236 fn len(&self) -> usize {
237 self.as_bytes().len()
238 }
239
240 #[inline]
241 fn as_ptr(&self) -> *const u8 {
242 self.as_bytes().as_ptr()
243 }
244}
245
246impl SliceLike for [u8] {
247 type Owned = Vec<u8>;
248 const EMPTY: &'static Self = b"";
249
250 #[inline]
251 fn as_bytes(&self) -> &[u8] {
252 self
253 }
254 #[inline]
255 fn to_owned(&self) -> Self::Owned {
256 self.to_vec()
257 }
258}