use crate::error::CliResult;
use crate::output::OutputStyle;
use std::path::Path;
pub struct BrandingManager;
impl BrandingManager {
pub fn load_ascii_logo() -> CliResult<String> {
let possible_paths = vec![
".branding/Ascii1.txt",
"projects/ricecoder/.branding/Ascii1.txt",
"/projects/ricecoder/.branding/Ascii1.txt",
];
for path in possible_paths {
if Path::new(path).exists() {
match std::fs::read_to_string(path) {
Ok(content) => return Ok(content),
Err(_) => continue,
}
}
}
Ok(Self::default_ascii_logo())
}
pub fn default_ascii_logo() -> String {
r#"
╔═══════════════════════════════════╗
║ ║
║ 🍚 RiceCoder 🍚 ║
║ ║
║ Terminal-first, Spec-driven ║
║ Coding Assistant ║
║ ║
╚═══════════════════════════════════╝
"#
.to_string()
}
pub fn display_startup_banner() -> CliResult<()> {
let style = OutputStyle::default();
let logo = Self::load_ascii_logo()?;
println!("{}", logo);
println!("{}", style.info("Type 'rice --help' for usage information"));
println!();
Ok(())
}
pub fn display_version_banner(version: &str) -> CliResult<()> {
let style = OutputStyle::default();
let logo = Self::load_ascii_logo()?;
println!("{}", logo);
println!("{}", style.header(&format!("Version: {}", version)));
println!();
Ok(())
}
pub fn detect_terminal_capabilities() -> TerminalCapabilities {
TerminalCapabilities {
supports_colors: atty::is(atty::Stream::Stdout),
supports_unicode: Self::supports_unicode(),
supports_images: Self::supports_images(),
width: Self::get_terminal_width(),
height: Self::get_terminal_height(),
}
}
pub fn supports_unicode() -> bool {
if let Ok(lang) = std::env::var("LANG") {
return lang.contains("UTF-8") || lang.contains("utf8");
}
if let Ok(lc_all) = std::env::var("LC_ALL") {
return lc_all.contains("UTF-8") || lc_all.contains("utf8");
}
true
}
pub fn supports_images() -> bool {
if let Ok(term) = std::env::var("TERM") {
return term.contains("kitty") || term.contains("iterm");
}
false
}
pub fn get_terminal_width() -> u16 {
term_size::dimensions().map(|(w, _)| w as u16).unwrap_or(80)
}
pub fn get_terminal_height() -> u16 {
term_size::dimensions().map(|(_, h)| h as u16).unwrap_or(24)
}
}
#[derive(Debug, Clone)]
pub struct TerminalCapabilities {
pub supports_colors: bool,
pub supports_unicode: bool,
pub supports_images: bool,
pub width: u16,
pub height: u16,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_ascii_logo() {
let logo = BrandingManager::default_ascii_logo();
assert!(logo.contains("RiceCoder"));
assert!(!logo.is_empty());
}
#[test]
fn test_terminal_capabilities() {
let caps = BrandingManager::detect_terminal_capabilities();
assert!(caps.width > 0);
assert!(caps.height > 0);
}
#[test]
fn test_supports_unicode() {
let supports = BrandingManager::supports_unicode();
assert!(supports || !supports);
}
}