agentic_forge_core/index/
mod.rs1use crate::types::ids::*;
4use std::collections::{HashMap, HashSet};
5
6#[derive(Debug, Default)]
7pub struct ForgeIndexes {
8 pub blueprint_index: HashSet<BlueprintId>,
9 pub entity_index: HashMap<EntityId, BlueprintId>,
10 pub file_index: HashMap<FileId, BlueprintId>,
11 pub dependency_index: HashMap<DependencyId, BlueprintId>,
12 pub name_index: HashMap<String, BlueprintId>,
13}
14
15impl ForgeIndexes {
16 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub fn add_blueprint(&mut self, id: BlueprintId) {
21 self.blueprint_index.insert(id);
22 }
23
24 pub fn remove_blueprint(&mut self, id: &BlueprintId) {
25 self.blueprint_index.remove(id);
26 self.entity_index.retain(|_, bp_id| bp_id != id);
27 self.file_index.retain(|_, bp_id| bp_id != id);
28 self.dependency_index.retain(|_, bp_id| bp_id != id);
29 self.name_index.retain(|_, bp_id| bp_id != id);
30 }
31
32 pub fn add_entity(&mut self, entity_id: EntityId, bp_id: BlueprintId) {
33 self.entity_index.insert(entity_id, bp_id);
34 }
35
36 pub fn add_file(&mut self, file_id: FileId, bp_id: BlueprintId) {
37 self.file_index.insert(file_id, bp_id);
38 }
39
40 pub fn add_dependency(&mut self, dep_id: DependencyId, bp_id: BlueprintId) {
41 self.dependency_index.insert(dep_id, bp_id);
42 }
43
44 pub fn add_name(&mut self, name: String, bp_id: BlueprintId) {
45 self.name_index.insert(name, bp_id);
46 }
47
48 pub fn lookup_entity_blueprint(&self, entity_id: &EntityId) -> Option<&BlueprintId> {
49 self.entity_index.get(entity_id)
50 }
51
52 pub fn lookup_file_blueprint(&self, file_id: &FileId) -> Option<&BlueprintId> {
53 self.file_index.get(file_id)
54 }
55
56 pub fn lookup_by_name(&self, name: &str) -> Option<&BlueprintId> {
57 self.name_index.get(name)
58 }
59
60 pub fn clear(&mut self) {
61 self.blueprint_index.clear();
62 self.entity_index.clear();
63 self.file_index.clear();
64 self.dependency_index.clear();
65 self.name_index.clear();
66 }
67
68 pub fn blueprint_count(&self) -> usize {
69 self.blueprint_index.len()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_index_add_remove() {
79 let mut idx = ForgeIndexes::new();
80 let bp_id = BlueprintId::new();
81 idx.add_blueprint(bp_id);
82 assert_eq!(idx.blueprint_count(), 1);
83 idx.remove_blueprint(&bp_id);
84 assert_eq!(idx.blueprint_count(), 0);
85 }
86
87 #[test]
88 fn test_entity_index() {
89 let mut idx = ForgeIndexes::new();
90 let bp_id = BlueprintId::new();
91 let eid = EntityId::new();
92 idx.add_entity(eid, bp_id);
93 assert_eq!(idx.lookup_entity_blueprint(&eid), Some(&bp_id));
94 }
95
96 #[test]
97 fn test_file_index() {
98 let mut idx = ForgeIndexes::new();
99 let bp_id = BlueprintId::new();
100 let fid = FileId::new();
101 idx.add_file(fid, bp_id);
102 assert_eq!(idx.lookup_file_blueprint(&fid), Some(&bp_id));
103 }
104
105 #[test]
106 fn test_name_index() {
107 let mut idx = ForgeIndexes::new();
108 let bp_id = BlueprintId::new();
109 idx.add_name("MyProject".into(), bp_id);
110 assert_eq!(idx.lookup_by_name("MyProject"), Some(&bp_id));
111 }
112
113 #[test]
114 fn test_clear() {
115 let mut idx = ForgeIndexes::new();
116 idx.add_blueprint(BlueprintId::new());
117 idx.add_blueprint(BlueprintId::new());
118 idx.clear();
119 assert_eq!(idx.blueprint_count(), 0);
120 }
121
122 #[test]
123 fn test_remove_cascades() {
124 let mut idx = ForgeIndexes::new();
125 let bp_id = BlueprintId::new();
126 let eid = EntityId::new();
127 idx.add_blueprint(bp_id);
128 idx.add_entity(eid, bp_id);
129 idx.remove_blueprint(&bp_id);
130 assert!(idx.lookup_entity_blueprint(&eid).is_none());
131 }
132}