facet_reflect/peek/
value.rs1use core::cmp::Ordering;
2use facet_core::{Opaque, OpaqueConst, Shape, TypeNameOpts, ValueVTable};
3
4use crate::Peek;
5
6#[derive(Clone, Copy)]
8pub struct PeekValue<'mem> {
9 data: OpaqueConst<'mem>,
10 shape: &'static Shape,
11}
12
13impl core::fmt::Display for PeekValue<'_> {
14 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15 if let Some(display_fn) = self.vtable().display {
16 unsafe { display_fn(self.data, f) }
17 } else {
18 write!(f, "⟨{}⟩", self.shape)
19 }
20 }
21}
22
23impl core::fmt::Debug for PeekValue<'_> {
24 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
25 if let Some(debug_fn) = self.vtable().debug {
26 unsafe { debug_fn(self.data, f) }
27 } else {
28 write!(f, "⟨{}⟩", self.shape)
29 }
30 }
31}
32
33impl core::cmp::PartialEq for PeekValue<'_> {
34 fn eq(&self, other: &Self) -> bool {
35 if self.shape != other.shape {
36 return false;
37 }
38 let eq_fn = match self.shape.vtable.eq {
39 Some(eq_fn) => eq_fn,
40 None => return false,
41 };
42 unsafe { eq_fn(self.data, other.data) }
43 }
44}
45
46impl core::cmp::PartialOrd for PeekValue<'_> {
47 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
48 if self.shape != other.shape {
49 return None;
50 }
51 let partial_ord_fn = self.shape.vtable.partial_ord?;
52 unsafe { partial_ord_fn(self.data, other.data) }
53 }
54}
55
56impl<'mem> PeekValue<'mem> {
57 pub(crate) unsafe fn unchecked_new(data: OpaqueConst<'mem>, shape: &'static Shape) -> Self {
64 Self { data, shape }
65 }
66
67 #[inline(always)]
69 pub fn vtable(&self) -> &'static ValueVTable {
70 self.shape.vtable
71 }
72
73 #[inline]
79 pub fn eq(&self, other: &PeekValue<'_>) -> Option<bool> {
80 unsafe {
81 self.shape
82 .vtable
83 .eq
84 .map(|eq_fn| eq_fn(self.data, other.data))
85 }
86 }
87
88 #[inline]
94 pub fn partial_cmp(&self, other: &PeekValue<'_>) -> Option<Ordering> {
95 unsafe {
96 self.shape
97 .vtable
98 .partial_ord
99 .and_then(|partial_ord_fn| partial_ord_fn(self.data, other.data))
100 }
101 }
102
103 #[inline]
109 #[expect(clippy::should_implement_trait)]
113 pub fn cmp(&self, other: &PeekValue<'_>) -> Option<Ordering> {
114 unsafe {
115 self.shape
116 .vtable
117 .ord
118 .map(|ord_fn| ord_fn(self.data, other.data))
119 }
120 }
121
122 #[inline]
128 pub fn gt(&self, other: &PeekValue<'_>) -> bool {
129 self.cmp(other)
130 .map(|ordering| ordering == Ordering::Greater)
131 .unwrap_or(false)
132 }
133
134 #[inline]
140 pub fn gte(&self, other: &PeekValue<'_>) -> bool {
141 self.cmp(other)
142 .map(|ordering| ordering == Ordering::Greater || ordering == Ordering::Equal)
143 .unwrap_or(false)
144 }
145
146 #[inline]
152 pub fn lt(&self, other: &PeekValue<'_>) -> bool {
153 self.cmp(other)
154 .map(|ordering| ordering == Ordering::Less)
155 .unwrap_or(false)
156 }
157
158 #[inline(always)]
164 pub fn lte(&self, other: &PeekValue<'_>) -> bool {
165 self.cmp(other)
166 .map(|ordering| ordering == Ordering::Less || ordering == Ordering::Equal)
167 .unwrap_or(false)
168 }
169
170 #[inline(always)]
176 pub fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Option<core::fmt::Result> {
177 unsafe {
178 self.shape
179 .vtable
180 .display
181 .map(|display_fn| display_fn(self.data, f))
182 }
183 }
184
185 #[inline(always)]
191 pub fn debug(&self, f: &mut core::fmt::Formatter<'_>) -> Option<core::fmt::Result> {
192 unsafe {
193 self.shape
194 .vtable
195 .debug
196 .map(|debug_fn| debug_fn(self.data, f))
197 }
198 }
199
200 #[inline(always)]
206 pub fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) -> bool {
207 unsafe {
208 if let Some(hash_fn) = self.shape.vtable.hash {
209 let hasher_opaque = Opaque::new(hasher);
210 hash_fn(self.data, hasher_opaque, |opaque, bytes| {
211 opaque.as_mut::<H>().write(bytes)
212 });
213 true
214 } else {
215 false
216 }
217 }
218 }
219
220 #[inline(always)]
231 pub fn type_name(
232 &self,
233 f: &mut core::fmt::Formatter<'_>,
234 opts: TypeNameOpts,
235 ) -> core::fmt::Result {
236 (self.shape.vtable.type_name)(f, opts)
237 }
238
239 #[inline(always)]
241 pub const fn shape(&self) -> &'static Shape {
242 self.shape
243 }
244
245 #[inline(always)]
247 pub const fn data(&self) -> OpaqueConst<'mem> {
248 self.data
249 }
250
251 #[inline(always)]
253 pub fn wrap(self) -> Peek<'mem> {
254 unsafe { Peek::unchecked_new(self.data, self.shape) }
255 }
256}