use super::types::{WizardStep, WizardStepKind, StepKindRef};
pub(super) fn step_kind_at(
steps: &'static [WizardStep],
target: usize,
counter: &mut usize,
) -> Option<StepKindRef> {
for step in steps {
match &step.kind {
WizardStepKind::Section(children) => {
if let r @ Some(_) = step_kind_at(children, target, counter) {
return r;
}
}
_ => {
if *counter == target {
return Some(match &step.kind {
WizardStepKind::Leaf => StepKindRef::Leaf,
WizardStepKind::Optional => StepKindRef::Optional,
WizardStepKind::Select(opts) => StepKindRef::Select(opts),
WizardStepKind::Array(sub_steps) => StepKindRef::Array(sub_steps),
WizardStepKind::Buttons(labels) => StepKindRef::Buttons(labels),
WizardStepKind::Section(_) => unreachable!(),
});
}
*counter += 1;
}
}
}
None
}
pub(super) fn count_leaves(steps: &[WizardStep]) -> usize {
steps.iter().map(|s| match &s.kind {
WizardStepKind::Section(children) => count_leaves(children),
_ => 1,
}).sum()
}
pub(super) fn max_sub_label(sub_steps: &[WizardStep]) -> usize {
sub_steps.iter().map(|s| s.label.chars().count()).max().unwrap_or(4)
}
pub(super) fn prev_char_boundary(s: &str, pos: usize) -> usize {
if pos == 0 { return 0; }
let mut p = pos - 1;
while !s.is_char_boundary(p) { p -= 1; }
p
}
pub(super) fn next_char_boundary(s: &str, pos: usize) -> usize {
if pos >= s.len() { return s.len(); }
let mut p = pos + 1;
while p < s.len() && !s.is_char_boundary(p) { p += 1; }
p
}