obj-cli 1.0.0

Command-line tools (dump, check, stat, backup) for the obj embedded document database.
Documentation
//! `obj stat <path>` — structured DB summary.
//!
//! Output is a sequence of `## <section>` markdown headings with
//! `key: value` pairs underneath. Stable for grepping; not a
//! commitment to a stable wire format.
//!
//! Per the AC: file size, page count, page size, format
//! major/minor, then per-collection name / doc count / index
//! count / total bytes (approximate, from doc-header `payload_len`
//! sums). Exit codes: 0 on success, 2 on I/O / engine error.

use std::path::Path;

use obj::{CollectionStat, Db, DbStat};

/// Run `obj stat <path>` and return the process exit code.
pub(crate) fn run(path: &Path) -> i32 {
    let db = match Db::open(path) {
        Ok(db) => db,
        Err(err) => {
            eprintln!("error: failed to open {}: {err}", path.display());
            return 2;
        }
    };
    let stat = match db.stat() {
        Ok(s) => s,
        Err(err) => {
            eprintln!("error: stat failed: {err}");
            return 2;
        }
    };
    print_header_section(path, &stat);
    for collection in &stat.collections {
        print_collection_section(collection);
    }
    0
}

/// Print the `## file` section — header + page summary.
fn print_header_section(path: &Path, stat: &DbStat) {
    println!("## file");
    println!("path: {}", path.display());
    println!("file_size_bytes: {}", stat.file_size_bytes);
    println!("page_size: {}", stat.page_size);
    println!("page_count: {}", stat.page_count);
    println!("format: {}.{}", stat.format_major, stat.format_minor,);
    println!("collection_count: {}", stat.collections.len());
    println!();
}

/// Print one `## <name>` section per collection.
fn print_collection_section(collection: &CollectionStat) {
    println!("## {}", collection.name);
    println!("collection_id: {}", collection.collection_id);
    println!("type_version: {}", collection.type_version);
    println!("doc_count: {}", collection.doc_count);
    println!(
        "total_payload_bytes_approx: {}",
        collection.total_payload_bytes,
    );
    println!("active_index_count: {}", collection.active_index_count);
    println!("dropped_index_count: {}", collection.dropped_index_count);
    println!();
}