use crate::Pattern;
impl<V> Pattern<V> {
pub fn depth_at(&self) -> Pattern<usize> {
self.extend(&|subpattern| subpattern.depth())
}
pub fn size_at(&self) -> Pattern<usize> {
self.extend(&|subpattern| subpattern.size())
}
pub fn indices_at(&self) -> Pattern<Vec<usize>> {
fn go<V>(path: Vec<usize>, pattern: &Pattern<V>) -> Pattern<Vec<usize>> {
Pattern {
value: path.clone(),
elements: pattern
.elements()
.iter()
.enumerate()
.map(|(i, elem)| {
let mut new_path = path.clone();
new_path.push(i);
go(new_path, elem)
})
.collect(),
}
}
go(vec![], self)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn depth_at_atomic_pattern() {
let p = Pattern::point("x");
let depths = p.depth_at();
assert_eq!(depths.extract(), &0);
}
#[test]
fn depth_at_with_children() {
let p = Pattern::pattern("root", vec![Pattern::point("a"), Pattern::point("b")]);
let depths = p.depth_at();
assert_eq!(depths.extract(), &1); }
#[test]
fn depth_at_nested() {
let p = Pattern::pattern(
"root",
vec![Pattern::pattern("a", vec![Pattern::point("x")])],
);
let depths = p.depth_at();
assert_eq!(depths.extract(), &2); assert_eq!(depths.elements()[0].extract(), &1);
}
#[test]
fn size_at_atomic_pattern() {
let p = Pattern::point("x");
let sizes = p.size_at();
assert_eq!(sizes.extract(), &1);
}
#[test]
fn size_at_with_children() {
let p = Pattern::pattern(
"root",
vec![
Pattern::point("a"),
Pattern::point("b"),
Pattern::point("c"),
],
);
let sizes = p.size_at();
assert_eq!(sizes.extract(), &4); assert_eq!(sizes.elements()[0].extract(), &1);
}
#[test]
fn indices_at_atomic_pattern() {
let p = Pattern::point("x");
let paths = p.indices_at();
assert_eq!(paths.extract(), &Vec::<usize>::new());
}
#[test]
fn indices_at_with_children() {
let p = Pattern::pattern("root", vec![Pattern::point("a"), Pattern::point("b")]);
let paths = p.indices_at();
assert_eq!(paths.extract(), &Vec::<usize>::new());
assert_eq!(paths.elements()[0].extract(), &vec![0]);
assert_eq!(paths.elements()[1].extract(), &vec![1]);
}
#[test]
fn indices_at_nested() {
let p = Pattern::pattern(
"root",
vec![
Pattern::pattern("a", vec![Pattern::point("x")]),
Pattern::point("b"),
],
);
let paths = p.indices_at();
assert_eq!(paths.extract(), &Vec::<usize>::new());
assert_eq!(paths.elements()[0].extract(), &vec![0]);
assert_eq!(paths.elements()[0].elements()[0].extract(), &vec![0, 0]);
assert_eq!(paths.elements()[1].extract(), &vec![1]);
}
}