binbuf/
bytes_ptr.rs

1use std::ops::{self, Index, IndexMut, RangeBounds};
2use crate::{private::Sealed, utils::{slice_to_array, slice_to_array_mut}};
3
4pub trait Instance
5    : Clone + Copy + Sized
6    + Index<usize, Output = u8>
7    + Sealed
8{
9    // Doesn't check if range is out of bounds.
10    unsafe fn range_at(self, at: usize, len: usize) -> Self;
11    unsafe fn range(self, start: usize, end: usize) -> Self;
12    unsafe fn range_from(self, start: usize) -> Self;
13    fn len(self) -> usize;
14    fn to_const(self) -> Const;
15}
16
17#[derive(Clone, Copy)]
18pub struct Const {
19    ptr: *const u8,
20    len: usize,
21}
22
23impl Instance for Const {
24    unsafe fn range_at(self, at: usize, len: usize) -> Self {
25        Self {
26            ptr: self.slice().get_unchecked(at .. at + len).as_ptr(),
27            len,
28        }
29    }
30
31    unsafe fn range(self, start: usize, end: usize) -> Self {
32        let slice = self.slice().get_unchecked(start .. end);
33        Self { ptr: slice.as_ptr(), len: slice.len() }
34    }
35
36    unsafe fn range_from(self, start: usize) -> Self {
37        let slice = self.slice().get_unchecked(start ..);
38        Self { ptr: slice.as_ptr(), len: slice.len() }
39    }
40
41    fn to_const(self) -> Const {
42        self
43    }
44    
45    fn len(self) -> usize {
46        self.len
47    }
48}
49
50impl Sealed for Const {}
51
52impl<'a> From<Const> for &'a [u8] {
53    fn from(value: Const) -> Self {
54        value.slice()
55    }
56}
57
58impl Index<usize> for Const {
59    type Output = u8;
60    fn index(&self, index: usize) -> &Self::Output {
61        self.slice().index(index)
62    }
63}
64
65impl Const {
66    pub unsafe fn new(ptr: *const u8, len: usize) -> Self {
67        Self { ptr, len }
68    }
69
70    // Ensure this ptr is of correct length.
71    // pub unsafe fn decode<T: crate::entry::Codable>(self) -> T {
72    //     T::decode(T::buf(self))
73    // }
74
75    pub unsafe fn cast_to_ref<'a, T>(self) -> &'a T {
76        &*self.ptr.cast::<T>()
77    }
78
79    pub unsafe fn from_slice(slice: &[u8]) -> Self {
80        Self { ptr: slice.as_ptr(), len: slice.len() }
81    }
82
83    pub fn slice<'a>(self) -> &'a [u8] {
84        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
85    }
86
87    // Doesn't check if length is correct.
88    pub unsafe fn array<'a, const L: usize>(self) -> &'a [u8; L] {
89        slice_to_array(self.slice())
90    }
91
92    pub fn copy_to(self, dst: Mut) {
93        dst.copy_from(self)
94    }
95
96    // Doesn't check if index is valid.
97    // pub unsafe fn get<I: SliceIndex<u8>>(self, index: I) -> &I::Output {
98    //     self.slice().get_unchecked(index)
99    // }
100}
101
102#[derive(Clone, Copy)]
103pub struct Mut {
104    ptr: *mut u8,
105    len: usize,
106}
107
108impl Sealed for Mut {}
109
110impl<'a> From<Mut> for &'a [u8] {
111    fn from(value: Mut) -> Self {
112        &*value.slice()
113    }
114}
115
116impl<'a> From<Mut> for &'a mut [u8] {
117    fn from(value: Mut) -> Self {
118        value.slice()
119    }
120}
121
122impl Instance for Mut {
123    unsafe fn range_at(self, at: usize, len: usize) -> Self {
124        Self {
125            ptr: self.slice()[at .. at + len].as_mut_ptr(),
126            len,
127        }
128    }
129
130    unsafe fn range(self, start: usize, end: usize) -> Self {
131        let slice = self.slice().get_unchecked_mut(start .. end);
132        Self { ptr: slice.as_mut_ptr(), len: slice.len() }
133    }
134
135    unsafe fn range_from(self, start: usize) -> Self {
136        let slice = self.slice().get_unchecked_mut(start ..);
137        Self { ptr: slice.as_mut_ptr(), len: slice.len() }
138    }
139
140    fn to_const(self) -> Const {
141        unsafe { Const::new(self.ptr as *const _, self.len) }
142    }
143
144    fn len(self) -> usize {
145        self.len
146    }
147}
148
149impl Index<usize> for Mut {
150    type Output = u8;
151    fn index(&self, index: usize) -> &Self::Output {
152        self.slice().index(index)
153    }
154}
155
156impl IndexMut<usize> for Mut {
157    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
158        self.slice().index_mut(index)
159    }
160}
161
162impl Mut {
163    pub unsafe fn new(ptr: *mut u8, len: usize) -> Self {
164        Self { ptr, len }
165    }
166
167    pub unsafe fn from_slice(slice: &mut [u8]) -> Self {
168        Self { ptr: slice.as_mut_ptr(), len: slice.len() }
169    }
170
171    pub unsafe fn cast_to_ref<'a, T>(self) -> &'a mut T {
172        &mut *self.ptr.cast::<T>()
173    }
174
175    // Ensure this ptr is of correct length.
176    // pub unsafe fn encode<T: entry::Codable>(self, value: &T) {
177    //     T::encode(value, T::buf(self))
178    // }
179
180    pub fn slice<'a>(self) -> &'a mut [u8] {
181        unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
182    }
183
184    // Doesn't check if length is correct.
185    pub unsafe fn array<'a, const L: usize>(self) -> &'a mut [u8; L] {
186        slice_to_array_mut(self.slice())
187    }
188
189    pub fn fill(self, value: u8) {
190        self.slice().fill(value)
191    }
192
193    pub fn fill_with(self, value: impl FnMut() -> u8) {
194        self.slice().fill_with(value)
195    }
196
197    pub fn copy_within<R: RangeBounds<usize>>(self, src: R, dest: usize) {
198        self.slice().copy_within(src, dest)
199    }
200
201    pub fn copy_from(self, src: Const) {
202        self.slice().copy_from_slice(src.slice())
203    }
204
205    pub fn copy_from_slice(self, slice: &[u8]) {
206        self.slice().copy_from_slice(slice);
207    }
208
209    pub fn swap(self, with: Mut) {
210        self.slice().swap_with_slice(with.slice())
211    }
212}