|
1 | 1 | use core::{cmp::Ordering, mem::size_of, ops::Deref, ptr::copy}; |
2 | 2 |
|
3 | | -use crate::transmute::{cast_slice_unchecked, cast_slice_unchecked_mut, Transmute}; |
| 3 | +use crate::{ |
| 4 | + error::{Result, TranslationError}, |
| 5 | + from_bytes::{FromBytes, FromBytesMut}, |
| 6 | + transmute::{cast_slice_unchecked, cast_slice_unchecked_mut, Transmute}, |
| 7 | +}; |
4 | 8 |
|
5 | 9 | pub trait Prefix: Transmute { |
6 | 10 | fn as_usize(&self) -> usize; |
|
62 | 66 | values: &'a [V], |
63 | 67 | } |
64 | 68 |
|
65 | | -impl<'a, P, V> ArraySet<'a, P, V> |
66 | | -where |
67 | | - P: Prefix, |
68 | | - V: Copy + Clone + Default + PartialOrd + Transmute, |
69 | | -{ |
70 | | - /// Loads a sorted array from its byte representation. |
71 | | - /// |
72 | | - /// # Safety |
73 | | - /// |
74 | | - /// This method does not check the length of the byte slice nor its |
75 | | - /// alignment. The caller must ensure that the byte slice contains a |
76 | | - /// valid representation. |
77 | | - pub unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self { |
78 | | - let (length, values) = bytes.split_at(size_of::<P>()); |
79 | | - Self { |
80 | | - length: P::transmute_unchecked(length), |
81 | | - values: cast_slice_unchecked(values), |
82 | | - } |
83 | | - } |
84 | | -} |
85 | | - |
86 | 69 | /// Macro to implement the read-only interface for an array set type. |
87 | 70 | macro_rules! readonly_impl { |
88 | 71 | ( $name:tt ) => { |
@@ -202,26 +185,11 @@ where |
202 | 185 | values: &'a mut [V], |
203 | 186 | } |
204 | 187 |
|
205 | | -impl<'a, P, V> ArraySetMut<'a, P, V> |
| 188 | +impl<P, V> ArraySetMut<'_, P, V> |
206 | 189 | where |
207 | 190 | P: Prefix, |
208 | 191 | V: Default + Copy + Clone + Ord + Transmute, |
209 | 192 | { |
210 | | - /// Loads a sorted array from its byte representation. |
211 | | - /// |
212 | | - /// # Safety |
213 | | - /// |
214 | | - /// This method does not check the length of the byte slice nor its |
215 | | - /// alignment. The caller must ensure that the byte slice contains a |
216 | | - /// valid representation. |
217 | | - pub unsafe fn from_bytes_unchecked_mut(bytes: &'a mut [u8]) -> Self { |
218 | | - let (length, values) = bytes.split_at_mut(size_of::<P>()); |
219 | | - Self { |
220 | | - length: P::transmute_unchecked_mut(length), |
221 | | - values: cast_slice_unchecked_mut(values), |
222 | | - } |
223 | | - } |
224 | | - |
225 | 193 | /// Returns a mutable reference to the value in the set, if any, that is equal to the |
226 | 194 | /// given value. |
227 | 195 | /// |
@@ -311,6 +279,74 @@ where |
311 | 279 | } |
312 | 280 | } |
313 | 281 |
|
| 282 | +unsafe impl<'a, P, V> FromBytes<'a> for ArraySet<'a, P, V> |
| 283 | +where |
| 284 | + P: Prefix, |
| 285 | + V: Default + Copy + Clone + Ord + Transmute, |
| 286 | +{ |
| 287 | + /// Loads a sorted array from its byte representation. |
| 288 | + fn from_bytes(bytes: &'a [u8]) -> Result<Self> { |
| 289 | + if bytes.len() < size_of::<P>() { |
| 290 | + return Err(TranslationError::InvalidLength); |
| 291 | + } |
| 292 | + |
| 293 | + if align_of_val(bytes) != align_of::<Self>() { |
| 294 | + return Err(TranslationError::InvalidLength); |
| 295 | + } |
| 296 | + |
| 297 | + Ok(unsafe { Self::from_bytes_unchecked(bytes) }) |
| 298 | + } |
| 299 | + |
| 300 | + /// Loads a sorted array from its byte representation. |
| 301 | + /// |
| 302 | + /// # Safety |
| 303 | + /// |
| 304 | + /// This method does not check the length of the byte slice nor its |
| 305 | + /// alignment. The caller must ensure that the byte slice contains a |
| 306 | + /// valid representation. |
| 307 | + unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self { |
| 308 | + let (length, values) = bytes.split_at(size_of::<P>()); |
| 309 | + Self { |
| 310 | + length: P::transmute_unchecked(length), |
| 311 | + values: cast_slice_unchecked(values), |
| 312 | + } |
| 313 | + } |
| 314 | +} |
| 315 | + |
| 316 | +unsafe impl<'a, P, V> FromBytesMut<'a> for ArraySetMut<'a, P, V> |
| 317 | +where |
| 318 | + P: Prefix, |
| 319 | + V: Default + Copy + Clone + Ord + Transmute, |
| 320 | +{ |
| 321 | + /// Loads a sorted array from its byte representation. |
| 322 | + fn from_bytes_mut(bytes: &'a mut [u8]) -> Result<Self> { |
| 323 | + if bytes.len() < size_of::<P>() { |
| 324 | + return Err(TranslationError::InvalidLength); |
| 325 | + } |
| 326 | + |
| 327 | + if align_of_val(bytes) != align_of::<Self>() { |
| 328 | + return Err(TranslationError::InvalidLength); |
| 329 | + } |
| 330 | + |
| 331 | + Ok(unsafe { Self::from_bytes_unchecked_mut(bytes) }) |
| 332 | + } |
| 333 | + |
| 334 | + /// Loads a sorted array from its byte representation. |
| 335 | + /// |
| 336 | + /// # Safety |
| 337 | + /// |
| 338 | + /// This method does not check the length of the byte slice nor its |
| 339 | + /// alignment. The caller must ensure that the byte slice contains a |
| 340 | + /// valid representation. |
| 341 | + unsafe fn from_bytes_unchecked_mut(bytes: &'a mut [u8]) -> Self { |
| 342 | + let (length, values) = bytes.split_at_mut(size_of::<P>()); |
| 343 | + Self { |
| 344 | + length: P::transmute_unchecked_mut(length), |
| 345 | + values: cast_slice_unchecked_mut(values), |
| 346 | + } |
| 347 | + } |
| 348 | +} |
| 349 | + |
314 | 350 | readonly_impl!(ArraySet); |
315 | 351 | readonly_impl!(ArraySetMut); |
316 | 352 |
|
|
0 commit comments