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}