facet_reflect/wip/
heap_value.rs1use crate::Peek;
2use crate::ReflectError;
3use crate::trace;
4use core::{alloc::Layout, marker::PhantomData};
5use facet_core::{Facet, PtrConst, PtrMut, Shape};
6#[cfg(feature = "log")]
7use owo_colors::OwoColorize as _;
8
9pub struct HeapValue<'facet, 'shape> {
11 pub(crate) guard: Option<Guard>,
12 pub(crate) shape: &'shape Shape<'shape>,
13 pub(crate) phantom: PhantomData<&'facet ()>,
14}
15
16impl<'facet, 'shape> Drop for HeapValue<'facet, 'shape> {
17 fn drop(&mut self) {
18 if let Some(guard) = self.guard.take() {
19 if let Some(drop_fn) = self.shape.vtable.drop_in_place {
20 unsafe { drop_fn(PtrMut::new(guard.ptr)) };
21 }
22 drop(guard);
23 }
24 }
25}
26
27impl<'facet, 'shape> HeapValue<'facet, 'shape> {
28 pub fn peek(&self) -> Peek<'_, 'facet, 'shape> {
30 unsafe { Peek::unchecked_new(PtrConst::new(self.guard.as_ref().unwrap().ptr), self.shape) }
31 }
32
33 pub fn materialize<T: Facet<'facet>>(mut self) -> Result<T, ReflectError<'shape>> {
35 if self.shape != T::SHAPE {
36 return Err(ReflectError::WrongShape {
37 expected: self.shape,
38 actual: T::SHAPE,
39 });
40 }
41
42 let guard = self.guard.take().unwrap();
43 let data = PtrConst::new(guard.ptr);
44 let res = unsafe { data.read::<T>() };
45 drop(guard); Ok(res)
47 }
48}
49
50impl<'facet, 'shape> HeapValue<'facet, 'shape> {
51 pub fn fmt_display(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53 if let Some(display_fn) = self.shape.vtable.display {
54 unsafe { display_fn(PtrConst::new(self.guard.as_ref().unwrap().ptr), f) }
55 } else {
56 write!(f, "⟨{}⟩", self.shape)
57 }
58 }
59
60 pub fn fmt_debug(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62 if let Some(debug_fn) = self.shape.vtable.debug {
63 unsafe { debug_fn(PtrConst::new(self.guard.as_ref().unwrap().ptr), f) }
64 } else {
65 write!(f, "⟨{}⟩", self.shape)
66 }
67 }
68}
69
70impl<'facet, 'shape> core::fmt::Display for HeapValue<'facet, 'shape> {
71 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72 self.fmt_display(f)
73 }
74}
75
76impl<'facet, 'shape> core::fmt::Debug for HeapValue<'facet, 'shape> {
77 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
78 self.fmt_debug(f)
79 }
80}
81
82impl<'facet, 'shape> PartialEq for HeapValue<'facet, 'shape> {
83 fn eq(&self, other: &Self) -> bool {
84 if self.shape != other.shape {
85 return false;
86 }
87 if let Some(eq_fn) = self.shape.vtable.eq {
88 unsafe {
89 eq_fn(
90 PtrConst::new(self.guard.as_ref().unwrap().ptr),
91 PtrConst::new(other.guard.as_ref().unwrap().ptr),
92 )
93 }
94 } else {
95 false
96 }
97 }
98}
99
100impl<'facet, 'shape> PartialOrd for HeapValue<'facet, 'shape> {
101 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
102 if self.shape != other.shape {
103 return None;
104 }
105 if let Some(partial_ord_fn) = self.shape.vtable.partial_ord {
106 unsafe {
107 partial_ord_fn(
108 PtrConst::new(self.guard.as_ref().unwrap().ptr),
109 PtrConst::new(other.guard.as_ref().unwrap().ptr),
110 )
111 }
112 } else {
113 None
114 }
115 }
116}
117
118pub struct Guard {
124 pub(crate) ptr: *mut u8,
126 pub(crate) layout: Layout,
128}
129
130impl Drop for Guard {
131 fn drop(&mut self) {
132 if self.layout.size() != 0 {
133 trace!(
134 "Deallocating memory at ptr: {:p}, size: {}, align: {}",
135 self.ptr.cyan(),
136 self.layout.size().yellow(),
137 self.layout.align().green()
138 );
139 unsafe { alloc::alloc::dealloc(self.ptr, self.layout) };
141 }
142 }
143}