#[derive(Copy, Clone)]
pub struct TermProgress {
status: Option<TermProgressStatus>,
percent: Option<u8>,
}
impl TermProgress {
pub fn none() -> Self {
Self {
status: None,
percent: None,
}
}
pub fn start() -> Self {
Self::none().status(TermProgressStatus::Normal)
}
pub fn error() -> Self {
Self::none().status(TermProgressStatus::Error)
}
pub fn remove() -> Self {
Self::none().status(TermProgressStatus::Removed)
}
pub fn percent(mut self, percent: u8) -> Self {
assert!(matches!(percent, 0..=100));
self.percent = Some(percent);
self
}
pub fn status(mut self, status: TermProgressStatus) -> Self {
self.status = Some(status);
self
}
}
impl Default for TermProgress {
fn default() -> Self {
Self::none()
}
}
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub enum TermProgressStatus {
Removed,
Normal,
Paused,
Error,
}
impl core::fmt::Display for TermProgress {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let Some(status) = self.status else {
return Ok(());
};
let (st, pr) = match (status, self.percent) {
(TermProgressStatus::Removed, _) => (0, None),
(TermProgressStatus::Normal, Some(_)) => (1, self.percent),
(TermProgressStatus::Error, _) => (2, self.percent),
(TermProgressStatus::Normal, None) => (3, None),
(TermProgressStatus::Paused, _) => (4, self.percent),
};
write!(f, "\x1b]9;4;{st};")?;
if let Some(pr) = pr {
write!(f, "{pr}")?;
}
write!(f, "\x1b\\")
}
}