on 1a6709c help sign in
bat/src/controller.rs
98 lines 3.1 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 let mut reader = input_file.get_reader(&stdin)?;
31 let result = if self.config.loop_through {
32 let mut printer = SimplePrinter::new();
33 self.print_file(reader, &mut printer, writer, *input_file)
34 } else {
35 let mut printer =
36 InteractivePrinter::new(&self.config, &self.assets, *input_file, &mut reader);
37 self.print_file(reader, &mut printer, writer, *input_file)
38 };
40 if let Err(error) = result {
41 handle_error(&error);
42 no_errors = false;
43 }
44 }
46 Ok(no_errors)
47 }
49 fn print_file<'a, P: Printer>(
50 &self,
51 reader: InputFileReader,
52 printer: &mut P,
53 writer: &mut Write,
54 input_file: InputFile<'a>,
55 ) -> Result<()> {
56 printer.print_header(writer, input_file)?;
57 self.print_file_ranges(printer, writer, reader, &self.config.line_range)?;
58 printer.print_footer(writer)?;
60 Ok(())
61 }
63 fn print_file_ranges<'a, P: Printer>(
64 &self,
65 printer: &mut P,
66 writer: &mut Write,
67 mut reader: InputFileReader,
68 line_ranges: &Option<LineRange>,
69 ) -> Result<()> {
70 let mut line_buffer = Vec::new();
72 let mut line_number: usize = 1;
74 while reader.read_line(&mut line_buffer)? {
75 match line_ranges {
76 &Some(ref range) => {
77 if line_number < range.lower {
78 // Call the printer in case we need to call the syntax highlighter
79 // for this line. However, set `out_of_range` to `true`.
80 printer.print_line(true, writer, line_number, &line_buffer)?;
81 } else if line_number > range.upper {
82 // no more lines in range, exit early
83 break;
84 } else {
85 printer.print_line(false, writer, line_number, &line_buffer)?;
86 }
87 }
88 &None => {
89 printer.print_line(false, writer, line_number, &line_buffer)?;
90 }
91 }
93 line_number += 1;
94 line_buffer.clear();
95 }
96 Ok(())
97 }