1use 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
12pub fn register_resource(resource: Box<dyn Resource>) {
14 RESOURCE_REGISTRY.write().unwrap_or_else(|e| e.into_inner()).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
26pub fn get_registered_menus() -> Vec<MenuItem> {
28 let resources = RESOURCE_REGISTRY.read().unwrap_or_else(|e| e.into_inner());
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_or_else(|e| e.into_inner()).clear();
66}
67
68pub fn resource_count() -> usize {
69 RESOURCE_REGISTRY.read().unwrap_or_else(|e| e.into_inner()).len()
70}