quillmark_core/quill/
query.rs1use std::path::{Path, PathBuf};
3
4use super::{FileTreeNode, QuillSource};
5
6impl QuillSource {
7 pub fn get_file<P: AsRef<Path>>(&self, path: P) -> Option<&[u8]> {
9 self.files.get_file(path)
10 }
11
12 pub fn file_exists<P: AsRef<Path>>(&self, path: P) -> bool {
14 self.files.file_exists(path)
15 }
16
17 pub fn dir_exists<P: AsRef<Path>>(&self, path: P) -> bool {
19 self.files.dir_exists(path)
20 }
21
22 pub fn list_files<P: AsRef<Path>>(&self, path: P) -> Vec<String> {
24 self.files.list_files(path)
25 }
26
27 pub fn list_subdirectories<P: AsRef<Path>>(&self, path: P) -> Vec<String> {
29 self.files.list_subdirectories(path)
30 }
31
32 pub fn list_directory<P: AsRef<Path>>(&self, dir_path: P) -> Vec<PathBuf> {
34 let dir_path = dir_path.as_ref();
35 let filenames = self.files.list_files(dir_path);
36
37 filenames
39 .iter()
40 .map(|name| {
41 if dir_path == Path::new("") {
42 PathBuf::from(name)
43 } else {
44 dir_path.join(name)
45 }
46 })
47 .collect()
48 }
49
50 pub fn list_directories<P: AsRef<Path>>(&self, dir_path: P) -> Vec<PathBuf> {
52 let dir_path = dir_path.as_ref();
53 let subdirs = self.files.list_subdirectories(dir_path);
54
55 subdirs
57 .iter()
58 .map(|name| {
59 if dir_path == Path::new("") {
60 PathBuf::from(name)
61 } else {
62 dir_path.join(name)
63 }
64 })
65 .collect()
66 }
67
68 pub fn find_files<P: AsRef<Path>>(&self, pattern: P) -> Vec<PathBuf> {
70 let pattern_str = pattern.as_ref().to_string_lossy();
71 let mut matches = Vec::new();
72
73 let glob_pattern = match glob::Pattern::new(&pattern_str) {
75 Ok(pat) => pat,
76 Err(_) => return matches, };
78
79 Self::find_files_recursive(&self.files, Path::new(""), &glob_pattern, &mut matches);
81
82 matches.sort();
83 matches
84 }
85
86 fn find_files_recursive(
88 node: &FileTreeNode,
89 current_path: &Path,
90 pattern: &glob::Pattern,
91 matches: &mut Vec<PathBuf>,
92 ) {
93 match node {
94 FileTreeNode::File { .. } => {
95 let path_str = current_path.to_string_lossy();
96 if pattern.matches(&path_str) {
97 matches.push(current_path.to_path_buf());
98 }
99 }
100 FileTreeNode::Directory { files } => {
101 for (name, child_node) in files {
102 let child_path = if current_path == Path::new("") {
103 PathBuf::from(name)
104 } else {
105 current_path.join(name)
106 };
107 Self::find_files_recursive(child_node, &child_path, pattern, matches);
108 }
109 }
110 }
111 }
112}