Simplify type signatures in main module

Exa::from_args used to be in the library, called by the binary, but now the binary is gone, it no longer needs to be as abstract. Instead of accepting a reference to a Write value, it takes a Stdout directly, which it owns itself, simplifying the type signature drastically.
This commit is contained in:
Benjamin Sago 2020-10-10 02:34:54 +01:00
parent 8046980806
commit 39c3f15602

View File

@ -3,7 +3,7 @@
use std::env;
use std::ffi::{OsStr, OsString};
use std::io::{stdout, stderr, Write, Result as IOResult, ErrorKind};
use std::io::{stdout, Stdout, stderr, Write, Result as IOResult, ErrorKind};
use std::path::{Component, PathBuf};
use ansi_term::{ANSIStrings, Style};
@ -31,8 +31,8 @@ fn main() {
logger::configure(env::var_os(vars::EXA_DEBUG));
let args: Vec<OsString> = env::args_os().skip(1).collect();
match Exa::from_args(args.iter(), &mut stdout()) {
let args: Vec<_> = env::args_os().skip(1).collect();
match Exa::from_args(args.iter(), stdout()) {
Ok(mut exa) => {
match exa.run() {
Ok(exit_status) => exit(exit_status),
@ -68,15 +68,13 @@ fn main() {
/// The main program wrapper.
pub struct Exa<'args, 'w, W: Write + 'w> {
pub struct Exa<'args> {
/// List of command-line options, having been successfully parsed.
pub options: Options,
/// The output handle that we write to. When running the program normally,
/// this will be `std::io::Stdout`, but it can accept any struct thats
/// `Write` so we can write into, say, a vector for testing.
pub writer: &'w mut W,
/// The output handle that we write to.
pub writer: Stdout,
/// List of the free command-line arguments that should correspond to file
/// names (anything that isnt an option).
@ -109,23 +107,23 @@ fn git_options(options: &Options, args: &[&OsStr]) -> Option<GitCache> {
}
}
impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
pub fn from_args<I>(args: I, writer: &'w mut W) -> Result<Exa<'args, 'w, W>, Misfire>
where I: Iterator<Item=&'args OsString> {
Options::parse(args, &LiveVars).map(move |(options, mut args)| {
debug!("Dir action from arguments: {:#?}", options.dir_action);
debug!("Filter from arguments: {:#?}", options.filter);
debug!("View from arguments: {:#?}", options.view.mode);
impl<'args> Exa<'args> {
pub fn from_args<I>(args: I, writer: Stdout) -> Result<Exa<'args>, Misfire>
where I: Iterator<Item=&'args OsString>
{
let (options, mut args) = Options::parse(args, &LiveVars)?;
debug!("Dir action from arguments: {:#?}", options.dir_action);
debug!("Filter from arguments: {:#?}", options.filter);
debug!("View from arguments: {:#?}", options.view.mode);
// List the current directory by default, like ls.
// This has to be done here, otherwise git_options wont see it.
if args.is_empty() {
args = vec![ OsStr::new(".") ];
}
// List the current directory by default, like ls.
// This has to be done here, otherwise git_options wont see it.
if args.is_empty() {
args = vec![ OsStr::new(".") ];
}
let git = git_options(&options, &args);
Exa { options, writer, args, git }
})
let git = git_options(&options, &args);
Ok(Exa { options, writer, args, git })
}
pub fn run(&mut self) -> IOResult<i32> {
@ -175,13 +173,13 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
first = false;
}
else {
writeln!(self.writer)?;
writeln!(&mut self.writer)?;
}
if !is_only_dir {
let mut bits = Vec::new();
escape(dir.path.display().to_string(), &mut bits, Style::default(), Style::default());
writeln!(self.writer, "{}:", ANSIStrings(&bits))?;
writeln!(&mut self.writer, "{}:", ANSIStrings(&bits))?;
}
let mut children = Vec::new();
@ -233,12 +231,12 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
match *mode {
Mode::Lines(ref opts) => {
let r = lines::Render { files, colours, style, opts };
r.render(self.writer)
r.render(&mut self.writer)
}
Mode::Grid(ref opts) => {
let r = grid::Render { files, colours, style, opts };
r.render(self.writer)
r.render(&mut self.writer)
}
Mode::Details(ref opts) => {
@ -247,7 +245,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
let r = details::Render { dir, files, colours, style, opts, filter, recurse, git_ignoring };
r.render(self.git.as_ref(), self.writer)
r.render(self.git.as_ref(), &mut self.writer)
}
Mode::GridDetails(ref opts) => {
@ -258,7 +256,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
let r = grid_details::Render { dir, files, colours, style, grid, details, filter, row_threshold, git_ignoring };
r.render(self.git.as_ref(), self.writer)
r.render(self.git.as_ref(), &mut self.writer)
}
}
}