on v0.8.0 help sign in
bat/src/controller.rs
108 lines 3.5 kB history raw
1use std::io::{self, Write};
3use app::Config;
4use assets::HighlightingAssets;
5use errors::*;
6use inputfile::{InputFile, InputFileReader};
7use line_range::LineRange;
8use output::OutputType;
9use printer::{InteractivePrinter, Printer, SimplePrinter};
11pub struct Controller<'a> {
12 config: &'a Config<'a>,
13 assets: &'a HighlightingAssets,
16impl<'b> Controller<'b> {
17 pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> {
18 Controller { config, assets }
19 }
21 pub fn run(&self) -> Result<bool> {
22 let mut output_type = OutputType::from_mode(self.config.paging_mode)?;
23 let writer = output_type.handle()?;
24 let mut no_errors: bool = true;
26 let stdin = io::stdin();
28 for input_file in &self.config.files {
29 match input_file.get_reader(&stdin) {
30 Err(error) => {
31 handle_error(&error);
32 no_errors = false;
33 }
34 Ok(mut reader) => {
35 let result = if self.config.loop_through {
36 let mut printer = SimplePrinter::new();
37 self.print_file(reader, &mut printer, writer, *input_file)
38 } else {
39 let mut printer = InteractivePrinter::new(
40 &self.config,
41 &self.assets,
42 *input_file,
43 &mut reader,
44 );
45 self.print_file(reader, &mut printer, writer, *input_file)
46 };
48 if let Err(error) = result {
49 handle_error(&error);
50 no_errors = false;
51 }
52 }
53 }
54 }
56 Ok(no_errors)
57 }
59 fn print_file<'a, P: Printer>(
60 &self,
61 reader: InputFileReader,
62 printer: &mut P,
63 writer: &mut Write,
64 input_file: InputFile<'a>,
65 ) -> Result<()> {
66 printer.print_header(writer, input_file)?;
67 self.print_file_ranges(printer, writer, reader, &self.config.line_range)?;
68 printer.print_footer(writer)?;
70 Ok(())
71 }
73 fn print_file_ranges<'a, P: Printer>(
74 &self,
75 printer: &mut P,
76 writer: &mut Write,
77 mut reader: InputFileReader,
78 line_ranges: &Option<LineRange>,
79 ) -> Result<()> {
80 let mut line_buffer = Vec::new();
82 let mut line_number: usize = 1;
84 while reader.read_line(&mut line_buffer)? {
85 match line_ranges {
86 &Some(ref range) => {
87 if line_number < range.lower {
88 // Call the printer in case we need to call the syntax highlighter
89 // for this line. However, set `out_of_range` to `true`.
90 printer.print_line(true, writer, line_number, &line_buffer)?;
91 } else if line_number > range.upper {
92 // no more lines in range, exit early
93 break;
94 } else {
95 printer.print_line(false, writer, line_number, &line_buffer)?;
96 }
97 }
98 &None => {
99 printer.print_line(false, writer, line_number, &line_buffer)?;
100 }
101 }
103 line_number += 1;
104 line_buffer.clear();
105 }
106 Ok(())
107 }