shapely_core/shape/
struct_shape.rs

1use super::ShapeDesc;
2
3/// Describes a field in a struct or tuple
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub struct Field {
6    /// key for the struct field (for tuples and tuple-structs, this is the 0-based index)
7    pub name: &'static str,
8
9    /// schema of the inner type
10    pub shape: ShapeDesc,
11
12    /// offset of the field in the struct (obtained through `std::mem::offset_of`)
13    pub offset: usize,
14
15    /// flags for the field (e.g. sensitive, etc.)
16    pub flags: FieldFlags,
17}
18
19/// Flags that can be applied to fields to modify their behavior
20///
21/// # Examples
22///
23/// ```rust
24/// use shapely_core::FieldFlags;
25///
26/// // Create flags with the sensitive bit set
27/// let flags = FieldFlags::SENSITIVE;
28/// assert!(flags.contains(FieldFlags::SENSITIVE));
29///
30/// // Combine multiple flags using bitwise OR
31/// let flags = FieldFlags::SENSITIVE | FieldFlags::EMPTY;
32/// ```
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34pub struct FieldFlags(u64);
35
36impl FieldFlags {
37    /// An empty set of flags
38    pub const EMPTY: Self = Self(0);
39
40    /// Flag indicating this field contains sensitive data that should not be displayed
41    pub const SENSITIVE: Self = Self(1 << 0);
42
43    /// Returns true if the given flag is set
44    #[inline]
45    pub fn contains(&self, flag: FieldFlags) -> bool {
46        self.0 & flag.0 != 0
47    }
48
49    /// Sets the given flag and returns self for chaining
50    #[inline]
51    pub fn set_flag(&mut self, flag: FieldFlags) -> &mut Self {
52        self.0 |= flag.0;
53        self
54    }
55
56    /// Unsets the given flag and returns self for chaining
57    #[inline]
58    pub fn unset_flag(&mut self, flag: FieldFlags) -> &mut Self {
59        self.0 &= !flag.0;
60        self
61    }
62
63    /// Creates a new FieldFlags with the given flag set
64    #[inline]
65    pub const fn with_flag(flag: FieldFlags) -> Self {
66        Self(flag.0)
67    }
68}
69
70impl std::ops::BitOr for FieldFlags {
71    type Output = Self;
72
73    fn bitor(self, rhs: Self) -> Self {
74        Self(self.0 | rhs.0)
75    }
76}
77
78impl std::ops::BitOrAssign for FieldFlags {
79    fn bitor_assign(&mut self, rhs: Self) {
80        self.0 |= rhs.0;
81    }
82}
83
84impl Default for FieldFlags {
85    #[inline(always)]
86    fn default() -> Self {
87        Self::EMPTY
88    }
89}
90
91impl std::fmt::Display for FieldFlags {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        if self.0 == 0 {
94            return write!(f, "none");
95        }
96
97        // Define a vector of flag entries: (flag bit, name)
98        let flags = [
99            (Self::SENSITIVE.0, "sensitive"),
100            // Future flags can be easily added here:
101            // (Self::SOME_FLAG.0, "some_flag"),
102            // (Self::ANOTHER_FLAG.0, "another_flag"),
103        ];
104
105        // Write all active flags with proper separators
106        let mut is_first = true;
107        for (bit, name) in flags {
108            if self.0 & bit != 0 {
109                if !is_first {
110                    write!(f, ", ")?;
111                }
112                is_first = false;
113                write!(f, "{}", name)?;
114            }
115        }
116
117        Ok(())
118    }
119}