Expand description
§docsrs
docsrs is a Rust crate for retrieving, parsing, and indexing rustdoc JSON files,
enabling fuzzy searching of Rust documentation content with a type-safe pipeline approach.
Whether you’re building a custom documentation browser, writing a Rust LSP plugin,
creating documentation analysis tools, or just need to programmatically explore docs —
docsrs gives you structured access to items and metadata in a searchable form.
§Features
The crate uses a type-state pattern to ensure compile-time safety when processing documentation through different stages:
default- Core functionality for loading and parsing JSON filesdecompress- Adds support for decompressing zstd-compressed filesfetch- Enables fetching compressed documentation directly from docs.rs
§Quick Start
§Basic Usage with Local JSON
use docsrs::Doc;
// Load and parse a local JSON documentation file
let doc = Doc::from_json("path/to/docs.json")?
    .parse()?
    .build_search_index();
// Search for items
let results = doc.search("HashMap", Some(10));
for item in results.unwrap_or_default() {
    println!("{}: {}", item.name, item.path.join("::"));
}§Fetching from docs.rs (requires fetch feature)
use docsrs::Doc;
// Fetch, decompress, parse, and index documentation from docs.rs
let doc = Doc::from_docs("serde", "latest")?
    .fetch()?
    .decompress()?
    .parse()?
    .build_search_index();
// Search for serialization-related items
let results = doc.search("Serialize", Some(5));§Working with Compressed Files (requires decompress feature)
use docsrs::Doc;
// Load and decompress a local zstd file
let doc = Doc::from_zst("docs/tokio.json.zst")?
    .decompress()?
    .parse()?
    .build_search_index();
let results = doc.search("tokio::spawn", None);§Type-State Pipeline
The crate uses a type-state pattern to ensure you process documentation in the correct order:
Flow:
  Remote ── fetch() ─→ Compressed ── decompress() ─→ RawJson ── parse() ─→ Parsed ── build_search_index() ─→ Indexed
               ↑                ↑                         ↑
        from_docs()      from_zst()                from_json()Each state represents a different stage in the documentation processing pipeline:
Remote- Documentation URL ready to be fetched from docs.rsCompressed- Downloaded or loaded compressed documentation dataRawJson- Decompressed JSON data in bytesParsed- Parsed documentation AST with structured dataIndexed- Documentation with built search index for fuzzy matching
§Search Capabilities
The fuzzy search functionality supports:
- Fully qualified paths: 
"std::collections::HashMap" - Partial matches: 
"vec push"matchesVec::push - Case-insensitive: 
"hashmap"matchesHashMap - Methods and functions: 
"tokio::spawn"finds the spawn function - Ranked results: Results are sorted by relevance score
 
§Item Information
Each search result provides comprehensive information:
let results = doc.search("HashMap::new", Some(1));
if let Some(items) = results {
    for item in items {
        println!("Name: {}", item.name);
        println!("Path: {}", item.path.join("::"));
        println!("Docs: {}", item.docs.as_deref().unwrap_or("No docs"));
        println!("Deprecated: {}", item.deprecation.is_some());
    }
}§Error Handling
All operations return Result<T, Error> where Error covers:
- HTTP errors when fetching from docs.rs
 - File I/O errors when reading local files
 - JSON parsing errors for malformed documentation
 - URL parsing errors for invalid docs.rs URLs
 
§Performance Considerations
- Memory usage: Large crates like 
stdcan use significant memory when indexed - Search speed: Fuzzy search is optimized but may be slower on very large indices
 - Parsing time: Initial parsing and indexing can take time for large documentation sets
 
Consider using search result limits and caching indexed documentation for better performance.
§Examples
§Building a Documentation Browser
use docsrs::Doc;
fn search_docs(query: &str) -> Result<(), Box<dyn std::error::Error>> {
    let doc = Doc::from_docs("tokio", "latest")?
        .fetch()?
        .decompress()?
        .parse()?
        .build_search_index();
    if let Some(results) = doc.search(query, Some(20)) {
        for item in results {
            println!("{}", item.path.join("::"));
            if let Some(docs) = &item.docs {
                println!("  {}", docs.lines().next().unwrap_or(""));
            }
        }
    }
    Ok(())
}§Analyzing Documentation Coverage
use docsrs::Doc;
fn analyze_coverage(crate_name: &str) -> Result<(), Box<dyn std::error::Error>> {
    let doc = Doc::from_docs(crate_name, "latest")?
        .fetch()?
        .decompress()?
        .parse()?
        .build_search_index();
    let all_items = doc.search("", None).unwrap_or_default();
    let documented = all_items.iter().filter(|item| item.docs.is_some()).count();
     
    println!("Total items: {}", all_items.len());
    println!("Documented: {}", documented);
    println!("Coverage: {:.1}%", (documented as f64 / all_items.len() as f64) * 100.0);
     
    Ok(())
}This was generated by Claude Sonnet 4, because:
- I’m really bad at writing documentation (everything would be very short one-liners)
 - I’m lazy
 - I don’t have the nerves to write a documentation this long
 
The code was written by me
Structs§
- Compressed
 - Represents compressed documentation data in zstd format.
 - Doc
 - A generic wrapper for documentation data in different processing states.
 - Indexed
 - Represents indexed documentation data with fuzzy search capabilities.
 - Item
 - Represents a single documentation item with all its metadata and content.
 - Parsed
 - Represents parsed documentation data with a structured AST.
 - RawJson
 - Represents raw JSON documentation data in bytes.
 - Remote
 - Represents a remote documentation source that can be fetched from docs.rs.
 
Enums§
- Error
 - Errors that can occur during documentation processing