summaryrefslogtreecommitdiffstats
path: root/src/poem/anthology/which.rs
blob: 6fe709cf8602c8e4d3df38780007806ef019b7ce (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
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
use crate::compose::Environment;
use crate::poem::Verse;
use std::os::unix::process::ExitStatusExt;
use std::process::{ExitStatus, Output};

pub fn incant(clause: &Option<Vec<String>>, uout: bool, uerr: bool, env: &Environment) -> Output {
    let mut status = 0;
    let mut out: Vec<u8> = Vec::new();
    let mut err: Vec<u8> = Vec::new();
    match clause {
        Some(clause) => {
            let mut output: String;
            for word in clause {
                // Check if it's an alias
                if env.aliases.contains_key(word) {
                    output = format!("{}: aliased to {}\n", word, env.aliases.get(word).unwrap());
                    if uout {
                        out.append(&mut output.as_bytes().to_vec());
                    } else {
                        print!("{}", output);
                    }
                    continue;
                }

                // Check if it's a built-in
                match super::lookup(&word) {
                    Some(_) => {
                        output = format!("{}: shell built-in command\n", word);
                        if uout {
                            out.append(&mut output.as_bytes().to_vec());
                        } else {
                            print!("{}", output);
                        }
                        continue;
                    }
                    None => {}
                }

                // Manually check the path
                let mut verb = Verse::new();
                verb.push(word.clone());
                match verb.spellcheck(&env.bins) {
                    Some(i) => {
                        output = format!("{}\n", env.bins[i]);
                        if uout {
                            out.append(&mut output.as_bytes().to_vec());
                        } else {
                            print!("{}", output);
                        }
                    }
                    None => {
                        output = format!("{} not found\n", word);
                        status = 1;
                        if uerr {
                            err.append(&mut output.as_bytes().to_vec());
                        } else {
                            eprint!("{}", output);
                        }
                    }
                }
            }
        }
        None => {
            status = 1;
            if uerr {
                err.append(&mut "which: not enough arguments".as_bytes().to_vec());
            } else {
                eprintln!("which: not enough arguments");
            }
            return Output {
                status: ExitStatus::from_raw(status),
                stdout: out,
                stderr: err,
            };
        }
    }

    Output {
        status: ExitStatus::from_raw(status),
        stdout: out,
        stderr: err,
    }
}