facet_reflect/peek/
option.rs

1use facet_core::{OptionDef, OptionVTable, Shape};
2
3/// Lets you read from an option (implements read-only option operations)
4#[derive(Clone, Copy)]
5pub struct PeekOption<'mem> {
6    value: crate::PeekValue<'mem>,
7    def: OptionDef,
8}
9
10/// Returns the option definition if the shape represents an option, None otherwise
11pub fn peek_option(shape: &'static Shape) -> Option<OptionDef> {
12    match shape.def {
13        facet_core::Def::Option(option_def) => Some(option_def),
14        _ => None,
15    }
16}
17
18impl<'mem> core::ops::Deref for PeekOption<'mem> {
19    type Target = crate::PeekValue<'mem>;
20
21    #[inline(always)]
22    fn deref(&self) -> &Self::Target {
23        &self.value
24    }
25}
26
27impl<'mem> PeekOption<'mem> {
28    /// Create a new peek option
29    pub(crate) fn new(value: crate::PeekValue<'mem>, def: OptionDef) -> Self {
30        Self { value, def }
31    }
32
33    /// Returns the option definition
34    #[inline(always)]
35    pub fn def(self) -> OptionDef {
36        self.def
37    }
38
39    /// Returns the option vtable
40    #[inline(always)]
41    pub fn vtable(self) -> &'static OptionVTable {
42        self.def.vtable
43    }
44
45    /// Returns whether the option is Some
46    #[inline]
47    pub fn is_some(self) -> bool {
48        unsafe { (self.vtable().is_some_fn)(self.value.data()) }
49    }
50
51    /// Returns whether the option is None
52    #[inline]
53    pub fn is_none(self) -> bool {
54        !self.is_some()
55    }
56
57    /// Returns the inner value as a Peek if the option is Some, None otherwise
58    pub fn value(self) -> Option<crate::Peek<'mem>> {
59        unsafe {
60            (self.vtable().get_value_fn)(self.value.data())
61                .map(|inner_data| crate::Peek::unchecked_new(inner_data, self.def.t))
62        }
63    }
64}