use super::ChildId;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct HoverState {
pub(crate) path: Vec<ChildId>,
}
impl HoverState {
#[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::HoverState;
#[test]
fn path_queries_match_full_paths_and_prefixes_only() {
let hover = HoverState::intent(["left", "save"]);
assert!(hover.is_path(["left", "save"]));
assert!(!hover.is_path(["right", "save"]));
assert!(!hover.is_path(["save"]));
assert!(!hover.is_path(["left"]));
assert!(!hover.is_path(["left", "save", "extra"]));
assert!(hover.contains_path(["left"]));
assert!(hover.contains_path(["left", "save"]));
assert!(!hover.contains_path(["right"]));
assert!(!hover.contains_path(["save"]));
assert!(!hover.contains_path(["left", "save", "extra"]));
}
#[test]
fn path_queries_on_and_with_the_empty_path() {
let empty: [&str; 0] = [];
let unhovered = HoverState::default();
assert!(unhovered.is_path(empty));
assert!(unhovered.contains_path(empty));
assert!(!unhovered.is_path(["save"]));
assert!(!unhovered.contains_path(["save"]));
let hover = HoverState::intent(["left", "save"]);
assert!(!hover.is_path(empty));
assert!(hover.contains_path(empty));
}
}