Skip to main content

a2ui_base/model/
components_model.rs

1//! Flat map of ComponentModels for a single surface.
2
3use std::collections::HashMap;
4
5use super::component_model::ComponentModel;
6use crate::error::A2uiError;
7
8/// Manages all components in a surface as a flat HashMap.
9pub struct SurfaceComponentsModel {
10    components: HashMap<String, ComponentModel>,
11}
12
13impl Default for SurfaceComponentsModel {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl SurfaceComponentsModel {
20    pub fn new() -> Self {
21        Self {
22            components: HashMap::new(),
23        }
24    }
25
26    /// Get a component by ID.
27    pub fn get(&self, id: &str) -> Option<&ComponentModel> {
28        self.components.get(id)
29    }
30
31    /// Get a mutable component by ID.
32    pub fn get_mut(&mut self, id: &str) -> Option<&mut ComponentModel> {
33        self.components.get_mut(id)
34    }
35
36    /// Add or update a component.
37    /// If the component already exists with a different type, replaces it.
38    pub fn upsert(&mut self, component: ComponentModel) {
39        self.components.insert(component.id.clone(), component);
40    }
41
42    /// Remove a component by ID.
43    pub fn remove(&mut self, id: &str) {
44        self.components.remove(id);
45    }
46
47    /// Returns true if a component with the given ID exists.
48    pub fn contains(&self, id: &str) -> bool {
49        self.components.contains_key(id)
50    }
51
52    /// Get all components.
53    pub fn all(&self) -> &HashMap<String, ComponentModel> {
54        &self.components
55    }
56
57    /// Parse and add multiple components from raw JSON.
58    pub fn add_from_json(&mut self, raw_components: &[serde_json::Value]) -> Vec<Result<(), A2uiError>> {
59        raw_components
60            .iter()
61            .map(|raw| {
62                let model = ComponentModel::from_json(raw)?;
63                self.upsert(model);
64                Ok(())
65            })
66            .collect()
67    }
68
69    /// Returns the number of components.
70    #[allow(dead_code)]
71    pub fn len(&self) -> usize {
72        self.components.len()
73    }
74
75    /// Returns true if there are no components.
76    #[allow(dead_code)]
77    pub fn is_empty(&self) -> bool {
78        self.components.is_empty()
79    }
80}