From 43052c5b06cd26efe43cddb7d5923cb6600a6044 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Sun, 2 Jul 2023 11:24:40 +0700 Subject: [PATCH] cleanup --- README.md | 2 +- src/context/mod.rs | 6 ++++-- src/main.rs | 40 +++++++++++----------------------------- src/progress.rs | 33 +++++++++++++++++++++++++++++++-- src/tree/mod.rs | 5 +---- 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index aef3f72d..f468a858 100644 --- a/README.md +++ b/README.md @@ -285,7 +285,7 @@ $ rustup toolchain install nightly-2023-06-11 Thereafter: ``` -$ cargo +nightly-2023-03-05 install erdtree +$ cargo +nightly-2023-06-11 install erdtree ``` ### Homebrew-core diff --git a/src/context/mod.rs b/src/context/mod.rs index 77648423..031bad09 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -257,8 +257,10 @@ impl Context { /// Initializes [Context], optionally reading in the configuration file to override defaults. /// Arguments provided will take precedence over config. pub fn try_init() -> Result { - let args = Self::compute_args()?; - Self::from_arg_matches(&args).map_err(Error::Config) + Self::compute_args().and_then(|args| { + color::no_color_env(); + Self::from_arg_matches(&args).map_err(Error::Config) + }) } /// Determines whether or not it's appropriate to display color in output based on diff --git a/src/main.rs b/src/main.rs index 5f5e0b46..11481fb2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,17 +11,13 @@ clippy::suspicious )] #![allow( - clippy::cast_possible_truncation, clippy::cast_precision_loss, - clippy::cast_sign_loss, - clippy::let_underscore_untyped, clippy::struct_excessive_bools, - clippy::too_many_arguments )] use clap::CommandFactory; use context::{layout, Context}; -use progress::Message; +use progress::{Indicator, IndicatorHandle, Message}; use render::{Engine, Flat, FlatInverted, Inverted, Regular}; use std::{error::Error, io::stdout, process::ExitCode, sync::Arc}; use tree::Tree; @@ -44,10 +40,7 @@ mod icons; /// Concerned with displaying a progress indicator when stdout is a tty. mod progress; -/// Concerned with taking an initialized [`Tree`] and its [`Node`]s and rendering the output. -/// -/// [`Tree`]: tree::Tree -/// [`Node`]: tree::node::Node +/// Concerned with taking an initialized [`tree::Tree`] and its [`tree::node::Node`]s and rendering the output. mod render; /// Global used throughout the program to paint the output. @@ -80,29 +73,18 @@ fn run() -> Result<(), Box> { return Ok(()); } - context::color::no_color_env(); - styles::init(ctx.no_color()); - let indicator = (ctx.stdout_is_tty && !ctx.no_progress) - .then(progress::Indicator::measure) - .map(Arc::new); - - if indicator.is_some() { - let indicator = indicator.clone(); + let indicator = Indicator::maybe_init(&ctx); - ctrlc::set_handler(move || { - let _ = progress::IndicatorHandle::terminate(indicator.clone()); - tty::restore_tty(); - })?; - } - - let (tree, ctx) = match Tree::try_init(ctx, indicator.clone()) { - Ok(res) => res, - Err(err) => { - let _ = progress::IndicatorHandle::terminate(indicator); - return Err(Box::new(err)); - }, + let (tree, ctx) = { + match Tree::try_init(ctx, indicator.clone()) { + Ok(res) => res, + Err(err) => { + IndicatorHandle::terminate(indicator); + return Err(Box::new(err)); + }, + } }; macro_rules! compute_output { diff --git a/src/progress.rs b/src/progress.rs index 440f1ddc..0f81a2b4 100644 --- a/src/progress.rs +++ b/src/progress.rs @@ -1,3 +1,4 @@ +use crate::{context::Context, tty}; use crossterm::{ cursor, terminal::{self, ClearType}, @@ -99,9 +100,15 @@ impl IndicatorHandle { self.mailbox.clone() } - /// Send a message through to the `priority_mailbox` tear down the [`Indicator`]. - pub fn terminate(this: Option>) -> Result<(), Error> { + /// Analogous to [`Self::try_terminate`] but panics if failure. + pub fn terminate(this: Option>) { + Self::try_terminate(this).expect("Failed to properly terminate the progress indicator"); + } + + /// Attempts to terminate the [`Indicator`] with cleanup. + pub fn try_terminate(this: Option>) -> Result<(), Error> { if let Some(mut handle) = this { + eprintln!("{}", Arc::strong_count(&handle)); handle.mailbox().send(Message::Finish)?; if let Some(hand) = Arc::get_mut(&mut handle) { @@ -117,6 +124,28 @@ impl IndicatorHandle { } impl<'a> Indicator<'a> { + /// Initializes an [`Indicator`] returning an atomic reference counter of an [`IndicatorHandle`] if + /// a progress indicator is enabled via [`Context`]. Upon initialization an interrupt handler is + /// also registered. Sources of panic can come from [`IndicatorHandle::terminate`] or + /// [`ctrlc::set_handler`]. + pub fn maybe_init(ctx: &Context) -> Option> { + (ctx.stdout_is_tty && !ctx.no_progress) + .then(Indicator::measure) + .map(|indicator| { + let indicator = Arc::new(indicator); + let arc = indicator.clone(); + + let int_handler = move || { + IndicatorHandle::terminate(Some(arc.clone())); + tty::restore_tty(); + }; + + ctrlc::set_handler(int_handler).expect("Failed to set interrupt handler"); + + indicator + }) + } + /// Initializes a worker thread that owns [`Indicator`] that awaits on [`Message`]s to traverse /// through its internal states. An [`IndicatorHandle`] is returned as a mechanism to allow the /// outside world to send messages to the worker thread and ultimately to the [`Indicator`]. diff --git a/src/tree/mod.rs b/src/tree/mod.rs index fff08152..dc6658bd 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -30,10 +30,7 @@ pub mod count; /// Errors related to traversal, [Tree] construction, and the like. pub mod error; -/// Contains components of the [`Tree`] data structure that derive from [`DirEntry`]. -/// -/// [`Tree`]: Tree -/// [`DirEntry`]: ignore::DirEntry +/// Contains components of the [`Tree`] data structure that derive from [`ignore::DirEntry`]. pub mod node; /// Custom visitor that operates on each thread during filesystem traversal.