agentic_forge_core/engine/
mod.rs1pub mod query;
4pub mod validator;
5pub mod write;
6
7pub use query::QueryEngine;
8pub use write::WriteEngine;
9
10use crate::index::ForgeIndexes;
11use crate::storage::BlueprintStore;
12use crate::types::blueprint::Blueprint;
13use crate::types::ids::BlueprintId;
14use crate::types::intent::Domain;
15use crate::types::ForgeResult;
16
17#[derive(Debug)]
18pub struct ForgeEngine {
19 pub store: BlueprintStore,
20 pub indexes: ForgeIndexes,
21 dirty: bool,
22}
23
24impl ForgeEngine {
25 pub fn new() -> Self {
26 Self {
27 store: BlueprintStore::new(),
28 indexes: ForgeIndexes::new(),
29 dirty: false,
30 }
31 }
32
33 pub fn with_store(store: BlueprintStore) -> Self {
34 Self {
35 store,
36 indexes: ForgeIndexes::new(),
37 dirty: false,
38 }
39 }
40
41 pub fn writer(&mut self) -> WriteEngine<'_> {
42 WriteEngine::new(self)
43 }
44
45 pub fn reader(&self) -> QueryEngine<'_> {
46 QueryEngine::new(self)
47 }
48
49 pub fn is_dirty(&self) -> bool {
50 self.dirty || self.store.is_dirty()
51 }
52
53 pub fn mark_dirty(&mut self) {
54 self.dirty = true;
55 }
56
57 pub fn mark_clean(&mut self) {
58 self.dirty = false;
59 self.store.mark_clean();
60 }
61
62 pub fn create_blueprint(
63 &mut self,
64 name: impl Into<String>,
65 description: impl Into<String>,
66 domain: Domain,
67 ) -> ForgeResult<BlueprintId> {
68 let bp = Blueprint::new(name, description, domain);
69 let id = bp.id;
70 self.store.save(bp)?;
71 self.indexes.add_blueprint(id);
72 self.dirty = true;
73 Ok(id)
74 }
75
76 pub fn blueprint_count(&self) -> usize {
77 self.store.count()
78 }
79}
80
81impl Default for ForgeEngine {
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_engine_creation() {
93 let engine = ForgeEngine::new();
94 assert_eq!(engine.blueprint_count(), 0);
95 assert!(!engine.is_dirty());
96 }
97
98 #[test]
99 fn test_engine_create_blueprint() {
100 let mut engine = ForgeEngine::new();
101 let id = engine
102 .create_blueprint("Test", "A test", Domain::Api)
103 .unwrap();
104 assert_eq!(engine.blueprint_count(), 1);
105 assert!(engine.is_dirty());
106 let bp = engine.store.load(&id).unwrap();
107 assert_eq!(bp.name, "Test");
108 }
109
110 #[test]
111 fn test_engine_writer_reader() {
112 let mut engine = ForgeEngine::new();
113 let id = engine
114 .create_blueprint("Test", "A test", Domain::Web)
115 .unwrap();
116 {
117 let reader = engine.reader();
118 let bp = reader.get_blueprint(&id).unwrap();
119 assert_eq!(bp.name, "Test");
120 }
121 {
122 let mut writer = engine.writer();
123 writer.rename_blueprint(&id, "Renamed").unwrap();
124 }
125 let reader = engine.reader();
126 assert_eq!(reader.get_blueprint(&id).unwrap().name, "Renamed");
127 }
128
129 #[test]
130 fn test_engine_dirty_tracking() {
131 let mut engine = ForgeEngine::new();
132 assert!(!engine.is_dirty());
133 engine
134 .create_blueprint("Test", "Test", Domain::Cli)
135 .unwrap();
136 assert!(engine.is_dirty());
137 engine.mark_clean();
138 assert!(!engine.is_dirty());
139 }
140}