File size: 4,419 Bytes
f14b4e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | use clap::ValueEnum;
use console::Style;
use firm_core::{Entity, EntitySchema};
use indicatif::{ProgressBar, ProgressStyle};
use std::{fmt, time::Duration};
use super::logging;
/// Helpers to create consistent console UI styles.
pub struct UiStyle;
impl UiStyle {
/// A regular message.
pub fn normal() -> Style {
Style::new()
}
/// A highlighted message.
pub fn highlight() -> Style {
Style::new().bold()
}
/// A dim message.
pub fn dim() -> Style {
Style::new().dim()
}
/// A warning message.
pub fn warning() -> Style {
Style::new().yellow().bold()
}
/// A success message.
pub fn success() -> Style {
Style::new().green().bold()
}
/// An error message
pub fn error() -> Style {
Style::new().red().bold()
}
}
/// Prints a header message.
pub fn header(msg: &str) {
eprintln!("{}", UiStyle::highlight().apply_to(msg));
}
/// Prints a debug message.
pub fn debug(msg: &str) {
eprintln!("{}", UiStyle::dim().apply_to(msg));
}
/// Prints an info message.
pub fn info(msg: &str) {
eprintln!("{}", UiStyle::normal().apply_to(msg));
}
/// Prints a warning message.
pub fn warning(msg: &str) {
eprintln!("{}", UiStyle::warning().apply_to(msg));
}
/// Prints a success message.
pub fn success(msg: &str) {
eprintln!("{}", UiStyle::success().apply_to(msg));
}
/// Prints an error message.
pub fn error(msg: &str) {
eprintln!("{}", UiStyle::error().apply_to(msg));
}
/// Prints an error message with added details.
pub fn error_with_details(main_msg: &str, details: &str) {
eprintln!("{}", UiStyle::error().apply_to(main_msg));
eprintln!(" {}", UiStyle::dim().apply_to(details));
}
/// Selects the output format used by the CLI.
#[derive(Clone, Debug, ValueEnum, PartialEq, Default)]
pub enum OutputFormat {
#[default]
Pretty,
Json,
}
impl fmt::Display for OutputFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
OutputFormat::Pretty => write!(f, "pretty"),
OutputFormat::Json => write!(f, "json"),
}
}
}
/// Outputs a single entity in pretty format.
pub fn pretty_output_entity_single(entity: &Entity) {
println!("\n{}", entity);
}
/// Outputs a list of entities in pretty format.
pub fn pretty_output_entity_list(entities: &Vec<&Entity>) {
for (i, entity) in entities.iter().enumerate() {
pretty_output_entity_single(entity);
// Add a separator after each entity, except for the last one.
if i < entities.len() - 1 {
println!("---------------------------------------");
}
}
}
/// Outputs a single entity schema in pretty format.
pub fn pretty_output_schema_single(schema: &EntitySchema) {
println!("\n{}", schema);
}
/// Outputs a serde-serializable object in json format.
pub fn json_output<T: serde::Serialize>(data: &T) {
if let Ok(json) = serde_json::to_string_pretty(data) {
println!("{}", json);
}
}
/// Outputs a list of strings (one per line for pretty, array for JSON).
pub fn list_output(items: &[&str], format: OutputFormat) {
match format {
OutputFormat::Pretty => {
for item in items {
println!("{}", item);
}
}
OutputFormat::Json => json_output(&items),
}
}
/// Outputs raw text (e.g., file paths, simple values).
pub fn raw_output(text: &str) {
println!("{}", text);
}
/// Creates a spinner progress indicator.
pub fn spinner(msg: &str) -> ProgressBar {
let pb = ProgressBar::new_spinner();
pb.set_style(
ProgressStyle::default_spinner()
.template("{spinner} {msg}")
.expect("Invalid template"),
);
pb.enable_steady_tick(Duration::from_millis(100));
pb.set_message(msg.to_string());
let tracker = logging::get_multi_progress();
tracker.add(pb.clone());
pb
}
/// Creates a progress bar indicator.
pub fn progress_bar(len: u64) -> ProgressBar {
let pb = ProgressBar::new(len);
pb.set_style(
ProgressStyle::default_bar()
.template("{spinner} {msg} [{bar}] {pos}/{len}")
.expect("Invalid template")
.progress_chars("# "),
);
pb.enable_steady_tick(Duration::from_millis(100));
let tracker = logging::get_multi_progress();
tracker.add(pb.clone());
pb
}
|