1#[cfg(feature = "alloc")]
2use crate::utils::alloc::AlignedBytes;
3use crate::{
4 emplacer::Emplacer,
5 error::Error,
6 traits::{Flat, FlatDefault},
7};
8#[cfg(feature = "alloc")]
9use alloc::{boxed::Box, ffi::CString, rc::Rc, string::String, sync::Arc, vec::Vec};
10use core::{
11 cell::{Ref, RefMut},
12 marker::PhantomData,
13 mem::ManuallyDrop,
14 ops::{Deref, DerefMut},
15 pin::Pin,
16};
17use stavec::{
18 traits::{Container, Length},
19 GenericVec,
20};
21
22pub unsafe trait TrustedDeref: Deref {}
29
30pub struct FlatWrap<F: Flat + ?Sized, P: TrustedDeref<Target = [u8]>> {
32 pointer: P,
33 _ghost: PhantomData<F>,
34}
35
36impl<F: Flat + ?Sized, P: TrustedDeref<Target = [u8]>> FlatWrap<F, P> {
37 pub unsafe fn from_wrapped_bytes_unchecked(pointer: P) -> Self {
38 Self {
39 pointer,
40 _ghost: PhantomData,
41 }
42 }
43 pub fn into_inner(self) -> P {
44 self.pointer
45 }
46
47 pub fn from_wrapped_bytes(pointer: P) -> Result<Self, Error> {
48 F::validate(&pointer)?;
49 Ok(unsafe { Self::from_wrapped_bytes_unchecked(pointer) })
50 }
51
52 pub fn new_in_place(mut pointer: P, emplacer: impl Emplacer<F>) -> Result<Self, Error>
53 where
54 P: DerefMut,
55 {
56 F::new_in_place(&mut pointer, emplacer)?;
57 Ok(unsafe { Self::from_wrapped_bytes_unchecked(pointer) })
58 }
59 pub fn default_in_place(pointer: P) -> Result<Self, Error>
60 where
61 P: DerefMut,
62 F: FlatDefault,
63 {
64 Self::new_in_place(pointer, F::default_emplacer())
65 }
66}
67
68impl<F: Flat + ?Sized, P: TrustedDeref<Target = [u8]>> Deref for FlatWrap<F, P> {
69 type Target = F;
70 fn deref(&self) -> &Self::Target {
71 unsafe { F::from_bytes_unchecked(&self.pointer) }
72 }
73}
74impl<F: Flat + ?Sized, P: TrustedDeref<Target = [u8]> + DerefMut> DerefMut for FlatWrap<F, P> {
75 fn deref_mut(&mut self) -> &mut Self::Target {
76 unsafe { F::from_mut_bytes_unchecked(&mut self.pointer) }
77 }
78}
79
80unsafe impl<'a, T: ?Sized> TrustedDeref for &'a T {}
81unsafe impl<'a, T: ?Sized> TrustedDeref for &'a mut T {}
82
83unsafe impl<P: Deref> TrustedDeref for Pin<P> {}
84unsafe impl<T: ?Sized> TrustedDeref for ManuallyDrop<T> {}
85unsafe impl<'a, T: ?Sized> TrustedDeref for Ref<'a, T> {}
86unsafe impl<'a, T: ?Sized> TrustedDeref for RefMut<'a, T> {}
87#[cfg(feature = "alloc")]
88unsafe impl<T: ?Sized> TrustedDeref for Box<T> {}
89#[cfg(feature = "alloc")]
90unsafe impl<T: ?Sized> TrustedDeref for Rc<T> {}
91#[cfg(feature = "alloc")]
92unsafe impl<T: ?Sized> TrustedDeref for Arc<T> {}
93
94#[cfg(feature = "alloc")]
95unsafe impl<T> TrustedDeref for Vec<T> {}
96#[cfg(feature = "alloc")]
97unsafe impl TrustedDeref for String {}
98#[cfg(feature = "alloc")]
99unsafe impl TrustedDeref for CString {}
100
101unsafe impl<C: Container + ?Sized, L: Length> TrustedDeref for GenericVec<C, L> {}
102#[cfg(feature = "alloc")]
103unsafe impl TrustedDeref for AlignedBytes {}
104
105#[cfg(all(test, feature = "std"))]
106mod tests {
107 use super::*;
108 use crate::{utils::alloc::AlignedBytes, vec::FlatVec};
109
110 #[test]
111 fn wrapped_vec() {
112 let mut wrap = FlatWrap::<FlatVec<u8, u16>, _>::default_in_place(AlignedBytes::new(2 + 4, 2)).unwrap();
113
114 assert_eq!(wrap.capacity(), 4);
115 assert_eq!(wrap.len(), 0);
116 assert_eq!(wrap.remaining(), 4);
117
118 assert_eq!(wrap.extend_from_slice(&[1, 2]), 2);
119 assert_eq!(wrap.len(), 2);
120 assert_eq!(wrap.remaining(), 2);
121 assert_eq!(wrap.as_slice(), [1, 2].as_slice());
122
123 assert_eq!(wrap.extend_from_slice(&[3, 4, 5]), 2);
124 assert_eq!(wrap.len(), 4);
125 assert_eq!(wrap.remaining(), 0);
126 assert_eq!(wrap.as_slice(), [1, 2, 3, 4].as_slice());
127
128 let bytes = wrap.into_inner();
129 assert_eq!(bytes.deref(), [4, 0, 1, 2, 3, 4].as_slice())
130 }
131}