use std::borrow::Cow;
use std::collections::BTreeMap;
use std::ops::Range;
use bitvec::order::Lsb0;
use bitvec::slice::BitSlice;
use bitvec::view::BitView as _;
use usize_cast::IntoUsize as _;
use crate::codecs::varint::parse_varint;
use crate::decoder::root02::{ColumnValues, parse_column_values, parse_strings};
use crate::decoder::stream::header02;
use crate::decoder::stream::header02::{
Count02, HAS_EXPLICIT_COUNT, StreamCtx02, is_packed_bitmap,
};
use crate::decoder::{
BoolLogical, Interior02, LogicalEncoding, MValues, NodeKind02, NodePresence, NodeType02,
ParsedStrings, PhysicalEncoding, RawPresence, RawStream, RawStrings,
};
use crate::tile::{MAX_NESTED_DEPTH, NestedKind, NestedValue, PropValue};
use crate::utils::{parse_string, parse_u8};
use crate::{Decode, DecodeState, Decoder, Lazy, MltError, MltRefResult, MltResult, Parser};
pub type Nested<'a, S = Lazy> = <S as DecodeState>::LazyOrParsed<RawNested<'a>, ParsedNested<'a>>;
const NODE_COST: u32 = 64;
#[derive(Debug, Clone, PartialEq)]
pub struct RawNested<'a> {
name: &'a str,
presence: RawPresence<'a>,
value_count: u32,
root: RawInterior<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum RawNode<'a> {
Interior(RawInterior<'a>),
Leaf(RawLeaf<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum RawInterior<'a> {
Struct(RawStruct<'a>),
List(RawList<'a>),
Map(RawMap<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawStruct<'a> {
presence: Option<RawStream<'a>>,
shapes: Option<RowShapes>,
fields: Vec<(&'a str, RawNode<'a>)>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawList<'a> {
presence: Option<RawStream<'a>>,
lengths: RawStream<'a>,
element: Box<RawNode<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawMap<'a> {
presence: Option<RawStream<'a>>,
shape: RawMapShape<'a>,
keys: Box<RawStrings<'a>>,
value: Box<RawNode<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
enum RawMapShape<'a> {
PerEntry(RawStream<'a>),
PerRow(RowShapes),
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawLeaf<'a> {
presence: Option<RawStream<'a>>,
values: Box<ColumnValues<'a>>,
}
impl RawNested<'_> {
#[must_use]
pub fn name(&self) -> &str {
self.name
}
pub(crate) fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
use crate::Analyze as _;
self.presence.for_each_stream(cb);
self.root.for_each_stream(cb);
}
}
impl RawNode<'_> {
fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
match self {
Self::Interior(i) => i.for_each_stream(cb),
Self::Leaf(l) => l.for_each_stream(cb),
}
}
}
impl RawInterior<'_> {
fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
match self {
Self::Struct(s) => s.for_each_stream(cb),
Self::List(l) => l.for_each_stream(cb),
Self::Map(m) => m.for_each_stream(cb),
}
}
}
impl RawStruct<'_> {
fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
use crate::Analyze as _;
self.presence.for_each_stream(cb);
for (_, node) in &self.fields {
node.for_each_stream(cb);
}
}
}
impl RawList<'_> {
fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
use crate::Analyze as _;
self.presence.for_each_stream(cb);
self.lengths.for_each_stream(cb);
self.element.for_each_stream(cb);
}
}
impl RawMap<'_> {
fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
use crate::Analyze as _;
self.presence.for_each_stream(cb);
if let RawMapShape::PerEntry(s) = &self.shape {
s.for_each_stream(cb);
}
self.keys.for_each_stream(cb);
self.value.for_each_stream(cb);
}
}
impl RawLeaf<'_> {
fn for_each_stream(&self, cb: &mut dyn FnMut(crate::decoder::StreamMeta)) {
use crate::Analyze as _;
self.presence.for_each_stream(cb);
self.values.for_each_stream(cb);
}
}
impl RawNested<'_> {
pub(crate) fn for_each_string_storage(
&self,
cb: &mut dyn FnMut(crate::decoder::ColumnStorage),
) {
self.root.for_each_string_storage(cb);
}
}
impl RawNode<'_> {
fn for_each_string_storage(&self, cb: &mut dyn FnMut(crate::decoder::ColumnStorage)) {
match self {
Self::Interior(i) => i.for_each_string_storage(cb),
Self::Leaf(l) => l.for_each_string_storage(cb),
}
}
}
impl RawInterior<'_> {
fn for_each_string_storage(&self, cb: &mut dyn FnMut(crate::decoder::ColumnStorage)) {
match self {
Self::Struct(s) => {
for (_, node) in &s.fields {
node.for_each_string_storage(cb);
}
}
Self::List(l) => l.element.for_each_string_storage(cb),
Self::Map(m) => {
cb(strings_storage(&m.keys));
m.value.for_each_string_storage(cb);
}
}
}
}
impl RawLeaf<'_> {
fn for_each_string_storage(&self, cb: &mut dyn FnMut(crate::decoder::ColumnStorage)) {
if let ColumnValues::Str(s) = &*self.values {
cb(strings_storage(s));
}
}
}
fn strings_storage(s: &RawStrings<'_>) -> crate::decoder::ColumnStorage {
use crate::decoder::{ColumnStorage, RawStringsEncoding, StringLayout};
let (string, dictionary) = match &s.encoding {
RawStringsEncoding::Plain(_) => (StringLayout::Plain, None),
RawStringsEncoding::Dictionary { dict, .. } => (StringLayout::Dict, Some(*dict)),
RawStringsEncoding::FsstPlain(_) => (StringLayout::Fsst, None),
RawStringsEncoding::FsstDictionary { dict, .. } => (StringLayout::FsstDict, Some(*dict)),
};
ColumnStorage {
string: Some(string),
dictionary,
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct RowShapes {
table: Vec<bool>,
width: usize,
ids: Vec<u32>,
}
impl RowShapes {
fn new(table: Vec<bool>, width: usize, ids: Vec<u32>) -> MltResult<Self> {
if width == 0 || !table.len().is_multiple_of(width) {
return Err(MltError::NestedRowShapeTableSize {
bits: table.len(),
keys: width,
});
}
let shapes = table.len() / width;
if let Some(&id) = ids.iter().find(|&&id| id.into_usize() >= shapes) {
return Err(MltError::NestedRowShapeOutOfRange { id, len: shapes });
}
Ok(Self { table, width, ids })
}
fn rows(&self) -> usize {
self.ids.len()
}
fn holds(&self, row: usize, key: usize) -> bool {
if key >= self.width {
return false;
}
let Some(&id) = self.ids.get(row) else {
return false;
};
self.table
.get(id.into_usize() * self.width + key)
.copied()
.unwrap_or(false)
}
fn held(&self, key: usize, dec: &mut Decoder) -> MltResult<Vec<bool>> {
let mut held = dec.alloc(self.rows())?;
held.extend((0..self.rows()).map(|row| self.holds(row, key)));
Ok(held)
}
fn present_count(&self, key: usize) -> MltResult<u32> {
Ok(u32::try_from(
(0..self.rows()).filter(|&row| self.holds(row, key)).count(),
)?)
}
pub(crate) fn child_count(&self, key: usize, parent: Count02) -> MltResult<Count02> {
Ok(match parent {
Count02::Explicit => Count02::Explicit,
Count02::Implied(_) => Count02::Implied(self.present_count(key)?),
})
}
fn length(&self, row: usize) -> usize {
(0..self.width).filter(|&key| self.holds(row, key)).count()
}
fn lengths(&self, dec: &mut Decoder) -> MltResult<Vec<u32>> {
let mut lengths = dec.alloc(self.rows())?;
for row in 0..self.rows() {
lengths.push(u32::try_from(self.length(row))?);
}
Ok(lengths)
}
fn codes(&self, dec: &mut Decoder) -> MltResult<Vec<u32>> {
let entries = (0..self.rows()).map(|row| self.length(row)).sum();
let mut codes = dec.alloc(entries)?;
for row in 0..self.rows() {
for key in 0..self.width {
if self.holds(row, key) {
codes.push(u32::try_from(key)?);
}
}
}
Ok(codes)
}
}
pub(crate) fn parse_nested<'a>(
input: &'a [u8],
name: &'a str,
presence: RawPresence<'a>,
kind: Interior02,
value_count: u32,
parser: &mut Parser,
) -> MltRefResult<'a, RawNested<'a>> {
parser.reserve(NODE_COST)?;
let count = if kind.has_lengths() {
Count02::Explicit
} else {
Count02::Implied(value_count)
};
let (input, per_row) = parse_root_per_row(input);
let body = Body {
presence: None,
count,
per_row,
};
let (input, root) = parse_interior(input, name, kind, body, 1, parser)?;
Ok((
input,
RawNested {
name,
presence,
value_count,
root,
},
))
}
fn parse_root_per_row(input: &[u8]) -> (&[u8], bool) {
match input.split_first() {
Some((&NodePresence::SHAPES, rest)) => (rest, true),
Some(_) | None => (input, false),
}
}
fn parse_node<'a>(
input: &'a [u8],
path: &str,
named: bool,
parent_count: Count02,
depth: usize,
parser: &mut Parser,
) -> MltRefResult<'a, (&'a str, RawNode<'a>)> {
if depth > MAX_NESTED_DEPTH {
return Err(MltError::NestedTooDeep(depth));
}
parser.reserve(NODE_COST)?;
let (input, typ_byte) = parse_u8(input)?;
let typ = NodeType02::parse(typ_byte)?;
let (input, name) = if named {
parse_string(input)?
} else {
(input, "")
};
let path = if name.is_empty() {
path.to_string()
} else {
format!("{path}.{name}")
};
let node_count = match typ.data.interior() {
Some(kind) if kind.has_lengths() => Count02::Explicit,
_ => parent_count,
};
let (input, presence) = match typ.presence {
NodePresence::AllPresent => (input, None),
NodePresence::Stream => {
require_bitmap_presence(input, &path)?;
require_explicit_count(input, &path, node_count)?;
let (input, stream) =
header02::parse_stream(input, StreamCtx02::NestedPresence, node_count, parser)?;
(input, Some(stream))
}
};
let body_count = match (node_count, &presence) {
(Count02::Explicit, _) => Count02::Explicit,
(Count02::Implied(_), Some(stream)) => Count02::Implied(presence_popcount(stream)?),
(Count02::Implied(count), None) => Count02::Implied(count),
};
let (input, node) = match typ.data {
NodeKind02::Leaf(values) => {
if typ.shapes {
return Err(MltError::NestedRowShapeUnsupported {
name: path,
kind: "leaf",
});
}
require_explicit_count(input, &path, body_count)?;
let (input, values) = parse_column_values(
input,
values,
name,
RawPresence::AllPresent,
body_count,
parser,
)?;
let values = Box::new(values);
(input, RawNode::Leaf(RawLeaf { presence, values }))
}
NodeKind02::Struct | NodeKind02::List | NodeKind02::Map => {
let kind = typ
.data
.interior()
.expect("an interior node names an interior");
let body = Body {
presence,
count: body_count,
per_row: typ.shapes,
};
let (input, interior) = parse_interior(input, &path, kind, body, depth, parser)?;
(input, RawNode::Interior(interior))
}
};
Ok((input, (name, node)))
}
struct Body<'a> {
presence: Option<RawStream<'a>>,
count: Count02,
per_row: bool,
}
fn parse_interior<'a>(
input: &'a [u8],
path: &str,
kind: Interior02,
body: Body<'a>,
depth: usize,
parser: &mut Parser,
) -> MltRefResult<'a, RawInterior<'a>> {
let Body {
presence,
count,
per_row,
} = body;
Ok(match kind {
Interior02::Struct => {
let (mut input, field_count) = parse_varint::<u32>(input)?;
if field_count == 0 {
return Err(MltError::EmptyStructNode);
}
if input.len() < field_count.into_usize() {
return Err(MltError::BufferUnderflow(field_count, input.len()));
}
parser.reserve(field_count.saturating_mul(NODE_COST))?;
let mut shapes = None;
if per_row {
let found;
(input, found) = parse_row_shapes(input, field_count, count, path, parser)?;
shapes = Some(found);
}
let mut fields: Vec<(&'a str, RawNode<'a>)> =
Vec::with_capacity(field_count.into_usize());
for index in 0..field_count.into_usize() {
let count = match &shapes {
Some(shapes) => {
reject_shaped_child_presence(input, path)?;
shapes.child_count(index, count)?
}
None => count,
};
let field;
(input, field) = parse_node(input, path, true, count, depth + 1, parser)?;
if fields.iter().any(|(name, _)| *name == field.0) {
return Err(MltError::DuplicateFieldName(field.0.to_string()));
}
fields.push(field);
}
(
input,
RawInterior::Struct(RawStruct {
presence,
shapes,
fields,
}),
)
}
Interior02::List => {
if per_row {
return Err(MltError::NestedRowShapeUnsupported {
name: path.to_string(),
kind: "list",
});
}
require_explicit_count(input, path, count)?;
let (input, lengths) =
header02::parse_stream(input, StreamCtx02::NestedLengths, count, parser)?;
let (input, (_, element)) =
parse_node(input, path, false, Count02::Explicit, depth + 1, parser)?;
(
input,
RawInterior::List(RawList {
presence,
lengths,
element: Box::new(element),
}),
)
}
Interior02::Map => {
let (input, keys, shape) = if per_row {
require_explicit_count(input, path, Count02::Explicit)?;
let (input, keys) = parse_strings(
input,
"",
RawPresence::AllPresent,
Count02::Explicit,
parser,
)?;
let (input, shapes) =
parse_row_shapes(input, keys.value_count(), count, path, parser)?;
(input, keys, RawMapShape::PerRow(shapes))
} else {
require_explicit_count(input, path, count)?;
let (input, lengths) =
header02::parse_stream(input, StreamCtx02::NestedLengths, count, parser)?;
require_explicit_count(input, path, Count02::Explicit)?;
let (input, keys) = parse_strings(
input,
"",
RawPresence::AllPresent,
Count02::Explicit,
parser,
)?;
(input, keys, RawMapShape::PerEntry(lengths))
};
let (input, (_, value)) =
parse_node(input, path, false, Count02::Explicit, depth + 1, parser)?;
(
input,
RawInterior::Map(RawMap {
presence,
shape,
keys: Box::new(keys),
value: Box::new(value),
}),
)
}
})
}
pub(crate) fn parse_row_shapes<'a>(
input: &'a [u8],
keys: u32,
rows: Count02,
path: &str,
parser: &mut Parser,
) -> MltRefResult<'a, RowShapes> {
require_explicit_count(input, path, Count02::Explicit)?;
require_bitmap_presence(input, path)?;
let (input, table) = header02::parse_stream(
input,
StreamCtx02::NestedShapeTable,
Count02::Explicit,
parser,
)?;
require_explicit_count(input, path, Count02::Explicit)?;
let (input, ids) = header02::parse_stream(
input,
StreamCtx02::NestedShapeIds,
Count02::Explicit,
parser,
)?;
let mut dec = Decoder::default();
let shapes = RowShapes::new(
table.decode_bools(&mut dec)?,
keys.into_usize(),
ids.decode_ints::<u32>(&mut dec)?,
)?;
if let Count02::Implied(expected) = rows
&& u32::try_from(shapes.rows())? != expected
{
return Err(MltError::NestedRowShapeCount {
name: path.to_string(),
expected,
actual: u32::try_from(shapes.rows())?,
});
}
Ok((input, shapes))
}
pub(crate) fn reject_shaped_child_presence(input: &[u8], path: &str) -> MltResult<()> {
let (_, typ_byte) = parse_u8(input)?;
if NodeType02::parse(typ_byte)?.presence == NodePresence::Stream {
return Err(MltError::NestedRowShapeChildPresence {
name: path.to_string(),
});
}
Ok(())
}
fn require_explicit_count(input: &[u8], path: &str, count: Count02) -> MltResult<()> {
if count != Count02::Explicit {
return Ok(());
}
let (_, enc_byte) = parse_u8(input)?;
if enc_byte & HAS_EXPLICIT_COUNT == 0 {
return Err(MltError::NestedImplicitCount {
name: path.to_string(),
byte: enc_byte,
});
}
Ok(())
}
fn require_bitmap_presence(input: &[u8], path: &str) -> MltResult<()> {
let (_, enc_byte) = parse_u8(input)?;
if !is_packed_bitmap(enc_byte) {
return Err(MltError::NestedPresenceEncoding {
name: path.to_string(),
byte: enc_byte,
});
}
Ok(())
}
pub(crate) fn presence_popcount(stream: &RawStream<'_>) -> MltResult<u32> {
let encoding = stream.meta.encoding;
if encoding.logical != LogicalEncoding::Bool(BoolLogical::None) {
return Err(MltError::UnsupportedLogicalEncoding(
encoding.logical,
"a nested presence stream, which is a raw packed bitmap",
));
}
if encoding.physical != PhysicalEncoding::None {
return Err(MltError::UnsupportedPhysicalEncodingForType(
encoding.physical,
"a nested presence stream, which is a raw packed bitmap",
));
}
let count = stream.meta.num_values.into_usize();
let bytes = stream
.data
.get(..count.div_ceil(8))
.ok_or(MltError::UnableToTake(stream.meta.num_values))?;
Ok(u32::try_from(
bytes.view_bits::<Lsb0>()[..count].count_ones(),
)?)
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedNested<'a> {
name: &'a str,
presence: Option<Cow<'a, BitSlice<u8, Lsb0>>>,
root: ParsedInterior<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParsedNode<'a> {
Interior(ParsedInterior<'a>),
Leaf(ParsedLeaf<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParsedInterior<'a> {
Struct(ParsedStruct<'a>),
List(ParsedList<'a>),
Map(ParsedMap<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedStruct<'a> {
presence: Option<Vec<bool>>,
fields: Vec<(&'a str, ParsedNode<'a>)>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedList<'a> {
presence: Option<Vec<bool>>,
lengths: Vec<u32>,
element: Box<ParsedNode<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedMap<'a> {
presence: Option<Vec<bool>>,
lengths: Vec<u32>,
keys: MapKeys<'a>,
value: Box<ParsedNode<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum MapKeys<'a> {
PerEntry(ParsedStrings<'a>),
Coded {
keys: ParsedStrings<'a>,
codes: Vec<u32>,
},
}
impl<'a> MapKeys<'a> {
fn strings(&self) -> &ParsedStrings<'a> {
match self {
Self::PerEntry(keys) | Self::Coded { keys, .. } => keys,
}
}
fn entry_count(&self) -> usize {
match self {
Self::PerEntry(keys) => keys.feature_count(),
Self::Coded { codes, .. } => codes.len(),
}
}
fn key(&self, entry: usize) -> Option<&str> {
match self {
Self::PerEntry(keys) => keys.get(u32::try_from(entry).ok()?),
Self::Coded { keys, codes } => keys.get(*codes.get(entry)?),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedLeaf<'a> {
presence: Option<Vec<bool>>,
values: MValues<'a>,
}
impl<'a> Decode<ParsedNested<'a>> for RawNested<'a> {
fn decode(self, dec: &mut Decoder) -> MltResult<ParsedNested<'a>> {
let root = self.root.decode(dec)?;
let parsed = ParsedNested {
name: self.name,
presence: self.presence.decode_bits(dec)?,
root,
};
parsed.root.check_counts()?;
let handed = parsed.root.parent_count();
if handed != self.value_count.into_usize() {
return Err(MltError::NestedRootCountMismatch {
name: self.name.to_string(),
expected: self.value_count,
actual: u32::try_from(handed)?,
});
}
Ok(parsed)
}
}
impl<'a> Decode<ParsedNode<'a>> for RawNode<'a> {
fn decode(self, dec: &mut Decoder) -> MltResult<ParsedNode<'a>> {
Ok(match self {
Self::Interior(interior) => ParsedNode::Interior(interior.decode(dec)?),
Self::Leaf(leaf) => ParsedNode::Leaf(ParsedLeaf {
presence: decode_node_presence(leaf.presence, dec)?,
values: (*leaf.values).decode(dec)?,
}),
})
}
}
impl<'a> Decode<ParsedInterior<'a>> for RawInterior<'a> {
fn decode(self, dec: &mut Decoder) -> MltResult<ParsedInterior<'a>> {
Ok(match self {
Self::Struct(node) => {
let presence = decode_node_presence(node.presence, dec)?;
let mut fields = dec.alloc::<(&'a str, ParsedNode<'a>)>(node.fields.len())?;
for (index, (name, field)) in node.fields.into_iter().enumerate() {
let mut field = field.decode(dec)?;
if let Some(shapes) = &node.shapes {
field.set_presence(shapes.held(index, dec)?);
}
fields.push((name, field));
}
ParsedInterior::Struct(ParsedStruct { presence, fields })
}
Self::List(node) => ParsedInterior::List(ParsedList {
presence: decode_node_presence(node.presence, dec)?,
lengths: node.lengths.decode_ints::<u32>(dec)?,
element: Box::new(node.element.decode(dec)?),
}),
Self::Map(node) => {
let presence = decode_node_presence(node.presence, dec)?;
let keys = node.keys.decode(dec)?;
let (lengths, keys) = match node.shape {
RawMapShape::PerEntry(lengths) => {
(lengths.decode_ints::<u32>(dec)?, MapKeys::PerEntry(keys))
}
RawMapShape::PerRow(shapes) => (
shapes.lengths(dec)?,
MapKeys::Coded {
codes: shapes.codes(dec)?,
keys,
},
),
};
ParsedInterior::Map(ParsedMap {
presence,
lengths,
keys,
value: Box::new(node.value.decode(dec)?),
})
}
})
}
}
impl ParsedNode<'_> {
fn set_presence(&mut self, presence: Vec<bool>) {
*match self {
Self::Interior(ParsedInterior::Struct(node)) => &mut node.presence,
Self::Interior(ParsedInterior::List(node)) => &mut node.presence,
Self::Interior(ParsedInterior::Map(node)) => &mut node.presence,
Self::Leaf(leaf) => &mut leaf.presence,
} = Some(presence);
}
}
fn decode_node_presence(
presence: Option<RawStream<'_>>,
dec: &mut Decoder,
) -> MltResult<Option<Vec<bool>>> {
presence.map(|stream| stream.decode_bools(dec)).transpose()
}
impl<'a> ParsedNested<'a> {
#[must_use]
pub fn name(&self) -> &'a str {
self.name
}
#[must_use]
pub fn is_present(&self, index: usize) -> bool {
self.presence
.as_deref()
.is_none_or(|bits| bits.get(index).as_deref().copied().unwrap_or(false))
}
#[must_use]
pub fn kind(&self) -> NestedKind {
self.root.kind()
}
pub fn row(&self, index: usize) -> MltResult<NestedValue> {
if !self.is_present(index) {
return Ok(self.root.kind().null_value());
}
let row = match self.presence.as_deref() {
Some(bits) => bits[..index].count_ones(),
None => index,
};
Ok(self
.root
.row(row)?
.unwrap_or_else(|| self.root.kind().null_value()))
}
}
impl ParsedInterior<'_> {
fn parent_count(&self) -> usize {
match self {
Self::Struct(node) => node
.presence
.as_ref()
.map_or_else(|| node.present_count(), Vec::len),
Self::List(node) => node.presence.as_ref().map_or(node.lengths.len(), Vec::len),
Self::Map(node) => node.presence.as_ref().map_or(node.lengths.len(), Vec::len),
}
}
fn check_counts(&self) -> MltResult<()> {
match self {
Self::Struct(node) => {
let present = node.present_count();
for (_, field) in &node.fields {
expect_count(present, field.parent_count())?;
field.check_counts()?;
}
}
Self::List(node) => {
let entries = sum_lengths(&node.lengths)?;
expect_count(entries.into_usize(), node.element.parent_count())?;
node.element.check_counts()?;
}
Self::Map(node) => {
let entries = sum_lengths(&node.lengths)?;
expect_count(entries.into_usize(), node.keys.entry_count())?;
expect_count(entries.into_usize(), node.value.parent_count())?;
node.value.check_counts()?;
}
}
Ok(())
}
fn kind(&self) -> NestedKind {
match self {
Self::Struct(node) => NestedKind::Map(
node.fields
.iter()
.map(|(name, field)| ((*name).to_string(), field.kind()))
.collect(),
),
Self::List(node) => NestedKind::List(Box::new(node.element.kind())),
Self::Map(node) => {
let keys = node.keys.strings();
NestedKind::Map(
(0..keys.feature_count())
.filter_map(|i| keys.get(u32::try_from(i).ok()?))
.map(|key| (key.to_string(), node.value.kind()))
.collect(),
)
}
}
}
fn row(&self, row: usize) -> MltResult<Option<NestedValue>> {
match self {
Self::Struct(node) => {
let Some(own) = dense_index(node.presence.as_deref(), row) else {
return Ok(None);
};
let mut entries = BTreeMap::new();
for (name, field) in &node.fields {
if let Some(value) = field.row(own)? {
entries.insert((*name).to_string(), value);
}
}
Ok(Some(NestedValue::Map(Some(entries))))
}
Self::List(node) => {
let Some(own) = dense_index(node.presence.as_deref(), row) else {
return Ok(None);
};
let span = span_of(&node.lengths, own)?;
let mut items = Vec::with_capacity(span.len());
for entry in span {
items.push(
node.element
.row(entry)?
.unwrap_or_else(|| node.element.kind().null_value()),
);
}
Ok(Some(NestedValue::List(Some(items))))
}
Self::Map(node) => {
let Some(own) = dense_index(node.presence.as_deref(), row) else {
return Ok(None);
};
let span = span_of(&node.lengths, own)?;
let mut entries = BTreeMap::new();
for entry in span {
let key = node.keys.key(entry).ok_or(MltError::NestedKeyOutOfRange {
entry,
len: node.keys.entry_count(),
})?;
if let Some(value) = node.value.row(entry)? {
entries.insert(key.to_string(), value);
}
}
Ok(Some(NestedValue::Map(Some(entries))))
}
}
}
}
impl ParsedStruct<'_> {
fn present_count(&self) -> usize {
match &self.presence {
Some(bits) => bits.iter().filter(|&&bit| bit).count(),
None => self.fields.first().map_or(0, |(_, f)| f.parent_count()),
}
}
}
impl ParsedNode<'_> {
fn parent_count(&self) -> usize {
match self {
Self::Interior(interior) => interior.parent_count(),
Self::Leaf(leaf) => leaf
.presence
.as_ref()
.map_or_else(|| leaf.values.len(), Vec::len),
}
}
fn check_counts(&self) -> MltResult<()> {
match self {
Self::Interior(interior) => interior.check_counts(),
Self::Leaf(_) => Ok(()),
}
}
fn kind(&self) -> NestedKind {
match self {
Self::Interior(interior) => interior.kind(),
Self::Leaf(leaf) => NestedKind::Leaf(leaf.values.kind()),
}
}
fn row(&self, row: usize) -> MltResult<Option<NestedValue>> {
match self {
Self::Interior(interior) => interior.row(row),
Self::Leaf(leaf) => {
let Some(own) = dense_index(leaf.presence.as_deref(), row) else {
return Ok(None);
};
let value = leaf.values.value(own)?;
Ok(Some(NestedValue::Leaf(value)))
}
}
}
}
fn dense_index(presence: Option<&[bool]>, row: usize) -> Option<usize> {
match presence {
None => Some(row),
Some(bits) => bits
.get(row)
.copied()
.unwrap_or(false)
.then(|| bits[..row].iter().filter(|&&bit| bit).count()),
}
}
fn span_of(lengths: &[u32], row: usize) -> MltResult<Range<usize>> {
let start: usize = lengths[..row.min(lengths.len())]
.iter()
.map(|&len| len.into_usize())
.sum();
let len = lengths
.get(row)
.copied()
.ok_or(MltError::NestedRowOutOfRange {
row,
len: lengths.len(),
})?
.into_usize();
Ok(start..start + len)
}
fn sum_lengths(lengths: &[u32]) -> MltResult<u32> {
lengths
.iter()
.try_fold(0_u32, |acc, &len| acc.checked_add(len))
.ok_or(MltError::IntegerOverflow)
}
fn expect_count(expected: usize, actual: usize) -> MltResult<()> {
if expected == actual {
return Ok(());
}
Err(MltError::NestedCountMismatch {
expected: u32::try_from(expected)?,
actual: u32::try_from(actual)?,
})
}
impl MValues<'_> {
pub(crate) fn value(&self, index: usize) -> MltResult<PropValue> {
let missing = || MltError::NestedValueOutOfRange {
index,
len: self.len(),
};
macro_rules! one {
($values:expr, $variant:ident) => {
PropValue::$variant(Some(*$values.get(index).ok_or_else(missing)?))
};
}
Ok(match self {
Self::Bool(v) => one!(v, Bool),
Self::I8(v) => one!(v, I8),
Self::U8(v) => one!(v, U8),
Self::I32(v) => one!(v, I32),
Self::U32(v) => one!(v, U32),
Self::I64(v) => one!(v, I64),
Self::U64(v) => one!(v, U64),
Self::F32(v) => one!(v, F32),
Self::F64(v) => one!(v, F64),
Self::Str(v) => {
let value = v.get(u32::try_from(index)?).ok_or_else(missing)?;
PropValue::Str(Some(value.to_string()))
}
})
}
}