pub struct UserOutput { /* private fields */ }Expand description
User-facing output handler with sink-based architecture
UserOutput provides a clean interface for displaying messages to users with support for:
- Multiple output sinks (console, file, telemetry, etc.)
- Verbosity levels (quiet, normal, verbose, debug)
- Customizable themes (emoji, plain text, ASCII)
- Optional formatter overrides (JSON, colored output)
- Dual-channel routing (stdout for results, stderr for progress)
§Examples
Basic usage:
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.progress("Starting operation...");
output.success("Operation completed successfully");
output.result(r#"{"status": "completed"}"#);With custom theme:
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel, Theme};
let mut output = UserOutput::with_theme(VerbosityLevel::Normal, Theme::plain());
output.progress("Processing...");Implementations§
Source§impl UserOutput
impl UserOutput
Sourcepub fn new(verbosity: VerbosityLevel) -> Self
pub fn new(verbosity: VerbosityLevel) -> Self
Create new UserOutput with default stdout/stderr channels and emoji theme
Uses StandardSink for backward compatibility with existing console output.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let output = UserOutput::new(VerbosityLevel::Normal);Sourcepub fn with_theme(verbosity: VerbosityLevel, theme: Theme) -> Self
pub fn with_theme(verbosity: VerbosityLevel, theme: Theme) -> Self
Create UserOutput with a specific theme
Allows customization of output symbols while using default stdout/stderr channels.
Uses StandardSink internally for backward compatibility.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel, Theme};
// Use plain text theme for CI/CD
let output = UserOutput::with_theme(VerbosityLevel::Normal, Theme::plain());
// Use ASCII theme for limited terminals
let output = UserOutput::with_theme(VerbosityLevel::Normal, Theme::ascii());Sourcepub fn with_theme_and_writers(
verbosity: VerbosityLevel,
theme: Theme,
stdout_writer: Box<dyn Write + Send + Sync>,
stderr_writer: Box<dyn Write + Send + Sync>,
) -> Self
pub fn with_theme_and_writers( verbosity: VerbosityLevel, theme: Theme, stdout_writer: Box<dyn Write + Send + Sync>, stderr_writer: Box<dyn Write + Send + Sync>, ) -> Self
Create UserOutput with theme and custom writers (for testing)
This constructor allows full customization including theme and writers, primarily used for testing where output needs to be captured.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel, Theme};
use std::io::Cursor;
let stdout_buf = Vec::new();
let stderr_buf = Vec::new();
let output = UserOutput::with_theme_and_writers(
VerbosityLevel::Normal,
Theme::plain(),
Box::new(Cursor::new(stdout_buf)),
Box::new(Cursor::new(stderr_buf)),
);Sourcepub fn progress(&mut self, message: &str)
pub fn progress(&mut self, message: &str)
Display progress message to stderr (Normal level and above)
Progress messages go to stderr following cargo/docker patterns. This keeps stdout clean for result data that may be piped.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.progress("Destroying environment...");
// Output to stderr: ⏳ Destroying environment...Sourcepub fn success(&mut self, message: &str)
pub fn success(&mut self, message: &str)
Display success message to stderr (Normal level and above)
Success status goes to stderr to allow clean result piping.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.success("Environment destroyed successfully");
// Output to stderr: ✅ Environment destroyed successfullySourcepub fn warn(&mut self, message: &str)
pub fn warn(&mut self, message: &str)
Display warning message to stderr (Normal level and above)
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.warn("Infrastructure may already be destroyed");
// Output to stderr: ⚠️ Infrastructure may already be destroyedSourcepub fn error(&mut self, message: &str)
pub fn error(&mut self, message: &str)
Display error message to stderr (all levels)
Errors are always shown regardless of verbosity level.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Quiet);
output.error("Failed to destroy environment");
// Output to stderr: ❌ Failed to destroy environmentSourcepub fn step_progress(&mut self, message: &str)
pub fn step_progress(&mut self, message: &str)
Display a step progress message to stderr (Verbose level and above)
Step progress messages mark workflow step boundaries during command
execution. They are shown when the user requests verbose output (-v).
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Verbose);
output.step_progress(" [Step 1/9] Rendering OpenTofu templates...");
// Output to stderr: 📋 [Step 1/9] Rendering OpenTofu templates...Sourcepub fn detail(&mut self, message: &str)
pub fn detail(&mut self, message: &str)
Display a detail message to stderr (VeryVerbose level and above)
Detail messages provide contextual information within steps during command
execution. They are shown when the user requests very verbose output (-vv).
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::VeryVerbose);
output.detail(" → Instance IP: 10.140.190.235");
// Output to stderr: 📋 → Instance IP: 10.140.190.235Sourcepub fn debug_detail(&mut self, message: &str)
pub fn debug_detail(&mut self, message: &str)
Display a debug detail message to stderr (Debug level and above)
Debug detail messages provide technical implementation details during command
execution. They are shown when the user requests maximum verbosity (-vvv).
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Debug);
output.debug_detail(" → Command: tofu init");
// Output to stderr: 🔍 → Command: tofu initSourcepub fn result(&mut self, message: &str)
pub fn result(&mut self, message: &str)
Output final results to stdout for piping/redirection
This is where deployment results, configuration summaries, etc. go. Since this goes to stdout, it can be cleanly piped to other commands.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.result("Deployment complete");
// Output to stdout: Deployment completeSourcepub fn data(&mut self, data: &str)
pub fn data(&mut self, data: &str)
Output structured data to stdout (JSON, etc.)
For machine-readable output that should be piped or processed.
This is equivalent to result() but exists for semantic clarity.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.data(r#"{"status": "destroyed", "environment": "test"}"#);
// Output to stdout: {"status": "destroyed", "environment": "test"}Sourcepub fn blank_line(&mut self)
pub fn blank_line(&mut self)
Display a blank line to stderr (Normal level and above)
Used for spacing between sections of output to improve readability.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.success("Configuration template generated");
output.blank_line();
output.progress("Starting next steps...");Sourcepub fn steps(&mut self, title: &str, steps: &[&str])
pub fn steps(&mut self, title: &str, steps: &[&str])
Display a numbered list of steps to stderr (Normal level and above)
Useful for displaying sequential instructions or action items.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.steps("Next steps:", &[
"Edit the configuration file",
"Review the settings",
"Run the deploy command",
]);
// Output to stderr:
// Next steps:
// 1. Edit the configuration file
// 2. Review the settings
// 3. Run the deploy commandSourcepub fn info_block(&mut self, title: &str, lines: &[&str])
pub fn info_block(&mut self, title: &str, lines: &[&str])
Display a multi-line information block to stderr (Normal level and above)
Useful for displaying grouped information or detailed messages.
§Examples
use torrust_tracker_deployer_lib::presentation::cli::views::{UserOutput, VerbosityLevel};
let mut output = UserOutput::new(VerbosityLevel::Normal);
output.info_block("Configuration options:", &[
" - username: 'torrust' (default)",
" - port: 22 (default SSH port)",
" - key_path: path/to/key",
]);
// Output to stderr:
// Configuration options:
// - username: 'torrust' (default)
// - port: 22 (default SSH port)
// - key_path: path/to/keyAuto Trait Implementations§
impl !RefUnwindSafe for UserOutput
impl !UnwindSafe for UserOutput
impl Freeze for UserOutput
impl Send for UserOutput
impl Sync for UserOutput
impl Unpin for UserOutput
impl UnsafeUnpin for UserOutput
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