facet_reflect/peek/
tuple.rs

1use core::fmt::Debug;
2use facet_core::Field;
3
4use super::{FieldIter, Peek};
5
6/// Local representation of a tuple type for peek operations
7#[derive(Clone, Copy, Debug)]
8pub struct TupleType {
9    /// Fields of the tuple, with offsets
10    pub fields: &'static [Field],
11}
12
13/// Field index and associated peek value
14pub type TupleField<'mem, 'facet> = (usize, Peek<'mem, 'facet>);
15
16/// Lets you read from a tuple
17#[derive(Clone, Copy)]
18pub struct PeekTuple<'mem, 'facet> {
19    /// Original peek value
20    pub(crate) value: Peek<'mem, 'facet>,
21    /// Tuple type information
22    pub(crate) ty: TupleType,
23}
24
25impl Debug for PeekTuple<'_, '_> {
26    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27        f.debug_struct("PeekTuple")
28            .field("type", &self.ty)
29            .finish_non_exhaustive()
30    }
31}
32
33impl<'mem, 'facet> PeekTuple<'mem, 'facet> {
34    /// Get the number of fields in this tuple
35    #[inline]
36    pub fn len(&self) -> usize {
37        self.ty.fields.len()
38    }
39
40    /// Returns true if this tuple has no fields
41    #[inline]
42    pub fn is_empty(&self) -> bool {
43        self.len() == 0
44    }
45
46    /// Access a field by index
47    #[inline]
48    pub fn field(&self, index: usize) -> Option<Peek<'mem, 'facet>> {
49        if index >= self.len() {
50            return None;
51        }
52
53        let field = &self.ty.fields[index];
54        // We can safely use field operations here since this is within facet-reflect
55        // which is allowed to use unsafe code
56        let field_ptr = unsafe { self.value.data().field(field.offset) };
57        let field_peek = unsafe { Peek::unchecked_new(field_ptr, field.shape()) };
58
59        Some(field_peek)
60    }
61
62    /// Iterate over all fields
63    #[inline]
64    pub fn fields(&self) -> FieldIter<'mem, 'facet> {
65        FieldIter::new_tuple(*self)
66    }
67
68    /// Type information
69    #[inline]
70    pub fn ty(&self) -> TupleType {
71        self.ty
72    }
73
74    /// Internal peek value
75    #[inline]
76    pub fn value(&self) -> Peek<'mem, 'facet> {
77        self.value
78    }
79}