From 20dd9f182ec842a267fc48c72578c6169c121ccb Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 15 Aug 2026 20:21:45 +0800 Subject: refactor: rename Confirmer to ResConfirm and OSC94 to ResOSC94 Rename `Confirmer` resource to `ResConfirm`, `ConfirmerCount` to `ConfirmCount`, and `ConfirmerPredicate` to `ConfirmPredicate`. Update related setups, guards, and documentation references. --- mingling/src/confirm/count.rs | 58 ++++++++++-- mingling/src/confirm/predicate.rs | 22 ++--- mingling/src/osc94/guard.rs | 34 +++---- mingling/src/res.rs | 4 +- mingling/src/res/confirm.rs | 184 ++++++++++++++++++++++++++++++++++++++ mingling/src/res/confirmer.rs | 184 -------------------------------------- mingling/src/res/osc94.rs | 14 +-- mingling/src/setups.rs | 4 +- mingling/src/setups/confirm.rs | 60 +++++++++++++ mingling/src/setups/confirmer.rs | 60 ------------- mingling/src/setups/osc94.rs | 8 +- 11 files changed, 338 insertions(+), 294 deletions(-) create mode 100644 mingling/src/res/confirm.rs delete mode 100644 mingling/src/res/confirmer.rs create mode 100644 mingling/src/setups/confirm.rs delete mode 100644 mingling/src/setups/confirmer.rs (limited to 'mingling') diff --git a/mingling/src/confirm/count.rs b/mingling/src/confirm/count.rs index b9753c2..373d42c 100644 --- a/mingling/src/confirm/count.rs +++ b/mingling/src/confirm/count.rs @@ -1,23 +1,67 @@ /// Specifies the maximum number of attempts for a confirmation prompt. +/// +/// # Default Implementations +/// +/// `ConfirmCount` implements the following traits by default: +/// +/// - [`Debug`] — for formatted output and debugging. +/// - [`Clone`] — to create a copy of the value. +/// - [`Copy`] — since the enum holds no heap-allocated data, it can be trivially copied. +/// - [`PartialEq`] — allows comparing two `ConfirmCount` values for equality. +/// - [`Eq`] — provides full equality semantics (as opposed to just partial). +/// - [`From`] for all primitive integer types (`i8`–`i128`, `isize`, `u8`–`u128`, `usize`), +/// allowing convenient conversion from a raw number. +/// +/// # What the Numbers Mean +/// +/// The numeric value passed to a `From` conversion represents the **maximum number of times** +/// the confirmation prompt will be shown to the user. For example: +/// +/// - `ConfirmCount::from(3)` → asks at most **3** times before giving up. +/// - `ConfirmCount::from(1)` → asks exactly **1** time. +/// - `ConfirmCount::from(0)` → interpreted as [`Loop`], meaning it will keep asking +/// indefinitely until a valid answer is parsed. +/// +/// # Examples +/// +/// ``` +/// use mingling::confirm::ConfirmCount; +/// +/// // Convert from a numeric value +/// let count: ConfirmCount = 3.into(); +/// assert_eq!(count, ConfirmCount::Max(3)); +/// +/// // Zero means loop forever +/// let loop_count: ConfirmCount = 0.into(); +/// assert_eq!(loop_count, ConfirmCount::Loop); +/// +/// // Large values are capped at usize::MAX +/// let big: ConfirmCount = i128::MAX.into(); +/// assert_eq!(big, ConfirmCount::Max(usize::MAX)); +/// +/// // From a usize directly +/// let from_usize = ConfirmCount::from(5usize); +/// assert_eq!(from_usize, ConfirmCount::Max(5)); +/// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ConfirmerCount { +pub enum ConfirmCount { /// Loop indefinitely until the user gives a parseable answer. Loop, /// Ask at most the specified number of times. Max(usize), } -macro_rules! impl_from_for_confirmer_count { +macro_rules! impl_from_for_Confirm_count { ($($t:ty),*) => { $( - impl From<$t> for ConfirmerCount { + impl From<$t> for ConfirmCount { fn from(n: $t) -> Self { if n == 0 { - ConfirmerCount::Loop + ConfirmCount::Loop } else { match usize::try_from(n) { - Ok(max) => ConfirmerCount::Max(max), - Err(_) => ConfirmerCount::Max(usize::MAX), + Ok(max) => ConfirmCount::Max(max), + Err(_) => ConfirmCount::Max(usize::MAX), } } } @@ -26,6 +70,6 @@ macro_rules! impl_from_for_confirmer_count { }; } -impl_from_for_confirmer_count!( +impl_from_for_Confirm_count!( i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize ); diff --git a/mingling/src/confirm/predicate.rs b/mingling/src/confirm/predicate.rs index f812608..786a459 100644 --- a/mingling/src/confirm/predicate.rs +++ b/mingling/src/confirm/predicate.rs @@ -1,7 +1,7 @@ /// Defines how to parse user confirmation input. /// /// A type implementing this trait determines which user input strings are treated as "yes" or "no". -pub trait ConfirmerPredicate { +pub trait ConfirmPredicate { /// Parses the user's input string, returning whether it is "yes". /// /// Returns `Some(true)` for yes, `Some(false)` for no, @@ -9,37 +9,37 @@ pub trait ConfirmerPredicate { fn is_yes(str: &str) -> Option; } -/// A `ConfirmerPredicate` implementation that accepts "y"/"yes" as yes and "n"/"no" as no. +/// A `ConfirmPredicate` implementation that accepts "y"/"yes" as yes and "n"/"no" as no. /// /// Input comparison is case-insensitive and automatically trims leading/trailing whitespace. /// /// # Examples /// /// ``` -/// use mingling::res::Confirmer; +/// use mingling::res::ResConfirm; /// use mingling::confirm::YesConfirm; /// -/// let confirmer = Confirmer::default(); -/// let confirmed = confirmer.ask::("Continue? [y/n] "); +/// let confirm = ResConfirm::default(); +/// let confirmed = confirm.ask::("Continue? [y/n] "); /// ``` pub struct YesConfirm; -/// A `ConfirmerPredicate` implementation that accepts "true"/"t" as yes and "false"/"f" as no. +/// A `ConfirmPredicate` implementation that accepts "true"/"t" as yes and "false"/"f" as no. /// /// Input comparison is case-insensitive and automatically trims leading/trailing whitespace. /// /// # Examples /// /// ``` -/// use mingling::res::Confirmer; +/// use mingling::res::ResConfirm; /// use mingling::confirm::TrueConfirm; /// -/// let confirmer = Confirmer::default(); -/// let confirmed = confirmer.ask::("Enable this feature? [true/false] "); +/// let confirm = ResConfirm::default(); +/// let confirmed = confirm.ask::("Enable this feature? [true/false] "); /// ``` pub struct TrueConfirm; -impl ConfirmerPredicate for YesConfirm { +impl ConfirmPredicate for YesConfirm { fn is_yes(str: &str) -> Option { match str.trim().to_lowercase().as_str() { "y" | "yes" => Some(true), @@ -49,7 +49,7 @@ impl ConfirmerPredicate for YesConfirm { } } -impl ConfirmerPredicate for TrueConfirm { +impl ConfirmPredicate for TrueConfirm { fn is_yes(str: &str) -> Option { match str.trim().to_lowercase().as_str() { "true" | "t" => Some(true), diff --git a/mingling/src/osc94/guard.rs b/mingling/src/osc94/guard.rs index 99c1084..793abec 100644 --- a/mingling/src/osc94/guard.rs +++ b/mingling/src/osc94/guard.rs @@ -7,14 +7,14 @@ use crate::osc94::OSC94State; /// /// # Example /// -/// Create a guard via [`OSC94`], and the state is automatically restored to Clean +/// Create a guard via [`ResOSC94`], and the state is automatically restored to Clean /// when the guard is dropped: /// /// ``` -/// use mingling::res::OSC94; +/// use mingling::res::ResOSC94; /// use mingling::osc94::OSC94Guard; /// -/// let osc94 = OSC94::default(); +/// let osc94 = ResOSC94::default(); /// { /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_progress(0.5); @@ -34,10 +34,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::{OSC94Guard, OSC94State}; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_progress(0.5); /// guard.set_clean_state(); @@ -57,10 +57,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::{OSC94Guard, OSC94State}; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_error_state(); /// assert_eq!(guard.state(), OSC94State::Error); @@ -80,10 +80,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::{OSC94Guard, OSC94State}; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_warn_state(); /// assert_eq!(guard.state(), OSC94State::Warn); @@ -102,10 +102,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::{OSC94Guard, OSC94State}; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_unknown_state(); /// assert_eq!(guard.state(), OSC94State::Unknown); @@ -131,10 +131,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::OSC94Guard; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_progress(0.5); /// assert_eq!(guard.progress(), 0.5); @@ -155,10 +155,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::{OSC94Guard, OSC94State}; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let guard: OSC94Guard = osc94.get_mut(); /// assert_eq!(guard.state(), OSC94State::Clean); /// ``` @@ -179,10 +179,10 @@ impl OSC94Guard { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::OSC94Guard; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let mut guard: OSC94Guard = osc94.get_mut(); /// guard.set_progress(0.25); /// assert_eq!(guard.progress(), 0.25); diff --git a/mingling/src/res.rs b/mingling/src/res.rs index 82c4e00..0314e39 100644 --- a/mingling/src/res.rs +++ b/mingling/src/res.rs @@ -7,8 +7,8 @@ pub use dirs::*; mod exit_code; pub use exit_code::*; -mod confirmer; -pub use confirmer::*; +mod confirm; +pub use confirm::*; mod osc94; pub use osc94::*; diff --git a/mingling/src/res/confirm.rs b/mingling/src/res/confirm.rs new file mode 100644 index 0000000..baf8caf --- /dev/null +++ b/mingling/src/res/confirm.rs @@ -0,0 +1,184 @@ +use std::io::{BufRead, Write}; + +use crate::confirm::{ConfirmCount, ConfirmPredicate}; + +/// A confirm for interactive confirmation. +/// +/// This structure caches the confirmed state to avoid repeated prompts. +/// +/// Typically, `ResConfirm` is registered via `ConfirmSetup`, and then injected into functions +/// through Mingling's resource injection system. +/// +/// # Registration +/// +/// Before use, the `ConfirmSetup` must be registered with the program: +/// +/// ``` +/// # use mingling::MockProgramCollect as ThisProgram; +/// use mingling::setup::ConfirmSetup; +/// use mingling::Program; +/// +/// let mut program = Program::::new(); +/// program.with_setup(ConfirmSetup); +/// ``` +/// +/// # Examples +/// +/// ``` +/// use mingling::res::ResConfirm; +/// use mingling::confirm::YesConfirm; +/// +/// // In actual use, obtain the registered Confirm through the resource injection system +/// let confirm = ResConfirm::new_confirmed(); +/// assert!(confirm.ask::("Continue? [y/n] ")); +/// ``` +#[derive(Debug, Default, Clone, Copy)] +pub struct ResConfirm { + pub(crate) confirmed: bool, +} + +impl ResConfirm { + /// Creates a new `ResConfirm` instance. + /// + /// # Examples + /// + /// ``` + /// use mingling::res::ResConfirm; + /// + /// let confirm = ResConfirm::new(); + /// ``` + #[must_use] + pub const fn new() -> Self { + Self { confirmed: false } + } + + /// Creates a `Confirm` instance in the confirmed state. + /// + /// The returned `Confirm` will directly return `true` when calling [`ask`](Confirm::ask) or + /// [`try_ask`](Confirm::try_ask), without prompting the user. + /// + /// # Examples + /// + /// ``` + /// use mingling::res::ResConfirm; + /// use mingling::confirm::YesConfirm; + /// + /// let confirm = ResConfirm::new_confirmed(); + /// assert!(confirm.ask::("Continue? [y/n] ")); + /// ``` + #[must_use] + pub const fn new_confirmed() -> Self { + Self { confirmed: true } + } + + /// Marks the Confirm as confirmed. + /// + /// After calling this method, subsequent calls to [`ask`](Confirm::ask) or + /// [`try_ask`](Confirm::try_ask) on this Confirm will directly return `true` + /// without prompting the user. + /// + /// # Examples + /// + /// ``` + /// use mingling::res::ResConfirm; + /// use mingling::confirm::YesConfirm; + /// + /// let mut confirm = ResConfirm::new(); + /// confirm.set_confirmed(); + /// assert!(confirm.ask::("Continue? [y/n] ")); + /// ``` + pub const fn set_confirmed(&mut self) { + self.confirmed = true; + } + + /// Asks the user a confirmation question, with at most one attempt. + /// + /// Returns `false` if the user provides an unrecognizable answer. + /// Returns `true` directly if already confirmed previously. + /// + /// # Parameters + /// + /// * `ask` - The prompt text to display to the user. + /// + /// # Returns + /// + /// Returns a boolean indicating whether the user confirmed. Returns `false` if the user's input + /// could not be parsed or the maximum number of attempts was reached. + /// + /// # Examples + /// + /// ``` + /// use mingling::res::ResConfirm; + /// use mingling::confirm::YesConfirm; + /// + /// let confirm = ResConfirm::new_confirmed(); + /// let confirmed = confirm.ask::("Delete this file? [y/n] "); + /// ``` + pub fn ask(&self, ask: impl AsRef) -> bool { + self.try_ask::

