#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum VisitDecision {
#[default]
Continue,
SkipChildren,
Stop,
}
impl VisitDecision {
#[inline]
pub fn should_continue(&self) -> bool {
!matches!(self, Self::Stop)
}
#[inline]
pub fn should_visit_children(&self) -> bool {
matches!(self, Self::Continue)
}
#[inline]
pub fn should_stop(&self) -> bool {
matches!(self, Self::Stop)
}
pub fn combine(self, other: Self) -> Self {
match (self, other) {
(Self::Stop, _) | (_, Self::Stop) => Self::Stop,
(Self::SkipChildren, _) | (_, Self::SkipChildren) => Self::SkipChildren,
_ => Self::Continue,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_should_continue() {
assert!(VisitDecision::Continue.should_continue());
assert!(VisitDecision::SkipChildren.should_continue());
assert!(!VisitDecision::Stop.should_continue());
}
#[test]
fn test_should_visit_children() {
assert!(VisitDecision::Continue.should_visit_children());
assert!(!VisitDecision::SkipChildren.should_visit_children());
assert!(!VisitDecision::Stop.should_visit_children());
}
#[test]
fn test_should_stop() {
assert!(!VisitDecision::Continue.should_stop());
assert!(!VisitDecision::SkipChildren.should_stop());
assert!(VisitDecision::Stop.should_stop());
}
#[test]
fn test_combine_stop_wins() {
assert_eq!(
VisitDecision::Stop.combine(VisitDecision::Continue),
VisitDecision::Stop
);
assert_eq!(
VisitDecision::Continue.combine(VisitDecision::Stop),
VisitDecision::Stop
);
assert_eq!(
VisitDecision::Stop.combine(VisitDecision::SkipChildren),
VisitDecision::Stop
);
}
#[test]
fn test_combine_skip_children_wins() {
assert_eq!(
VisitDecision::SkipChildren.combine(VisitDecision::Continue),
VisitDecision::SkipChildren
);
assert_eq!(
VisitDecision::Continue.combine(VisitDecision::SkipChildren),
VisitDecision::SkipChildren
);
}
#[test]
fn test_combine_continue() {
assert_eq!(
VisitDecision::Continue.combine(VisitDecision::Continue),
VisitDecision::Continue
);
}
#[test]
fn test_default() {
assert_eq!(VisitDecision::default(), VisitDecision::Continue);
}
#[test]
fn test_equality() {
assert_eq!(VisitDecision::Continue, VisitDecision::Continue);
assert_ne!(VisitDecision::Continue, VisitDecision::Stop);
}
#[test]
fn test_clone_copy() {
let decision = VisitDecision::SkipChildren;
let cloned = decision;
assert_eq!(decision, cloned);
}
#[test]
fn test_debug() {
let debug = format!("{:?}", VisitDecision::Continue);
assert!(debug.contains("Continue"));
}
#[test]
fn test_hash() {
use std::collections::HashSet;
let mut set = HashSet::new();
set.insert(VisitDecision::Continue);
set.insert(VisitDecision::SkipChildren);
set.insert(VisitDecision::Stop);
assert_eq!(set.len(), 3);
}
}