use agcodex_core::tools::BuildInput;
use agcodex_core::tools::IndexConfig;
use agcodex_core::tools::IndexTool;
use agcodex_core::tools::SearchInput;
use agcodex_core::tools::SearchQuery;
use agcodex_core::tools::UpdateInput;
use std::fs;
use tempfile::TempDir;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?;
let source_dir = temp_dir.path().join("source");
fs::create_dir_all(&source_dir)?;
let rust_file = source_dir.join("main.rs");
fs::write(
&rust_file,
r#"
fn main() {
println!("Hello, world!");
let numbers = vec![1, 2, 3, 4, 5];
let sum = calculate_sum(&numbers);
println!("Sum: {}", sum);
}
fn calculate_sum(numbers: &[i32]) -> i32 {
numbers.iter().sum()
}
struct Person {
name: String,
age: u32,
}
impl Person {
fn new(name: String, age: u32) -> Self {
Person { name, age }
}
fn greet(&self) {
println!("Hello, my name is {}", self.name);
}
}
"#,
)?;
let python_file = source_dir.join("utils.py");
fs::write(
&python_file,
r#"
def fibonacci(n):
"""Calculate the nth Fibonacci number."""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
class Calculator:
"""A simple calculator class."""
def __init__(self):
self.history = []
def add(self, a, b):
"""Add two numbers."""
result = a + b
self.history.append(f"{a} + {b} = {result}")
return result
def multiply(self, a, b):
"""Multiply two numbers."""
result = a * b
self.history.append(f"{a} * {b} = {result}")
return result
"#,
)?;
let js_file = source_dir.join("script.js");
fs::write(
&js_file,
r#"
function processArray(arr) {
return arr
.filter(x => x > 0)
.map(x => x * 2)
.reduce((sum, x) => sum + x, 0);
}
class EventEmitter {
constructor() {
this.events = {};
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(...args));
}
}
}
const emitter = new EventEmitter();
emitter.on('data', data => console.log('Received:', data));
"#,
)?;
let index_dir = temp_dir.path().join("index");
let config = IndexConfig {
index_path: index_dir,
include_extensions: vec!["rs".to_string(), "py".to_string(), "js".to_string()],
max_file_size: 10 * 1024 * 1024, incremental: true,
writer_memory_mb: 64, num_threads: Some(2),
..Default::default()
};
println!("🏗️ Building index for directory: {:?}", source_dir);
let index_tool = IndexTool::new(config.clone())?;
let build_input = BuildInput {
directory: source_dir.clone(),
config: config.clone(),
force_rebuild: true,
};
let stats = index_tool.build(build_input).await?;
println!("✅ Index built successfully!");
println!("📊 Statistics:");
println!(" - Documents: {}", stats.result.document_count);
println!(" - Size: {} bytes", stats.result.size_bytes);
println!(" - Segments: {}", stats.result.segment_count);
println!(" - Languages: {:?}", stats.result.language_stats);
println!("\n🔍 Searching for 'function'...");
let search_query = SearchQuery {
query: "function".to_string(),
language: None,
path_filter: None,
symbol_type: None,
limit: Some(10),
fuzzy: false,
min_score: None,
};
let search_input = SearchInput {
query: search_query,
config: config.clone(),
};
let results = index_tool.search(search_input).await?;
println!("Found {} results:", results.result.len());
for (i, result) in results.result.iter().enumerate().take(3) {
println!(
"{}. {} (score: {:.2})",
i + 1,
result.document.path,
result.score
);
println!(" Language: {}", result.document.language);
println!(" Size: {} bytes", result.document.size);
if !result.document.symbols.is_empty() {
println!(" Symbols: {} found", result.document.symbols.len());
}
}
println!("\n🐍 Searching for Python files with 'class'...");
let python_search = SearchQuery {
query: "class".to_string(),
language: Some("python".to_string()),
path_filter: None,
symbol_type: None,
limit: Some(5),
fuzzy: false,
min_score: None,
};
let python_search_input = SearchInput {
query: python_search,
config: config.clone(),
};
let python_results = index_tool.search(python_search_input).await?;
println!("Found {} Python results:", python_results.result.len());
for result in python_results.result {
println!("- {} (score: {:.2})", result.document.path, result.score);
}
println!("\n🔄 Adding a new file and updating index...");
let new_file = source_dir.join("new_module.rs");
fs::write(
&new_file,
r#"
/// A new module for demonstration
pub mod demo {
use std::collections::HashMap;
/// Configuration struct
pub struct Config {
pub name: String,
pub settings: HashMap<String, String>,
}
impl Config {
/// Create a new configuration
pub fn new(name: String) -> Self {
Self {
name,
settings: HashMap::new(),
}
}
/// Add a setting
pub fn add_setting(&mut self, key: String, value: String) {
self.settings.insert(key, value);
}
}
/// Process configuration
pub fn process_config(config: &Config) -> String {
format!("Processing config: {}", config.name)
}
}
"#,
)?;
let update_input = UpdateInput {
files: vec![new_file.clone()],
config: config.clone(),
};
let updated_stats = index_tool.update(update_input).await?;
println!("✅ Index updated!");
println!("📊 New statistics:");
println!(" - Documents: {}", updated_stats.result.document_count);
println!(" - Size: {} bytes", updated_stats.result.size_bytes);
println!("\n🔍 Searching for 'HashMap'...");
let hashmap_search = SearchQuery {
query: "HashMap".to_string(),
language: None,
path_filter: None,
symbol_type: None,
limit: Some(5),
fuzzy: false,
min_score: None,
};
let hashmap_search_input = SearchInput {
query: hashmap_search,
config: config.clone(),
};
let hashmap_results = index_tool.search(hashmap_search_input).await?;
println!(
"Found {} results containing 'HashMap':",
hashmap_results.result.len()
);
for result in hashmap_results.result {
println!("- {} (score: {:.2})", result.document.path, result.score);
}
println!("\n⚡ Optimizing index...");
index_tool.optimize().await?;
println!("✅ Index optimization completed!");
let final_stats = index_tool.stats().await?;
println!("\n📈 Final Index Statistics:");
println!(
" - Total documents: {}",
final_stats.result.document_count
);
println!(" - Total size: {} bytes", final_stats.result.size_bytes);
println!(" - Segments: {}", final_stats.result.segment_count);
println!(
" - Average document size: {:.2} bytes",
final_stats.result.avg_document_size
);
if !final_stats.result.language_stats.is_empty() {
println!(" - Language distribution:");
for (lang, count) in &final_stats.result.language_stats {
println!(" • {}: {} files", lang, count);
}
}
println!("\n🎉 IndexTool demonstration completed successfully!");
Ok(())
}