loq_cli/
lib.rs

1//! Command-line interface for loq.
2//!
3//! Provides the main entry point and CLI argument handling for the loq tool.
4
5#![forbid(unsafe_code)]
6#![warn(missing_docs)]
7
8mod baseline;
9mod check;
10mod cli;
11mod init;
12mod output;
13
14use std::ffi::OsString;
15use std::io::{self, Read};
16use std::process::ExitCode;
17
18use clap::Parser;
19use termcolor::{ColorChoice, StandardStream, WriteColor};
20
21use baseline::run_baseline;
22use check::{output_mode, run_check};
23use init::run_init;
24
25pub use cli::{Cli, Command};
26
27/// Exit status for the CLI.
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum ExitStatus {
30    /// All checks passed.
31    Success,
32    /// Violations found (errors).
33    Failure,
34    /// Runtime error occurred.
35    Error,
36}
37
38impl From<ExitStatus> for ExitCode {
39    fn from(status: ExitStatus) -> Self {
40        match status {
41            ExitStatus::Success => Self::from(0),
42            ExitStatus::Failure => Self::from(1),
43            ExitStatus::Error => Self::from(2),
44        }
45    }
46}
47
48/// Runs the CLI using environment args and stdio.
49#[must_use]
50pub fn run_env() -> ExitStatus {
51    let args = std::env::args_os();
52    let stdin = io::stdin();
53    let mut stdout = StandardStream::stdout(ColorChoice::Auto);
54    let mut stderr = StandardStream::stderr(ColorChoice::Auto);
55    run_with(args, stdin.lock(), &mut stdout, &mut stderr)
56}
57
58/// Runs the CLI with custom args and streams (for testing).
59pub fn run_with<I, R, W1, W2>(args: I, mut stdin: R, stdout: &mut W1, stderr: &mut W2) -> ExitStatus
60where
61    I: IntoIterator<Item = OsString>,
62    R: Read,
63    W1: WriteColor,
64    W2: WriteColor,
65{
66    let cli = Cli::parse_from(args);
67    let mode = output_mode(&cli);
68
69    let default_check = Command::Check(cli::CheckArgs {
70        paths: vec![],
71        no_cache: false,
72    });
73    match cli.command.as_ref().unwrap_or(&default_check) {
74        Command::Check(args) => run_check(args, &mut stdin, stdout, stderr, mode),
75        Command::Init(args) => run_init(args, stdout, stderr),
76        Command::Baseline(args) => run_baseline(args, stdout, stderr),
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn exit_status_to_exit_code() {
86        assert_eq!(ExitCode::from(ExitStatus::Success), ExitCode::from(0));
87        assert_eq!(ExitCode::from(ExitStatus::Failure), ExitCode::from(1));
88        assert_eq!(ExitCode::from(ExitStatus::Error), ExitCode::from(2));
89    }
90}