pub struct ProgressReporter { /* private fields */ }Expand description
Progress reporter for multi-step operations
Tracks progress through multiple steps of a long-running operation, providing clear feedback with step numbers, descriptions, and timing.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output, 2);
progress.start_step("Step 1")?;
progress.complete_step(Some("Step 1 done"))?;
progress.start_step("Step 2")?;
progress.complete_step(None)?;
progress.complete("All done!")?;Implementations§
Source§impl ProgressReporter
impl ProgressReporter
Sourcepub fn new(
output: Arc<ReentrantMutex<RefCell<UserOutput>>>,
total_steps: usize,
) -> Self
pub fn new( output: Arc<ReentrantMutex<RefCell<UserOutput>>>, total_steps: usize, ) -> Self
Create a new progress reporter
§Arguments
output- Shared user output handler for displaying messagestotal_steps- Total number of steps in the operation
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let progress = ProgressReporter::new(output, 5);Sourcepub fn start_step(
&mut self,
description: &str,
) -> Result<(), ProgressReporterError>
pub fn start_step( &mut self, description: &str, ) -> Result<(), ProgressReporterError>
Start a new step with a description
Increments the current step counter and displays a progress message
in the format [current/total] description....
§Arguments
description- Human-readable description of what this step does
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output, 3);
progress.start_step("Loading configuration")?;
// Output: ⏳ [1/3] Loading configuration...Sourcepub fn complete_step(
&mut self,
result: Option<&str>,
) -> Result<(), ProgressReporterError>
pub fn complete_step( &mut self, result: Option<&str>, ) -> Result<(), ProgressReporterError>
Complete the current step with optional result message
Displays a completion message with timing information. The message shows either the provided result or a generic “Done” message.
§Arguments
result- Optional description of what was accomplished
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output, 2);
progress.start_step("Loading data")?;
progress.complete_step(Some("Data loaded successfully"))?;
// Output: ✓ Data loaded successfully (took 150ms)
progress.start_step("Processing")?;
progress.complete_step(None)?;
// Output: ✓ Done (took 2.3s)Sourcepub fn sub_step(
&mut self,
description: &str,
) -> Result<(), ProgressReporterError>
pub fn sub_step( &mut self, description: &str, ) -> Result<(), ProgressReporterError>
Report a sub-step within the current step
Displays an indented message indicating progress within the current step. Useful for showing detailed progress without starting a new numbered step.
§Arguments
description- What is currently happening within this step
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output.clone(), 1);
progress.start_step("Provisioning infrastructure")?;
progress.sub_step("Creating virtual machine")?;
progress.sub_step("Configuring network")?;
progress.sub_step("Setting up storage")?;
progress.complete_step(Some("Infrastructure ready"))?;Sourcepub fn complete(&mut self, summary: &str) -> Result<(), ProgressReporterError>
pub fn complete(&mut self, summary: &str) -> Result<(), ProgressReporterError>
Complete all steps and show summary
Displays a final success message indicating the entire operation completed. This should be called after all steps are done.
§Arguments
summary- Final success message describing what was accomplished
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output.clone(), 1);
progress.start_step("Creating environment")?;
progress.complete_step(None)?;
progress.complete("Environment 'test-env' created successfully")?;
// Output: ✅ Environment 'test-env' created successfullySourcepub fn output(&self) -> &Arc<ReentrantMutex<RefCell<UserOutput>>> ⓘ
pub fn output(&self) -> &Arc<ReentrantMutex<RefCell<UserOutput>>> ⓘ
Get a reference to the shared UserOutput
This allows using other output methods (like error, warn)
while progress is being tracked.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output.clone(), 1);
progress.start_step("Checking conditions");
progress.output().lock().borrow_mut().warn("Some non-critical warning");
progress.complete_step(None);Sourcepub fn blank_line(&self) -> Result<(), ProgressReporterError>
pub fn blank_line(&self) -> Result<(), ProgressReporterError>
Add a blank line to the output
This is a wrapper around UserOutput::blank_line() that handles
mutex acquisition with timeout protection.
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
Returns ProgressReporterError::UserOutputMutexTimeout if the mutex cannot be acquired within the timeout.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output, 3);
progress.blank_line()?;Sourcepub fn steps(
&self,
title: &str,
steps: &[&str],
) -> Result<(), ProgressReporterError>
pub fn steps( &self, title: &str, steps: &[&str], ) -> Result<(), ProgressReporterError>
Display a list of steps with a title
This is a wrapper around UserOutput::steps() that handles
mutex acquisition with timeout protection.
§Arguments
title- The title for the steps liststeps- Array of step descriptions
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
Returns ProgressReporterError::UserOutputMutexTimeout if the mutex cannot be acquired within the timeout.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let mut progress = ProgressReporter::new(output, 3);
progress.steps("Next steps:", &[
"Edit the configuration file",
"Review the settings",
"Run the deploy command"
])?;Sourcepub fn result(&self, message: &str) -> Result<(), ProgressReporterError>
pub fn result(&self, message: &str) -> Result<(), ProgressReporterError>
Output result data to stdout
Wraps UserOutput::result() to write result data to stdout.
Result data goes to stdout (not stderr) so it can be piped or redirected.
§Arguments ///
message- The result data to output
§Errors
Returns error if the user output mutex is poisoned
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let progress = ProgressReporter::new(output, 1);
progress.result(r#"{"schema": "..."}"#)?;Sourcepub fn warn(&self, message: &str) -> Result<(), ProgressReporterError>
pub fn warn(&self, message: &str) -> Result<(), ProgressReporterError>
Display a warning message to stderr
Wraps UserOutput::warn() for use during progress-tracked workflows.
Warnings are non-blocking — they do not stop the current operation.
§Arguments
message- Warning text (may contain newlines for multi-line warnings)
§Errors
Returns ProgressReporterError::UserOutputMutexPoisoned if the mutex is poisoned.
§Examples
use std::sync::Arc;
use std::cell::RefCell;
use parking_lot::ReentrantMutex;
use torrust_tracker_deployer_lib::presentation::cli::views::progress::ProgressReporter;
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = Arc::new(ReentrantMutex::new(RefCell::new(UserOutput::new(VerbosityLevel::Normal))));
let progress = ProgressReporter::new(output, 1);
progress.warn("SSH key appears to be passphrase-protected")?;Auto Trait Implementations§
impl !RefUnwindSafe for ProgressReporter
impl !UnwindSafe for ProgressReporter
impl Freeze for ProgressReporter
impl Send for ProgressReporter
impl Sync for ProgressReporter
impl Unpin for ProgressReporter
impl UnsafeUnpin for ProgressReporter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request