use crate::{Error, Result};
use figlet_rs::{FIGlet, Toilet};
pub fn render(text: &str) -> Result<String> {
render_with_font(text, "standard")
}
pub fn render_with_font(text: &str, font: &str) -> Result<String> {
let normalized = normalize_font_name(font);
macro_rules! render_font {
($font_loader:expr) => {{
let font = $font_loader.map_err(map_figlet_error)?;
let figure = font.convert(text).ok_or_else(render_failed)?;
Ok(figure.to_string())
}};
}
match normalized.as_str() {
"standard" => render_font!(FIGlet::standard()),
"small" => render_font!(FIGlet::small()),
"big" => render_font!(FIGlet::big()),
"slant" => render_font!(FIGlet::slant()),
"smblock" => render_font!(Toilet::smblock()),
"mono12" => render_font!(Toilet::mono12()),
"future" => render_font!(Toilet::future()),
"wideterm" => render_font!(Toilet::wideterm()),
"mono9" => render_font!(Toilet::mono9()),
_ if looks_like_file(font) => {
if font.ends_with(".tlf") {
render_font!(Toilet::from_file(font))
} else {
render_font!(FIGlet::from_file(font))
}
}
other => Err(Error::Render(format!(
"unknown figlet font '{other}'. built-in fonts: standard, small, big, slant, smblock, mono12, future, wideterm, mono9"
))),
}
}
fn normalize_font_name(font: &str) -> String {
font.trim().to_ascii_lowercase()
}
fn looks_like_file(font: &str) -> bool {
font.contains('/') || font.contains('\\') || font.ends_with(".flf") || font.ends_with(".tlf")
}
fn render_failed() -> Error {
Error::Render("failed to render figlet text".to_string())
}
fn map_figlet_error(err: impl std::fmt::Display) -> Error {
Error::Render(err.to_string())
}