pub struct Theme {
    pub id: String,
    pub label: String,
}

pub trait ThemeRepository: Send + Sync {
    fn list(&self) -> Vec<Theme>;
    fn get_css(&self, id: &str) -> Option<String>;
}

#[cfg(test)]
mod tests {
    use super::*;

    struct StubRepo;
    impl ThemeRepository for StubRepo {
        fn list(&self) -> Vec<Theme> {
            vec![Theme { id: "a".into(), label: "A".into() }]
        }
        fn get_css(&self, id: &str) -> Option<String> {
            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<dyn ThemeRepository> = Box::new(StubRepo);
        assert_eq!(repo.list().len(), 1);
        assert!(repo.get_css("a").is_some());
        assert!(repo.get_css("unknown").is_none());
    }
}
