use crate::node::Node;
#[derive(Clone, Debug)]
pub(crate) struct Bounds {
lower: usize,
upper: usize,
}
impl Default for Bounds {
fn default() -> Self {
Self {
lower: usize::MAX,
upper: 0,
}
}
}
impl Bounds {
pub(crate) fn compute<S, T>(node: &Node<S, T>) -> Self {
Self {
lower: Self::compute_lower(node),
upper: Self::compute_upper(node),
}
}
pub(crate) const fn lower(&self) -> usize {
self.lower
}
pub(crate) const fn upper(&self) -> usize {
self.upper
}
fn compute_lower<S, T>(node: &Node<S, T>) -> usize {
if node.data.is_some() {
return 0;
}
if node.end_wildcard.is_some() {
return 1;
}
let static_lengths = node
.static_children
.iter()
.map(|child| child.state.prefix.len().saturating_add(child.bounds.lower));
let dynamic_lengths = node
.dynamic_children
.iter()
.map(|child| child.bounds.lower.saturating_add(1));
let wildcard_lengths = node
.wildcard_children
.iter()
.map(|child| child.bounds.lower.saturating_add(1));
static_lengths
.chain(dynamic_lengths)
.chain(wildcard_lengths)
.min()
.unwrap_or(usize::MAX)
}
fn compute_upper<S, T>(node: &Node<S, T>) -> usize {
if node.has_parameters() {
return usize::MAX;
}
node.static_children
.iter()
.map(|child| child.state.prefix.len().saturating_add(child.bounds.upper))
.max()
.unwrap_or(0)
}
}