pub struct Theme { pub id: String, pub label: String, } pub trait ThemeRepository: Send + Sync { fn list(&self) -> Vec; fn get_css(&self, id: &str) -> Option; } #[cfg(test)] mod tests { use super::*; struct StubRepo; impl ThemeRepository for StubRepo { fn list(&self) -> Vec { vec![Theme { id: "a".into(), label: "A".into() }] } fn get_css(&self, id: &str) -> Option { if id == "a" { Some(".x{}".into()) } else { None } } } #[test] fn theme_fields_accessible() { let t = Theme { id: "dark".into(), label: "Mode sombre".into() }; assert_eq!(t.id, "dark"); assert_eq!(t.label, "Mode sombre"); } #[test] fn repository_trait_object_works() { let repo: Box = Box::new(StubRepo); assert_eq!(repo.list().len(), 1); assert!(repo.get_css("a").is_some()); assert!(repo.get_css("unknown").is_none()); } }