#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
pub enum ConstraintKind {
UNSET,
INDEXED,
UNIQUE,
IDENTITY,
PRIMARY_KEY,
PRIMARY_KEY_AUTO,
PRIMARY_KEY_IDENTITY,
}
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Eq, PartialEq)]
pub enum AttributeKind {
UNSET,
INDEXED,
AUTO_INC,
UNIQUE,
IDENTITY,
PRIMARY_KEY,
PRIMARY_KEY_AUTO,
PRIMARY_KEY_IDENTITY,
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct ColumnAttribute: u8 {
const UNSET = Self::empty().bits();
const INDEXED = 0b0001;
const AUTO_INC = 0b0010;
const UNIQUE = Self::INDEXED.bits() | 0b0100;
const IDENTITY = Self::UNIQUE.bits() | Self::AUTO_INC.bits();
const PRIMARY_KEY = Self::UNIQUE.bits() | 0b1000;
const PRIMARY_KEY_AUTO = Self::PRIMARY_KEY.bits() | Self::AUTO_INC.bits();
const PRIMARY_KEY_IDENTITY = Self::PRIMARY_KEY.bits() | Self::IDENTITY.bits() ;
}
}
impl ColumnAttribute {
pub const fn has_autoinc(&self) -> bool {
self.contains(Self::IDENTITY) || self.contains(Self::PRIMARY_KEY_AUTO) || self.contains(Self::AUTO_INC)
}
pub const fn has_unique(&self) -> bool {
self.contains(Self::UNIQUE)
}
pub const fn has_indexed(&self) -> bool {
self.contains(ColumnAttribute::INDEXED)
}
pub const fn has_primary_key(&self) -> bool {
self.contains(ColumnAttribute::PRIMARY_KEY)
|| self.contains(ColumnAttribute::PRIMARY_KEY_AUTO)
|| self.contains(ColumnAttribute::PRIMARY_KEY_IDENTITY)
}
pub fn kind(&self) -> AttributeKind {
match *self {
x if x == Self::UNSET => AttributeKind::UNSET,
x if x == Self::INDEXED => AttributeKind::INDEXED,
x if x == Self::UNIQUE => AttributeKind::UNIQUE,
x if x == Self::AUTO_INC => AttributeKind::AUTO_INC,
x if x == Self::IDENTITY => AttributeKind::IDENTITY,
x if x == Self::PRIMARY_KEY => AttributeKind::PRIMARY_KEY,
x if x == Self::PRIMARY_KEY_AUTO => AttributeKind::PRIMARY_KEY_AUTO,
x if x == Self::PRIMARY_KEY_IDENTITY => AttributeKind::PRIMARY_KEY_IDENTITY,
x => unreachable!("Unexpected value {x:?}"),
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct Constraints {
attr: ColumnAttribute,
}
impl Constraints {
#[inline(always)]
const fn new(attr: ColumnAttribute) -> Self {
Self { attr }
}
pub const fn from_is_unique(is_unique: bool) -> Self {
if is_unique {
Self::unique()
} else {
Self::indexed()
}
}
pub const fn unset() -> Self {
Self::new(ColumnAttribute::UNSET)
}
pub const fn indexed() -> Self {
Self::new(ColumnAttribute::INDEXED)
}
pub const fn unique() -> Self {
Self::new(ColumnAttribute::UNIQUE)
}
pub const fn identity() -> Self {
Self::new(ColumnAttribute::IDENTITY)
}
pub const fn primary_key() -> Self {
Self::new(ColumnAttribute::PRIMARY_KEY)
}
pub const fn primary_key_auto() -> Self {
Self::new(ColumnAttribute::PRIMARY_KEY_AUTO)
}
pub const fn primary_key_identity() -> Self {
Self::new(ColumnAttribute::PRIMARY_KEY_IDENTITY)
}
pub const fn auto_inc() -> Self {
Self::new(ColumnAttribute::AUTO_INC)
}
pub fn push(self, other: Constraints) -> Self {
Self::new(self.attr | other.attr)
}
#[allow(clippy::result_unit_err)]
pub fn push_auto_inc(self) -> Result<Self, ()> {
Self::try_from(self.attr | ColumnAttribute::AUTO_INC)
}
pub const fn bits(&self) -> u8 {
self.attr.bits()
}
pub fn kind(&self) -> ConstraintKind {
match self {
x if x.attr == ColumnAttribute::UNSET => ConstraintKind::UNSET,
x if x.attr == ColumnAttribute::INDEXED => ConstraintKind::INDEXED,
x if x.attr == ColumnAttribute::UNIQUE => ConstraintKind::UNIQUE,
x if x.attr == ColumnAttribute::IDENTITY => ConstraintKind::IDENTITY,
x if x.attr == ColumnAttribute::PRIMARY_KEY => ConstraintKind::PRIMARY_KEY,
x if x.attr == ColumnAttribute::PRIMARY_KEY_AUTO => ConstraintKind::PRIMARY_KEY_AUTO,
x if x.attr == ColumnAttribute::PRIMARY_KEY_IDENTITY => ConstraintKind::PRIMARY_KEY_IDENTITY,
x => unreachable!("Unexpected value {x:?}"),
}
}
pub fn contains(&self, other: &Self) -> bool {
self.attr.contains(other.attr)
}
pub const fn has_unique(&self) -> bool {
self.attr.has_unique()
}
pub const fn has_indexed(&self) -> bool {
self.attr.has_indexed()
}
pub const fn has_autoinc(&self) -> bool {
self.attr.has_autoinc()
}
pub const fn has_primary_key(&self) -> bool {
self.attr.has_primary_key()
}
}
impl TryFrom<u8> for Constraints {
type Error = ();
fn try_from(v: u8) -> Result<Self, Self::Error> {
ColumnAttribute::from_bits(v).ok_or(()).map(Self::new)
}
}
impl TryFrom<ColumnAttribute> for Constraints {
type Error = ();
fn try_from(value: ColumnAttribute) -> Result<Self, Self::Error> {
Ok(match value.kind() {
AttributeKind::UNSET => Self::unset(),
AttributeKind::INDEXED => Self::indexed(),
AttributeKind::UNIQUE => Self::unique(),
AttributeKind::IDENTITY => Self::identity(),
AttributeKind::PRIMARY_KEY => Self::primary_key(),
AttributeKind::PRIMARY_KEY_AUTO => Self::primary_key_auto(),
AttributeKind::PRIMARY_KEY_IDENTITY => Self::primary_key_identity(),
AttributeKind::AUTO_INC => return Err(()),
})
}
}