use crate::{Label, ValueType};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ColumnDef {
pub(crate) value_type: ValueType,
pub(crate) label: Label,
pub(crate) count: usize,
pub(crate) flags: Vec<FlagDef>,
}
pub struct ColumnBuilder(ColumnDef);
#[derive(Debug, Clone, PartialEq, Default)]
pub(crate) struct ColumnMap {
pub columns: Vec<ColumnDef>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FlagDef {
pub(crate) label: String,
pub(crate) mask: u32,
#[cfg_attr(feature = "serde", serde(rename = "index"))]
pub(crate) flag_index: usize,
}
impl ColumnDef {
pub fn new(ty: ValueType, label: Label) -> Self {
Self::with_flags(ty, label, Vec::new())
}
fn with_flags(ty: ValueType, label: Label, flags: Vec<FlagDef>) -> Self {
Self {
value_type: ty,
label,
flags,
count: 1,
}
}
pub fn value_type(&self) -> ValueType {
self.value_type
}
pub fn label(&self) -> &Label {
&self.label
}
pub fn label_mut(&mut self) -> &mut Label {
&mut self.label
}
pub fn count(&self) -> usize {
self.count
}
pub fn flags(&self) -> &[FlagDef] {
&self.flags
}
pub fn data_size(&self) -> usize {
self.value_type.data_len() * self.count
}
}
impl FlagDef {
pub fn new(label: impl Into<String>, mask: u32, shift_amount: usize) -> Self {
Self {
label: label.into(),
mask,
flag_index: shift_amount,
}
}
pub fn new_bit(label: impl Into<String>, bit: u32) -> Self {
Self::new(label, 1 << bit, bit as usize)
}
pub fn label(&self) -> &str {
&self.label
}
pub fn mask(&self) -> u32 {
self.mask
}
pub fn shift_amount(&self) -> usize {
self.flag_index
}
}
impl ColumnBuilder {
pub fn new(value_type: ValueType, label: Label) -> Self {
Self(ColumnDef::new(value_type, label))
}
pub fn set_flags(mut self, flags: Vec<FlagDef>) -> Self {
self.0.flags = flags;
self
}
pub fn set_count(mut self, count: usize) -> Self {
assert!(count > 0);
self.0.count = count;
self
}
pub fn build(self) -> ColumnDef {
self.0
}
}
impl ColumnMap {
pub fn position(&self, label: &Label) -> Option<usize> {
self.columns.iter().position(|c| &c.label == label)
}
pub fn push(&mut self, column: ColumnDef) {
self.columns.push(column);
}
pub fn as_slice(&self) -> &[ColumnDef] {
&self.columns
}
pub fn as_mut_slice(&mut self) -> &mut [ColumnDef] {
&mut self.columns
}
pub fn into_raw(self) -> Vec<ColumnDef> {
self.columns
}
}
impl<T> From<T> for ColumnMap
where
T: IntoIterator<Item = ColumnDef>,
{
fn from(value: T) -> Self {
Self {
columns: value.into_iter().collect(),
}
}
}