contextlite_client/
lib.rs

1//! # ContextLite Rust Client
2//! 
3//! A high-performance, async Rust client for the ContextLite context engine.
4//! 
5//! ## Features
6//! 
7//! - **Async/Await Support**: Built on Tokio for high-performance async operations
8//! - **Type Safety**: Comprehensive type definitions with builder patterns
9//! - **Error Handling**: Rich error types with proper error chaining
10//! - **Connection Pooling**: HTTP connection pooling for optimal performance
11//! - **Authentication**: Bearer token authentication support
12//! - **Validation**: Client-side validation for better error messages
13//! - **Flexible API**: Builder patterns for easy configuration
14//! 
15//! ## Quick Start
16//! 
17//! ```rust,no_run
18//! use contextlite_client::{ContextLiteClient, ClientConfig, Document, SearchQuery};
19//! 
20//! #[tokio::main]
21//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//!     // Create a client with default configuration
23//!     let client = ContextLiteClient::new("http://localhost:8080")?;
24//!     
25//!     // Or with custom configuration
26//!     let config = ClientConfig::new("http://localhost:8083")
27//!         .with_auth_token("your-token")
28//!         .with_timeout(60);
29//!     let client = ContextLiteClient::with_config(config)?;
30//!     
31//!     // Add a document
32//!     let document = Document::new("example.txt", "This is an example document");
33//!     let doc_id = client.add_document(&document).await?;
34//!     
35//!     // Search for documents
36//!     let query = SearchQuery::new("example").with_limit(10);
37//!     let results = client.search(&query).await?;
38//!     
39//!     println!("Found {} documents", results.documents.len());
40//!     
41//!     Ok(())
42//! }
43//! ```
44//! 
45//! ## Error Handling
46//! 
47//! The client provides comprehensive error handling with detailed error messages:
48//! 
49//! ```rust,no_run
50//! use contextlite_client::{ContextLiteClient, ContextLiteError};
51//! 
52//! #[tokio::main]
53//! async fn main() {
54//!     let client = ContextLiteClient::new("http://localhost:8080").unwrap();
55//!     
56//!     match client.health().await {
57//!         Ok(health) => println!("Server is healthy: {}", health.status),
58//!         Err(ContextLiteError::AuthError { message }) => {
59//!             eprintln!("Authentication failed: {}", message);
60//!         },
61//!         Err(ContextLiteError::ServerError { status, message }) => {
62//!             eprintln!("Server error {}: {}", status, message);
63//!         },
64//!         Err(err) => eprintln!("Error: {}", err),
65//!     }
66//! }
67//! ```
68
69#![deny(missing_docs)]
70#![warn(clippy::all)]
71
72pub mod client;
73pub mod error;
74pub mod types;
75
76// Re-export main types for convenience
77pub use client::ContextLiteClient;
78pub use error::{ContextLiteError, Result};
79pub use types::{
80    CompleteHealthStatus, SmtInfo, DatabaseStats, Features,
81    ClientConfig, ContextRequest, ContextResponse, Document, DocumentReference,
82    SearchQuery, SearchResponse, StorageInfo,
83};
84
85/// Convenience alias for the main client type
86pub type Client = ContextLiteClient;
87
88#[cfg(test)]
89mod integration_tests {
90    use super::*;
91    
92    #[tokio::test]
93    async fn test_client_creation_and_basic_operations() {
94        // This test requires a running ContextLite server
95        // Skip if server is not available
96        let client = match ContextLiteClient::new("http://127.0.0.1:8082") {
97            Ok(client) => client,
98            Err(_) => return, // Skip test if client creation fails
99        };
100        
101        // Try to check health - this will fail if server is not running
102        if client.health().await.is_err() {
103            return; // Skip test if server is not available
104        }
105        
106        // Test document operations
107        let mut metadata = std::collections::HashMap::new();
108        metadata.insert("test".to_string(), "true".to_string());
109        let document = Document::new("test.txt", "This is a test document")
110            .with_metadata(metadata);
111        
112        let doc_id = client.add_document(&document).await.unwrap();
113        assert!(!doc_id.is_empty());
114        
115        // Test search
116        let query = SearchQuery::new("test").with_limit(5);
117        let results = client.search(&query).await.unwrap();
118        assert!(!results.documents.is_empty());
119        
120        // Test context assembly
121        let context_request = ContextRequest::new("test document")
122            .with_budget(1000)
123            .with_max_results(3);
124        let context = client.assemble_context(&context_request).await.unwrap();
125        assert!(context.total_documents > 0);
126        
127        // Clean up
128        let _ = client.delete_document(&doc_id).await;
129    }
130}