(ask, ConfirmCount::Max(1)) + .unwrap_or(false) + } + + /// Asks the user a confirmation question, allowing a specified maximum number of attempts. + /// + /// # Parameters + /// + /// * `ask` - The prompt text to display to the user. + /// * `count` - The maximum number of attempts. Passing `0` means unlimited attempts (loop + /// indefinitely), passing a positive integer means at most that many attempts. + /// + /// # Returns + /// + /// Returns `Some(true)` for confirmation, `Some(false)` for rejection. + /// Returns `None` if the maximum number of attempts is reached without being able to parse + /// the user's input. + /// + /// # Panics + /// + /// This function panics when the standard error output (`stderr`) cannot be flushed or when + /// reading from standard input fails. + /// + /// # Examples + /// + /// ``` + /// use mingling::res::ResConfirm; + /// use mingling::confirm::YesConfirm; + /// + /// let confirm = ResConfirm::new_confirmed(); + /// let confirmed = confirm.try_ask::("Confirm execution? [y/n] ", 3); + /// ``` + pub fn try_ask( + &self, + ask: impl AsRef, + count: impl Into, + ) -> Option { + if self.confirmed { + return Some(true); + } + + let count = count.into(); + let mut attempts = 0usize; + + loop { + eprint!("{}", ask.as_ref()); + std::io::stderr().flush().unwrap(); + + let stdin = std::io::stdin(); + let mut input = String::new(); + stdin.lock().read_line(&mut input).unwrap(); + if let Some(result) = P::is_yes(&input) { + return Some(result); + } + + attempts += 1; + match count { + ConfirmCount::Loop => {} + ConfirmCount::Max(max) => { + if attempts >= max { + return None; + } + } + } + } + } +} diff --git a/mingling/src/res/confirmer.rs b/mingling/src/res/confirmer.rs deleted file mode 100644 index 146a2e8..0000000 --- a/mingling/src/res/confirmer.rs +++ /dev/null @@ -1,184 +0,0 @@ -use std::io::{BufRead, Write}; - -use crate::confirm::{ConfirmerCount, ConfirmerPredicate}; - -/// A confirmer for interactive confirmation. -/// -/// This structure caches the confirmed state to avoid repeated prompts. -/// -/// Typically, `Confirmer` is registered via `ConfirmerSetup`, and then injected into functions -/// through Mingling's resource injection system. -/// -/// # Registration -/// -/// Before use, the `ConfirmerSetup` must be registered with the program: -/// -/// ``` -/// # use mingling::MockProgramCollect as ThisProgram; -/// use mingling::setup::ConfirmerSetup; -/// use mingling::Program; -/// -/// let mut program = Program::::new(); -/// program.with_setup(ConfirmerSetup); -/// ``` -/// -/// # Examples -/// -/// ``` -/// use mingling::res::Confirmer; -/// use mingling::confirm::YesConfirm; -/// -/// // In actual use, obtain the registered confirmer through the resource injection system -/// let confirmer = Confirmer::new_confirmed(); -/// assert!(confirmer.ask::("Continue? [y/n] ")); -/// ``` -#[derive(Debug, Default, Clone, Copy)] -pub struct Confirmer { - pub(crate) confirmed: bool, -} - -impl Confirmer { - /// Creates a new `Confirmer` instance. - /// - /// # Examples - /// - /// ``` - /// use mingling::res::Confirmer; - /// - /// let confirmer = Confirmer::new(); - /// ``` - #[must_use] - pub const fn new() -> Self { - Self { confirmed: false } - } - - /// Creates a `Confirmer` instance in the confirmed state. - /// - /// The returned `Confirmer` will directly return `true` when calling [`ask`](Confirmer::ask) or - /// [`try_ask`](Confirmer::try_ask), without prompting the user. - /// - /// # Examples - /// - /// ``` - /// use mingling::res::Confirmer; - /// use mingling::confirm::YesConfirm; - /// - /// let confirmer = Confirmer::new_confirmed(); - /// assert!(confirmer.ask::("Continue? [y/n] ")); - /// ``` - #[must_use] - pub const fn new_confirmed() -> Self { - Self { confirmed: true } - } - - /// Marks the confirmer as confirmed. - /// - /// After calling this method, subsequent calls to [`ask`](Confirmer::ask) or - /// [`try_ask`](Confirmer::try_ask) on this confirmer will directly return `true` - /// without prompting the user. - /// - /// # Examples - /// - /// ``` - /// use mingling::res::Confirmer; - /// use mingling::confirm::YesConfirm; - /// - /// let mut confirmer = Confirmer::new(); - /// confirmer.set_confirmed(); - /// assert!(confirmer.ask::("Continue? [y/n] ")); - /// ``` - pub const fn set_confirmed(&mut self) { - self.confirmed = true; - } - - /// Asks the user a confirmation question, with at most one attempt. - /// - /// Returns `false` if the user provides an unrecognizable answer. - /// Returns `true` directly if already confirmed previously. - /// - /// # Parameters - /// - /// * `ask` - The prompt text to display to the user. - /// - /// # Returns - /// - /// Returns a boolean indicating whether the user confirmed. Returns `false` if the user's input - /// could not be parsed or the maximum number of attempts was reached. - /// - /// # Examples - /// - /// ``` - /// use mingling::res::Confirmer; - /// use mingling::confirm::YesConfirm; - /// - /// let confirmer = Confirmer::new_confirmed(); - /// let confirmed = confirmer.ask::("Delete this file? [y/n] "); - /// ``` - pub fn ask(&self, ask: impl AsRef) -> bool { - self.try_ask::

