1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::fs;
use crate::ast::Solution;
use jwalk::{Parallelism, WalkDir};
use std::option::Option::Some;
pub mod ast;
mod lex;
pub mod msbuild;
mod parser;
#[macro_use]
extern crate lalrpop_util;
extern crate jwalk;
extern crate nom;
extern crate petgraph;
#[cfg(test)]
#[macro_use]
extern crate spectral;
#[cfg(test)]
extern crate rstest;
lalrpop_mod!(
#[allow(clippy::all)]
#[allow(unused)]
pub solp
);
pub trait Consume {
fn ok(&mut self, path: &str, solution: &Solution);
fn err(&self, path: &str);
fn is_debug(&self) -> bool;
}
pub fn parse_file(path: &str, consumer: &mut dyn Consume) {
match fs::read_to_string(path) {
Ok(contents) => match parse(consumer, &contents) {
Some(solution) => consumer.ok(path, &solution),
None => consumer.err(path),
},
Err(e) => eprintln!("{} - {}", path, e),
}
}
pub fn parse<'a>(consumer: &mut dyn Consume, contents: &'a str) -> Option<Solution<'a>> {
parser::parse_str(contents, consumer.is_debug())
}
pub fn scan(path: &str, extension: &str, consumer: &mut dyn Consume) -> usize {
let parallelism = Parallelism::RayonNewPool(num_cpus::get_physical());
let iter = WalkDir::new(path)
.skip_hidden(false)
.follow_links(false)
.parallelism(parallelism);
let ext = extension.trim_start_matches('.');
iter.into_iter()
.filter(Result::is_ok)
.map(Result::unwrap)
.filter(|f| f.file_type().is_file())
.map(|f| f.path())
.filter(|p| {
return match p.extension() {
Some(s) => s == ext,
None => false,
};
})
.map(|f| f.to_str().unwrap_or("").to_string())
.inspect(|fp| parse_file(fp, consumer))
.count()
}