fact_tools/
lib.rs

1//! # FACT - Fast Augmented Context Tools
2//! 
3//! A high-performance context processing engine for Rust.
4//! 
5//! ## Features
6//! 
7//! - **High Performance**: Optimized data structures and algorithms
8//! - **Intelligent Caching**: Multi-tier caching with LRU eviction
9//! - **Cognitive Templates**: Pre-built templates for common patterns
10//! - **Async Support**: Full async/await support with Tokio
11//! - **Cross-Platform**: Works on Linux, macOS, and Windows
12//! 
13//! ## Example
14//! 
15//! ```rust
16//! use fact::{FactEngine, Template};
17//! 
18//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
19//! // Create a new FACT engine
20//! let mut engine = FactEngine::new();
21//! 
22//! // Process with a template
23//! let result = engine.process(
24//!     "analysis-basic",
25//!     serde_json::json!({
26//!         "data": [1, 2, 3, 4, 5],
27//!         "operation": "sum"
28//!     })
29//! ).await?;
30//! 
31//! println!("Result: {}", result);
32//! # Ok(())
33//! # }
34//! ```
35
36use parking_lot::RwLock;
37use serde::{Deserialize, Serialize};
38use std::sync::Arc;
39use std::time::Duration;
40use thiserror::Error;
41
42pub mod cache;
43pub mod engine;
44pub mod processor;
45pub mod templates;
46
47pub use cache::{Cache, CacheStats};
48pub use engine::{FactEngine, ProcessingOptions};
49pub use processor::QueryProcessor;
50pub use templates::{Template, TemplateRegistry};
51
52/// Result type for FACT operations
53pub type Result<T> = std::result::Result<T, FactError>;
54
55/// Errors that can occur in FACT operations
56#[derive(Error, Debug)]
57pub enum FactError {
58    #[error("Template not found: {0}")]
59    TemplateNotFound(String),
60    
61    #[error("Processing error: {0}")]
62    ProcessingError(String),
63    
64    #[error("Serialization error: {0}")]
65    SerializationError(#[from] serde_json::Error),
66    
67    #[error("IO error: {0}")]
68    IoError(#[from] std::io::Error),
69    
70    #[error("Cache error: {0}")]
71    CacheError(String),
72    
73    #[error("Timeout exceeded: {0:?}")]
74    Timeout(Duration),
75}
76
77/// Main entry point for FACT functionality
78pub struct Fact {
79    engine: FactEngine,
80    cache: Arc<RwLock<Cache>>,
81}
82
83impl Fact {
84    /// Create a new FACT instance
85    pub fn new() -> Self {
86        Self {
87            engine: FactEngine::new(),
88            cache: Arc::new(RwLock::new(Cache::new())),
89        }
90    }
91    
92    /// Create a new FACT instance with custom configuration
93    pub fn with_config(config: FactConfig) -> Self {
94        Self {
95            engine: FactEngine::with_config(config.engine_config),
96            cache: Arc::new(RwLock::new(Cache::with_capacity(config.cache_size))),
97        }
98    }
99    
100    /// Process a query using a cognitive template
101    pub async fn process(
102        &self,
103        template_id: &str,
104        context: serde_json::Value,
105    ) -> Result<serde_json::Value> {
106        // Check cache first
107        let cache_key = self.generate_cache_key(template_id, &context);
108        
109        // Need to use write lock for get() since it updates access stats
110        if let Some(cached) = self.cache.write().get(&cache_key) {
111            return Ok(cached.clone());
112        }
113        
114        // Process with engine
115        let result = self.engine.process(template_id, context).await?;
116        
117        // Cache the result
118        self.cache.write().put(cache_key, result.clone());
119        
120        Ok(result)
121    }
122    
123    /// Get cache statistics
124    pub fn cache_stats(&self) -> CacheStats {
125        self.cache.read().stats()
126    }
127    
128    /// Clear the cache
129    pub fn clear_cache(&self) {
130        self.cache.write().clear();
131    }
132    
133    fn generate_cache_key(&self, template_id: &str, context: &serde_json::Value) -> String {
134        use std::collections::hash_map::DefaultHasher;
135        use std::hash::{Hash, Hasher};
136        
137        let mut hasher = DefaultHasher::new();
138        template_id.hash(&mut hasher);
139        context.to_string().hash(&mut hasher);
140        
141        format!("fact:{}:{:x}", template_id, hasher.finish())
142    }
143}
144
145impl Default for Fact {
146    fn default() -> Self {
147        Self::new()
148    }
149}
150
151/// Configuration for FACT
152#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct FactConfig {
154    /// Engine configuration
155    pub engine_config: engine::EngineConfig,
156    
157    /// Cache size in bytes
158    pub cache_size: usize,
159    
160    /// Enable performance monitoring
161    pub enable_monitoring: bool,
162    
163    /// Maximum processing timeout
164    pub timeout: Option<Duration>,
165}
166
167impl Default for FactConfig {
168    fn default() -> Self {
169        Self {
170            engine_config: Default::default(),
171            cache_size: 100 * 1024 * 1024, // 100MB
172            enable_monitoring: true,
173            timeout: Some(Duration::from_secs(30)),
174        }
175    }
176}
177
178/// Performance metrics
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct Metrics {
181    pub total_requests: u64,
182    pub cache_hits: u64,
183    pub cache_misses: u64,
184    pub avg_processing_time_ms: f64,
185    pub error_count: u64,
186}
187
188#[cfg(test)]
189mod tests {
190    use super::*;
191    
192    #[tokio::test]
193    async fn test_fact_creation() {
194        let fact = Fact::new();
195        let stats = fact.cache_stats();
196        assert_eq!(stats.entries, 0);
197    }
198    
199    #[tokio::test]
200    async fn test_basic_processing() {
201        let fact = Fact::new();
202        let context = serde_json::json!({
203            "data": [1, 2, 3, 4, 5],
204            "operation": "sum"
205        });
206        
207        // This will use a mock template since we haven't loaded real ones
208        match fact.process("test-template", context).await {
209            Ok(_) => {
210                // Template found and processed
211            }
212            Err(FactError::TemplateNotFound(_)) => {
213                // Expected if template not loaded
214            }
215            Err(e) => panic!("Unexpected error: {}", e),
216        }
217    }
218}