facet_reflect/peek/
value.rs1use core::cmp::Ordering;
2use facet_core::{Opaque, OpaqueConst, Shape, TypeNameOpts, ValueVTable};
3
4use crate::{Peek, ScalarType};
5
6#[derive(Clone, Copy)]
8pub struct PeekValue<'mem> {
9 data: OpaqueConst<'mem>,
10 shape: &'static Shape,
11}
12impl<'mem> PeekValue<'mem> {
13 pub(crate) unsafe fn unchecked_new(data: OpaqueConst<'mem>, shape: &'static Shape) -> Self {
20 Self { data, shape }
21 }
22
23 #[inline(always)]
25 pub fn vtable(&self) -> &'static ValueVTable {
26 self.shape.vtable
27 }
28
29 #[inline]
35 pub fn eq(&self, other: &PeekValue<'_>) -> Option<bool> {
36 unsafe {
37 self.shape
38 .vtable
39 .eq
40 .map(|eq_fn| eq_fn(self.data, other.data))
41 }
42 }
43
44 #[inline]
50 pub fn partial_cmp(&self, other: &PeekValue<'_>) -> Option<Ordering> {
51 unsafe {
52 self.shape
53 .vtable
54 .partial_ord
55 .and_then(|partial_ord_fn| partial_ord_fn(self.data, other.data))
56 }
57 }
58
59 #[inline]
65 #[expect(clippy::should_implement_trait)]
69 pub fn cmp(&self, other: &PeekValue<'_>) -> Option<Ordering> {
70 unsafe {
71 self.shape
72 .vtable
73 .ord
74 .map(|ord_fn| ord_fn(self.data, other.data))
75 }
76 }
77
78 #[inline]
84 pub fn gt(&self, other: &PeekValue<'_>) -> bool {
85 self.cmp(other)
86 .map(|ordering| ordering == Ordering::Greater)
87 .unwrap_or(false)
88 }
89
90 #[inline]
96 pub fn gte(&self, other: &PeekValue<'_>) -> bool {
97 self.cmp(other)
98 .map(|ordering| ordering == Ordering::Greater || ordering == Ordering::Equal)
99 .unwrap_or(false)
100 }
101
102 #[inline]
108 pub fn lt(&self, other: &PeekValue<'_>) -> bool {
109 self.cmp(other)
110 .map(|ordering| ordering == Ordering::Less)
111 .unwrap_or(false)
112 }
113
114 #[inline(always)]
120 pub fn lte(&self, other: &PeekValue<'_>) -> bool {
121 self.cmp(other)
122 .map(|ordering| ordering == Ordering::Less || ordering == Ordering::Equal)
123 .unwrap_or(false)
124 }
125
126 #[inline(always)]
132 pub fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Option<core::fmt::Result> {
133 unsafe {
134 self.shape
135 .vtable
136 .display
137 .map(|display_fn| display_fn(self.data, f))
138 }
139 }
140
141 #[inline(always)]
147 pub fn debug(&self, f: &mut core::fmt::Formatter<'_>) -> Option<core::fmt::Result> {
148 unsafe {
149 self.shape
150 .vtable
151 .debug
152 .map(|debug_fn| debug_fn(self.data, f))
153 }
154 }
155
156 #[inline(always)]
162 pub fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) -> bool {
163 unsafe {
164 if let Some(hash_fn) = self.shape.vtable.hash {
165 let hasher_opaque = Opaque::new(hasher);
166 hash_fn(self.data, hasher_opaque, |opaque, bytes| {
167 opaque.as_mut::<H>().write(bytes)
168 });
169 true
170 } else {
171 false
172 }
173 }
174 }
175
176 #[inline(always)]
187 pub fn type_name(
188 &self,
189 f: &mut core::fmt::Formatter<'_>,
190 opts: TypeNameOpts,
191 ) -> core::fmt::Result {
192 (self.shape.vtable.type_name)(f, opts)
193 }
194
195 #[inline(always)]
197 pub const fn shape(&self) -> &'static Shape {
198 self.shape
199 }
200
201 #[inline(always)]
203 pub const fn data(&self) -> OpaqueConst<'mem> {
204 self.data
205 }
206
207 #[inline(always)]
209 pub fn wrap(self) -> Peek<'mem> {
210 unsafe { Peek::unchecked_new(self.data, self.shape) }
211 }
212
213 pub fn scalar_type(&self) -> Option<ScalarType> {
215 ScalarType::try_from_shape(self.shape)
216 }
217}
218
219impl core::fmt::Display for PeekValue<'_> {
220 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
221 if let Some(display_fn) = self.vtable().display {
222 unsafe { display_fn(self.data, f) }
223 } else {
224 write!(f, "⟨{}⟩", self.shape)
225 }
226 }
227}
228
229impl core::fmt::Debug for PeekValue<'_> {
230 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
231 if let Some(debug_fn) = self.vtable().debug {
232 unsafe { debug_fn(self.data, f) }
233 } else {
234 write!(f, "⟨{}⟩", self.shape)
235 }
236 }
237}
238
239impl core::cmp::PartialEq for PeekValue<'_> {
240 fn eq(&self, other: &Self) -> bool {
241 if self.shape != other.shape {
242 return false;
243 }
244 let eq_fn = match self.shape.vtable.eq {
245 Some(eq_fn) => eq_fn,
246 None => return false,
247 };
248 unsafe { eq_fn(self.data, other.data) }
249 }
250}
251
252impl core::cmp::PartialOrd for PeekValue<'_> {
253 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
254 if self.shape != other.shape {
255 return None;
256 }
257 let partial_ord_fn = self.shape.vtable.partial_ord?;
258 unsafe { partial_ord_fn(self.data, other.data) }
259 }
260}