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)]
8#[non_exhaustive]
9pub enum Characteristic {
10    // Marker traits
11    /// Implements Send
12    Send,
13
14    /// Implements Sync
15    Sync,
16
17    /// Implements Copy
18    Copy,
19
20    /// Implements Eq
21    Eq,
22
23    /// Implements Unpin
24    Unpin,
25
26    // Functionality traits
27    /// Implements Clone
28    Clone,
29
30    /// Implements Display
31    Display,
32
33    /// Implements Debug
34    Debug,
35
36    /// Implements PartialEq
37    PartialEq,
38
39    /// Implements PartialOrd
40    PartialOrd,
41
42    /// Implements Ord
43    Ord,
44
45    /// Implements Hash
46    Hash,
47
48    /// Implements Default
49    Default,
50
51    /// Implements FromStr
52    FromStr,
53}
54
55impl Characteristic {
56    /// Checks if all shapes have the given characteristic.
57    pub const fn all(self, shapes: &'static [&'static 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    pub const fn any(self, shapes: &'static [&'static Shape]) -> bool {
70        let mut i = 0;
71        while i < shapes.len() {
72            if shapes[i].is(self) {
73                return true;
74            }
75            i += 1;
76        }
77        false
78    }
79
80    /// Checks if none of the shapes have the given characteristic.
81    pub const fn none(self, shapes: &'static [&'static Shape]) -> bool {
82        let mut i = 0;
83        while i < shapes.len() {
84            if shapes[i].is(self) {
85                return false;
86            }
87            i += 1;
88        }
89        true
90    }
91}
92
93impl Shape {
94    /// Checks if a shape has the given characteristic.
95    pub const fn is(&'static self, characteristic: Characteristic) -> bool {
96        match characteristic {
97            // Marker traits
98            Characteristic::Send => self.vtable.marker_traits.contains(MarkerTraits::SEND),
99            Characteristic::Sync => self.vtable.marker_traits.contains(MarkerTraits::SYNC),
100            Characteristic::Copy => self.vtable.marker_traits.contains(MarkerTraits::COPY),
101            Characteristic::Eq => self.vtable.marker_traits.contains(MarkerTraits::EQ),
102            Characteristic::Unpin => self.vtable.marker_traits.contains(MarkerTraits::UNPIN),
103
104            // Functionality traits
105            Characteristic::Clone => self.vtable.clone_into.is_some(),
106            Characteristic::Display => self.vtable.display.is_some(),
107            Characteristic::Debug => self.vtable.debug.is_some(),
108            Characteristic::PartialEq => self.vtable.eq.is_some(),
109            Characteristic::PartialOrd => self.vtable.partial_ord.is_some(),
110            Characteristic::Ord => self.vtable.ord.is_some(),
111            Characteristic::Hash => self.vtable.hash.is_some(),
112            Characteristic::Default => self.vtable.default_in_place.is_some(),
113            Characteristic::FromStr => self.vtable.parse.is_some(),
114        }
115    }
116
117    /// Check if this shape implements the Send trait
118    pub const fn is_send(&'static self) -> bool {
119        self.is(Characteristic::Send)
120    }
121
122    /// Check if this shape implements the Sync trait
123    pub const fn is_sync(&'static self) -> bool {
124        self.is(Characteristic::Sync)
125    }
126
127    /// Check if this shape implements the Copy trait
128    pub const fn is_copy(&'static self) -> bool {
129        self.is(Characteristic::Copy)
130    }
131
132    /// Check if this shape implements the Eq trait
133    pub const fn is_eq(&'static self) -> bool {
134        self.is(Characteristic::Eq)
135    }
136
137    /// Check if this shape implements the Clone trait
138    pub const fn is_clone(&'static self) -> bool {
139        self.is(Characteristic::Clone)
140    }
141
142    /// Check if this shape implements the Display trait
143    pub const fn is_display(&'static self) -> bool {
144        self.vtable.display.is_some()
145    }
146
147    /// Check if this shape implements the Debug trait
148    pub const fn is_debug(&'static self) -> bool {
149        self.is(Characteristic::Debug)
150    }
151
152    /// Check if this shape implements the PartialEq trait
153    pub const fn is_partial_eq(&'static self) -> bool {
154        self.is(Characteristic::PartialEq)
155    }
156
157    /// Check if this shape implements the PartialOrd trait
158    pub const fn is_partial_ord(&'static self) -> bool {
159        self.is(Characteristic::PartialOrd)
160    }
161
162    /// Check if this shape implements the Ord trait
163    pub const fn is_ord(&'static self) -> bool {
164        self.is(Characteristic::Ord)
165    }
166
167    /// Check if this shape implements the Hash trait
168    pub const fn is_hash(&'static self) -> bool {
169        self.is(Characteristic::Hash)
170    }
171
172    /// Check if this shape implements the Default trait
173    pub const fn is_default(&'static self) -> bool {
174        self.is(Characteristic::Default)
175    }
176
177    /// Check if this shape implements the FromStr trait
178    pub const fn is_from_str(&'static self) -> bool {
179        self.is(Characteristic::FromStr)
180    }
181
182    /// Writes the name of this type to the given formatter
183    pub fn write_type_name(&self, f: &mut fmt::Formatter<'_>, opts: TypeNameOpts) -> fmt::Result {
184        (self.vtable.type_name)(f, opts)
185    }
186}