shrupl/src/output.rs

72 lines
1.8 KiB
Rust

use std::{fmt, process, sync::LazyLock};
use console::{StyledObject, style};
use dialoguer::{Select, theme::ColorfulTheme};
use log::{error, info};
use crate::sharry;
type StaticStyled<'t> = LazyLock<StyledObject<&'t str>>;
pub static SHRUPL: StaticStyled = LazyLock::new(|| style("ShrUpl").yellow().bold());
pub fn prompt_continue() -> bool {
let prompt = format!(
"This operation has previously been stopped. {}",
style("How to proceed?").cyan()
);
let choices = [
format!("Load and {}", style("continue operation").green().bold()),
format!("Start a {}", style("new operation").cyan().bold()),
format!("Quit {}", *SHRUPL),
];
let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt(prompt)
.default(0)
.items(&choices)
.interact()
.unwrap_or(2);
if selection == 2 {
process::exit(0);
}
selection == 0
}
pub fn style_all<'t, F>(strs: &[&'t str], f: F) -> Vec<String>
where
F: Fn(&'t str) -> StyledObject<&'t str>,
{
strs.iter().map(|&s| f(s).to_string()).collect()
}
pub enum Log {}
impl Log {
fn eprintln(kind: impl fmt::Display, msg: impl fmt::Display) {
eprintln!("{} {}: {}", *SHRUPL, kind, style(msg).cyan().italic(),);
}
pub fn warning(msg: impl fmt::Display) {
Self::eprintln(style("Warning").magenta().bold(), msg);
}
pub fn error(msg: impl fmt::Display) -> ! {
Self::eprintln(style("Error").red().bold(), msg);
process::exit(1);
}
pub fn handle(e: &sharry::ClientError) {
if e.is_fatal() {
// react to fatal error
error!("fatal error: {e:?}");
Self::error(e);
}
// handle recoverable error
info!("recoverable error: {e:?}");
}
}