use super::ChildId;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct FocusState {
pub(crate) path: Vec<ChildId>,
}
impl FocusState {
#[must_use]
pub fn intent(path: impl IntoIterator<Item = impl Into<ChildId>>) -> Self {
Self {
path: path.into_iter().map(Into::into).collect(),
}
}
#[must_use]
pub fn is_path(&self, path: impl IntoIterator<Item = impl Into<ChildId>>) -> bool {
let mut ids = self.path.iter();
path.into_iter().all(|id| ids.next() == Some(&id.into())) && ids.next().is_none()
}
#[must_use]
pub fn contains_path(&self, path: impl IntoIterator<Item = impl Into<ChildId>>) -> bool {
let mut ids = self.path.iter();
path.into_iter().all(|id| ids.next() == Some(&id.into()))
}
#[must_use]
pub fn path(&self) -> &[ChildId] {
&self.path
}
}
#[cfg(test)]
mod tests {
use super::FocusState;
#[test]
fn is_path_matches_the_full_path_only() {
let focus = FocusState::intent(["left", "save"]);
assert!(focus.is_path(["left", "save"]));
assert!(!focus.is_path(["right", "save"]));
assert!(!focus.is_path(["save"]));
assert!(!focus.is_path(["left"]));
assert!(!focus.is_path(["left", "save", "extra"]));
}
#[test]
fn contains_path_matches_prefixes_of_the_path() {
let focus = FocusState::intent(["left", "save"]);
assert!(focus.contains_path(["left"]));
assert!(focus.contains_path(["left", "save"]));
assert!(!focus.contains_path(["right"]));
assert!(!focus.contains_path(["save"]));
assert!(!focus.contains_path(["left", "save", "extra"]));
}
#[test]
fn path_queries_on_a_single_segment_path() {
let focus = FocusState::intent(["save"]);
assert!(focus.is_path(["save"]));
assert!(focus.contains_path(["save"]));
assert!(!focus.is_path(["left", "save"]));
assert!(!focus.contains_path(["left", "save"]));
}
#[test]
fn path_queries_on_and_with_the_empty_path() {
let empty: [&str; 0] = [];
let unresolved = FocusState::default();
assert!(unresolved.is_path(empty));
assert!(unresolved.contains_path(empty));
assert!(!unresolved.is_path(["save"]));
assert!(!unresolved.contains_path(["save"]));
let focus = FocusState::intent(["left", "save"]);
assert!(!focus.is_path(empty));
assert!(focus.contains_path(empty));
}
#[test]
fn path_queries_compare_static_and_dynamic_ids_by_content() {
let focus = FocusState::intent([String::from("left"), String::from("save")]);
assert!(focus.is_path(["left", "save"]));
assert!(!focus.is_path(["right", "save"]));
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TabWrap {
#[default]
Escape,
Wrap,
}