-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
build.rs
106 lines (83 loc) · 2.83 KB
/
build.rs
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
use glob::glob;
use std::collections::HashMap;
use std::env;
use std::fmt::{self, Write};
use std::fs;
use std::path::{Path, PathBuf};
#[derive(Debug, Default)]
struct Level {
nested: HashMap<String, Level>,
files: Vec<PathBuf>,
}
fn main() {
let home = env::var("CARGO_MANIFEST_DIR").unwrap();
let pattern = format!("{}/../../website/docs/**/*.md*", home);
let base = format!("{}/../../website", home);
let base = Path::new(&base).canonicalize().unwrap();
let dir_pattern = format!("{}/../../website/docs/**", home);
for dir in glob(&dir_pattern).unwrap() {
println!("cargo:rerun-if-changed={}", dir.unwrap().display());
}
let mut level = Level::default();
for entry in glob(&pattern).unwrap() {
let path = entry.unwrap();
let path = Path::new(&path).canonicalize().unwrap();
println!("cargo:rerun-if-changed={}", path.display());
let rel = path.strip_prefix(&base).unwrap();
let mut parts = vec![];
for part in rel {
parts.push(part.to_str().unwrap());
}
level.insert(path.clone(), &parts[..]);
}
let out = format!("{}/website_tests.rs", env::var("OUT_DIR").unwrap());
fs::write(&out, level.to_contents()).unwrap();
}
impl Level {
fn insert(&mut self, path: PathBuf, rel: &[&str]) {
if rel.len() == 1 {
self.files.push(path);
} else {
let nested = self.nested.entry(rel[0].to_string()).or_default();
nested.insert(path, &rel[1..]);
}
}
fn to_contents(&self) -> String {
let mut dst = String::new();
self.write_inner(&mut dst, 0).unwrap();
dst
}
fn write_into(&self, dst: &mut String, name: &str, level: usize) -> fmt::Result {
self.write_space(dst, level);
let name = name.replace(|c| c == '-' || c == '.', "_");
writeln!(dst, "pub mod {} {{", name)?;
self.write_inner(dst, level + 1)?;
self.write_space(dst, level);
writeln!(dst, "}}")?;
Ok(())
}
fn write_inner(&self, dst: &mut String, level: usize) -> fmt::Result {
for (name, nested) in &self.nested {
nested.write_into(dst, name, level)?;
}
self.write_space(dst, level);
for file in &self.files {
let stem = Path::new(file)
.file_stem()
.unwrap()
.to_str()
.unwrap()
.replace('-', "_");
self.write_space(dst, level);
writeln!(dst, "#[doc = include_str!(r\"{}\")]", file.display())?;
self.write_space(dst, level);
writeln!(dst, "pub fn {}_md() {{}}", stem)?;
}
Ok(())
}
fn write_space(&self, dst: &mut String, level: usize) {
for _ in 0..level {
dst.push_str(" ");
}
}
}