1use crate::rete::facts::TypedFacts;
7use crate::errors::{Result, RuleEngineError};
8use std::collections::HashMap;
9
10#[derive(Debug, Clone)]
12pub struct FactInstance {
13 pub fact_type: String,
15 pub data: TypedFacts,
17}
18
19impl FactInstance {
20 pub fn new(fact_type: impl Into<String>, data: TypedFacts) -> Self {
22 Self {
23 fact_type: fact_type.into(),
24 data,
25 }
26 }
27}
28
29#[derive(Debug, Clone)]
31pub struct Deffacts {
32 pub name: String,
34 pub facts: Vec<FactInstance>,
36 pub description: Option<String>,
38}
39
40impl Deffacts {
41 pub fn new(name: impl Into<String>) -> Self {
43 Self {
44 name: name.into(),
45 facts: Vec::new(),
46 description: None,
47 }
48 }
49
50 pub fn add_fact(&mut self, fact_type: impl Into<String>, data: TypedFacts) {
52 self.facts.push(FactInstance::new(fact_type, data));
53 }
54
55 pub fn set_description(&mut self, description: impl Into<String>) {
57 self.description = Some(description.into());
58 }
59
60 pub fn fact_count(&self) -> usize {
62 self.facts.len()
63 }
64
65 pub fn is_empty(&self) -> bool {
67 self.facts.is_empty()
68 }
69}
70
71#[derive(Debug, Clone)]
74pub struct DeffactsRegistry {
75 deffacts: HashMap<String, Deffacts>,
76}
77
78impl DeffactsRegistry {
79 pub fn new() -> Self {
81 Self {
82 deffacts: HashMap::new(),
83 }
84 }
85
86 pub fn register(&mut self, deffacts: Deffacts) -> Result<()> {
88 let name = deffacts.name.clone();
89
90 if self.deffacts.contains_key(&name) {
91 return Err(RuleEngineError::EvaluationError {
92 message: format!("Deffacts '{}' already exists", name),
93 });
94 }
95
96 self.deffacts.insert(name, deffacts);
97 Ok(())
98 }
99
100 pub fn register_or_replace(&mut self, deffacts: Deffacts) {
102 let name = deffacts.name.clone();
103 self.deffacts.insert(name, deffacts);
104 }
105
106 pub fn get(&self, name: &str) -> Option<&Deffacts> {
108 self.deffacts.get(name)
109 }
110
111 pub fn get_mut(&mut self, name: &str) -> Option<&mut Deffacts> {
113 self.deffacts.get_mut(name)
114 }
115
116 pub fn exists(&self, name: &str) -> bool {
118 self.deffacts.contains_key(name)
119 }
120
121 pub fn remove(&mut self, name: &str) -> Result<Deffacts> {
123 self.deffacts.remove(name).ok_or_else(|| {
124 RuleEngineError::EvaluationError {
125 message: format!("Deffacts '{}' not found", name),
126 }
127 })
128 }
129
130 pub fn list_deffacts(&self) -> Vec<String> {
132 self.deffacts.keys().cloned().collect()
133 }
134
135 pub fn get_all_facts(&self) -> Vec<(String, FactInstance)> {
137 let mut all_facts = Vec::new();
138
139 for (deffacts_name, deffacts) in &self.deffacts {
140 for fact in &deffacts.facts {
141 all_facts.push((deffacts_name.clone(), fact.clone()));
142 }
143 }
144
145 all_facts
146 }
147
148 pub fn total_fact_count(&self) -> usize {
150 self.deffacts.values().map(|d| d.fact_count()).sum()
151 }
152
153 pub fn clear(&mut self) {
155 self.deffacts.clear();
156 }
157
158 pub fn len(&self) -> usize {
160 self.deffacts.len()
161 }
162
163 pub fn is_empty(&self) -> bool {
165 self.deffacts.is_empty()
166 }
167}
168
169impl Default for DeffactsRegistry {
170 fn default() -> Self {
171 Self::new()
172 }
173}
174
175pub struct DeffactsBuilder {
177 name: String,
178 facts: Vec<FactInstance>,
179 description: Option<String>,
180}
181
182impl DeffactsBuilder {
183 pub fn new(name: impl Into<String>) -> Self {
185 Self {
186 name: name.into(),
187 facts: Vec::new(),
188 description: None,
189 }
190 }
191
192 pub fn add_fact(mut self, fact_type: impl Into<String>, data: TypedFacts) -> Self {
194 self.facts.push(FactInstance::new(fact_type, data));
195 self
196 }
197
198 pub fn add_facts(mut self, fact_type: impl Into<String>, facts: Vec<TypedFacts>) -> Self {
200 let fact_type_str = fact_type.into();
201 for data in facts {
202 self.facts.push(FactInstance::new(fact_type_str.clone(), data));
203 }
204 self
205 }
206
207 pub fn with_description(mut self, description: impl Into<String>) -> Self {
209 self.description = Some(description.into());
210 self
211 }
212
213 pub fn build(self) -> Deffacts {
215 Deffacts {
216 name: self.name,
217 facts: self.facts,
218 description: self.description,
219 }
220 }
221}
222
223#[cfg(test)]
224mod tests {
225 use super::*;
226 use crate::rete::facts::FactValue;
227
228 #[test]
229 fn test_create_fact_instance() {
230 let mut data = TypedFacts::new();
231 data.set("name", FactValue::String("John".to_string()));
232 data.set("age", FactValue::Integer(30));
233
234 let fact = FactInstance::new("Person", data);
235 assert_eq!(fact.fact_type, "Person");
236 assert_eq!(fact.data.get("name"), Some(&FactValue::String("John".to_string())));
237 }
238
239 #[test]
240 fn test_deffacts_basic() {
241 let mut deffacts = Deffacts::new("initial-data");
242
243 let mut person_data = TypedFacts::new();
244 person_data.set("name", FactValue::String("Alice".to_string()));
245
246 deffacts.add_fact("Person", person_data);
247 deffacts.set_description("Initial person data");
248
249 assert_eq!(deffacts.name, "initial-data");
250 assert_eq!(deffacts.fact_count(), 1);
251 assert!(!deffacts.is_empty());
252 assert_eq!(deffacts.description, Some("Initial person data".to_string()));
253 }
254
255 #[test]
256 fn test_registry_register() {
257 let mut registry = DeffactsRegistry::new();
258
259 let mut deffacts = Deffacts::new("test");
260 let mut data = TypedFacts::new();
261 data.set("value", FactValue::Integer(42));
262 deffacts.add_fact("Config", data);
263
264 registry.register(deffacts).unwrap();
265
266 assert!(registry.exists("test"));
267 assert_eq!(registry.len(), 1);
268 }
269
270 #[test]
271 fn test_registry_duplicate_error() {
272 let mut registry = DeffactsRegistry::new();
273
274 let deffacts1 = Deffacts::new("test");
275 let deffacts2 = Deffacts::new("test");
276
277 registry.register(deffacts1).unwrap();
278 let result = registry.register(deffacts2);
279
280 assert!(result.is_err());
281 }
282
283 #[test]
284 fn test_registry_register_or_replace() {
285 let mut registry = DeffactsRegistry::new();
286
287 let mut deffacts1 = Deffacts::new("test");
288 let mut data1 = TypedFacts::new();
289 data1.set("version", FactValue::Integer(1));
290 deffacts1.add_fact("Config", data1);
291
292 let mut deffacts2 = Deffacts::new("test");
293 let mut data2 = TypedFacts::new();
294 data2.set("version", FactValue::Integer(2));
295 deffacts2.add_fact("Config", data2);
296
297 registry.register_or_replace(deffacts1);
298 registry.register_or_replace(deffacts2);
299
300 assert_eq!(registry.len(), 1);
301 let deffacts = registry.get("test").unwrap();
302 assert_eq!(deffacts.fact_count(), 1);
303 }
304
305 #[test]
306 fn test_registry_get_all_facts() {
307 let mut registry = DeffactsRegistry::new();
308
309 let mut deffacts1 = Deffacts::new("set1");
311 let mut data1 = TypedFacts::new();
312 data1.set("name", FactValue::String("Alice".to_string()));
313 deffacts1.add_fact("Person", data1);
314
315 let mut data2 = TypedFacts::new();
316 data2.set("name", FactValue::String("Bob".to_string()));
317 deffacts1.add_fact("Person", data2);
318
319 let mut deffacts2 = Deffacts::new("set2");
321 let mut data3 = TypedFacts::new();
322 data3.set("debug", FactValue::Boolean(true));
323 deffacts2.add_fact("Config", data3);
324
325 registry.register(deffacts1).unwrap();
326 registry.register(deffacts2).unwrap();
327
328 let all_facts = registry.get_all_facts();
329 assert_eq!(all_facts.len(), 3);
330 assert_eq!(registry.total_fact_count(), 3);
331 }
332
333 #[test]
334 fn test_registry_remove() {
335 let mut registry = DeffactsRegistry::new();
336
337 let deffacts = Deffacts::new("temp");
338 registry.register(deffacts).unwrap();
339
340 assert!(registry.exists("temp"));
341
342 let removed = registry.remove("temp").unwrap();
343 assert_eq!(removed.name, "temp");
344 assert!(!registry.exists("temp"));
345 }
346
347 #[test]
348 fn test_registry_list_deffacts() {
349 let mut registry = DeffactsRegistry::new();
350
351 registry.register(Deffacts::new("set1")).unwrap();
352 registry.register(Deffacts::new("set2")).unwrap();
353 registry.register(Deffacts::new("set3")).unwrap();
354
355 let list = registry.list_deffacts();
356 assert_eq!(list.len(), 3);
357 assert!(list.contains(&"set1".to_string()));
358 assert!(list.contains(&"set2".to_string()));
359 assert!(list.contains(&"set3".to_string()));
360 }
361
362 #[test]
363 fn test_registry_clear() {
364 let mut registry = DeffactsRegistry::new();
365
366 registry.register(Deffacts::new("set1")).unwrap();
367 registry.register(Deffacts::new("set2")).unwrap();
368
369 assert_eq!(registry.len(), 2);
370
371 registry.clear();
372
373 assert_eq!(registry.len(), 0);
374 assert!(registry.is_empty());
375 }
376
377 #[test]
378 fn test_builder_basic() {
379 let mut data = TypedFacts::new();
380 data.set("name", FactValue::String("Charlie".to_string()));
381 data.set("age", FactValue::Integer(25));
382
383 let deffacts = DeffactsBuilder::new("people")
384 .add_fact("Person", data)
385 .with_description("Initial people data")
386 .build();
387
388 assert_eq!(deffacts.name, "people");
389 assert_eq!(deffacts.fact_count(), 1);
390 assert_eq!(deffacts.description, Some("Initial people data".to_string()));
391 }
392
393 #[test]
394 fn test_builder_multiple_facts() {
395 let mut person1 = TypedFacts::new();
396 person1.set("name", FactValue::String("Alice".to_string()));
397
398 let mut person2 = TypedFacts::new();
399 person2.set("name", FactValue::String("Bob".to_string()));
400
401 let mut config = TypedFacts::new();
402 config.set("debug", FactValue::Boolean(true));
403
404 let deffacts = DeffactsBuilder::new("startup")
405 .add_fact("Person", person1)
406 .add_fact("Person", person2)
407 .add_fact("Config", config)
408 .build();
409
410 assert_eq!(deffacts.fact_count(), 3);
411 }
412
413 #[test]
414 fn test_builder_add_facts_batch() {
415 let mut person1 = TypedFacts::new();
416 person1.set("name", FactValue::String("Alice".to_string()));
417
418 let mut person2 = TypedFacts::new();
419 person2.set("name", FactValue::String("Bob".to_string()));
420
421 let people = vec![person1, person2];
422
423 let deffacts = DeffactsBuilder::new("batch-people")
424 .add_facts("Person", people)
425 .build();
426
427 assert_eq!(deffacts.fact_count(), 2);
428 assert_eq!(deffacts.facts[0].fact_type, "Person");
429 assert_eq!(deffacts.facts[1].fact_type, "Person");
430 }
431
432 #[test]
433 fn test_integration_with_registry() {
434 let mut registry = DeffactsRegistry::new();
435
436 let mut person_data = TypedFacts::new();
438 person_data.set("name", FactValue::String("Admin".to_string()));
439 person_data.set("role", FactValue::String("administrator".to_string()));
440
441 let mut config_data = TypedFacts::new();
442 config_data.set("max_users", FactValue::Integer(1000));
443 config_data.set("debug_mode", FactValue::Boolean(false));
444
445 let deffacts = DeffactsBuilder::new("system-startup")
446 .add_fact("User", person_data)
447 .add_fact("SystemConfig", config_data)
448 .with_description("System initialization facts")
449 .build();
450
451 registry.register(deffacts).unwrap();
453
454 assert!(registry.exists("system-startup"));
456 let retrieved = registry.get("system-startup").unwrap();
457 assert_eq!(retrieved.fact_count(), 2);
458 assert_eq!(retrieved.description, Some("System initialization facts".to_string()));
459 }
460}