#![cfg_attr(feature = "rkyv_08", allow(missing_docs))]
use nonmax::NonMaxUsize;
use super::{
resolve_arithmetic_terminal_stem_idx, resolve_mapped_terminal_stem_idx, StemLeafResolution,
};
#[cfg_attr(
feature = "rkyv_08",
derive(rkyv_08::Archive, rkyv_08::Serialize, rkyv_08::Deserialize)
)]
#[cfg_attr(feature = "rkyv_08", rkyv(crate = rkyv_08))]
#[cfg_attr(feature = "rkyv_08", rkyv(attr(allow(missing_docs))))]
#[cfg_attr(
feature = "rkyv_08",
rkyv(archived = ArchivedStemLeafResolution)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(missing_docs)]
#[derive(Clone, Debug, PartialEq)]
pub enum OwnedStemLeafResolution {
Arithmetic {
stems_depth: usize,
leaf_count: usize,
},
Pristine {
stems_depth: usize,
leaf_count: usize,
},
Mapped {
min_stem_leaf_idx: usize,
#[cfg_attr(
feature = "serde",
serde(with = "crate::custom_serde::option_nonmax_usize_vec")
)]
#[cfg_attr(
feature = "rkyv_08",
rkyv(with = rkyv_08::with::Map<crate::rkyv::adapters::OptionNonMaxUsizeAsUsize>)
)]
leaf_idx_map: Vec<Option<NonMaxUsize>>,
},
}
impl StemLeafResolution for OwnedStemLeafResolution {
#[inline(always)]
fn uses_arithmetic(&self) -> bool {
matches!(self, Self::Arithmetic { .. } | Self::Pristine { .. })
}
#[inline(always)]
fn resolve_terminal_stem_idx(&self, stem_idx: usize, arithmetic_leaf_idx: usize) -> usize {
match self {
Self::Mapped {
min_stem_leaf_idx,
leaf_idx_map,
} => resolve_mapped_terminal_stem_idx(
stem_idx,
*min_stem_leaf_idx,
leaf_idx_map.len(),
|map_idx| {
leaf_idx_map
.get(map_idx)
.and_then(|opt| opt.map(|n| n.get()))
},
),
Self::Arithmetic {
stems_depth,
leaf_count,
}
| Self::Pristine {
stems_depth,
leaf_count,
} => resolve_arithmetic_terminal_stem_idx(
stem_idx,
arithmetic_leaf_idx,
*stems_depth,
*leaf_count,
),
}
}
#[inline(always)]
fn is_terminal_stem_idx(&self, stem_idx: usize) -> bool {
match self {
Self::Mapped {
min_stem_leaf_idx,
leaf_idx_map,
} if stem_idx >= *min_stem_leaf_idx => {
let map_idx = stem_idx - *min_stem_leaf_idx;
leaf_idx_map.get(map_idx).is_some_and(Option::is_some)
}
_ => false,
}
}
}
impl OwnedStemLeafResolution {
#[inline(always)]
pub fn uses_arithmetic(&self) -> bool {
<Self as StemLeafResolution>::uses_arithmetic(self)
}
#[inline(always)]
pub fn resolve_terminal_stem_idx(&self, stem_idx: usize, arithmetic_leaf_idx: usize) -> usize {
<Self as StemLeafResolution>::resolve_terminal_stem_idx(self, stem_idx, arithmetic_leaf_idx)
}
#[inline(always)]
pub fn is_terminal_stem_idx(&self, stem_idx: usize) -> bool {
<Self as StemLeafResolution>::is_terminal_stem_idx(self, stem_idx)
}
}
#[cfg(feature = "rkyv_08")]
impl StemLeafResolution for ArchivedStemLeafResolution {
#[inline(always)]
fn uses_arithmetic(&self) -> bool {
matches!(self, Self::Arithmetic { .. } | Self::Pristine { .. })
}
#[inline(always)]
fn resolve_terminal_stem_idx(&self, stem_idx: usize, arithmetic_leaf_idx: usize) -> usize {
match self {
Self::Mapped {
min_stem_leaf_idx,
leaf_idx_map,
} => resolve_mapped_terminal_stem_idx(
stem_idx,
min_stem_leaf_idx.to_native() as usize,
leaf_idx_map.len(),
|map_idx| {
let value = leaf_idx_map.get(map_idx)?.to_native() as usize;
crate::rkyv::adapters::archived_option_nonmax_usize_is_some(value)
.then_some(value)
},
),
Self::Arithmetic {
stems_depth,
leaf_count,
}
| Self::Pristine {
stems_depth,
leaf_count,
} => resolve_arithmetic_terminal_stem_idx(
stem_idx,
arithmetic_leaf_idx,
stems_depth.to_native() as usize,
leaf_count.to_native() as usize,
),
}
}
#[inline(always)]
fn is_terminal_stem_idx(&self, stem_idx: usize) -> bool {
match self {
Self::Mapped {
min_stem_leaf_idx,
leaf_idx_map,
} => {
let min_stem_leaf_idx = min_stem_leaf_idx.to_native() as usize;
if stem_idx >= min_stem_leaf_idx {
let map_idx = stem_idx - min_stem_leaf_idx;
leaf_idx_map.get(map_idx).is_some_and(|value| {
crate::rkyv::adapters::archived_option_nonmax_usize_is_some(
value.to_native() as usize,
)
})
} else {
false
}
}
_ => false,
}
}
}