From 2b9f425bdaa5556d72909119c9b70bf6e1d4dd12 Mon Sep 17 00:00:00 2001 From: Ossama Hjaji Date: Sat, 10 Oct 2020 14:24:15 +0200 Subject: [PATCH] further refactoring of main.rs --- src/{app.rs => clap_app.rs} | 0 src/image_backends/mod.rs | 31 +++++++++-- src/info.rs | 33 +++++++++++- src/main.rs | 100 +++++++++++------------------------- 4 files changed, 89 insertions(+), 75 deletions(-) rename src/{app.rs => clap_app.rs} (100%) diff --git a/src/app.rs b/src/clap_app.rs similarity index 100% rename from src/app.rs rename to src/clap_app.rs diff --git a/src/image_backends/mod.rs b/src/image_backends/mod.rs index 7d769c766..da5bc762f 100644 --- a/src/image_backends/mod.rs +++ b/src/image_backends/mod.rs @@ -1,15 +1,15 @@ use image::DynamicImage; -#[cfg(target_os = "linux")] +#[cfg(unix)] pub mod kitty; -#[cfg(target_os = "linux")] +#[cfg(unix)] pub mod sixel; pub trait ImageBackend { fn add_image(&self, lines: Vec, image: &DynamicImage) -> String; } -#[cfg(target_os = "linux")] +#[cfg(unix)] pub fn get_best_backend() -> Option> { if kitty::KittyBackend::supported() { Some(Box::new(kitty::KittyBackend::new())) @@ -20,7 +20,30 @@ pub fn get_best_backend() -> Option> { } } -#[cfg(not(target_os = "linux"))] +pub fn get_image_backend( + image: &Option, + backend_name: &str, +) -> Option> { + if image.is_some() { + #[cfg(unix)] + let backend = Some(match backend_name { + "kitty" => { + Box::new(kitty::KittyBackend::new()) as Box + } + "sixel" => { + Box::new(sixel::SixelBackend::new()) as Box + } + _ => unreachable!(), + }); + #[cfg(not(unix))] + let backend = None; + backend + } else { + None + } +} + +#[cfg(not(unix))] pub fn get_best_backend() -> Option> { None } diff --git a/src/info.rs b/src/info.rs index f45e7931c..5b96d673a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -8,7 +8,7 @@ use { colored::{Color, ColoredString, Colorize}, git2::Repository, regex::Regex, - std::{ffi::OsStr, fmt::Write, fs}, + std::{ffi::OsStr, fmt::Write, fs, str::FromStr}, strum::{EnumCount, EnumIter, EnumString, IntoStaticStr}, tokio::process::Command, }; @@ -77,6 +77,37 @@ pub struct Info { config: Options, } +pub fn get_disabled_fields(fields_to_hide: Vec) -> Result { + let mut disabled_fields = InfoFieldOn { + ..Default::default() + }; + + for field in fields_to_hide.iter() { + let item = InfoFields::from_str(field.to_lowercase().as_str()) + .unwrap_or(InfoFields::UnrecognizedField); + + match item { + InfoFields::GitInfo => disabled_fields.git_info = true, + InfoFields::Project => disabled_fields.project = true, + InfoFields::HEAD => disabled_fields.head = true, + InfoFields::Version => disabled_fields.version = true, + InfoFields::Created => disabled_fields.created = true, + InfoFields::Languages => disabled_fields.languages = true, + InfoFields::Authors => disabled_fields.authors = true, + InfoFields::LastChange => disabled_fields.last_change = true, + InfoFields::Repo => disabled_fields.repo = true, + InfoFields::Pending => disabled_fields.pending = true, + InfoFields::Commits => disabled_fields.commits = true, + InfoFields::LinesOfCode => disabled_fields.lines_of_code = true, + InfoFields::Size => disabled_fields.size = true, + InfoFields::License => disabled_fields.license = true, + _ => (), + } + } + + Ok(disabled_fields) +} + impl std::fmt::Display for Info { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let mut buf = String::new(); diff --git a/src/main.rs b/src/main.rs index cba23b827..41eb4a6c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,20 @@ #[macro_use] extern crate clap; -#[cfg(target_os = "linux")] -use image_backends::ImageBackend; +#[cfg(unix)] use { ascii_art::AsciiArt, commit_info::CommitInfo, error::Error, exit_codes::ExitCode, - info::{Info, InfoFieldOn, InfoFields}, + info::Info, language::Language, process::{Command, Stdio}, std::{convert::From, env, process, result, str::FromStr}, strum::IntoEnumIterator, }; -mod app; +mod clap_app; mod ascii_art; mod commit_info; mod error; @@ -28,90 +27,38 @@ mod options; type Result = result::Result; -fn run() -> Result<()> { - #[cfg(target_os = "windows")] - let enabled = ansi_term::enable_ansi_support().is_ok(); - - #[cfg(not(target_os = "windows"))] - let enabled = true; - - if enabled { - colored::control::set_override(true); - } +/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and +/// `Ok(false)` if any intermediate errors occurred (were printed). +fn run() -> Result { + #[cfg(windows)] + let _ = ansi_term::enable_ansi_support(); if !is_git_installed() { return Err(Error::GitNotInstalled); } - let matches = app::build_app().get_matches_from(env::args_os()); + let matches = clap_app::build_app().get_matches_from(env::args_os()); if matches.is_present("languages") { - let iterator = Language::iter().filter(|x| *x != Language::Unknown); - - for l in iterator { - println!("{}", l); - } - std::process::exit(0); + return list_languages(); } - let mut disabled_fields = InfoFieldOn { - ..Default::default() - }; - let fields_to_hide: Vec = if let Some(values) = matches.values_of("disable-fields") { values.map(String::from).collect() } else { Vec::new() }; - for field in fields_to_hide.iter() { - let item = InfoFields::from_str(field.to_lowercase().as_str()) - .unwrap_or(InfoFields::UnrecognizedField); - - match item { - InfoFields::GitInfo => disabled_fields.git_info = true, - InfoFields::Project => disabled_fields.project = true, - InfoFields::HEAD => disabled_fields.head = true, - InfoFields::Version => disabled_fields.version = true, - InfoFields::Created => disabled_fields.created = true, - InfoFields::Languages => disabled_fields.languages = true, - InfoFields::Authors => disabled_fields.authors = true, - InfoFields::LastChange => disabled_fields.last_change = true, - InfoFields::Repo => disabled_fields.repo = true, - InfoFields::Pending => disabled_fields.pending = true, - InfoFields::Commits => disabled_fields.commits = true, - InfoFields::LinesOfCode => disabled_fields.lines_of_code = true, - InfoFields::Size => disabled_fields.size = true, - InfoFields::License => disabled_fields.license = true, - _ => (), - } - } - let image = if let Some(image_path) = matches.value_of("image") { Some(image::open(image_path).map_err(|_| Error::ImageLoadError)?) } else { None }; - let image_backend = if image.is_some() { - if let Some(backend_name) = matches.value_of("image-backend") { - #[cfg(target_os = "linux")] - let backend = - Some(match backend_name { - "kitty" => Box::new(image_backends::kitty::KittyBackend::new()) - as Box, - "sixel" => Box::new(image_backends::sixel::SixelBackend::new()) - as Box, - _ => unreachable!(), - }); - #[cfg(not(target_os = "linux"))] - let backend = None; - backend - } else { - crate::image_backends::get_best_backend() - } + let image_backend = if let Some(backend_name) = matches.value_of("image-backend") { + image_backends::get_image_backend(&image, backend_name) } else { - None + image_backends::get_best_backend() }; let config = options::Options { @@ -126,9 +73,9 @@ fn run() -> Result<()> { } else { Vec::new() }, - disabled_fields, + disabled_fields: info::get_disabled_fields(fields_to_hide)?, no_bold: !matches.is_present("no-bold"), - image: image, + image, image_backend, no_merges: matches.is_present("no-merge-commits"), no_color_blocks: matches.is_present("no-color-blocks"), @@ -147,15 +94,28 @@ fn run() -> Result<()> { let info = Info::new(config)?; print!("{}", info); - Ok(()) + Ok(true) +} + +pub fn list_languages() -> Result { + let iterator = Language::iter().filter(|x| *x != Language::Unknown); + + for l in iterator { + println!("{}", l); + } + + Ok(true) } fn main() { let result = run(); match result { - Ok(_) => { + Ok(true) => { process::exit(ExitCode::Success.into()); } + Ok(false) => { + process::exit(ExitCode::GeneralError.into()); + } Err(_) => { process::exit(ExitCode::GeneralError.into()); }