facet_core/types/
characteristic.rs

1use core::fmt;
2
3use super::{MarkerTraits, Shape, TypeNameOpts};
4
5/// A characteristic a shape can have
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[repr(C)]
8pub enum Characteristic {
9    // Marker traits
10    /// Implements Send
11    Send,
12
13    /// Implements Sync
14    Sync,
15
16    /// Implements Copy
17    Copy,
18
19    /// Implements Eq
20    Eq,
21
22    /// Implements Unpin
23    Unpin,
24
25    // Functionality traits
26    /// Implements Clone
27    Clone,
28
29    /// Implements Display
30    Display,
31
32    /// Implements Debug
33    Debug,
34
35    /// Implements PartialEq
36    PartialEq,
37
38    /// Implements PartialOrd
39    PartialOrd,
40
41    /// Implements Ord
42    Ord,
43
44    /// Implements Hash
45    Hash,
46
47    /// Implements Default
48    Default,
49
50    /// Implements FromStr
51    FromStr,
52}
53
54impl Characteristic {
55    /// Checks if all shapes have the given characteristic.
56    #[inline]
57    pub fn all(self, shapes: &[&Shape]) -> bool {
58        let mut i = 0;
59        while i < shapes.len() {
60            if !shapes[i].is(self) {
61                return false;
62            }
63            i += 1;
64        }
65        true
66    }
67
68    /// Checks if any shape has the given characteristic.
69    #[inline]
70    pub fn any(self, shapes: &[&Shape]) -> bool {
71        let mut i = 0;
72        while i < shapes.len() {
73            if shapes[i].is(self) {
74                return true;
75            }
76            i += 1;
77        }
78        false
79    }
80
81    /// Checks if none of the shapes have the given characteristic.
82    #[inline]
83    pub fn none(self, shapes: &[&Shape]) -> bool {
84        let mut i = 0;
85        while i < shapes.len() {
86            if shapes[i].is(self) {
87                return false;
88            }
89            i += 1;
90        }
91        true
92    }
93
94    /// Checks if all shapes have the `Default` characteristic
95    #[inline]
96    pub fn all_default(shapes: &[&Shape]) -> bool {
97        let mut i = 0;
98        while i < shapes.len() {
99            if !shapes[i].is_default() {
100                return false;
101            }
102            i += 1;
103        }
104        true
105    }
106
107    /// Checks if all shapes have the `PartialEq` characteristic
108    #[inline]
109    pub fn all_partial_eq(shapes: &[&Shape]) -> bool {
110        let mut i = 0;
111        while i < shapes.len() {
112            if !shapes[i].is_partial_eq() {
113                return false;
114            }
115            i += 1;
116        }
117        true
118    }
119
120    /// Checks if all shapes have the `PartialOrd` characteristic
121    #[inline]
122    pub fn all_partial_ord(shapes: &[&Shape]) -> bool {
123        let mut i = 0;
124        while i < shapes.len() {
125            if !shapes[i].is_partial_ord() {
126                return false;
127            }
128            i += 1;
129        }
130        true
131    }
132
133    /// Checks if all shapes have the `Ord` characteristic
134    #[inline]
135    pub fn all_ord(shapes: &[&Shape]) -> bool {
136        let mut i = 0;
137        while i < shapes.len() {
138            if !shapes[i].is_ord() {
139                return false;
140            }
141            i += 1;
142        }
143        true
144    }
145
146    /// Checks if all shapes have the `Hash` characteristic
147    #[inline]
148    pub fn all_hash(shapes: &[&Shape]) -> bool {
149        let mut i = 0;
150        while i < shapes.len() {
151            if !shapes[i].is_hash() {
152                return false;
153            }
154            i += 1;
155        }
156        true
157    }
158}
159
160impl Shape {
161    /// Checks if a shape has the given characteristic.
162    #[inline]
163    pub fn is(&self, characteristic: Characteristic) -> bool {
164        match characteristic {
165            // Marker traits
166            Characteristic::Send => self.vtable.marker_traits().contains(MarkerTraits::SEND),
167            Characteristic::Sync => self.vtable.marker_traits().contains(MarkerTraits::SYNC),
168            Characteristic::Copy => self.vtable.marker_traits().contains(MarkerTraits::COPY),
169            Characteristic::Eq => self.vtable.marker_traits().contains(MarkerTraits::EQ),
170            Characteristic::Unpin => self.vtable.marker_traits().contains(MarkerTraits::UNPIN),
171
172            // Functionality traits
173            Characteristic::Clone => self.vtable.has_clone_into(),
174            Characteristic::Display => self.vtable.has_display(),
175            Characteristic::Debug => self.vtable.has_debug(),
176            Characteristic::PartialEq => self.vtable.has_partial_eq(),
177            Characteristic::PartialOrd => self.vtable.has_partial_ord(),
178            Characteristic::Ord => self.vtable.has_ord(),
179            Characteristic::Hash => self.vtable.has_hash(),
180            Characteristic::Default => self.vtable.has_default_in_place(),
181            Characteristic::FromStr => self.vtable.has_parse(),
182        }
183    }
184
185    /// Check if this shape implements the Send trait
186    #[inline]
187    pub fn is_send(&self) -> bool {
188        self.is(Characteristic::Send)
189    }
190
191    /// Check if this shape implements the Sync trait
192    #[inline]
193    pub fn is_sync(&self) -> bool {
194        self.is(Characteristic::Sync)
195    }
196
197    /// Check if this shape implements the Copy trait
198    #[inline]
199    pub fn is_copy(&self) -> bool {
200        self.is(Characteristic::Copy)
201    }
202
203    /// Check if this shape implements the Eq trait
204    #[inline]
205    pub fn is_eq(&self) -> bool {
206        self.is(Characteristic::Eq)
207    }
208
209    /// Check if this shape implements the Clone trait
210    #[inline]
211    pub fn is_clone(&self) -> bool {
212        self.is(Characteristic::Clone)
213    }
214
215    /// Check if this shape implements the Display trait
216    #[inline]
217    pub fn is_display(&self) -> bool {
218        self.is(Characteristic::Display)
219    }
220
221    /// Check if this shape implements the Debug trait
222    #[inline]
223    pub fn is_debug(&self) -> bool {
224        self.is(Characteristic::Debug)
225    }
226
227    /// Check if this shape implements the PartialEq trait
228    #[inline]
229    pub fn is_partial_eq(&self) -> bool {
230        self.is(Characteristic::PartialEq)
231    }
232
233    /// Check if this shape implements the PartialOrd trait
234    #[inline]
235    pub fn is_partial_ord(&self) -> bool {
236        self.is(Characteristic::PartialOrd)
237    }
238
239    /// Check if this shape implements the Ord trait
240    #[inline]
241    pub fn is_ord(&self) -> bool {
242        self.is(Characteristic::Ord)
243    }
244
245    /// Check if this shape implements the Hash trait
246    #[inline]
247    pub fn is_hash(&self) -> bool {
248        self.is(Characteristic::Hash)
249    }
250
251    /// Check if this shape implements the Default trait
252    #[inline]
253    pub fn is_default(&self) -> bool {
254        self.is(Characteristic::Default)
255    }
256
257    /// Check if this shape implements the FromStr trait
258    #[inline]
259    pub fn is_from_str(&self) -> bool {
260        self.is(Characteristic::FromStr)
261    }
262
263    /// Writes the name of this type to the given formatter
264    #[inline]
265    pub fn write_type_name(&self, f: &mut fmt::Formatter<'_>, opts: TypeNameOpts) -> fmt::Result {
266        (self.vtable.type_name())(f, opts)
267    }
268}