greentic-flow-builder 0.1.0

AI-powered Adaptive Card flow builder with visual graph editor and demo runner
Documentation
//! Theme management: loading, merging, and HostConfig generation.

mod loader;
mod merger;

pub use loader::load_theme_from_str;
pub use merger::merge_themes;

use crate::template::Theme;
use std::collections::BTreeMap;

/// Registry of available themes.
pub struct ThemeRegistry {
    themes: BTreeMap<String, Theme>,
}

impl ThemeRegistry {
    pub fn new() -> Self {
        Self {
            themes: BTreeMap::new(),
        }
    }

    pub fn insert(&mut self, theme: Theme) {
        self.themes.insert(theme.name.clone(), theme);
    }

    pub fn get(&self, name: &str) -> Option<&Theme> {
        self.themes.get(name)
    }

    pub fn list(&self) -> Vec<&Theme> {
        self.themes.values().collect()
    }

    pub fn names(&self) -> Vec<String> {
        self.themes.keys().cloned().collect()
    }

    /// Resolve a theme name into a merged theme.
    /// Falls back to "default" if name not found.
    pub fn resolve(&self, name: Option<&str>) -> anyhow::Result<Theme> {
        let default = self
            .themes
            .get("default")
            .ok_or_else(|| anyhow::anyhow!("default theme missing from registry"))?
            .clone();

        let Some(selected_name) = name else {
            return Ok(default);
        };

        if selected_name == "default" {
            return Ok(default);
        }

        let selected = self
            .themes
            .get(selected_name)
            .ok_or_else(|| anyhow::anyhow!("theme '{}' not found", selected_name))?;

        Ok(merge_themes(&default, selected))
    }
}

impl Default for ThemeRegistry {
    fn default() -> Self {
        Self::new()
    }
}