polymathy 0.2.0

Turn search results into answers - a web service that fetches, chunks, and returns semantic content from search queries
Documentation
# Code Style Guide

Coding conventions for Polymathy contributors.

## Rust Style

### General Rules

- Follow the official [Rust Style Guide]https://doc.rust-lang.org/nightly/style-guide/
- Use `cargo fmt` before every commit
- Address all `cargo clippy` warnings

### Formatting

Run before committing:

```bash
cargo fmt
```

### Linting

Ensure no warnings:

```bash
cargo clippy -- -D warnings
```

## Naming Conventions

### Functions and Variables

Use `snake_case`:

```rust
fn process_search_results() { }
let chunk_counter = 0;
```

### Types and Traits

Use `PascalCase`:

```rust
struct SearchQuery { }
trait ContentProcessor { }
enum ProcessingError { }
```

### Constants

Use `SCREAMING_SNAKE_CASE`:

```rust
const MAX_URLS: usize = 10;
const DEFAULT_CHUNK_SIZE: u32 = 100;
```

### Modules

Use `snake_case`:

```rust
mod search_processing;
mod content_handler;
```

## Documentation

### Module Documentation

Every module should have a doc comment:

```rust
//! Search query processing and data structures.
//!
//! This module provides types for handling search queries
//! and processing their results.
```

### Public Items

Document all public functions, structs, and traits:

```rust
/// Creates a new vector index for similarity search.
///
/// # Returns
///
/// A configured `Index` with 384 dimensions and Inner Product metric.
///
/// # Example
///
/// ```rust
/// let index = create_index();
/// ```
pub fn create_index() -> Index {
    // ...
}
```

### Struct Fields

Document non-obvious fields:

```rust
/// Processed content from a URL.
pub struct ProcessedContent {
    /// The source URL of the content.
    pub url: String,

    /// Map of chunk IDs to chunk text.
    pub chunks: HashMap<String, String>,

    /// Map of chunk IDs to their embedding vectors (384 dimensions).
    pub embeddings: HashMap<String, Vec<f32>>,
}
```

## Error Handling

### Use Result and Option

```rust
// Prefer Result for operations that can fail
fn process_url(url: &str) -> Result<ProcessedContent> { }

// Use Option for optional values
fn get_embedding(id: &str) -> Option<Vec<f32>> { }
```

### Use anyhow for Application Code

```rust
use anyhow::{Context, Result};

fn fetch_content(url: &str) -> Result<String> {
    let response = reqwest::blocking::get(url)
        .context("Failed to fetch URL")?;

    response.text()
        .context("Failed to read response body")
}
```

### Don't Panic in Library Code

```rust
// Bad
fn get_item(index: usize) -> &Item {
    &self.items[index]  // Panics if out of bounds
}

// Good
fn get_item(&self, index: usize) -> Option<&Item> {
    self.items.get(index)
}
```

## Async Code

### Use async/await

```rust
async fn process_url(url: &str) -> Result<ProcessedContent> {
    let response = client.get(url).send().await?;
    let content = response.json().await?;
    Ok(content)
}
```

### Prefer join_all for Concurrent Operations

```rust
use futures::future::join_all;

let futures: Vec<_> = urls
    .iter()
    .map(|url| process_url(url))
    .collect();

let results = join_all(futures).await;
```

## Code Organization

### Import Order

1. Standard library
2. External crates
3. Local modules

```rust
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use actix_web::{web, HttpResponse};
use serde::{Deserialize, Serialize};

use crate::search::SearchQuery;
use crate::index::create_index;
```

### Module Structure

Keep modules focused and cohesive:

```rust
// Good: search.rs contains search-related items
pub struct SearchQuery { }
pub struct ProcessedContent { }

// Bad: mixing unrelated concerns
pub struct SearchQuery { }
pub struct DatabaseConnection { }  // Should be in a different module
```

## Testing

### Test Module Placement

Place unit tests in the same file:

```rust
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 2), 4);
    }
}
```

### Integration Tests

Place in `tests/` directory:

```rust
// tests/integration_tests.rs
use polymathy::search::SearchQuery;

#[test]
fn test_search_query_creation() {
    let query = SearchQuery { q: "test".to_string() };
    assert_eq!(query.q, "test");
}
```

### Test Naming

Use descriptive names:

```rust
#[test]
fn test_process_url_returns_error_for_invalid_url() { }

#[test]
fn test_create_index_with_correct_dimensions() { }
```

## Comments

### When to Comment

- Explain **why**, not **what**
- Document non-obvious behavior
- Add context for complex algorithms

```rust
// Good: explains why
// Skip URLs that returned server errors to avoid poisoning the index
// with error page content
if response.status().is_server_error() {
    continue;
}

// Bad: states the obvious
// Check if status is server error
if response.status().is_server_error() {
    continue;
}
```

### TODO Comments

Use for future improvements:

```rust
// TODO: Add retry logic for transient failures
// TODO(#123): Implement caching for repeated queries
```