Skip to main content

adminx_core/
registry.rs

1// adminx-core/src/registry.rs
2use crate::menu::MenuItem;
3use crate::resource::Resource;
4use lazy_static::lazy_static;
5use std::collections::HashMap;
6use std::sync::RwLock;
7
8lazy_static! {
9    static ref RESOURCE_REGISTRY: RwLock<Vec<Box<dyn Resource>>> = RwLock::new(vec![]);
10}
11
12/// Register a resource globally.
13pub fn register_resource(resource: Box<dyn Resource>) {
14    RESOURCE_REGISTRY.write().unwrap().push(resource);
15}
16
17pub fn all_resources() -> Vec<Box<dyn Resource>> {
18    RESOURCE_REGISTRY
19        .read()
20        .unwrap()
21        .iter()
22        .map(|r| r.clone_box())
23        .collect()
24}
25
26/// Collect and group menus from every registered resource.
27pub fn get_registered_menus() -> Vec<MenuItem> {
28    let resources = RESOURCE_REGISTRY.read().unwrap();
29    let mut grouped: HashMap<String, Vec<MenuItem>> = HashMap::new();
30    let mut ungrouped: Vec<MenuItem> = Vec::new();
31
32    for resource in resources.iter() {
33        if let Some(item) = resource.generate_menu() {
34            match resource.menu_group() {
35                Some(group) => grouped.entry(group.to_string()).or_default().push(item),
36                None => ungrouped.push(item),
37            }
38        }
39    }
40
41    let mut final_menus = Vec::new();
42    for (group_name, mut children) in grouped {
43        children.sort_by(|a, b| a.title.cmp(&b.title));
44        final_menus.push(MenuItem {
45            title: group_name,
46            path: String::new(),
47            icon: Some("folder".to_string()),
48            order: Some(5),
49            children: Some(children),
50        });
51    }
52    final_menus.extend(ungrouped);
53
54    final_menus.sort_by(|a, b| match (a.order, b.order) {
55        (Some(x), Some(y)) => x.cmp(&y),
56        (Some(_), None) => std::cmp::Ordering::Less,
57        (None, Some(_)) => std::cmp::Ordering::Greater,
58        (None, None) => a.title.cmp(&b.title),
59    });
60
61    final_menus
62}
63
64pub fn clear_registry() {
65    RESOURCE_REGISTRY.write().unwrap().clear();
66}
67
68pub fn resource_count() -> usize {
69    RESOURCE_REGISTRY.read().unwrap().len()
70}