Skip to main content

sbox/
dispatch.rs

1pub fn command_string(argv: &[String]) -> String {
2    argv.join(" ")
3}
4
5pub fn matches(pattern: &str, command: &str) -> bool {
6    if !pattern.contains('*') {
7        return pattern == command;
8    }
9
10    let starts_with_wildcard = pattern.starts_with('*');
11    let ends_with_wildcard = pattern.ends_with('*');
12    let parts: Vec<&str> = pattern.split('*').filter(|part| !part.is_empty()).collect();
13
14    if parts.is_empty() {
15        return true;
16    }
17
18    let mut cursor = 0usize;
19
20    for (index, part) in parts.iter().enumerate() {
21        if index == 0 && !starts_with_wildcard {
22            if !command[cursor..].starts_with(part) {
23                return false;
24            }
25            cursor += part.len();
26            continue;
27        }
28
29        match command[cursor..].find(part) {
30            Some(found) => cursor += found + part.len(),
31            None => return false,
32        }
33    }
34
35    if !ends_with_wildcard {
36        let last = parts.last().expect("parts is not empty");
37        return command.ends_with(last);
38    }
39
40    true
41}
42
43#[cfg(test)]
44mod tests {
45    use super::{command_string, matches};
46
47    #[test]
48    fn joins_command_tokens_with_single_spaces() {
49        let command = vec![
50            "cargo".to_string(),
51            "build".to_string(),
52            "--release".to_string(),
53        ];
54        assert_eq!(command_string(&command), "cargo build --release");
55    }
56
57    #[test]
58    fn exact_match_requires_full_string_equality() {
59        assert!(matches("npm install", "npm install"));
60        assert!(!matches("npm install", "npm install lodash"));
61    }
62
63    #[test]
64    fn wildcard_match_handles_prefix_suffix_and_infix() {
65        assert!(matches("cargo build*", "cargo build --release"));
66        assert!(matches("*pytest", "python -m pytest"));
67        assert!(matches("python * pytest", "python -m pytest"));
68        assert!(!matches("cargo build*", "cargo test"));
69    }
70}