use crate::components::Text;
use crate::core::{Color, Element};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum AvatarSize {
Small,
#[default]
Medium,
Large,
}
#[derive(Debug, Clone)]
pub struct Avatar {
initials: String,
color: Color,
background: Color,
size: AvatarSize,
}
impl Avatar {
pub fn new(name: impl Into<String>) -> Self {
let name = name.into();
let initials = Self::extract_initials(&name);
Self {
initials,
color: Color::White,
background: Color::Blue,
size: AvatarSize::Medium,
}
}
pub fn initials(initials: impl Into<String>) -> Self {
Self {
initials: initials.into(),
color: Color::White,
background: Color::Blue,
size: AvatarSize::Medium,
}
}
pub fn color(mut self, color: Color) -> Self {
self.color = color;
self
}
pub fn background(mut self, color: Color) -> Self {
self.background = color;
self
}
pub fn size(mut self, size: AvatarSize) -> Self {
self.size = size;
self
}
fn extract_initials(name: &str) -> String {
name.split_whitespace()
.filter_map(|word| word.chars().next())
.take(2)
.collect::<String>()
.to_uppercase()
}
pub fn into_element(self) -> Element {
let (left, right) = match self.size {
AvatarSize::Small => ("(", ")"),
AvatarSize::Medium => ("[", "]"),
AvatarSize::Large => ("【", "】"),
};
let content = format!("{}{}{}", left, self.initials, right);
Text::new(content)
.color(self.color)
.background(self.background)
.bold()
.into_element()
}
}
impl Default for Avatar {
fn default() -> Self {
Self::initials("?")
}
}
pub fn avatar(name: impl Into<String>) -> Element {
Avatar::new(name).into_element()
}
pub fn avatar_initials(initials: impl Into<String>) -> Element {
Avatar::initials(initials).into_element()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_avatar_from_name() {
let av = Avatar::new("John Doe");
assert_eq!(av.initials, "JD");
}
#[test]
fn test_avatar_single_name() {
let av = Avatar::new("Alice");
assert_eq!(av.initials, "A");
}
#[test]
fn test_avatar_initials() {
let av = Avatar::initials("XY");
assert_eq!(av.initials, "XY");
}
#[test]
fn test_avatar_into_element() {
let _ = Avatar::new("Test User").into_element();
let _ = Avatar::initials("TU").size(AvatarSize::Large).into_element();
}
#[test]
fn test_avatar_helpers() {
let _ = avatar("John");
let _ = avatar_initials("AB");
}
}