use super::Page;
pub fn filter_pages(
pages: Vec<Page>,
include: &Option<Vec<String>>,
exclude: &Option<Vec<String>>,
) -> Vec<Page> {
pages
.into_iter()
.filter(|page| {
if let Some(include_slugs) = include {
if !include_slugs.iter().any(|s| slug_matches(&page.slug, s)) {
return false;
}
}
if let Some(exclude_slugs) = exclude {
if exclude_slugs.iter().any(|s| slug_matches(&page.slug, s)) {
return false;
}
}
true
})
.collect()
}
fn slug_matches(slug: &str, pattern: &str) -> bool {
if slug == pattern {
return true;
}
if let Some(rest) = slug.strip_prefix(pattern) {
if rest.starts_with('-') || rest.starts_with('.') {
return true;
}
}
false
}
#[cfg(test)]
mod tests {
use super::*;
fn make_page(slug: &str) -> Page {
Page {
slug: slug.to_string(),
title: slug.to_string(),
depth: 0,
content: None,
error: None,
}
}
#[test]
fn test_no_filters() {
let pages = vec![make_page("a"), make_page("b")];
let result = filter_pages(pages, &None, &None);
assert_eq!(result.len(), 2);
}
#[test]
fn test_include_filter() {
let pages = vec![
make_page("1-overview"),
make_page("2-setup"),
make_page("3-arch"),
];
let include = Some(vec!["1-overview".to_string(), "3-arch".to_string()]);
let result = filter_pages(pages, &include, &None);
assert_eq!(result.len(), 2);
assert_eq!(result[0].slug, "1-overview");
assert_eq!(result[1].slug, "3-arch");
}
#[test]
fn test_exclude_filter() {
let pages = vec![
make_page("1-overview"),
make_page("2-setup"),
make_page("3-arch"),
];
let exclude = Some(vec!["2-setup".to_string()]);
let result = filter_pages(pages, &None, &exclude);
assert_eq!(result.len(), 2);
assert_eq!(result[0].slug, "1-overview");
assert_eq!(result[1].slug, "3-arch");
}
#[test]
fn test_slug_prefix_match() {
assert!(slug_matches("3-architecture", "3"));
assert!(slug_matches("3.1-data-pipeline", "3.1"));
assert!(!slug_matches("3-architecture", "31"));
assert!(!slug_matches("30-other", "3"));
}
#[test]
fn test_slug_exact_match() {
assert!(slug_matches("1-overview", "1-overview"));
assert!(!slug_matches("1-overview", "1-over"));
}
#[test]
fn test_include_and_exclude_combined() {
let pages = vec![
make_page("1-overview"),
make_page("2-setup"),
make_page("3-arch"),
make_page("3.1-data"),
];
let include = Some(vec![
"1-overview".to_string(),
"3-arch".to_string(),
"3.1-data".to_string(),
]);
let exclude = Some(vec!["3-arch".to_string()]);
let result = filter_pages(pages, &include, &exclude);
assert_eq!(result.len(), 2);
assert_eq!(result[0].slug, "1-overview");
assert_eq!(result[1].slug, "3.1-data");
}
}