1#![forbid(unsafe_code)]
6#![warn(missing_docs)]
7
8mod accept_defeat;
9mod baseline;
10mod check;
11mod cli;
12mod config_edit;
13mod init;
14mod output;
15
16use std::ffi::OsString;
17use std::io::{self, Read};
18use std::process::ExitCode;
19
20use clap::Parser;
21use termcolor::{ColorChoice, StandardStream, WriteColor};
22
23use accept_defeat::run_accept_defeat;
24use baseline::run_baseline;
25use check::{output_mode, run_check};
26use init::run_init;
27
28pub use cli::{Cli, Command};
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum ExitStatus {
33 Success,
35 Failure,
37 Error,
39}
40
41impl From<ExitStatus> for ExitCode {
42 fn from(status: ExitStatus) -> Self {
43 match status {
44 ExitStatus::Success => Self::from(0),
45 ExitStatus::Failure => Self::from(1),
46 ExitStatus::Error => Self::from(2),
47 }
48 }
49}
50
51#[must_use]
53pub fn run_env() -> ExitStatus {
54 let args = std::env::args_os();
55 let stdin = io::stdin();
56 let mut stdout = StandardStream::stdout(ColorChoice::Auto);
57 let mut stderr = StandardStream::stderr(ColorChoice::Auto);
58 run_with(args, stdin.lock(), &mut stdout, &mut stderr)
59}
60
61pub fn run_with<I, R, W1, W2>(args: I, mut stdin: R, stdout: &mut W1, stderr: &mut W2) -> ExitStatus
63where
64 I: IntoIterator<Item = OsString>,
65 R: Read,
66 W1: WriteColor,
67 W2: WriteColor,
68{
69 let cli = Cli::parse_from(args);
70 let mode = output_mode(&cli);
71
72 let default_check = Command::Check(cli::CheckArgs {
73 paths: vec![],
74 no_cache: false,
75 });
76 match cli.command.as_ref().unwrap_or(&default_check) {
77 Command::Check(args) => run_check(args, &mut stdin, stdout, stderr, mode),
78 Command::Init(args) => run_init(args, stdout, stderr),
79 Command::Baseline(args) => run_baseline(args, stdout, stderr),
80 Command::AcceptDefeat(args) => run_accept_defeat(args, stdout, stderr),
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn exit_status_to_exit_code() {
90 assert_eq!(ExitCode::from(ExitStatus::Success), ExitCode::from(0));
91 assert_eq!(ExitCode::from(ExitStatus::Failure), ExitCode::from(1));
92 assert_eq!(ExitCode::from(ExitStatus::Error), ExitCode::from(2));
93 }
94}