Implemented --file-name for multiple files + tests

This commit is contained in:
Kyle Criddle 2020-03-24 18:26:00 -06:00
parent cfa2cb6ec7
commit 59f2e2d58d
5 changed files with 80 additions and 21 deletions

View File

@ -137,6 +137,12 @@ impl App {
}
});
if self.matches.value_of("file-name").is_some()
&& self.matches.values_of("file-name").unwrap().len() != files.len()
{
return Err("When using --file-name, each input file must have a corresponding --file-name specified.".into());
}
Ok(Config {
true_color: is_truecolor_terminal(),
language: self.matches.value_of("language").or_else(|| {
@ -222,7 +228,10 @@ impl App {
.transpose()?
.unwrap_or_else(|| vec![LineRange { lower: 0, upper: 0 }]),
),
filename: self.matches.value_of("file-name").or_else(|| None),
filenames: self
.matches
.values_of("file-name")
.map(|values| values.collect()),
})
}

View File

@ -41,7 +41,20 @@ impl<'b> Controller<'b> {
let stdin = io::stdin();
for input_file in &self.config.files {
let filenames = if self.config.filenames.is_none() {
vec![None; self.config.files.len()]
} else {
self.config
.filenames
.as_ref()
.unwrap()
.into_iter()
.map(|name| Some(*name))
.collect()
};
for it in self.config.files.iter().zip(filenames) {
let (input_file, file_name) = it;
match input_file.get_reader(&stdin) {
Err(error) => {
handle_error(&error);
@ -50,7 +63,7 @@ impl<'b> Controller<'b> {
Ok(mut reader) => {
let result = if self.config.loop_through {
let mut printer = SimplePrinter::new();
self.print_file(reader, &mut printer, writer, *input_file)
self.print_file(reader, &mut printer, writer, *input_file, file_name)
} else {
let mut printer = InteractivePrinter::new(
&self.config,
@ -58,7 +71,7 @@ impl<'b> Controller<'b> {
*input_file,
&mut reader,
);
self.print_file(reader, &mut printer, writer, *input_file)
self.print_file(reader, &mut printer, writer, *input_file, file_name)
};
if let Err(error) = result {
@ -78,9 +91,10 @@ impl<'b> Controller<'b> {
printer: &mut P,
writer: &mut dyn Write,
input_file: InputFile<'a>,
file_name: Option<&str>,
) -> Result<()> {
if !reader.first_line.is_empty() || self.config.output_components.header() {
printer.print_header(writer, input_file)?;
printer.print_header(writer, input_file, file_name)?;
}
if !reader.first_line.is_empty() {

View File

@ -131,5 +131,5 @@ pub struct Config<'a> {
pub highlight_lines: LineRanges,
/// Name of file to display when printing
pub filename: Option<&'a str>,
pub filenames: Option<Vec<&'a str>>,
}

View File

@ -34,7 +34,12 @@ use crate::terminal::{as_terminal_escaped, to_ansi_color};
use crate::Config;
pub trait Printer {
fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()>;
fn print_header(
&mut self,
handle: &mut dyn Write,
file: InputFile,
file_name: Option<&str>,
) -> Result<()>;
fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()>;
fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>;
@ -57,7 +62,12 @@ impl SimplePrinter {
}
impl Printer for SimplePrinter {
fn print_header(&mut self, _handle: &mut dyn Write, _file: InputFile) -> Result<()> {
fn print_header(
&mut self,
_handle: &mut dyn Write,
_file: InputFile,
_file_name: Option<&str>,
) -> Result<()> {
Ok(())
}
@ -224,15 +234,20 @@ impl<'a> InteractivePrinter<'a> {
}
impl<'a> Printer for InteractivePrinter<'a> {
fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()> {
fn print_header(
&mut self,
handle: &mut dyn Write,
file: InputFile,
file_name: Option<&str>,
) -> Result<()> {
if !self.config.output_components.header() {
if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
let input = match file {
InputFile::Ordinary(filename) => format!(
"file '{}'",
self.config.filename.unwrap_or(&filename.to_string_lossy())
file_name.unwrap_or(&filename.to_string_lossy())
),
_ => self.config.filename.unwrap_or("STDIN").to_owned(),
_ => file_name.unwrap_or("STDIN").to_owned(),
};
writeln!(
@ -269,17 +284,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
let (prefix, name) = match file {
InputFile::Ordinary(filename) => (
"File: ",
Cow::from(
self.config
.filename
.unwrap_or(&filename.to_string_lossy())
.to_owned(),
),
),
_ => (
"File: ",
Cow::from(self.config.filename.unwrap_or("STDIN").to_owned()),
Cow::from(file_name.unwrap_or(&filename.to_string_lossy()).to_owned()),
),
_ => ("File: ", Cow::from(file_name.unwrap_or("STDIN").to_owned())),
};
let mode = match self.content_type {

View File

@ -598,3 +598,32 @@ fn filename_stdin_binary() {
.stdout("File: foo <BINARY>\n")
.stderr("");
}
#[test]
fn filename_multiple_ok() {
bat()
.arg("--decorations=always")
.arg("--style=header")
.arg("-r=0:0")
.arg("test.txt")
.arg("--file-name=foo")
.arg("single-line.txt")
.arg("--file-name=bar")
.assert()
.success()
.stdout("File: foo\nFile: bar\n")
.stderr("");
}
#[test]
fn filename_multiple_err() {
bat()
.arg("--decorations=always")
.arg("--style=header")
.arg("-r=0:0")
.arg("test.txt")
.arg("--file-name=foo")
.arg("single-line.txt")
.assert()
.failure();
}