cascade_cli/cli/
output.rs1use console::{style, Emoji};
2use std::fmt::Display;
3
4pub struct Output;
6
7impl Output {
8 pub fn success<T: Display>(message: T) {
10 println!("{} {}", style("✓").green(), message);
11 }
12
13 pub fn error<T: Display>(message: T) {
15 println!("{} {}", style("✗").red(), message);
16 }
17
18 pub fn warning<T: Display>(message: T) {
20 println!("{} {}", style("⚠").yellow(), message);
21 }
22
23 pub fn info<T: Display>(message: T) {
25 println!("{} {}", style("ℹ").cyan(), message);
26 }
27
28 pub fn sub_item<T: Display>(message: T) {
30 println!(" {} {}", style("→").dim(), message);
31 }
32
33 pub fn bullet<T: Display>(message: T) {
35 println!(" {} {}", style("•").dim(), message);
36 }
37
38 pub fn section<T: Display>(title: T) {
40 println!("\n{}", style(title).bold().underlined());
41 }
42
43 pub fn tip<T: Display>(message: T) {
45 println!("{} {}", style("💡").bright(), style(message).dim());
46 }
47
48 pub fn progress<T: Display>(message: T) {
50 println!("{} {}", style("→").cyan(), message);
51 }
52
53 pub fn divider() {
55 println!("{}", style("─".repeat(50)).dim());
56 }
57
58 pub fn stack_info(
60 name: &str,
61 id: &str,
62 base_branch: &str,
63 working_branch: Option<&str>,
64 is_active: bool,
65 ) {
66 Self::success(format!("Created stack '{name}'"));
67 Self::sub_item(format!("Stack ID: {}", style(id).dim()));
68 Self::sub_item(format!("Base branch: {}", style(base_branch).cyan()));
69
70 if let Some(working) = working_branch {
71 Self::sub_item(format!("Working branch: {}", style(working).cyan()));
72 }
73
74 if is_active {
75 Self::sub_item(format!("Status: {}", style("Active").green()));
76 }
77 }
78
79 pub fn next_steps(steps: &[&str]) {
81 println!();
82 Self::tip("Next steps:");
83 for step in steps {
84 Self::bullet(step);
85 }
86 }
87
88 pub fn command_example<T: Display>(command: T) {
90 println!(" {}", style(command).yellow());
91 }
92
93 pub fn check_start<T: Display>(message: T) {
95 println!("\n{} {}", style("🔍").bright(), style(message).bold());
96 }
97
98 pub fn solution<T: Display>(message: T) {
100 println!(" {}: {}", style("Solution").yellow(), message);
101 }
102
103 pub fn numbered_item<T: Display>(number: usize, message: T) {
105 println!(" {}. {}", style(number).cyan(), message);
106 }
107
108 pub fn spacing() {
110 println!();
111 }
112}
113
114pub struct Emojis;
116
117impl Emojis {
118 pub const SUCCESS: Emoji<'_, '_> = Emoji("✓", "OK");
119 pub const ERROR: Emoji<'_, '_> = Emoji("✗", "ERROR");
120 pub const WARNING: Emoji<'_, '_> = Emoji("⚠", "WARNING");
121 pub const INFO: Emoji<'_, '_> = Emoji("ℹ", "INFO");
122 pub const TIP: Emoji<'_, '_> = Emoji("💡", "TIP");
123 pub const ROCKET: Emoji<'_, '_> = Emoji("🚀", "ROCKET");
124 pub const SEARCH: Emoji<'_, '_> = Emoji("🔍", "SEARCH");
125 pub const UPLOAD: Emoji<'_, '_> = Emoji("📤", "UPLOAD");
126 pub const STACK: Emoji<'_, '_> = Emoji("📊", "STACK");
127}