refactor(config): order functions by importance

To better communicate which functions are more fundamental,
`parse_contents` has been put above `parse_keybinds` and
`extract_curly_brace`.
main
Angelo Fallaria 2 years ago
parent ba84ffab6a
commit ba1ad4845c

@ -93,125 +93,6 @@ fn load_file_contents(path: path::PathBuf) -> Result<String, Error> {
Ok(contents)
}
fn extract_curly_brace(line: &str) -> Vec<String> {
if !line.is_ascii() {
return vec![line.to_string()];
}
let mut output: Vec<String> = Vec::new();
let index_open_brace = line.chars().position(|c| c == '{');
let index_close_brace = line.chars().position(|c| c == '}');
if index_open_brace.is_none() || index_close_brace.is_none() {
return vec![line.to_string()];
}
let start_index = index_open_brace.unwrap();
let end_index = index_close_brace.unwrap();
// There are no expansions to build if } is earlier than {
if start_index >= end_index {
return vec![line.to_string()];
}
let str_before_braces = line[..start_index].to_string();
let str_after_braces = line[end_index + 1..].to_string();
let comma_separated_items = line[start_index + 1..end_index].split(',');
for item in comma_separated_items {
let mut push_one_item = || {
output.push(format!("{}{}{}", str_before_braces, item.trim(), str_after_braces));
};
if !item.contains('-') {
push_one_item();
continue;
}
// Parse dash ranges like {1-5} and {a-f}
let mut range = item.split('-').map(|s| s.trim());
let begin_char: &str;
let end_char: &str;
if let Some(b) = range.next() {
begin_char = b;
} else {
push_one_item();
continue;
}
if let Some(e) = range.next() {
end_char = e;
} else {
push_one_item();
continue;
}
// Do not accept range values that are longer than one char
// Example invalid: {ef,p} {3,56}
// Beginning of the range cannot be greater than end
// Example invalid: {9,4} {3,2}
if begin_char.len() != 1 || end_char.len() != 1 || begin_char > end_char {
push_one_item();
continue;
}
// In swhkd we will parse the full range using ASCII values.
let begin_ascii_val = begin_char.parse::<char>().unwrap() as u8;
let end_ascii_val = end_char.parse::<char>().unwrap() as u8;
for ascii_number in begin_ascii_val..=end_ascii_val {
output
.push(format!("{}{}{}", str_before_braces, ascii_number as char, str_after_braces));
}
}
output
}
// We need to get the reference to key_to_evdev_key
// and mod_to_mod enum instead of recreating them
// after each function call because it's too expensive
fn parse_keybind(
line: &str,
line_nr: u32,
key_to_evdev_key: &HashMap<&str, evdev::Key>,
mod_to_mod_enum: &HashMap<&str, Modifier>,
) -> Result<(evdev::Key, Vec<Modifier>), Error> {
let line = line.split('#').next().unwrap();
let tokens: Vec<String> = line.split('+').map(|s| s.trim().to_lowercase()).collect();
let last_token = tokens.last().unwrap().trim();
// Check if each token is valid
for token in &tokens {
if key_to_evdev_key.contains_key(token.as_str()) {
// Can't have a key that's like a modifier
if token != last_token {
return Err(Error::InvalidConfig(ParseError::InvalidModifier(line_nr)));
}
} else if mod_to_mod_enum.contains_key(token.as_str()) {
// Can't have a modifier that's like a modifier
if token == last_token {
return Err(Error::InvalidConfig(ParseError::InvalidKeysym(line_nr)));
}
} else {
return Err(Error::InvalidConfig(ParseError::UnknownSymbol(line_nr)));
}
}
// Translate keypress into evdev key
let keysym = key_to_evdev_key.get(last_token).unwrap();
let modifiers: Vec<Modifier> = tokens[0..(tokens.len() - 1)]
.iter()
.map(|token| *mod_to_mod_enum.get(token.as_str()).unwrap())
.collect();
Ok((*keysym, modifiers))
}
fn parse_contents(contents: String) -> Result<Vec<Hotkey>, Error> {
let key_to_evdev_key: HashMap<&str, evdev::Key> = HashMap::from([
("q", evdev::Key::KEY_Q),
@ -410,6 +291,125 @@ fn parse_contents(contents: String) -> Result<Vec<Hotkey>, Error> {
Ok(hotkeys)
}
// We need to get the reference to key_to_evdev_key
// and mod_to_mod enum instead of recreating them
// after each function call because it's too expensive
fn parse_keybind(
line: &str,
line_nr: u32,
key_to_evdev_key: &HashMap<&str, evdev::Key>,
mod_to_mod_enum: &HashMap<&str, Modifier>,
) -> Result<(evdev::Key, Vec<Modifier>), Error> {
let line = line.split('#').next().unwrap();
let tokens: Vec<String> = line.split('+').map(|s| s.trim().to_lowercase()).collect();
let last_token = tokens.last().unwrap().trim();
// Check if each token is valid
for token in &tokens {
if key_to_evdev_key.contains_key(token.as_str()) {
// Can't have a key that's like a modifier
if token != last_token {
return Err(Error::InvalidConfig(ParseError::InvalidModifier(line_nr)));
}
} else if mod_to_mod_enum.contains_key(token.as_str()) {
// Can't have a modifier that's like a modifier
if token == last_token {
return Err(Error::InvalidConfig(ParseError::InvalidKeysym(line_nr)));
}
} else {
return Err(Error::InvalidConfig(ParseError::UnknownSymbol(line_nr)));
}
}
// Translate keypress into evdev key
let keysym = key_to_evdev_key.get(last_token).unwrap();
let modifiers: Vec<Modifier> = tokens[0..(tokens.len() - 1)]
.iter()
.map(|token| *mod_to_mod_enum.get(token.as_str()).unwrap())
.collect();
Ok((*keysym, modifiers))
}
fn extract_curly_brace(line: &str) -> Vec<String> {
if !line.is_ascii() {
return vec![line.to_string()];
}
let mut output: Vec<String> = Vec::new();
let index_open_brace = line.chars().position(|c| c == '{');
let index_close_brace = line.chars().position(|c| c == '}');
if index_open_brace.is_none() || index_close_brace.is_none() {
return vec![line.to_string()];
}
let start_index = index_open_brace.unwrap();
let end_index = index_close_brace.unwrap();
// There are no expansions to build if } is earlier than {
if start_index >= end_index {
return vec![line.to_string()];
}
let str_before_braces = line[..start_index].to_string();
let str_after_braces = line[end_index + 1..].to_string();
let comma_separated_items = line[start_index + 1..end_index].split(',');
for item in comma_separated_items {
let mut push_one_item = || {
output.push(format!("{}{}{}", str_before_braces, item.trim(), str_after_braces));
};
if !item.contains('-') {
push_one_item();
continue;
}
// Parse dash ranges like {1-5} and {a-f}
let mut range = item.split('-').map(|s| s.trim());
let begin_char: &str;
let end_char: &str;
if let Some(b) = range.next() {
begin_char = b;
} else {
push_one_item();
continue;
}
if let Some(e) = range.next() {
end_char = e;
} else {
push_one_item();
continue;
}
// Do not accept range values that are longer than one char
// Example invalid: {ef,p} {3,56}
// Beginning of the range cannot be greater than end
// Example invalid: {9,4} {3,2}
if begin_char.len() != 1 || end_char.len() != 1 || begin_char > end_char {
push_one_item();
continue;
}
// In swhkd we will parse the full range using ASCII values.
let begin_ascii_val = begin_char.parse::<char>().unwrap() as u8;
let end_ascii_val = end_char.parse::<char>().unwrap() as u8;
for ascii_number in begin_ascii_val..=end_ascii_val {
output
.push(format!("{}{}{}", str_before_braces, ascii_number as char, str_after_braces));
}
}
output
}
#[cfg(test)]
mod tests {
use super::*;

Loading…
Cancel
Save