summaryrefslogtreecommitdiff
path: root/support/texlab/crates/commands/src/placeholders.rs
blob: 913af33edf35933793d4bc22f96484d38c9c518c (plain)
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
use rustc_hash::FxHashMap;

pub fn replace_placeholders(args: &[String], pairs: &[(char, &str)]) -> Vec<String> {
    let map = FxHashMap::from_iter(pairs.iter().copied());
    args.iter()
        .map(|input| {
            let quoted = input
                .strip_prefix('"')
                .and_then(|input| input.strip_suffix('"'));

            match quoted {
                Some(output) => String::from(output),
                None => {
                    let mut output = String::new();
                    let mut chars = input.chars();
                    while let Some(ch) = chars.next() {
                        if ch == '%' {
                            match chars.next() {
                                Some(key) => match map.get(&key) {
                                    Some(value) => output.push_str(&value),
                                    None => output.push(key),
                                },
                                None => output.push('%'),
                            };
                        } else {
                            output.push(ch);
                        }
                    }

                    output
                }
            }
        })
        .collect()
}

#[cfg(test)]
mod tests {
    use super::replace_placeholders;

    #[test]
    fn test_quoted() {
        let output = replace_placeholders(
            &["foo".into(), "\"%f\"".into(), "%%f".into(), "%fbar".into()],
            &[('f', "foo")],
        );

        assert_eq!(output, vec!["foo".into(), "%f", "%f".into(), "foobar"]);
    }
}