use rand::prelude::IndexedRandom;
use serde_json::{json, Value};
use std::fs;
use std::path::Path;
pub fn load_avatars() -> Value {
let path = Path::new(".fur/avatars.json");
if path.exists() {
let content = fs::read_to_string(path).unwrap_or_default();
serde_json::from_str(&content).unwrap_or_else(|_| json!({}))
} else {
json!({})
}
}
pub fn save_avatars(avatars: &Value) {
let path = Path::new(".fur/avatars.json");
if let Ok(serialized) = serde_json::to_string_pretty(avatars) {
let _ = fs::write(path, serialized);
}
}
pub fn resolve_avatar(avatars: &Value, key: &str) -> (String, String) {
if let Some(emoji) = avatars.get(key).and_then(|v| v.as_str()) {
return (key.to_string(), emoji.to_string());
}
if let Some((name, _)) = avatars
.as_object()
.and_then(|map| map.iter().find(|(_, v)| v.as_str() == Some(key)))
{
return (name.clone(), key.to_string());
}
(key.to_string(), "🐾".to_string()) }
fn is_bot_name(name: &str) -> bool {
let n = name.to_lowercase();
const MARKERS: [&str; 8] = [
"gpt", "claude", "gemini", "bard", "grok", "bot", "ai", "llm",
];
if MARKERS.iter().any(|m| n.contains(m)) {
return true;
}
if n.split(|c: char| !c.is_alphanumeric())
.any(|tok| tok == "agent")
{
return true;
}
false
}
pub fn get_random_emoji_for_name(name: &str) -> String {
if is_bot_name(name) {
return "🤖".to_string();
}
let pool = ["👤"];
pool.choose(&mut rand::rng()).unwrap_or(&"👔").to_string()
}