facet_reflect/poke/
result.rs1use core::mem::ManuallyDrop;
2
3use facet_core::{Facet, PtrUninit, ResultDef, ResultVTable};
4
5use crate::{HeapValue, ReflectError, ReflectErrorKind};
6
7use super::Poke;
8
9pub struct PokeResult<'mem, 'facet> {
11 value: Poke<'mem, 'facet>,
12 def: ResultDef,
13}
14
15impl<'mem, 'facet> core::fmt::Debug for PokeResult<'mem, 'facet> {
16 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17 f.debug_struct("PokeResult").finish_non_exhaustive()
18 }
19}
20
21impl<'mem, 'facet> PokeResult<'mem, 'facet> {
22 #[inline]
30 pub const unsafe fn new(value: Poke<'mem, 'facet>, def: ResultDef) -> Self {
31 Self { value, def }
32 }
33
34 fn err_reflect(&self, kind: ReflectErrorKind) -> ReflectError {
35 self.value.err(kind)
36 }
37
38 #[inline(always)]
40 pub const fn def(&self) -> ResultDef {
41 self.def
42 }
43
44 #[inline(always)]
46 pub const fn vtable(&self) -> &'static ResultVTable {
47 self.def.vtable
48 }
49
50 #[inline]
52 pub fn is_ok(&self) -> bool {
53 unsafe { (self.vtable().is_ok)(self.value.data()) }
54 }
55
56 #[inline]
58 pub fn is_err(&self) -> bool {
59 !self.is_ok()
60 }
61
62 #[inline]
64 pub fn ok(&self) -> Option<crate::Peek<'_, 'facet>> {
65 unsafe {
66 let inner_data = (self.vtable().get_ok)(self.value.data());
67 if inner_data.is_null() {
68 None
69 } else {
70 Some(crate::Peek::unchecked_new(
71 facet_core::PtrConst::new_sized(inner_data),
72 self.def.t(),
73 ))
74 }
75 }
76 }
77
78 #[inline]
80 pub fn err(&self) -> Option<crate::Peek<'_, 'facet>> {
81 unsafe {
82 let inner_data = (self.vtable().get_err)(self.value.data());
83 if inner_data.is_null() {
84 None
85 } else {
86 Some(crate::Peek::unchecked_new(
87 facet_core::PtrConst::new_sized(inner_data),
88 self.def.e(),
89 ))
90 }
91 }
92 }
93
94 #[inline]
96 pub fn ok_mut(&mut self) -> Option<Poke<'_, 'facet>> {
97 unsafe {
98 let inner_data = (self.vtable().get_ok)(self.value.data());
99 if inner_data.is_null() {
100 return None;
101 }
102 let offset = inner_data.offset_from(self.value.data().as_byte_ptr()) as usize;
103 let inner_data = self.value.data_mut().field(offset);
104 Some(Poke::from_raw_parts(inner_data, self.def.t()))
105 }
106 }
107
108 #[inline]
110 pub fn err_mut(&mut self) -> Option<Poke<'_, 'facet>> {
111 unsafe {
112 let inner_data = (self.vtable().get_err)(self.value.data());
113 if inner_data.is_null() {
114 return None;
115 }
116 let offset = inner_data.offset_from(self.value.data().as_byte_ptr()) as usize;
117 let inner_data = self.value.data_mut().field(offset);
118 Some(Poke::from_raw_parts(inner_data, self.def.e()))
119 }
120 }
121
122 pub fn set_ok<T: Facet<'facet>>(&mut self, value: T) -> Result<(), ReflectError> {
124 if self.def.t() != T::SHAPE {
125 return Err(self.err_reflect(ReflectErrorKind::WrongShape {
126 expected: self.def.t(),
127 actual: T::SHAPE,
128 }));
129 }
130
131 let mut value = ManuallyDrop::new(value);
132 unsafe {
133 self.value.shape.call_drop_in_place(self.value.data_mut());
135 let uninit = PtrUninit::new(self.value.data_mut().as_mut_byte_ptr());
136 let value_ptr = facet_core::PtrMut::new(&mut value as *mut ManuallyDrop<T> as *mut u8);
137 (self.vtable().init_ok)(uninit, value_ptr);
138 }
139 Ok(())
140 }
141
142 pub fn set_err<E: Facet<'facet>>(&mut self, value: E) -> Result<(), ReflectError> {
144 if self.def.e() != E::SHAPE {
145 return Err(self.err_reflect(ReflectErrorKind::WrongShape {
146 expected: self.def.e(),
147 actual: E::SHAPE,
148 }));
149 }
150
151 let mut value = ManuallyDrop::new(value);
152 unsafe {
153 self.value.shape.call_drop_in_place(self.value.data_mut());
154 let uninit = PtrUninit::new(self.value.data_mut().as_mut_byte_ptr());
155 let value_ptr = facet_core::PtrMut::new(&mut value as *mut ManuallyDrop<E> as *mut u8);
156 (self.vtable().init_err)(uninit, value_ptr);
157 }
158 Ok(())
159 }
160
161 pub fn set_ok_from_heap<const BORROW: bool>(
165 &mut self,
166 value: HeapValue<'facet, BORROW>,
167 ) -> Result<(), ReflectError> {
168 if self.def.t() != value.shape() {
169 return Err(self.err_reflect(ReflectErrorKind::WrongShape {
170 expected: self.def.t(),
171 actual: value.shape(),
172 }));
173 }
174
175 let mut value = value;
176 let guard = value
177 .guard
178 .take()
179 .expect("HeapValue guard was already taken");
180 unsafe {
181 self.value.shape.call_drop_in_place(self.value.data_mut());
182 let uninit = PtrUninit::new(self.value.data_mut().as_mut_byte_ptr());
183 let value_ptr = facet_core::PtrMut::new(guard.ptr.as_ptr());
184 (self.vtable().init_ok)(uninit, value_ptr);
185 }
186 drop(guard);
187 Ok(())
188 }
189
190 pub fn set_err_from_heap<const BORROW: bool>(
194 &mut self,
195 value: HeapValue<'facet, BORROW>,
196 ) -> Result<(), ReflectError> {
197 if self.def.e() != value.shape() {
198 return Err(self.err_reflect(ReflectErrorKind::WrongShape {
199 expected: self.def.e(),
200 actual: value.shape(),
201 }));
202 }
203
204 let mut value = value;
205 let guard = value
206 .guard
207 .take()
208 .expect("HeapValue guard was already taken");
209 unsafe {
210 self.value.shape.call_drop_in_place(self.value.data_mut());
211 let uninit = PtrUninit::new(self.value.data_mut().as_mut_byte_ptr());
212 let value_ptr = facet_core::PtrMut::new(guard.ptr.as_ptr());
213 (self.vtable().init_err)(uninit, value_ptr);
214 }
215 drop(guard);
216 Ok(())
217 }
218
219 #[inline]
221 pub const fn into_inner(self) -> Poke<'mem, 'facet> {
222 self.value
223 }
224
225 #[inline]
227 pub fn as_peek_result(&self) -> crate::PeekResult<'_, 'facet> {
228 crate::PeekResult {
229 value: self.value.as_peek(),
230 def: self.def,
231 }
232 }
233}
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238
239 #[test]
240 fn poke_result_is_ok_is_err() {
241 let mut x: Result<i32, String> = Ok(42);
242 let poke = Poke::new(&mut x);
243 let res = poke.into_result().unwrap();
244 assert!(res.is_ok());
245 assert!(!res.is_err());
246
247 let mut y: Result<i32, String> = Err(String::from("nope"));
248 let poke = Poke::new(&mut y);
249 let res = poke.into_result().unwrap();
250 assert!(res.is_err());
251 }
252
253 #[test]
254 fn poke_result_set_ok_then_err() {
255 let mut x: Result<i32, String> = Err(String::from("initial"));
256 let poke = Poke::new(&mut x);
257 let mut res = poke.into_result().unwrap();
258 res.set_ok(7i32).unwrap();
259 assert_eq!(x, Ok(7));
260
261 let poke = Poke::new(&mut x);
262 let mut res = poke.into_result().unwrap();
263 res.set_err(String::from("oops")).unwrap();
264 assert_eq!(x, Err(String::from("oops")));
265 }
266
267 #[test]
268 fn poke_result_ok_mut() {
269 let mut x: Result<i32, String> = Ok(1);
270 let poke = Poke::new(&mut x);
271 let mut res = poke.into_result().unwrap();
272
273 {
274 let mut inner = res.ok_mut().unwrap();
275 inner.set(123i32).unwrap();
276 }
277 assert_eq!(x, Ok(123));
278 }
279
280 #[test]
281 fn poke_result_set_ok_from_heap() {
282 let mut x: Result<i32, String> = Err(String::from("initial"));
283 let poke = Poke::new(&mut x);
284 let mut res = poke.into_result().unwrap();
285
286 let hv = crate::Partial::alloc::<i32>()
287 .unwrap()
288 .set(42i32)
289 .unwrap()
290 .build()
291 .unwrap();
292 res.set_ok_from_heap(hv).unwrap();
293 assert_eq!(x, Ok(42));
294 }
295
296 #[test]
297 fn poke_result_set_err_from_heap() {
298 let mut x: Result<i32, String> = Ok(1);
299 let poke = Poke::new(&mut x);
300 let mut res = poke.into_result().unwrap();
301
302 let hv = crate::Partial::alloc::<String>()
303 .unwrap()
304 .set(String::from("boom"))
305 .unwrap()
306 .build()
307 .unwrap();
308 res.set_err_from_heap(hv).unwrap();
309 assert_eq!(x, Err(String::from("boom")));
310 }
311}