use crate::provider::data::{DotType, MappingKind};
use zerovec::ule::{AsULE, ULE};
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "datagen", derive(serde::Serialize))]
pub struct ExceptionBits {
pub double_width_slots: bool,
pub no_simple_case_folding: bool,
pub negative_delta: bool,
pub is_sensitive: bool,
pub dot_type: DotType,
pub has_conditional_special: bool,
pub has_conditional_fold: bool,
}
impl ExceptionBits {
pub(crate) fn from_integer(int: u8) -> Self {
let ule = ExceptionBitsULE(int);
let double_width_slots = ule.double_width_slots();
let no_simple_case_folding = ule.no_simple_case_folding();
let negative_delta = ule.negative_delta();
let is_sensitive = ule.is_sensitive();
let has_conditional_special = ule.has_conditional_special();
let has_conditional_fold = ule.has_conditional_fold();
let dot_type = ule.dot_type();
Self {
double_width_slots,
no_simple_case_folding,
negative_delta,
is_sensitive,
dot_type,
has_conditional_special,
has_conditional_fold,
}
}
pub(crate) fn to_integer(self) -> u8 {
let mut int = 0;
let dot_data = (self.dot_type as u8) << ExceptionBitsULE::DOT_SHIFT;
int |= dot_data;
if self.double_width_slots {
int |= ExceptionBitsULE::DOUBLE_SLOTS_FLAG
}
if self.no_simple_case_folding {
int |= ExceptionBitsULE::NO_SIMPLE_CASE_FOLDING_FLAG
}
if self.negative_delta {
int |= ExceptionBitsULE::NEGATIVE_DELTA_FLAG
}
if self.is_sensitive {
int |= ExceptionBitsULE::SENSITIVE_FLAG
}
if self.has_conditional_special {
int |= ExceptionBitsULE::CONDITIONAL_SPECIAL_FLAG
}
if self.has_conditional_fold {
int |= ExceptionBitsULE::CONDITIONAL_FOLD_FLAG
}
int
}
}
#[derive(Copy, Clone, PartialEq, Eq, ULE, Debug, Default)]
#[repr(transparent)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "datagen", derive(serde::Serialize))]
pub struct SlotPresence(pub u8);
impl SlotPresence {
pub(crate) fn add_slot(&mut self, slot: ExceptionSlot) {
self.0 |= 1 << slot as u8;
}
pub(crate) fn has_slot(self, slot: ExceptionSlot) -> bool {
let bit = 1 << (slot as u8);
self.0 & bit != 0
}
}
#[derive(Copy, Clone, PartialEq, Eq, ULE, Debug)]
#[repr(transparent)]
pub struct ExceptionBitsULE(pub u8);
impl ExceptionBitsULE {
const DOUBLE_SLOTS_FLAG: u8 = 0x1;
const NO_SIMPLE_CASE_FOLDING_FLAG: u8 = 0x2;
const NEGATIVE_DELTA_FLAG: u8 = 0x4;
const SENSITIVE_FLAG: u8 = 0x8;
const DOT_SHIFT: u8 = 4;
const CONDITIONAL_SPECIAL_FLAG: u8 = 0x40;
const CONDITIONAL_FOLD_FLAG: u8 = 0x80;
}
impl ExceptionBitsULE {
pub fn double_width_slots(self) -> bool {
self.0 & Self::DOUBLE_SLOTS_FLAG != 0
}
pub fn no_simple_case_folding(self) -> bool {
self.0 & Self::NO_SIMPLE_CASE_FOLDING_FLAG != 0
}
pub fn negative_delta(self) -> bool {
self.0 & Self::NEGATIVE_DELTA_FLAG != 0
}
pub fn is_sensitive(self) -> bool {
self.0 & Self::SENSITIVE_FLAG != 0
}
pub fn has_conditional_special(self) -> bool {
self.0 & Self::CONDITIONAL_SPECIAL_FLAG != 0
}
pub fn has_conditional_fold(self) -> bool {
self.0 & Self::CONDITIONAL_FOLD_FLAG != 0
}
pub fn dot_type(self) -> DotType {
DotType::from_masked_bits((u16::from(self.0 >> Self::DOT_SHIFT)) & DotType::DOT_MASK)
}
}
impl AsULE for ExceptionBits {
type ULE = ExceptionBitsULE;
fn from_unaligned(u: ExceptionBitsULE) -> Self {
ExceptionBits::from_integer(u.0)
}
fn to_unaligned(self) -> ExceptionBitsULE {
ExceptionBitsULE(self.to_integer())
}
}
impl AsULE for SlotPresence {
type ULE = SlotPresence;
fn from_unaligned(u: Self) -> Self {
u
}
fn to_unaligned(self) -> Self {
self
}
}
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub(crate) enum ExceptionSlot {
Lower = 0,
Fold = 1,
Upper = 2,
Title = 3,
Delta = 4,
Closure = 6,
FullMappings = 7,
}
impl ExceptionSlot {
pub(crate) const STRING_SLOTS_START: Self = Self::Closure;
}
impl From<MappingKind> for ExceptionSlot {
fn from(full: MappingKind) -> Self {
match full {
MappingKind::Lower => Self::Lower,
MappingKind::Fold => Self::Fold,
MappingKind::Upper => Self::Upper,
MappingKind::Title => Self::Title,
}
}
}