Skip to content

Commit 3cffcc5

Browse files
author
Kyle Criddle
committed
Moved user_provided_filename to be contained within OrdinaryFile struct
1 parent 56629da commit 3cffcc5

File tree

9 files changed

+142
-126
lines changed

9 files changed

+142
-126
lines changed

examples/cat.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// A very simple colorized `cat` clone, using `bat` as a library.
22
/// See `src/bin/bat` for the full `bat` application.
33
use bat::{
4-
config::{Config, InputFile, StyleComponent, StyleComponents},
4+
config::{Config, InputFile, OrdinaryFile, StyleComponent, StyleComponents},
55
Controller, HighlightingAssets,
66
};
77
use console::Term;
@@ -24,7 +24,10 @@ fn main() {
2424
StyleComponent::Grid,
2525
StyleComponent::Numbers,
2626
]),
27-
files: files.iter().map(|file| InputFile::Ordinary(file)).collect(),
27+
files: files
28+
.iter()
29+
.map(|file| InputFile::Ordinary(OrdinaryFile::new(file, None)))
30+
.collect(),
2831
..Default::default()
2932
};
3033
let assets = HighlightingAssets::from_binary();

examples/simple.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// A simple program that prints its own source code using the bat library
22
use bat::{
3-
config::{Config, InputFile},
3+
config::{Config, InputFile, OrdinaryFile},
44
Controller, HighlightingAssets,
55
};
66
use std::ffi::OsStr;
@@ -9,7 +9,10 @@ fn main() {
99
let path_to_this_file = OsStr::new(file!());
1010

1111
let config = Config {
12-
files: vec![InputFile::Ordinary(path_to_this_file)],
12+
files: vec![InputFile::Ordinary(OrdinaryFile::new(
13+
path_to_this_file,
14+
None,
15+
))],
1316
colored_output: true,
1417
true_color: true,
1518
..Default::default()

src/assets.rs

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,13 @@ impl HighlightingAssets {
177177
&self,
178178
language: Option<&str>,
179179
file: InputFile,
180-
file_name: Option<&str>,
181180
reader: &mut InputFileReader,
182181
mapping: &SyntaxMapping,
183182
) -> &SyntaxReference {
184-
let syntax = match (language, file, file_name) {
185-
(Some(language), _, _) => self.syntax_set.find_syntax_by_token(language),
186-
(None, InputFile::Ordinary(file), _) => {
187-
let path = Path::new(file);
183+
let syntax = match (language, file) {
184+
(Some(language), _) => self.syntax_set.find_syntax_by_token(language),
185+
(None, InputFile::Ordinary(ofile)) => {
186+
let path = Path::new(ofile.filename());
188187

189188
let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
190189
let extension = path.extension().and_then(|x| x.to_str()).unwrap_or("");
@@ -208,12 +207,12 @@ impl HighlightingAssets {
208207
None => ext_syntax.or(line_syntax),
209208
}
210209
}
211-
(None, InputFile::StdIn, None) => String::from_utf8(reader.first_line.clone())
210+
(None, InputFile::StdIn(None)) => String::from_utf8(reader.first_line.clone())
212211
.ok()
213212
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l)),
214-
(None, InputFile::StdIn, Some(file_name)) => self
213+
(None, InputFile::StdIn(Some(file_name))) => self
215214
.syntax_set
216-
.find_syntax_by_extension(&file_name)
215+
.find_syntax_by_extension(file_name.to_str().unwrap())
217216
.or_else(|| {
218217
self.syntax_set.find_syntax_by_extension(
219218
Path::new(file_name)
@@ -225,7 +224,7 @@ impl HighlightingAssets {
225224
.or(String::from_utf8(reader.first_line.clone())
226225
.ok()
227226
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l))),
228-
(_, InputFile::ThemePreviewFile, _) => self.syntax_set.find_syntax_by_name("Rust"),
227+
(_, InputFile::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"),
229228
};
230229

231230
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
@@ -242,7 +241,7 @@ mod tests {
242241
use tempdir::TempDir;
243242

244243
use crate::assets::HighlightingAssets;
245-
use crate::inputfile::InputFile;
244+
use crate::inputfile::{InputFile, OrdinaryFile};
246245
use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
247246

248247
struct SyntaxDetectionTest<'a> {
@@ -261,28 +260,17 @@ mod tests {
261260
}
262261
}
263262

264-
fn syntax_for_file_with_content(
265-
&self,
266-
file_name: &str,
267-
first_line: &str,
268-
as_stdin: bool,
269-
) -> String {
263+
fn syntax_for_file_with_content(&self, file_name: &str, first_line: &str) -> String {
270264
let file_path = self.temp_dir.path().join(file_name);
271265
{
272266
let mut temp_file = File::create(&file_path).unwrap();
273267
writeln!(temp_file, "{}", first_line).unwrap();
274268
}
275269

276-
let input_file = InputFile::Ordinary(OsStr::new(&file_path));
277-
let (file, file_name) = if as_stdin {
278-
(InputFile::StdIn, Some(file_name))
279-
} else {
280-
(input_file, None)
281-
};
270+
let input_file = InputFile::Ordinary(OrdinaryFile::new(OsStr::new(&file_path), None));
282271
let syntax = self.assets.get_syntax(
283272
None,
284-
file,
285-
file_name,
273+
input_file,
286274
&mut input_file.get_reader(&io::stdin()).unwrap(),
287275
&self.syntax_mapping,
288276
);
@@ -291,7 +279,7 @@ mod tests {
291279
}
292280

293281
fn syntax_for_file(&self, file_name: &str) -> String {
294-
self.syntax_for_file_with_content(file_name, "", false)
282+
self.syntax_for_file_with_content(file_name, "")
295283
}
296284
}
297285

@@ -325,15 +313,15 @@ mod tests {
325313
let test = SyntaxDetectionTest::new();
326314

327315
assert_eq!(
328-
test.syntax_for_file_with_content("my_script", "#!/bin/bash", false),
316+
test.syntax_for_file_with_content("my_script", "#!/bin/bash"),
329317
"Bourne Again Shell (bash)"
330318
);
331319
assert_eq!(
332-
test.syntax_for_file_with_content("build", "#!/bin/bash", false),
320+
test.syntax_for_file_with_content("build", "#!/bin/bash"),
333321
"Bourne Again Shell (bash)"
334322
);
335323
assert_eq!(
336-
test.syntax_for_file_with_content("my_script", "<?php", false),
324+
test.syntax_for_file_with_content("my_script", "<?php"),
337325
"PHP"
338326
);
339327
}
@@ -365,13 +353,10 @@ mod tests {
365353
let test = SyntaxDetectionTest::new();
366354

367355
// from file extension
368-
assert_eq!(
369-
test.syntax_for_file_with_content("test.cpp", "", true),
370-
"C++"
371-
);
356+
assert_eq!(test.syntax_for_file_with_content("test.cpp", ""), "C++");
372357
// from first line (fallback)
373358
assert_eq!(
374-
test.syntax_for_file_with_content("my_script", "#!/bin/bash", true),
359+
test.syntax_for_file_with_content("my_script", "#!/bin/bash"),
375360
"Bourne Again Shell (bash)"
376361
);
377362
}

src/bin/bat/app.rs

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::HashSet;
22
use std::env;
3+
use std::ffi::OsStr;
34
use std::str::FromStr;
45

56
use atty::{self, Stream};
@@ -18,8 +19,8 @@ use ansi_term;
1819

1920
use bat::{
2021
config::{
21-
Config, HighlightedLineRanges, InputFile, LineRange, LineRanges, MappingTarget, OutputWrap,
22-
PagingMode, StyleComponent, StyleComponents, SyntaxMapping,
22+
Config, HighlightedLineRanges, InputFile, LineRange, LineRanges, MappingTarget,
23+
OrdinaryFile, OutputWrap, PagingMode, StyleComponent, StyleComponents, SyntaxMapping,
2324
},
2425
errors::*,
2526
HighlightingAssets,
@@ -77,7 +78,7 @@ impl App {
7778
}
7879

7980
pub fn config(&self) -> Result<Config> {
80-
let files = self.files();
81+
let files = self.files()?;
8182
let style_components = self.style_components()?;
8283

8384
let paging_mode = match self.matches.value_of("paging") {
@@ -87,7 +88,7 @@ impl App {
8788
if self.matches.occurrences_of("plain") > 1 {
8889
// If we have -pp as an option when in auto mode, the pager should be disabled.
8990
PagingMode::Never
90-
} else if files.contains(&InputFile::StdIn) {
91+
} else if files.contains(&InputFile::StdIn(None)) {
9192
// If we are reading from stdin, only enable paging if we write to an
9293
// interactive terminal and if we do not *read* from an interactive
9394
// terminal.
@@ -136,13 +137,6 @@ impl App {
136137
}
137138
});
138139

139-
match self.matches.values_of("file-name") {
140-
Some(filenames) if filenames.len() != files.len() => {
141-
return Err(format!("{} {}", filenames.len(), files.len()).into());
142-
}
143-
_ => {}
144-
}
145-
146140
Ok(Config {
147141
true_color: is_truecolor_terminal(),
148142
language: self.matches.value_of("language").or_else(|| {
@@ -229,28 +223,59 @@ impl App {
229223
.map(LineRanges::from)
230224
.map(|lr| HighlightedLineRanges(lr))
231225
.unwrap_or_default(),
232-
filenames: self
233-
.matches
234-
.values_of("file-name")
235-
.map(|values| values.collect()),
236226
})
237227
}
238228

239-
fn files(&self) -> Vec<InputFile> {
240-
self.matches
229+
fn files(&self) -> Result<Vec<InputFile>> {
230+
// verify equal length of file-names and input FILEs
231+
match self.matches.values_of("file-name") {
232+
Some(filenames)
233+
if self.matches.values_of_os("FILE").is_some()
234+
&& filenames.len() != self.matches.values_of_os("FILE").unwrap().len() =>
235+
{
236+
return Err("Must be one file name per input type.".into());
237+
}
238+
_ => {}
239+
}
240+
let filenames: Option<Vec<&str>> = self
241+
.matches
242+
.values_of("file-name")
243+
.map(|values| values.collect());
244+
245+
let mut filenames_or_none: Box<dyn Iterator<Item = _>> = match filenames {
246+
Some(ref filenames) => {
247+
Box::new(filenames.into_iter().map(|name| Some(OsStr::new(*name))))
248+
}
249+
None => Box::new(std::iter::repeat(None)),
250+
};
251+
let files: Option<Vec<&str>> = self
252+
.matches
241253
.values_of_os("FILE")
242-
.map(|values| {
243-
values
244-
.map(|filename| {
245-
if filename == "-" {
246-
InputFile::StdIn
247-
} else {
248-
InputFile::Ordinary(filename)
249-
}
250-
})
251-
.collect()
252-
})
253-
.unwrap_or_else(|| vec![InputFile::StdIn])
254+
.map(|values| values.map(|fname| fname.to_str()).collect())
255+
.unwrap_or(None);
256+
257+
if files.is_none() {
258+
return Ok(vec![InputFile::StdIn(filenames_or_none.nth(0).unwrap())]);
259+
}
260+
let files_or_none: Box<dyn Iterator<Item = _>> = match files {
261+
Some(ref files) => Box::new(files.into_iter().map(|name| Some(OsStr::new(*name)))),
262+
None => Box::new(std::iter::repeat(None)),
263+
};
264+
265+
let mut file_input = Vec::new();
266+
for (input, name) in files_or_none.zip(filenames_or_none) {
267+
match input {
268+
Some(input) => {
269+
if input.to_str().unwrap() == "-" {
270+
file_input.push(InputFile::StdIn(name));
271+
} else {
272+
file_input.push(InputFile::Ordinary(OrdinaryFile::new(input, name)))
273+
}
274+
}
275+
None => {}
276+
}
277+
}
278+
return Ok(file_input);
254279
}
255280

256281
fn style_components(&self) -> Result<StyleComponents> {

src/bin/bat/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use bat::Controller;
2828
use directories::PROJECT_DIRS;
2929

3030
use bat::{
31-
config::{Config, InputFile, StyleComponent, StyleComponents},
31+
config::{Config, InputFile, OrdinaryFile, StyleComponent, StyleComponents},
3232
errors::*,
3333
HighlightingAssets,
3434
};
@@ -169,7 +169,10 @@ fn run() -> Result<bool> {
169169
Ok(true)
170170
} else {
171171
let mut config = app.config()?;
172-
config.files = vec![InputFile::Ordinary(OsStr::new("cache"))];
172+
config.files = vec![InputFile::Ordinary(OrdinaryFile::new(
173+
OsStr::new("cache"),
174+
None,
175+
))];
173176

174177
run_controller(&config)
175178
}

src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub use crate::inputfile::InputFile;
2+
pub use crate::inputfile::OrdinaryFile;
23
pub use crate::line_range::{HighlightedLineRanges, LineRange, LineRanges};
34
pub use crate::style::{StyleComponent, StyleComponents};
45
pub use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
@@ -70,9 +71,8 @@ pub struct Config<'a> {
7071

7172
/// Ranges of lines which should be highlighted with a special background color
7273
pub highlighted_lines: HighlightedLineRanges,
73-
74-
/// Names of files to display when printing
75-
pub filenames: Option<Vec<&'a str>>,
74+
///// Names of files to display when printing
75+
// pub filenames: Option<Vec<&'a str>>,
7676
}
7777

7878
#[test]

src/controller.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ impl<'b> Controller<'b> {
2828
let mut paging_mode = self.config.paging_mode;
2929
if self.config.paging_mode != PagingMode::Never {
3030
let call_pager = self.config.files.iter().any(|file| {
31-
if let InputFile::Ordinary(path) = file {
32-
return Path::new(path).exists();
31+
if let InputFile::Ordinary(ofile) = file {
32+
return Path::new(ofile.filename()).exists();
3333
} else {
3434
return true;
3535
}
@@ -45,12 +45,7 @@ impl<'b> Controller<'b> {
4545

4646
let stdin = io::stdin();
4747

48-
let filenames: Box<dyn Iterator<Item = _>> = match self.config.filenames {
49-
Some(ref filenames) => Box::new(filenames.into_iter().map(|name| Some(*name))),
50-
None => Box::new(std::iter::repeat(None)),
51-
};
52-
53-
for (input_file, file_name) in self.config.files.iter().zip(filenames) {
48+
for input_file in self.config.files.iter() {
5449
match input_file.get_reader(&stdin) {
5550
Err(error) => {
5651
handle_error(&error);
@@ -59,16 +54,15 @@ impl<'b> Controller<'b> {
5954
Ok(mut reader) => {
6055
let result = if self.config.loop_through {
6156
let mut printer = SimplePrinter::new();
62-
self.print_file(reader, &mut printer, writer, *input_file, file_name)
57+
self.print_file(reader, &mut printer, writer, *input_file)
6358
} else {
6459
let mut printer = InteractivePrinter::new(
6560
&self.config,
6661
&self.assets,
6762
*input_file,
68-
file_name,
6963
&mut reader,
7064
);
71-
self.print_file(reader, &mut printer, writer, *input_file, file_name)
65+
self.print_file(reader, &mut printer, writer, *input_file)
7266
};
7367

7468
if let Err(error) = result {
@@ -88,10 +82,9 @@ impl<'b> Controller<'b> {
8882
printer: &mut P,
8983
writer: &mut dyn Write,
9084
input_file: InputFile<'a>,
91-
file_name: Option<&str>,
9285
) -> Result<()> {
9386
if !reader.first_line.is_empty() || self.config.style_components.header() {
94-
printer.print_header(writer, input_file, file_name)?;
87+
printer.print_header(writer, input_file)?;
9588
}
9689

9790
if !reader.first_line.is_empty() {

0 commit comments

Comments
 (0)