Skip to main content

package_parser/helper/
mod.rs

1use std::path::Path;
2
3use ignore::{types::Types, DirEntry, Walk, WalkBuilder};
4use tree_sitter::{Node, Query, QueryCapture, QueryCursor};
5
6pub fn query_matches<'tree>(
7    node: Node<'tree>,
8    query: &Query,
9    code_raw: &[u8],
10) -> Vec<Vec<QueryCapture<'tree>>> {
11    let mut cursor = QueryCursor::new();
12
13    let mut ret = vec![];
14    for m in cursor.matches(query, node, code_raw) {
15        ret.push(m.captures.to_vec())
16    }
17    ret
18}
19
20pub fn build_walker<P: AsRef<Path>>(path: P, types: &[&str]) -> (Walk, Types) {
21    let mut types_builder = ignore::types::TypesBuilder::new();
22    types_builder.add_defaults();
23    for ty in types {
24        types_builder.select(ty);
25    }
26    let matcher = types_builder.build().unwrap();
27
28    (
29        WalkBuilder::new(path)
30            .git_global(false)
31            .parents(false)
32            .types(matcher.clone())
33            .build(),
34        matcher,
35    )
36}
37
38pub fn match_ftyp(entry: &DirEntry, matcher: &Types) -> Option<String> {
39    let file_type = entry.file_type()?;
40
41    if file_type.is_dir() {
42        return None;
43    }
44
45    if let ignore::Match::Whitelist(x) = matcher.matched(entry.path(), false) {
46        x.file_type_def().map(|def| def.name().to_owned())
47    } else {
48        None
49    }
50}
51
52#[cfg(test)]
53pub mod testing {
54    use ignore::WalkBuilder;
55    use std::path::{Path, PathBuf};
56
57    /// Finds all files in the given directory that match the given extension.
58    pub fn all_files_with_extensions<'a>(
59        dir: &Path,
60        extensions: &'a [&'a str],
61    ) -> impl Iterator<Item = Result<PathBuf, ignore::Error>> + 'a {
62        WalkBuilder::new(dir)
63            .build()
64            .filter_map(|result| match result {
65                Ok(entry) => {
66                    if entry.file_type().unwrap().is_file() {
67                        let path = entry.path();
68
69                        if let Some(ext) = path.extension() {
70                            if extensions.contains(&ext.to_str().unwrap()) {
71                                Some(Ok(path.to_path_buf()))
72                            } else {
73                                None
74                            }
75                        } else {
76                            None
77                        }
78                    } else {
79                        None
80                    }
81                }
82                Err(e) => Some(Err(e)),
83            })
84    }
85}