spacetimedb_primitives/
attr.rs1#[allow(non_camel_case_types)]
40#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
41pub enum ConstraintKind {
42 UNSET,
43 INDEXED,
45 UNIQUE,
47 IDENTITY,
49 PRIMARY_KEY,
51 PRIMARY_KEY_AUTO,
53 PRIMARY_KEY_IDENTITY,
55}
56
57#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
59#[derive(Eq, PartialEq)]
60pub enum AttributeKind {
61 UNSET,
62 INDEXED,
64 AUTO_INC,
66 UNIQUE,
68 IDENTITY,
70 PRIMARY_KEY,
72 PRIMARY_KEY_AUTO,
74 PRIMARY_KEY_IDENTITY,
76}
77
78bitflags::bitflags! {
79 #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
80 pub struct ColumnAttribute: u8 {
81 const UNSET = Self::empty().bits();
82 const INDEXED = 0b0001;
84 const AUTO_INC = 0b0010;
86 const UNIQUE = Self::INDEXED.bits() | 0b0100;
88 const IDENTITY = Self::UNIQUE.bits() | Self::AUTO_INC.bits();
90 const PRIMARY_KEY = Self::UNIQUE.bits() | 0b1000;
92 const PRIMARY_KEY_AUTO = Self::PRIMARY_KEY.bits() | Self::AUTO_INC.bits();
94 const PRIMARY_KEY_IDENTITY = Self::PRIMARY_KEY.bits() | Self::IDENTITY.bits() ;
96 }
97}
98
99impl ColumnAttribute {
100 pub const fn has_autoinc(&self) -> bool {
103 self.contains(Self::IDENTITY) || self.contains(Self::PRIMARY_KEY_AUTO) || self.contains(Self::AUTO_INC)
104 }
105
106 pub const fn has_unique(&self) -> bool {
108 self.contains(Self::UNIQUE)
109 }
110
111 pub const fn has_indexed(&self) -> bool {
113 self.contains(ColumnAttribute::INDEXED)
114 }
115
116 pub const fn has_primary_key(&self) -> bool {
118 self.contains(ColumnAttribute::PRIMARY_KEY)
119 || self.contains(ColumnAttribute::PRIMARY_KEY_AUTO)
120 || self.contains(ColumnAttribute::PRIMARY_KEY_IDENTITY)
121 }
122
123 pub fn kind(&self) -> AttributeKind {
128 match *self {
129 x if x == Self::UNSET => AttributeKind::UNSET,
130 x if x == Self::INDEXED => AttributeKind::INDEXED,
131 x if x == Self::UNIQUE => AttributeKind::UNIQUE,
132 x if x == Self::AUTO_INC => AttributeKind::AUTO_INC,
133 x if x == Self::IDENTITY => AttributeKind::IDENTITY,
134 x if x == Self::PRIMARY_KEY => AttributeKind::PRIMARY_KEY,
135 x if x == Self::PRIMARY_KEY_AUTO => AttributeKind::PRIMARY_KEY_AUTO,
136 x if x == Self::PRIMARY_KEY_IDENTITY => AttributeKind::PRIMARY_KEY_IDENTITY,
137 x => unreachable!("Unexpected value {x:?}"),
138 }
139 }
140}
141
142#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
144pub struct Constraints {
145 attr: ColumnAttribute,
146}
147
148impl Constraints {
149 #[inline(always)]
151 const fn new(attr: ColumnAttribute) -> Self {
152 Self { attr }
153 }
154
155 pub const fn from_is_unique(is_unique: bool) -> Self {
158 if is_unique {
159 Self::unique()
160 } else {
161 Self::indexed()
162 }
163 }
164
165 pub const fn unset() -> Self {
167 Self::new(ColumnAttribute::UNSET)
168 }
169
170 pub const fn indexed() -> Self {
172 Self::new(ColumnAttribute::INDEXED)
173 }
174
175 pub const fn unique() -> Self {
177 Self::new(ColumnAttribute::UNIQUE)
178 }
179
180 pub const fn identity() -> Self {
182 Self::new(ColumnAttribute::IDENTITY)
183 }
184
185 pub const fn primary_key() -> Self {
187 Self::new(ColumnAttribute::PRIMARY_KEY)
188 }
189
190 pub const fn primary_key_auto() -> Self {
192 Self::new(ColumnAttribute::PRIMARY_KEY_AUTO)
193 }
194
195 pub const fn primary_key_identity() -> Self {
197 Self::new(ColumnAttribute::PRIMARY_KEY_IDENTITY)
198 }
199
200 pub const fn auto_inc() -> Self {
202 Self::new(ColumnAttribute::AUTO_INC)
203 }
204
205 pub fn push(self, other: Constraints) -> Self {
216 Self::new(self.attr | other.attr)
217 }
218
219 #[allow(clippy::result_unit_err)]
222 pub fn push_auto_inc(self) -> Result<Self, ()> {
223 Self::try_from(self.attr | ColumnAttribute::AUTO_INC)
224 }
225
226 pub const fn bits(&self) -> u8 {
228 self.attr.bits()
229 }
230
231 pub fn kind(&self) -> ConstraintKind {
236 match self {
237 x if x.attr == ColumnAttribute::UNSET => ConstraintKind::UNSET,
238 x if x.attr == ColumnAttribute::INDEXED => ConstraintKind::INDEXED,
239 x if x.attr == ColumnAttribute::UNIQUE => ConstraintKind::UNIQUE,
240 x if x.attr == ColumnAttribute::IDENTITY => ConstraintKind::IDENTITY,
241 x if x.attr == ColumnAttribute::PRIMARY_KEY => ConstraintKind::PRIMARY_KEY,
242 x if x.attr == ColumnAttribute::PRIMARY_KEY_AUTO => ConstraintKind::PRIMARY_KEY_AUTO,
243 x if x.attr == ColumnAttribute::PRIMARY_KEY_IDENTITY => ConstraintKind::PRIMARY_KEY_IDENTITY,
244 x => unreachable!("Unexpected value {x:?}"),
245 }
246 }
247
248 pub fn contains(&self, other: &Self) -> bool {
249 self.attr.contains(other.attr)
250 }
251
252 pub const fn has_unique(&self) -> bool {
254 self.attr.has_unique()
255 }
256
257 pub const fn has_indexed(&self) -> bool {
259 self.attr.has_indexed()
260 }
261
262 pub const fn has_autoinc(&self) -> bool {
265 self.attr.has_autoinc()
266 }
267
268 pub const fn has_primary_key(&self) -> bool {
270 self.attr.has_primary_key()
271 }
272}
273
274impl TryFrom<u8> for Constraints {
275 type Error = ();
276 fn try_from(v: u8) -> Result<Self, Self::Error> {
277 ColumnAttribute::from_bits(v).ok_or(()).map(Self::new)
278 }
279}
280
281impl TryFrom<ColumnAttribute> for Constraints {
282 type Error = ();
283
284 fn try_from(value: ColumnAttribute) -> Result<Self, Self::Error> {
285 Ok(match value.kind() {
286 AttributeKind::UNSET => Self::unset(),
287 AttributeKind::INDEXED => Self::indexed(),
288 AttributeKind::UNIQUE => Self::unique(),
289 AttributeKind::IDENTITY => Self::identity(),
290 AttributeKind::PRIMARY_KEY => Self::primary_key(),
291 AttributeKind::PRIMARY_KEY_AUTO => Self::primary_key_auto(),
292 AttributeKind::PRIMARY_KEY_IDENTITY => Self::primary_key_identity(),
293 AttributeKind::AUTO_INC => return Err(()),
294 })
295 }
296}