use std::borrow::Cow;
use std::ops::Deref;
#[cfg(feature = "unstable-v2")]
use bitvec::order::Lsb0;
#[cfg(feature = "unstable-v2")]
use bitvec::slice::BitSlice;
use enum_dispatch::enum_dispatch;
#[cfg(feature = "unstable-v2")]
use crate::decoder::Alp;
use crate::decoder::RawStream;
use crate::utils::Presence;
use crate::{DecodeState, Lazy};
pub type Property<'a, S = Lazy> =
<S as DecodeState>::LazyOrParsed<RawProperty<'a>, ParsedProperty<'a>>;
#[derive(Debug, Clone, PartialEq)]
pub struct RawScalar<'a> {
pub(crate) name: &'a str,
pub(crate) presence: RawPresence<'a>,
pub(crate) data: RawStream<'a>,
}
impl<'a> RawScalar<'a> {
pub(crate) fn new(name: &'a str, presence: RawPresence<'a>, data: RawStream<'a>) -> Self {
Self {
name,
presence,
data,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawFloats<'a> {
pub name: &'a str,
pub presence: RawPresence<'a>,
pub encoding: RawFloatsEncoding<'a>,
}
impl<'a> RawFloats<'a> {
pub(crate) fn single(name: &'a str, presence: RawPresence<'a>, data: RawStream<'a>) -> Self {
Self {
name,
presence,
encoding: RawFloatsEncoding::Single(data),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum RawFloatsEncoding<'a> {
Single(RawStream<'a>),
#[cfg(feature = "unstable-v2")]
Dictionary {
codes: RawStream<'a>,
dictionary: RawStream<'a>,
},
#[cfg(feature = "unstable-v2")]
Alp { params: Alp, data: RawStream<'a> },
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawStrings<'a> {
pub name: &'a str,
pub presence: RawPresence<'a>,
pub encoding: RawStringsEncoding<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum RawStringsEncoding<'a> {
Plain(RawPlainData<'a>),
Dictionary {
plain_data: RawPlainData<'a>,
offsets: RawStream<'a>,
dict: DictLayout,
},
FsstPlain(RawFsstData<'a>),
FsstDictionary {
fsst_data: RawFsstData<'a>,
offsets: RawStream<'a>,
dict: DictLayout,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::EnumIter)]
pub enum DictLayout {
Plain,
#[cfg(feature = "unstable-v2")]
FrontCoded,
}
#[derive(Debug, Clone, PartialEq)]
pub enum RawSharedDictEncoding<'a> {
Plain(RawPlainData<'a>),
FsstPlain(RawFsstData<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawSharedDict<'a> {
pub name: &'a str,
pub encoding: RawSharedDictEncoding<'a>,
pub dict: DictLayout,
pub children: Vec<RawSharedDictItem<'a>>,
}
#[derive(Debug, PartialEq, Clone)]
pub enum RawProperty<'a> {
Bool(RawScalar<'a>),
I8(RawScalar<'a>),
U8(RawScalar<'a>),
I32(RawScalar<'a>),
U32(RawScalar<'a>),
I64(RawScalar<'a>),
U64(RawScalar<'a>),
F32(RawFloats<'a>),
F64(RawFloats<'a>),
Str(RawStrings<'a>),
SharedDict(RawSharedDict<'a>),
}
#[derive(Clone, Debug, PartialEq, strum::IntoStaticStr)]
#[strum(serialize_all = "snake_case")]
#[enum_dispatch(Analyze)]
pub enum ParsedProperty<'a> {
Bool(ParsedScalar<'a, bool>),
I8(ParsedScalar<'a, i8>),
U8(ParsedScalar<'a, u8>),
I32(ParsedScalar<'a, i32>),
U32(ParsedScalar<'a, u32>),
I64(ParsedScalar<'a, i64>),
U64(ParsedScalar<'a, u64>),
F32(ParsedScalar<'a, f32>),
F64(ParsedScalar<'a, f64>),
Str(ParsedStrings<'a>),
SharedDict(ParsedSharedDict<'a>),
}
#[derive(Clone, Debug, PartialEq)]
pub struct ParsedScalar<'a, T: Copy + PartialEq> {
pub(crate) name: &'a str,
pub(crate) presence: Presence<'a, T>,
}
impl<'a, T: Copy + PartialEq> Deref for ParsedScalar<'a, T> {
type Target = Presence<'a, T>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.presence
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct DictRange {
pub start: i32,
pub end: i32,
}
impl DictRange {
pub const NULL: Self = Self { start: -1, end: -1 };
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(all(not(test), feature = "arbitrary"), derive(arbitrary::Arbitrary))]
pub struct ParsedSharedDictItem<'a> {
pub(crate) suffix: &'a str,
pub(crate) ranges: Vec<DictRange>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParsedStrings<'a> {
pub(crate) name: &'a str,
pub(crate) lengths: Vec<i32>,
pub(crate) data: Cow<'a, str>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParsedSharedDict<'a> {
pub(crate) prefix: &'a str,
pub(crate) data: Cow<'a, str>,
pub(crate) items: Vec<ParsedSharedDictItem<'a>>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct RawSharedDictItem<'a> {
pub name: &'a str,
pub presence: RawPresence<'a>,
pub data: RawStream<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawPlainData<'a> {
pub lengths: RawStream<'a>,
pub data: RawStream<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawFsstData<'a> {
pub symbol_lengths: RawStream<'a>,
pub symbol_table: RawStream<'a>,
pub lengths: RawStream<'a>,
pub corpus: RawStream<'a>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub enum RawPresence<'a> {
#[default]
AllPresent,
Stream(RawStream<'a>),
#[cfg(feature = "unstable-v2")]
Bitfield(&'a BitSlice<u8, Lsb0>),
}
impl RawPresence<'_> {
#[must_use]
pub(crate) fn is_optional(&self) -> bool {
!matches!(self, Self::AllPresent)
}
}