/// The severity of a message #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] pub enum MessageLevel { /// Rarely sent information related to the progress, not to be confused with the progress itself Info, /// Used to indicate that a task has failed, along with the reason Failure, /// Indicates a task was completed successfully Success, } pub trait Progress { type SubProgress: Progress; /// Adds a new child, whose parent is this instance, with the given name. /// /// This will make the child progress to appear contained in the parent progress. fn add_child(&mut self, name: impl Into) -> Self::SubProgress; /// Initialize the Item for receiving progress information. /// /// If `max` is `Some(…)`, it will be treated as upper bound. When progress is [set(…)](./struct.Item.html#method.set) /// it should not exceed the given maximum. /// If `max` is `None`, the progress is unbounded. Use this if the amount of work cannot accurately /// be determined in advance. /// /// If `unit` is `Some(…)`, it is used for display purposes only. It should be using the plural. /// /// If this method is never called, this `Progress` instance will serve as organizational unit, useful to add more structure /// to the progress tree (e.g. a headline). /// /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will. fn init(&mut self, max: Option, unit: Option<&'static str>); /// Set the current progress to the given `step`. The cost of this call is negligible, /// making manual throttling *not* necessary. /// /// **Note**: that this call has no effect unless `init(…)` was called before. fn set(&mut self, step: u32); /// Create a `message` of the given `level` and store it with the progress tree. /// /// Use this to provide additional,human-readable information about the progress /// made, including indicating success or failure. fn message(&mut self, level: MessageLevel, message: impl Into); /// Create a message providing additional information about the progress thus far. fn info(&mut self, message: impl Into) { self.message(MessageLevel::Info, message) } /// Create a message indicating the task is done successfully fn done(&mut self, message: impl Into) { self.message(MessageLevel::Success, message) } /// Create a message indicating the task failed fn fail(&mut self, message: impl Into) { self.message(MessageLevel::Failure, message) } } pub struct Discard; impl Progress for Discard { type SubProgress = Discard; fn add_child(&mut self, _name: impl Into) -> Self::SubProgress { Discard } fn init(&mut self, _max: Option, _unit: Option<&'static str>) {} fn set(&mut self, _step: u32) {} fn message(&mut self, _level: MessageLevel, _message: impl Into) {} } pub enum Either { Left(L), Right(R), } impl Progress for Either where L: Progress, R: Progress, { type SubProgress = Either; fn add_child(&mut self, name: impl Into) -> Self::SubProgress { match self { Either::Left(l) => Either::Left(l.add_child(name)), Either::Right(r) => Either::Right(r.add_child(name)), } } fn init(&mut self, max: Option, unit: Option<&'static str>) { match self { Either::Left(l) => l.init(max, unit), Either::Right(r) => r.init(max, unit), } } fn set(&mut self, step: u32) { match self { Either::Left(l) => l.set(step), Either::Right(r) => r.set(step), } } fn message(&mut self, level: MessageLevel, message: impl Into) { match self { Either::Left(l) => l.message(level, message), Either::Right(r) => r.message(level, message), } } } pub struct DoOrDiscard(Either); impl From> for DoOrDiscard where T: Progress, { fn from(p: Option) -> Self { match p { Some(p) => DoOrDiscard(Either::Left(p)), None => DoOrDiscard(Either::Right(Discard)), } } } impl Progress for DoOrDiscard where T: Progress, { type SubProgress = DoOrDiscard; fn add_child(&mut self, name: impl Into) -> Self::SubProgress { DoOrDiscard(self.0.add_child(name)) } fn init(&mut self, max: Option, unit: Option<&'static str>) { self.0.init(max, unit) } fn set(&mut self, step: u32) { self.0.set(step) } fn message(&mut self, level: MessageLevel, message: impl Into) { self.0.message(level, message) } } #[cfg(feature = "progress-log")] mod log; #[cfg(feature = "progress-log")] pub use self::log::Log; #[cfg(feature = "progress-prodash")] mod prodash;