use derive_debug::Dbg;
use num_enum::TryFromPrimitive;
use crate::utils::formatter::{bytes_dbg, compact_dbg};
use crate::{MltError, MltResult};
#[derive(Debug, Clone, Copy, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum LogicalTechnique {
None = 0b0000_0000,
Delta = 0b0010_0000,
ComponentwiseDelta = 0b0100_0000,
Rle = 0b0110_0000,
Morton = 0b1000_0000,
PseudoDecimal = 0b1010_0000,
}
#[derive(Debug, Clone, Copy, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum LogicalCombination {
None = 0b0000_0000,
Delta = 0b0010_0000,
DeltaRle = 0b0010_1100,
ComponentwiseDelta = 0b0100_0000,
Rle = 0b0110_0000,
Morton = 0b1000_0000,
MortonDelta = 0b1000_0100,
MortonRle = 0b1000_1100,
PseudoDecimal = 0b1010_0000,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RleLayout {
Split,
#[cfg(feature = "unstable-v2")]
Interleaved,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RleMeta {
Split { runs: u32, num_rle_values: u32 },
#[cfg(feature = "unstable-v2")]
Interleaved { num_rle_values: u32 },
}
impl RleMeta {
#[cfg(feature = "unstable-v2")]
#[must_use]
pub(crate) fn num_rle_values(self) -> u32 {
match self {
Self::Split { num_rle_values, .. } => num_rle_values,
#[cfg(feature = "unstable-v2")]
Self::Interleaved { num_rle_values } => num_rle_values,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Morton {
pub(crate) bits: u32,
pub(crate) shift: u32,
}
impl Morton {
pub fn new(bits: u32, shift: u32) -> MltResult<Self> {
if bits <= 16 {
Ok(Self { bits, shift })
} else {
Err(MltError::InvalidMortonBits(bits))
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LogicalEncoding {
None,
Delta,
DeltaRle(RleMeta),
ComponentwiseDelta,
Rle(RleMeta),
Morton(Morton),
MortonDelta(Morton),
MortonRle(Morton),
PseudoDecimal,
}
#[derive(Debug, PartialEq)]
pub struct LogicalValue {
pub(crate) meta: StreamMeta,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, TryFromPrimitive)]
#[repr(u8)]
pub enum DictionaryType {
None = 0b0000_0000,
Single = 0b0000_0001,
Shared = 0b0000_0010,
Vertex = 0b0000_0011,
Morton = 0b0000_0100,
Fsst = 0b0000_0101,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, TryFromPrimitive)]
#[repr(u8)]
pub enum OffsetType {
Vertex = 0b0000_0000,
Index = 0b0000_0001,
String = 0b0000_0010,
Key = 0b0000_0011,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, TryFromPrimitive)]
#[repr(u8)]
pub enum LengthType {
VarBinary = 0b0000_0000,
Geometries = 0b0000_0001,
Parts = 0b0000_0010,
Rings = 0b0000_0011,
Triangles = 0b0000_0100,
Symbol = 0b0000_0101,
Dictionary = 0b0000_0110,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum StreamType {
Present,
Data(DictionaryType),
Offset(OffsetType),
Length(LengthType),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, TryFromPrimitive)]
#[repr(u8)]
pub enum PhysicalEncoding {
None = 0b0000_0000,
FastPFor256 = 0b0000_0001,
VarInt = 0b0000_0010,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct IntEncoding {
pub logical: LogicalEncoding,
pub physical: PhysicalEncoding,
}
impl IntEncoding {
#[must_use]
pub(crate) const fn new(logical: LogicalEncoding, physical: PhysicalEncoding) -> Self {
Self { logical, physical }
}
#[must_use]
pub(crate) const fn none() -> Self {
Self::new(LogicalEncoding::None, PhysicalEncoding::None)
}
}
#[derive(Clone, Copy, Dbg, PartialEq)]
pub struct StreamMeta {
#[dbg(formatter = "compact_dbg")]
pub stream_type: StreamType,
#[dbg(formatter = "compact_dbg")]
pub encoding: IntEncoding,
pub(crate) num_values: u32,
}
impl StreamMeta {
#[inline]
pub(crate) fn new(stream_type: StreamType, encoding: IntEncoding, num_values: u32) -> Self {
Self {
stream_type,
encoding,
num_values,
}
}
#[inline]
pub(crate) fn new2(
stream_type: StreamType,
logical: LogicalEncoding,
physical: PhysicalEncoding,
num_values: usize,
) -> MltResult<Self> {
let enc = IntEncoding::new(logical, physical);
Ok(Self::new(stream_type, enc, u32::try_from(num_values)?))
}
#[inline]
pub(crate) fn new_none(stream_type: StreamType, num_values: usize) -> MltResult<Self> {
let enc = IntEncoding::none();
Ok(Self::new(stream_type, enc, u32::try_from(num_values)?))
}
}
#[derive(Clone, Dbg, PartialEq)]
pub struct RawStream<'a> {
pub meta: StreamMeta,
#[dbg(formatter = "bytes_dbg")]
pub(crate) data: &'a [u8],
}
impl<'a> RawStream<'a> {
#[must_use]
pub(crate) fn new(meta: StreamMeta, data: &'a [u8]) -> Self {
Self { meta, data }
}
}