1use console::{Emoji, style};
2use indicatif::{ProgressBar, ProgressStyle};
3use miette::{IntoDiagnostic, Result};
4use std::time::Duration;
5
6pub type TermEmoji = Emoji<'static, 'static>;
8
9pub enum AppEmoji {
15 Sparkle,
17 Clipboard,
19 Rocket,
21 Floppy,
23}
24
25impl AppEmoji {
26 pub fn as_emoji(&self) -> TermEmoji {
28 match self {
29 AppEmoji::Sparkle => Emoji("β¨ ", ":-)"),
30 AppEmoji::Clipboard => Emoji("π ", ""),
31 AppEmoji::Rocket => Emoji("π ", ""),
32 AppEmoji::Floppy => Emoji("πΎ ", ""),
33 }
34 }
35}
36
37pub fn print_header(title: &str) {
44 println!(
45 "\n{} {}",
46 AppEmoji::Sparkle.as_emoji(),
47 style(title).bold().green()
48 );
49}
50
51pub fn print_step(emoji: AppEmoji, message: &str) {
60 println!("\n{} {}", emoji.as_emoji(), style(message).bold());
61}
62
63pub fn print_success(message: &str) {
70 println!(
71 "\n{} {}",
72 AppEmoji::Clipboard.as_emoji(),
73 style(message).bold().green()
74 );
75}
76
77pub fn print_warning(message: &str) {
86 println!("{} {}", style("Warning:").yellow(), message);
87}
88
89pub fn start_spinner(message: &str) -> Result<ProgressBar> {
98 let spinner = ProgressBar::new_spinner();
99 spinner.set_style(
100 ProgressStyle::default_spinner()
101 .tick_chars("β β β Ήβ Έβ Όβ ΄β ¦β §β β ")
102 .template("{spinner:.blue} {msg}")
103 .into_diagnostic()?,
104 );
105 spinner.set_message(message.to_string());
106 spinner.enable_steady_tick(Duration::from_millis(80));
107 Ok(spinner)
108}
109
110pub fn finish_spinner_success(spinner: &ProgressBar, message: &str) {
117 spinner.finish_with_message(format!("{} {}", style("β").green(), message));
118}
119
120pub fn finish_spinner_error(spinner: &ProgressBar, message: &str) {
127 spinner.finish_with_message(format!("{} {}", style("β").red(), message));
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn test_app_emoji_variants() {
136 let sparkle = AppEmoji::Sparkle.as_emoji();
137 let clipboard = AppEmoji::Clipboard.as_emoji();
138 let rocket = AppEmoji::Rocket.as_emoji();
139 let floppy = AppEmoji::Floppy.as_emoji();
140
141 assert!(!sparkle.to_string().is_empty());
142 assert!(!clipboard.to_string().is_empty());
143 assert!(!rocket.to_string().is_empty());
144 assert!(!floppy.to_string().is_empty());
145 }
146
147 #[test]
148 fn test_start_spinner_template_valid() {
149 let spinner_result = start_spinner("Fetching token...");
150 assert!(spinner_result.is_ok(), "Spinner template should be valid");
151 }
152
153 #[test]
154 fn test_spinner_success_lifecycle() {
155 let spinner = start_spinner("Working...").unwrap();
156 assert!(!spinner.is_finished());
157
158 finish_spinner_success(&spinner, "Done!");
159 assert!(spinner.is_finished());
160 }
161
162 #[test]
163 fn test_spinner_error_lifecycle() {
164 let spinner = start_spinner("Working...").unwrap();
165 assert!(!spinner.is_finished());
166
167 finish_spinner_error(&spinner, "Failed!");
168 assert!(spinner.is_finished());
169 }
170}