dot_over/overlays/
repository.rs1use std::path::PathBuf;
2
3use globset::GlobBuilder;
4use serde::Serialize;
5use walkdir::WalkDir;
6
7use anyhow::Result;
8
9use super::overlay::Overlay;
10use super::pattern;
11
12#[derive(Debug, Default, Serialize, Clone)]
14pub struct Repository {
15 pub root: PathBuf,
17}
18
19impl Repository {
26 pub fn new(root: PathBuf) -> Self {
27 Self { root }
28 }
29
30 pub fn overlays(&self) -> Result<Vec<Overlay>> {
32 let glob = GlobBuilder::new(&pattern())
33 .literal_separator(true)
34 .build()?
35 .compile_matcher();
36
37 let mut dirs: Vec<PathBuf> = WalkDir::new(&self.root)
38 .into_iter()
39 .filter_map(Result::ok)
40 .filter(|e| glob.is_match(e.path().strip_prefix(&self.root).ok().unwrap()))
41 .map(|e| e.path().parent().unwrap().to_path_buf())
42 .collect();
43
44 dirs.sort();
45
46 Ok(dirs
47 .iter()
48 .enumerate()
49 .filter_map(|(idx, dir)| match dirs.get(idx + 1) {
50 Some(next) if next.starts_with(dir) => None,
51 _ => Some(Overlay::new(self, dir).expect("failed")),
52 })
53 .collect())
54 }
55
56 pub fn get(&self, name: &str) -> Result<Overlay> {
58 let root = self.root.join(name);
59 let overlay = Overlay::new(self, &root)?;
60 Ok(overlay)
61 }
62}