forked from embedded-graphics/bdf
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.rs
More file actions
123 lines (99 loc) · 2.82 KB
/
Copy pathlib.rs
File metadata and controls
123 lines (99 loc) · 2.82 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use anyhow::Result;
use owo_colors::OwoColorize;
use std::{
ffi::OsStr,
fs, io,
path::{Path, PathBuf},
};
use bdf_parser::{Font, ParserError};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct FontPath {
pub absolute: PathBuf,
pub relative: PathBuf,
}
#[derive(Debug)]
pub struct FontFile {
pub path: FontPath,
pub parsed: Result<Font, ParserError>,
}
#[derive(Debug, Default)]
struct DirWalker {
files: Vec<FontPath>,
prefix: PathBuf,
}
impl DirWalker {
fn new<F: Fn(&Path) -> bool>(path: &Path, filter: F) -> io::Result<Self> {
let mut self_ = Self::default();
self_.walk(path, &filter, true)?;
self_.files.sort();
Ok(self_)
}
fn walk<F: Fn(&Path) -> bool>(
&mut self,
path: &Path,
filter: &F,
root: bool,
) -> io::Result<()> {
let file_name = path.file_name().unwrap();
if path.is_dir() {
let old_prefix = self.prefix.clone();
if !root {
self.prefix.push(file_name);
}
for entry in fs::read_dir(path)? {
let entry = entry?;
self.walk(&entry.path(), filter, false)?;
}
self.prefix = old_prefix;
} else if path.is_file() {
if path.extension() == Some(OsStr::new("bdf")) && filter(path) {
self.files.push(FontPath {
absolute: path.to_path_buf(),
relative: self.prefix.join(file_name),
});
}
} else {
panic!("path is not a dir or file");
}
Ok(())
}
}
pub fn parse_fonts(path: &Path) -> Result<Vec<FontFile>> {
parse_fonts_with_filter(path, |_| true)
}
pub fn parse_fonts_with_filter<F: Fn(&Path) -> bool>(
path: &Path,
filter: F,
) -> Result<Vec<FontFile>> {
let paths = DirWalker::new(path, filter).map(|walker| walker.files)?;
let files = paths
.into_iter()
.map(|path| {
let bdf = std::fs::read(&path.absolute).unwrap();
let str = String::from_utf8_lossy(&bdf);
let parsed = Font::parse(&str);
FontFile { path, parsed }
})
.collect::<Vec<_>>();
Ok(files)
}
pub fn print_parser_result(files: &[FontFile]) -> usize {
let mut num_errors = 0;
for font_file in files {
if font_file.parsed.is_err() {
num_errors += 1;
}
print!("{0: <60}", font_file.path.relative.to_string_lossy());
match &font_file.parsed {
Ok(_font) => println!("{}", "OK".green()),
Err(e) => println!("{} {:}", "Error:".red(), e),
}
}
println!(
"\n{} out of {} fonts passed ({} failed)\n",
files.len() - num_errors,
files.len(),
num_errors
);
num_errors
}