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
use anyhow::Context;
use indexmap::IndexMap;
use pest::{error::Error, iterators::Pairs, Parser};
#[derive(Parser, Debug)]
#[grammar = "pest/controlmap.pest"]
pub struct ControlMapParser;
pub fn parse(input: &str) -> Result<String, Error<ControlMapParser>> {
let successful_parse = ControlMapParser::parse(Rule::rows, &input)
.with_context(|| format!("unsuccessful parse"))
.unwrap();
Ok(parse_ctrlmap(successful_parse))
}
fn parse_ctrlmap(pairs: Pairs<Rule>) -> String {
let ctrlmap_category = vec![
"Main Gameplay",
"Menu Mode",
"Console",
"Item Menus",
"Inventory",
"Debug Text",
"Favorites menu",
"Map Menu",
"Stats",
"Cursor",
"Book",
"Debug overlay",
"Journal",
"TFC mode",
"Debug Map Menu-like mode (but not the actual map menu)",
"Lockpicking",
"Favor",
];
let mut event_count = 0;
let mut index: usize = 0;
let mut event_name = String::new();
let mut event = IndexMap::new();
let mut events = IndexMap::new();
let mut comment = vec![];
let mut keycode_list = vec![];
pairs.for_each(|row| match row.as_rule() {
Rule::event_name => {
if event_count != 0 {
event.insert("comment".to_string(), comment.clone());
if event_count == 1 {
event.insert(event_name.clone(), keycode_list.clone());
}
keycode_list = vec![];
}
event_name = row.as_str().to_string();
event_count += 1;
}
Rule::comment => comment.push(row.as_str()),
Rule::keycode => {
keycode_list.push(row.as_str());
if event_count > 1 {
event.insert(event_name.clone(), keycode_list.clone());
}
}
Rule::blank_line => {
events.insert(ctrlmap_category[index], event.clone());
event = IndexMap::new();
comment = vec![];
index += 1;
}
Rule::EOI => {
events.insert(ctrlmap_category[index], event.clone());
format!("END: {}", &row.as_str());
}
_ => unreachable!(),
});
format!("{:?}", events.clone()).to_string()
}