use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, Not};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct Flags(pub u32);
impl Flags {
pub const NONE: Flags = Flags(0);
pub const IGNORECASE: Flags = Flags(1 << 0);
pub const MULTILINE: Flags = Flags(1 << 1);
pub const DOTALL: Flags = Flags(1 << 2);
pub const UNICODE: Flags = Flags(1 << 3);
pub const ASCII: Flags = Flags(1 << 4);
pub const VERBOSE: Flags = Flags(1 << 5);
pub const FULLCASE: Flags = Flags(1 << 6);
pub const WORD: Flags = Flags(1 << 7);
pub const LOCALE: Flags = Flags(1 << 8);
pub const VERSION0: Flags = Flags(1 << 16);
pub const VERSION1: Flags = Flags(1 << 17);
#[inline]
pub const fn contains(self, other: Flags) -> bool {
(self.0 & other.0) == other.0
}
#[inline]
pub const fn intersects(self, other: Flags) -> bool {
(self.0 & other.0) != 0
}
#[inline]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
#[inline]
pub fn insert(&mut self, other: Flags) {
self.0 |= other.0;
}
#[inline]
pub fn remove(&mut self, other: Flags) {
self.0 &= !other.0;
}
#[inline]
pub const fn union(self, other: Flags) -> Flags {
Flags(self.0 | other.0)
}
#[inline]
pub const fn intersection(self, other: Flags) -> Flags {
Flags(self.0 & other.0)
}
#[inline]
pub const fn difference(self, other: Flags) -> Flags {
Flags(self.0 & !other.0)
}
#[inline]
pub const fn bits(self) -> u32 {
self.0
}
pub const fn scoped(self) -> Flags {
Flags(self.0 & Self::SCOPED_BITS)
}
pub const fn global(self) -> Flags {
Flags(self.0 & Self::GLOBAL_BITS)
}
const SCOPED_BITS: u32 = 0x1FF; const GLOBAL_BITS: u32 = (1 << 16) | (1 << 17);
}
impl BitOr for Flags {
type Output = Flags;
#[inline]
fn bitor(self, rhs: Flags) -> Flags {
Flags(self.0 | rhs.0)
}
}
impl BitOrAssign for Flags {
#[inline]
fn bitor_assign(&mut self, rhs: Flags) {
self.0 |= rhs.0;
}
}
impl BitAnd for Flags {
type Output = Flags;
#[inline]
fn bitand(self, rhs: Flags) -> Flags {
Flags(self.0 & rhs.0)
}
}
impl BitAndAssign for Flags {
#[inline]
fn bitand_assign(&mut self, rhs: Flags) {
self.0 &= rhs.0;
}
}
impl BitXor for Flags {
type Output = Flags;
#[inline]
fn bitxor(self, rhs: Flags) -> Flags {
Flags(self.0 ^ rhs.0)
}
}
impl Not for Flags {
type Output = Flags;
#[inline]
fn not(self) -> Flags {
Flags(!self.0)
}
}
pub(crate) fn resolve_defaults(mut f: Flags) -> Flags {
if !f.intersects(Flags::ASCII | Flags::UNICODE | Flags::LOCALE) {
f |= Flags::UNICODE;
}
if !f.intersects(Flags::VERSION0 | Flags::VERSION1) {
f |= Flags::VERSION1; }
f
}
pub const IGNORECASE: Flags = Flags::IGNORECASE;
pub const MULTILINE: Flags = Flags::MULTILINE;
pub const DOTALL: Flags = Flags::DOTALL;
pub const UNICODE: Flags = Flags::UNICODE;
pub const ASCII: Flags = Flags::ASCII;
pub const VERBOSE: Flags = Flags::VERBOSE;
pub const FULLCASE: Flags = Flags::FULLCASE;
pub const WORD: Flags = Flags::WORD;
pub const LOCALE: Flags = Flags::LOCALE;
pub const VERSION0: Flags = Flags::VERSION0;
pub const VERSION1: Flags = Flags::VERSION1;