Skip to content

Commit

Permalink
Add --stdio to process STDIN
Browse files Browse the repository at this point in the history
  • Loading branch information
leonbohn committed Sep 10, 2024
1 parent f2689ac commit 484277f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 23 deletions.
18 changes: 2 additions & 16 deletions src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Utilities for logging
use crate::Cli;
use colored::{Color, Colorize};
use env_logger::Builder;
use log::Level;
Expand Down Expand Up @@ -94,23 +93,10 @@ const fn get_log_color(log_level: Level) -> Color {
}
}

/// Parse the log level from the command line arguments
const fn get_log_level(args: &Cli) -> LevelFilter {
if args.trace {
LevelFilter::Trace
} else if args.verbose {
LevelFilter::Info
} else if args.quiet {
LevelFilter::Error
} else {
LevelFilter::Warn
}
}

/// Start the logger
pub fn init_logger(args: &Cli) {
pub fn init_logger(level_filter: LevelFilter) {
Builder::new()
.filter_level(get_log_level(args))
.filter_level(level_filter)
.format(|buf, record| {
writeln!(
buf,
Expand Down
26 changes: 20 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,36 @@ const LINE_END: &str = "\r\n";

fn main() {
let mut args = Cli::parse();
init_logger(args.log_level());

args.resolve();
init_logger(&args);
let mut exit_code = 0;

for file in &args.files {
let mut logs = Vec::<Log>::new();
if let Some((file, text)) = read(file, &mut logs) {
if args.stdin {
let mut logs = vec![];
if let Some((file, text)) = read_stdin(&mut logs) {
let new_text = format_file(&text, &file, &args, &mut logs);
exit_code = process_output(
&args, &file, &text, &new_text, exit_code, &mut logs,
);
} else {
exit_code = 1;
};

}
print_logs(logs);
} else {
for file in &args.files {
let mut logs = vec![];
if let Some((file, text)) = read(file, &mut logs) {
let new_text = format_file(&text, &file, &args, &mut logs);
exit_code = process_output(
&args, &file, &text, &new_text, exit_code, &mut logs,
);
} else {
exit_code = 1;
};
print_logs(logs);
}
}

exit(exit_code)
}
62 changes: 61 additions & 1 deletion src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::logging::*;
use crate::regexes::*;
use clap::Parser;
use log::Level::Error;
use log::LevelFilter;
use std::fs;

/// Command line arguments
Expand All @@ -24,16 +25,47 @@ pub struct Cli {
pub quiet: bool,
#[arg(long, short, help = "Show trace log messages")]
pub trace: bool,
#[arg(required = true)]
#[arg(help = "List of files that should be formatted")]
pub files: Vec<String>,
#[arg(
long,
short,
help = "Process STDIN as a single file and output formatted text to STDOUT"
)]
pub stdin: bool,
}

impl Cli {
/// Get the log level.
pub const fn log_level(&self) -> LevelFilter {
if self.trace {
LevelFilter::Trace
} else if self.verbose {
LevelFilter::Info
} else if self.quiet {
LevelFilter::Error
} else {
LevelFilter::Warn
}
}

/// Ensure the provided arguments are consistent
pub fn resolve(&mut self) {
use std::process::exit;

if self.trace {
self.verbose = true;
}
self.print |= self.stdin;

if !self.stdin && self.files.is_empty() {
log::error!("No files specified, either provide at least one filename or set the --stdin flag.");
exit(1);
}
if self.stdin && !self.files.is_empty() {
log::warn!("Provided file name(s) will be ignored when using the --stdin flag.");
self.files.clear();
}
}

#[cfg(test)]
Expand All @@ -43,6 +75,7 @@ impl Cli {
print: false,
keep: false,
verbose: false,
stdin: false,
quiet: false,
trace: false,
files: Vec::<String>::new(),
Expand All @@ -69,3 +102,30 @@ pub fn read(file: &str, logs: &mut Vec<Log>) -> Option<(String, String)> {
}
None
}

/// Attempts to read from STDIN and return the filename `<STDIN>` and text.
pub fn read_stdin(logs: &mut Vec<Log>) -> Option<(String, String)> {
use std::io::Read;

let mut text = String::new();
match std::io::stdin().read_to_string(&mut text) {
Ok(bytes) => {
record_file_log(
logs,
log::Level::Trace,
"<STDIN>",
&format!("Read {bytes} bytes."),
);
Some((String::from("<STDIN>"), text))
}
Err(e) => {
record_file_log(
logs,
Error,
"<STDIN>",
&format!("Could not read from STDIN: {e}"),
);
None
}
}
}

0 comments on commit 484277f

Please sign in to comment.