(ask, ConfirmerCount::Max(1)) - .unwrap_or(false) - } - - /// Asks the user a confirmation question, allowing a specified maximum number of attempts. - /// - /// # Parameters - /// - /// * `ask` - The prompt text to display to the user. - /// * `count` - The maximum number of attempts. Passing `0` means unlimited attempts (loop - /// indefinitely), passing a positive integer means at most that many attempts. - /// - /// # Returns - /// - /// Returns `Some(true)` for confirmation, `Some(false)` for rejection. - /// Returns `None` if the maximum number of attempts is reached without being able to parse - /// the user's input. - /// - /// # Panics - /// - /// This function panics when the standard error output (`stderr`) cannot be flushed or when - /// reading from standard input fails. - /// - /// # Examples - /// - /// ``` - /// use mingling::res::Confirmer; - /// use mingling::confirm::YesConfirm; - /// - /// let confirmer = Confirmer::new_confirmed(); - /// let confirmed = confirmer.try_ask::("Confirm execution? [y/n] ", 3); - /// ``` - pub fn try_ask( - &self, - ask: impl AsRef, - count: impl Into, - ) -> Option { - if self.confirmed { - return Some(true); - } - - let count = count.into(); - let mut attempts = 0usize; - - loop { - eprint!("{}", ask.as_ref()); - std::io::stderr().flush().unwrap(); - - let stdin = std::io::stdin(); - let mut input = String::new(); - stdin.lock().read_line(&mut input).unwrap(); - if let Some(result) = P::is_yes(&input) { - return Some(result); - } - - attempts += 1; - match count { - ConfirmerCount::Loop => {} - ConfirmerCount::Max(max) => { - if attempts >= max { - return None; - } - } - } - } - } -} diff --git a/mingling/src/res/osc94.rs b/mingling/src/res/osc94.rs index 8e03b21..ea8538d 100644 --- a/mingling/src/res/osc94.rs +++ b/mingling/src/res/osc94.rs @@ -5,7 +5,7 @@ use crate::osc94::{OSC94Guard, OSC94State}; /// Provides support for the `OSC 9;4` protocol. You can inject it into the execution flow /// through Mingling's resource injection system, and use it to control your process state. /// -/// Typically, `OSC94` is registered via `OSC94Setup`, and then injected into functions +/// Typically, `ResOSC94` is registered via `OSC94Setup`, and then injected into functions /// through Mingling's resource injection system. /// /// # Registration @@ -24,21 +24,21 @@ use crate::osc94::{OSC94Guard, OSC94State}; /// # Example /// /// ``` -/// use mingling::res::OSC94; +/// use mingling::res::ResOSC94; /// use mingling::osc94::OSC94State; /// -/// let osc94 = OSC94::default(); +/// let osc94 = ResOSC94::default(); /// let mut guard = osc94.get_mut(); /// /// guard.set_progress(0.5); /// assert_eq!(guard.state(), OSC94State::Normal(0.5)); /// ``` #[derive(Debug, Default, Clone, Copy)] -pub struct OSC94 { +pub struct ResOSC94 { pub(crate) is_support: bool, } -impl OSC94 { +impl ResOSC94 { /// Get a guard for modifying progress. /// /// The returned [`OSC94Guard`] allows you to set the process state and progress. @@ -52,10 +52,10 @@ impl OSC94 { /// # Example /// /// ``` - /// use mingling::res::OSC94; + /// use mingling::res::ResOSC94; /// use mingling::osc94::OSC94State; /// - /// let osc94 = OSC94::default(); + /// let osc94 = ResOSC94::default(); /// let guard = osc94.get_mut(); /// assert_eq!(guard.state(), OSC94State::Clean); /// ``` diff --git a/mingling/src/setups.rs b/mingling/src/setups.rs index 7a523cc..e1835e7 100644 --- a/mingling/src/setups.rs +++ b/mingling/src/setups.rs @@ -8,8 +8,8 @@ pub mod picker; mod basic; pub use basic::*; -mod confirmer; -pub use confirmer::*; +mod confirm; +pub use confirm::*; mod dirs; pub use dirs::*; diff --git a/mingling/src/setups/confirm.rs b/mingling/src/setups/confirm.rs new file mode 100644 index 0000000..6635420 --- /dev/null +++ b/mingling/src/setups/confirm.rs @@ -0,0 +1,60 @@ +use mingling_core::{ + Program, ProgramCollect, config, hook::ProgramHook, setup::ProgramSetup, this, +}; + +use crate::res::ResConfirm; + +/// Confirm setup for managing confirmation state +/// +/// This Setup manages the confirmation flag within the program's resource +/// store. It registers a [`ResConfirm`] resource and sets up a hook that +/// checks the user's confirmation mode during program execution. +/// +/// # Usage +/// +/// This Setup can be registered using the +/// [`Program`](https://docs.rs/mingling/latest/mingling/struct.Program.html) +/// `with_setup` method, for example: +/// +/// ```rust +/// # use mingling::MockProgramCollect as ThisProgram; +/// use mingling::Program; +/// use mingling::setup::ConfirmSetup; +/// +/// let mut program = Program::::new(); +/// program.with_setup(ConfirmSetup); +/// ``` +/// +/// # Behavior +/// +/// - Registers a [`ResConfirm`] resource that tracks confirmation state. +/// - At the beginning of command execution, checks whether the user's +/// confirmation mode is set to `Skip`. +/// - If confirmation is skipped, the [`Confirm`] resource is updated +/// to record the confirmed state. +/// +/// # Notes +/// +/// - This Setup applies uniformly to all subcommands of the entire program. +/// - The confirmation state is determined by the global `config` setting; +/// it does not support per-command overrides. +pub struct ConfirmSetup; + +impl ProgramSetup for ConfirmSetup +where + C: ProgramCollect + 'static, +{ + fn setup(self, program: &mut Program) { + program.with_resource(ResConfirm::new()); + + program.with_hook(ProgramHook::empty().on_pre_dispatch::<_, ()>(|_| { + let p = this::(); + let confirmed = p.user_context.confirmation == config::ConfirmationMode::Skip; + if confirmed { + p.modify_res(|c: &mut ResConfirm| { + c.set_confirmed(); + }); + } + })); + } +} diff --git a/mingling/src/setups/confirmer.rs b/mingling/src/setups/confirmer.rs deleted file mode 100644 index 1824745..0000000 --- a/mingling/src/setups/confirmer.rs +++ /dev/null @@ -1,60 +0,0 @@ -use mingling_core::{ - Program, ProgramCollect, config, hook::ProgramHook, setup::ProgramSetup, this, -}; - -use crate::res::Confirmer; - -/// Confirmer setup for managing confirmation state -/// -/// This Setup manages the confirmation flag within the program's resource -/// store. It registers a [`Confirmer`] resource and sets up a hook that -/// checks the user's confirmation mode during program execution. -/// -/// # Usage -/// -/// This Setup can be registered using the -/// [`Program`](https://docs.rs/mingling/latest/mingling/struct.Program.html) -/// `with_setup` method, for example: -/// -/// ```rust -/// # use mingling::MockProgramCollect as ThisProgram; -/// use mingling::Program; -/// use mingling::setup::ConfirmerSetup; -/// -/// let mut program = Program::::new(); -/// program.with_setup(ConfirmerSetup); -/// ``` -/// -/// # Behavior -/// -/// - Registers a [`Confirmer`] resource that tracks confirmation state. -/// - At the beginning of command execution, checks whether the user's -/// confirmation mode is set to `Skip`. -/// - If confirmation is skipped, the [`Confirmer`] resource is updated -/// to record the confirmed state. -/// -/// # Notes -/// -/// - This Setup applies uniformly to all subcommands of the entire program. -/// - The confirmation state is determined by the global `config` setting; -/// it does not support per-command overrides. -pub struct ConfirmerSetup; - -impl ProgramSetup for ConfirmerSetup -where - C: ProgramCollect + 'static, -{ - fn setup(self, program: &mut Program) { - program.with_resource(Confirmer::new()); - - program.with_hook(ProgramHook::empty().on_pre_dispatch::<_, ()>(|_| { - let p = this::(); - let confirmed = p.user_context.confirmation == config::ConfirmationMode::Skip; - if confirmed { - p.modify_res(|c: &mut Confirmer| { - c.set_confirmed(); - }); - } - })); - } -} diff --git a/mingling/src/setups/osc94.rs b/mingling/src/setups/osc94.rs index 548005a..b08312f 100644 --- a/mingling/src/setups/osc94.rs +++ b/mingling/src/setups/osc94.rs @@ -1,11 +1,11 @@ use mingling_core::{Program, ProgramCollect, setup::ProgramSetup}; -use crate::res::OSC94; +use crate::res::ResOSC94; /// `OSC 9;4` Setup for managing terminal progress notification state /// /// This Setup manages the terminal's `OSC 9;4` protocol support state within the -/// program's resource store. It registers an [`OSC94`] resource that tracks whether +/// program's resource store. It registers an [`ResOSC94`] resource that tracks whether /// the current terminal supports the protocol, and provides a helper resource that /// can be used to send progress notification messages. /// @@ -26,7 +26,7 @@ use crate::res::OSC94; /// /// # Behavior /// -/// - Registers an [`OSC94`] resource that tracks whether the current terminal +/// - Registers an [`ResOSC94`] resource that tracks whether the current terminal /// supports the `OSC 9;4` protocol. /// - The support check inspects various environment variables such as `TERM_PROGRAM`, /// `WT_SESSION`, `VTE_VERSION`, and `TERM`. @@ -42,7 +42,7 @@ where C: ProgramCollect + 'static, { fn setup(self, program: &mut Program) { - program.with_resource(OSC94 { + program.with_resource(ResOSC94 { is_support: is_support_osc94(), }); } -- cgit