diff --git a/crates/shared/cli-utils/src/lib.rs b/crates/shared/cli-utils/src/lib.rs index fe92be91..e7053816 100644 --- a/crates/shared/cli-utils/src/lib.rs +++ b/crates/shared/cli-utils/src/lib.rs @@ -19,4 +19,7 @@ mod version; pub use version::Version; mod runtime; -pub use runtime::{build_runtime, run_until_ctrl_c, run_until_ctrl_c_fallible}; +pub use runtime::RuntimeManager; + +mod styles; +pub use styles::CliStyles; diff --git a/crates/shared/cli-utils/src/runtime.rs b/crates/shared/cli-utils/src/runtime.rs index ac2b61e4..f8af5368 100644 --- a/crates/shared/cli-utils/src/runtime.rs +++ b/crates/shared/cli-utils/src/runtime.rs @@ -2,42 +2,48 @@ use std::future::Future; -/// Builds a multi-threaded Tokio runtime with all features enabled. -pub fn build_runtime() -> eyre::Result { - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .map_err(|e| eyre::eyre!("Failed to build tokio runtime: {}", e)) -} +/// A runtime manager. +#[derive(Debug, Clone, Copy)] +pub struct RuntimeManager; + +impl RuntimeManager { + /// Builds a multi-threaded Tokio runtime with all features enabled. + pub fn build_runtime() -> eyre::Result { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .map_err(|e| eyre::eyre!("Failed to build tokio runtime: {}", e)) + } -/// Runs a future to completion, returning early on Ctrl+C. -pub async fn run_until_ctrl_c(fut: F) -> eyre::Result<()> -where - F: Future, -{ - let ctrl_c = async { - tokio::signal::ctrl_c().await.expect("Failed to install Ctrl+C handler"); - }; + /// Runs a future to completion, returning early on Ctrl+C. + pub async fn run_until_ctrl_c(fut: F) -> eyre::Result<()> + where + F: Future, + { + let ctrl_c = async { + tokio::signal::ctrl_c().await.expect("Failed to install Ctrl+C handler"); + }; - tokio::select! { - biased; - () = ctrl_c => Ok(()), - () = fut => Ok(()), + tokio::select! { + biased; + () = ctrl_c => Ok(()), + () = fut => Ok(()), + } } -} -/// Runs a fallible future to completion, returning early on Ctrl+C. -pub async fn run_until_ctrl_c_fallible(fut: F) -> eyre::Result<()> -where - F: Future>, -{ - let ctrl_c = async { - tokio::signal::ctrl_c().await.expect("Failed to install Ctrl+C handler"); - }; + /// Runs a fallible future to completion, returning early on Ctrl+C. + pub async fn run_until_ctrl_c_fallible(fut: F) -> eyre::Result<()> + where + F: Future>, + { + let ctrl_c = async { + tokio::signal::ctrl_c().await.expect("Failed to install Ctrl+C handler"); + }; - tokio::select! { - biased; - () = ctrl_c => Ok(()), - result = fut => result, + tokio::select! { + biased; + () = ctrl_c => Ok(()), + result = fut => result, + } } } diff --git a/crates/shared/cli-utils/src/styles.rs b/crates/shared/cli-utils/src/styles.rs new file mode 100644 index 00000000..12f27572 --- /dev/null +++ b/crates/shared/cli-utils/src/styles.rs @@ -0,0 +1,24 @@ +//! Cli styles for [clap]. + +use clap::builder::{ + Styles, + styling::{AnsiColor, Color, Style}, +}; + +/// A wrapper type for CLI styles. +#[derive(Debug, Clone, Copy)] +pub struct CliStyles; + +impl CliStyles { + /// Initialize the CLI styles, returning a [`Styles`] instance. + pub const fn init() -> Styles { + clap::builder::Styles::styled() + .usage(Style::new().bold().underline().fg_color(Some(Color::Ansi(AnsiColor::Yellow)))) + .header(Style::new().bold().underline().fg_color(Some(Color::Ansi(AnsiColor::Yellow)))) + .literal(Style::new().fg_color(Some(Color::Ansi(AnsiColor::Green)))) + .invalid(Style::new().bold().fg_color(Some(Color::Ansi(AnsiColor::Red)))) + .error(Style::new().bold().fg_color(Some(Color::Ansi(AnsiColor::Red)))) + .valid(Style::new().bold().underline().fg_color(Some(Color::Ansi(AnsiColor::Green)))) + .placeholder(Style::new().fg_color(Some(Color::Ansi(AnsiColor::Blue)))) + } +}