aboutsummaryrefslogtreecommitdiff
path: root/mingling/src/res
diff options
context:
space:
mode:
Diffstat (limited to 'mingling/src/res')
-rw-r--r--mingling/src/res/confirm.rs184
-rw-r--r--mingling/src/res/confirmer.rs268
-rw-r--r--mingling/src/res/osc94.rs215
-rw-r--r--mingling/src/res/osc94/state.rs74
4 files changed, 195 insertions, 546 deletions
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::<ThisProgram>::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::<YesConfirm>("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::<YesConfirm>("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::<YesConfirm>("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::<YesConfirm>("Delete this file? [y/n] ");
+ /// ```
+ pub fn ask<P: ConfirmPredicate>(&self, ask: impl AsRef<str>) -> bool {
+ self.try_ask::<P>(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::<YesConfirm>("Confirm execution? [y/n] ", 3);
+ /// ```
+ pub fn try_ask<P: ConfirmPredicate>(
+ &self,
+ ask: impl AsRef<str>,
+ count: impl Into<ConfirmCount>,
+ ) -> Option<bool> {
+ 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 900562b..0000000
--- a/mingling/src/res/confirmer.rs
+++ /dev/null
@@ -1,268 +0,0 @@
-use std::io::{BufRead, Write};
-
-/// 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::<ThisProgram>::new();
-/// program.with_setup(ConfirmerSetup);
-/// ```
-///
-/// # Examples
-///
-/// ```
-/// use mingling::res::{Confirmer, YesConfirm};
-///
-/// // In actual use, obtain the registered confirmer through the resource injection system
-/// let confirmer = Confirmer::new_confirmed();
-/// assert!(confirmer.ask::<YesConfirm>("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, YesConfirm};
- ///
- /// let confirmer = Confirmer::new_confirmed();
- /// assert!(confirmer.ask::<YesConfirm>("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, YesConfirm};
- ///
- /// let mut confirmer = Confirmer::new();
- /// confirmer.set_confirmed();
- /// assert!(confirmer.ask::<YesConfirm>("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, YesConfirm};
- ///
- /// let confirmer = Confirmer::new_confirmed();
- /// let confirmed = confirmer.ask::<YesConfirm>("Delete this file? [y/n] ");
- /// ```
- pub fn ask<P: ConfirmerPredicate>(&self, ask: impl AsRef<str>) -> bool {
- self.try_ask::<P>(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, YesConfirm};
- ///
- /// let confirmer = Confirmer::new_confirmed();
- /// let confirmed = confirmer.try_ask::<YesConfirm>("Confirm execution? [y/n] ", 3);
- /// ```
- pub fn try_ask<P: ConfirmerPredicate>(
- &self,
- ask: impl AsRef<str>,
- count: impl Into<ConfirmerCount>,
- ) -> Option<bool> {
- 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;
- }
- }
- }
- }
- }
-}
-
-/// Specifies the maximum number of attempts for a confirmation prompt.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum ConfirmerCount {
- /// 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 {
- ($($t:ty),*) => {
- $(
- impl From<$t> for ConfirmerCount {
- fn from(n: $t) -> Self {
- if n == 0 {
- ConfirmerCount::Loop
- } else {
- match usize::try_from(n) {
- Ok(max) => ConfirmerCount::Max(max),
- Err(_) => ConfirmerCount::Max(usize::MAX),
- }
- }
- }
- }
- )*
- };
-}
-
-impl_from_for_confirmer_count!(
- i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
-);
-
-/// 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 {
- /// Parses the user's input string, returning whether it is "yes".
- ///
- /// Returns `Some(true)` for yes, `Some(false)` for no,
- /// and `None` if the input cannot be parsed (requiring re-entry).
- fn is_yes(str: &str) -> Option<bool>;
-}
-
-/// A `ConfirmerPredicate` 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, YesConfirm};
-///
-/// let confirmer = Confirmer::default();
-/// let confirmed = confirmer.ask::<YesConfirm>("Continue? [y/n] ");
-/// ```
-pub struct YesConfirm;
-
-/// A `ConfirmerPredicate` 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, TrueConfirm};
-///
-/// let confirmer = Confirmer::default();
-/// let confirmed = confirmer.ask::<TrueConfirm>("Enable this feature? [true/false] ");
-/// ```
-pub struct TrueConfirm;
-
-impl ConfirmerPredicate for YesConfirm {
- fn is_yes(str: &str) -> Option<bool> {
- match str.trim().to_lowercase().as_str() {
- "y" | "yes" => Some(true),
- "n" | "no" => Some(false),
- _ => None,
- }
- }
-}
-
-impl ConfirmerPredicate for TrueConfirm {
- fn is_yes(str: &str) -> Option<bool> {
- match str.trim().to_lowercase().as_str() {
- "true" | "t" => Some(true),
- "false" | "f" => Some(false),
- _ => None,
- }
- }
-}
diff --git a/mingling/src/res/osc94.rs b/mingling/src/res/osc94.rs
index 0c5a5a9..ea8538d 100644
--- a/mingling/src/res/osc94.rs
+++ b/mingling/src/res/osc94.rs
@@ -1,17 +1,16 @@
-mod state;
-pub use state::*;
+use crate::osc94::{OSC94Guard, OSC94State};
/// Process `OSC 9;4` status.
///
/// 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
///
-/// Before use, the [`OSC94Setup`] must be registered with the program:
+/// Before use, the `OSC94Setup` must be registered with the program:
///
/// ```
/// # use mingling::MockProgramCollect as ThisProgram;
@@ -25,20 +24,21 @@ pub use state::*;
/// # Example
///
/// ```
-/// use mingling::res::{OSC94, OSC94State};
+/// 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,9 +52,10 @@ impl OSC94 {
/// # Example
///
/// ```
- /// use mingling::res::{OSC94, OSC94State};
+ /// 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);
/// ```
@@ -66,197 +67,3 @@ impl OSC94 {
}
}
}
-
-/// A guard for modifying process state.
-///
-/// Obtained via [`OSC94::get_mut`]. When the guard is dropped, the process state is
-/// automatically restored to [`OS94State::Clean`], so no manual cleanup is needed.
-///
-/// # Example
-///
-/// Create a guard via [`OSC94`], and the state is automatically restored to Clean
-/// when the guard is dropped:
-///
-/// ```
-/// use mingling::res::OSC94;
-///
-/// let osc94 = OSC94::default();
-/// {
-/// let mut guard = osc94.get_mut();
-/// guard.set_progress(0.5);
-/// // When leaving this scope, the guard is dropped and the process state is automatically restored to Clean
-/// }
-/// ```
-pub struct OSC94Guard {
- pub(crate) is_support: bool,
- msg: OSC94State,
-}
-
-impl OSC94Guard {
- /// Set the process state to Clean.
- ///
- /// Indicates that the process has finished or is in a normal, problem-free state.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::{OSC94, OSC94State};
- ///
- /// let osc94 = OSC94::default();
- /// let mut guard = osc94.get_mut();
- /// guard.set_progress(0.5);
- /// guard.set_clean_state();
- /// assert_eq!(guard.state(), OSC94State::Clean);
- /// ```
- pub fn set_clean_state(&mut self) {
- self.msg = OSC94State::Clean;
- if self.is_support {
- self.msg.send();
- }
- }
-
- /// Set the process state to Error.
- ///
- /// Indicates that an error occurred during process execution.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::{OSC94, OSC94State};
- ///
- /// let osc94 = OSC94::default();
- /// let mut guard = osc94.get_mut();
- /// guard.set_error_state();
- /// assert_eq!(guard.state(), OSC94State::Error);
- /// ```
- pub fn set_error_state(&mut self) {
- self.msg = OSC94State::Error;
- if self.is_support {
- self.msg.send();
- }
- }
-
- /// Set the process state to Warn.
- ///
- /// Indicates that a warning occurred during process execution, but it has not
- /// reached the level of an error.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::{OSC94, OSC94State};
- ///
- /// let osc94 = OSC94::default();
- /// let mut guard = osc94.get_mut();
- /// guard.set_warn_state();
- /// assert_eq!(guard.state(), OSC94State::Warn);
- /// ```
- pub fn set_warn_state(&mut self) {
- self.msg = OSC94State::Warn;
- if self.is_support {
- self.msg.send();
- }
- }
-
- /// Set the process state to Unknown.
- ///
- /// Indicates that the process state cannot be determined or has not been defined.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::{OSC94, OSC94State};
- ///
- /// let osc94 = OSC94::default();
- /// let mut guard = osc94.get_mut();
- /// guard.set_unknown_state();
- /// assert_eq!(guard.state(), OSC94State::Unknown);
- /// ```
- pub fn set_unknown_state(&mut self) {
- self.msg = OSC94State::Unknown;
- if self.is_support {
- self.msg.send();
- }
- }
-
- /// Set the progress of the process.
- ///
- /// The `progress` parameter should be between `0.0` and `1.0`. `0.0` indicates
- /// the start of the task, and `1.0` indicates the completion of the task.
- /// Values outside this range are not clamped, but it is recommended to keep them
- /// within this range.
- ///
- /// # Parameters
- ///
- /// * `progress` - The progress value, ranging from `0.0` to `1.0`.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::OSC94;
- ///
- /// let osc94 = OSC94::default();
- /// let mut guard = osc94.get_mut();
- /// guard.set_progress(0.5);
- /// assert_eq!(guard.progress(), 0.5);
- /// ```
- pub fn set_progress(&mut self, progress: f32) {
- self.msg = OSC94State::Normal(progress);
- if self.is_support {
- self.msg.send();
- }
- }
-
- /// Get the current process state.
- ///
- /// # Returns
- ///
- /// Returns the current [`OSC94State`] value, representing the state of the process.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::{OSC94, OSC94State};
- ///
- /// let osc94 = OSC94::default();
- /// let guard = osc94.get_mut();
- /// assert_eq!(guard.state(), OSC94State::Clean);
- /// ```
- #[must_use]
- pub const fn state(&self) -> OSC94State {
- self.msg
- }
-
- /// Get the current progress value.
- ///
- /// Returns the actual progress value only when the state is [`OSC94State::Normal`];
- /// otherwise returns `0.0`.
- ///
- /// # Returns
- ///
- /// Returns an `f32` progress value, ranging from `0.0` to `1.0`.
- ///
- /// # Example
- ///
- /// ```
- /// use mingling::res::OSC94;
- ///
- /// let osc94 = OSC94::default();
- /// let mut guard = osc94.get_mut();
- /// guard.set_progress(0.25);
- /// assert_eq!(guard.progress(), 0.25);
- /// ```
- #[must_use]
- pub const fn progress(&self) -> f32 {
- match self.msg {
- OSC94State::Normal(progress) => progress,
- _ => 0.0,
- }
- }
-}
-
-impl Drop for OSC94Guard {
- fn drop(&mut self) {
- OSC94State::Clean.send();
- }
-}
diff --git a/mingling/src/res/osc94/state.rs b/mingling/src/res/osc94/state.rs
deleted file mode 100644
index c3d2bdf..0000000
--- a/mingling/src/res/osc94/state.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-/// `OSC 9;4` 协议消息
-///
-/// 用于通过 ANSI 转义序列向终端发送任务进度通知消息
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum OSC94State {
- /// 清除/隐藏进度(任务完成时使用),对应状态码 `0`
- Clean,
- /// 正常状态,对应状态码 `1`,需要配合进度值(0-100)
- Normal(f32),
- /// 错误状态,对应状态码 `2`(通常显示为红色)
- Error,
- /// 不确定状态,对应状态码 `3`(显示为无限循环的动画,用于进度未知的任务)
- Unknown,
- /// 警告状态,对应状态码 `4`(通常显示为黄色)
- Warn,
-}
-
-impl OSC94State {
- /// Returns the state code for the `OSC 9;4` protocol.
- #[must_use]
- pub const fn state_code(&self) -> u8 {
- match self {
- Self::Clean => 0,
- Self::Normal(_) => 1,
- Self::Error => 2,
- Self::Unknown => 3,
- Self::Warn => 4,
- }
- }
-
- /// Returns the progress value (0-100) for the `Normal` state, clamped to the valid range.
- #[must_use]
- pub const fn progress(&self) -> f32 {
- match self {
- Self::Normal(progress) => (progress.clamp(0.0, 1.0) * 100.0).round(),
- _ => 0.0,
- }
- }
-
- /// Converts the message into the corresponding `OSC 9;4` escape sequence string.
- #[must_use]
- pub fn to_escape_sequence(&self) -> String {
- format!("\x1b]9;4;{};{}\x07", self.state_code(), self.progress())
- }
-
- /// Sends the OSC 9;4 message to the terminal via stdout.
- ///
- /// # Panics
- ///
- /// Panics if the stdout stream cannot be flushed.
- pub fn send(&self) {
- use std::io::Write;
- print!("{}", self.to_escape_sequence());
- std::io::stdout().flush().unwrap();
- }
-}
-
-impl std::fmt::Display for OSC94State {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.to_escape_sequence())
- }
-}
-
-impl From<OSC94State> for String {
- fn from(msg: OSC94State) -> Self {
- msg.to_escape_sequence()
- }
-}
-
-impl From<&OSC94State> for String {
- fn from(msg: &OSC94State) -> Self {
- msg.to_escape_sequence()
- }
-}