use std::path::Path;
use crate::core::NormalizedPath;
#[derive(Debug, Clone, Default)]
pub struct IncludeSearchPaths {
pub iquote: Vec<NormalizedPath>,
pub user: Vec<NormalizedPath>,
pub system: Vec<NormalizedPath>,
pub after: Vec<NormalizedPath>,
}
impl IncludeSearchPaths {
pub fn quoted_search_dirs(&self) -> impl Iterator<Item = &Path> {
self.iquote
.iter()
.chain(self.user.iter())
.chain(self.system.iter())
.chain(self.after.iter())
.map(|p| p.as_path())
}
pub fn angle_search_dirs(&self) -> impl Iterator<Item = &Path> {
self.user
.iter()
.chain(self.system.iter())
.chain(self.after.iter())
.map(|p| p.as_path())
}
pub fn all_search_dirs(&self) -> impl Iterator<Item = &Path> {
self.iquote
.iter()
.chain(self.user.iter())
.chain(self.system.iter())
.chain(self.after.iter())
.map(|p| p.as_path())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn quoted_search_includes_iquote_first() {
let paths = IncludeSearchPaths {
iquote: vec!["/q".into()],
user: vec!["/u".into()],
system: vec!["/s".into()],
after: vec!["/a".into()],
};
let dirs: Vec<&Path> = paths.quoted_search_dirs().collect();
assert_eq!(
dirs,
vec![
Path::new("/q"),
Path::new("/u"),
Path::new("/s"),
Path::new("/a"),
]
);
}
#[test]
fn angle_search_skips_iquote() {
let paths = IncludeSearchPaths {
iquote: vec!["/q".into()],
user: vec!["/u".into()],
system: vec!["/s".into()],
after: vec!["/a".into()],
};
let dirs: Vec<&Path> = paths.angle_search_dirs().collect();
assert_eq!(
dirs,
vec![Path::new("/u"), Path::new("/s"), Path::new("/a"),]
);
}
#[test]
fn empty_paths_produce_empty_iterators() {
let paths = IncludeSearchPaths::default();
assert_eq!(paths.quoted_search_dirs().count(), 0);
assert_eq!(paths.angle_search_dirs().count(), 0);
}
#[test]
fn user_dir_order_preserved() {
let paths = IncludeSearchPaths {
user: vec!["/first".into(), "/second".into(), "/third".into()],
..Default::default()
};
let dirs: Vec<&Path> = paths.angle_search_dirs().collect();
assert_eq!(
dirs,
vec![
Path::new("/first"),
Path::new("/second"),
Path::new("/third")
]
);
}
}