use std::cell::Cell; use std::sync::Arc; use rand::seq::SliceRandom; use rand::thread_rng; use phreak_engine::condition::ConditionBuilder; use phreak_engine::Phreak; use phreak_facts::FactsBuilder; use phreak_rules::ProductionCallback; #[derive(Debug)] struct CountCallback { counter: Arc> } impl ProductionCallback for CountCallback { fn activate(&self) { self.counter.replace(self.counter.take() + 1); } fn deactivate(&self) { self.counter.replace(self.counter.take() - 1); } } #[test] fn api_test() { use uuid; use phreak_facts::Value; let mut phreak = Phreak::new(); let counter1: Arc> = Arc::new(Cell::new(0)); let callback = Box::new(CountCallback { counter: counter1.clone() }); // we are looking for small cars, but we don't like blue ones phreak.add_production(&[ ConditionBuilder::new(String::from("car")) .variable_field1(String::from("id")) .const_field2(String::from("size")) .const_field3(String::from("small")) .build() , ConditionBuilder::new(String::from("car")) .negative(String::from("car")) .variable_field1(String::from("id")) .const_field2(String::from("color")) .const_field3(String::from("blue")) .build() ], callback); for _j in 0..3 { let mut arr = Vec::new(); let colors = ["red", "blue", "yellow", "green", "purple", "black", "orange"]; let sizes = ["small", "medium", "large"]; let mut verification_counter = 0; for i in 0..40 { let id = uuid::Uuid::new_v4(); arr.push(FactsBuilder::new("car".to_string()) .add_values(Value::from(id), Value::from("color"), Value::from(colors[i % colors.len()])) .add_values(Value::from(id), Value::from("size"), Value::from(sizes[i % sizes.len()])) .build() ); // size[0] == "small", color[1] == "blue" if (i % sizes.len() == 0) && (i % colors.len() != 1) { verification_counter += 1; } } phreak.add_facts(&arr); assert_eq!(counter1.get(), verification_counter); let mut rng = thread_rng(); arr.shuffle(&mut rng); phreak.remove_facts(&arr); assert_eq!(counter1.get(), 0); } }