forked from jmacdonald/amp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
69 lines (63 loc) · 2.91 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
extern crate syntex_syntax as syntax;
use std::env;
use std::fs::File;
use std::io::Write;
use crate::syntax::parse::{parse_crate_from_file, ParseSess};
use crate::syntax::ast::{ItemKind, Visibility};
fn main() {
generate_commands();
}
/// This build task generates a Rust snippet which, when included later on in
/// build process, adds logic to construct a HashMap<String, Command> for all
/// public commands declared in the commands module. This facilitates runtime
/// command referencing via string, which is required for command mode, as well
/// as user-defined keymaps.
fn generate_commands() {
// Create the output file and write the opening lines.
let current_dir = env::current_dir().expect("Couldn't get the current directory");
let out_dir = env::var("OUT_DIR").expect("The compiler did not provide $OUT_DIR");
let out_file: std::path::PathBuf = [&out_dir, "hash_map"].iter().collect();
let mut output = File::create(&out_file)
.expect(&format!("Couldn't create output file: {}", out_file.to_string_lossy()));
output
.write("{\n let mut commands: HashMap<&'static str, Command> = HashMap::new();\n"
.as_bytes())
.expect("Failed to write command hash init");
// Parse the crate and get a reference to the command module.
let session = ParseSess::new();
let parsed_crate =
parse_crate_from_file(¤t_dir.join("src/lib.rs"), &session)
.expect("Couldn't parse amp crate");
let ref command_module = parsed_crate
.module
.items
.iter()
.find(|m| m.ident.name.as_str().starts_with("command"))
.expect("Couldn't find command module")
.node;
// Locate any public methods under the command module
// and generate String => Command map entries for them.
if let &ItemKind::Mod(ref module) = command_module {
for module_item in module.items.iter() {
if let ItemKind::Mod(ref submodule) = module_item.node {
for submodule_item in submodule.items.iter() {
if submodule_item.node.descriptive_variant() == "function" &&
submodule_item.vis == Visibility::Public {
output
.write(format!(" commands.insert(\"{}::{}\", {}::{});\n",
module_item.ident.name.as_str(),
submodule_item.ident.name.as_str(),
module_item.ident.name.as_str(),
submodule_item.ident.name.as_str())
.as_bytes())
.expect("Failed to write command");
}
}
}
}
}
// Finalize the output file.
output
.write(" commands\n}\n".as_bytes())
.expect("Failed to write command hash return");
}