use anyhow::Result;
use std::io::IsTerminal;
use weave::ReadMode;
pub fn handle(json: bool, demo: Option<String>) -> Result<()> {
if let Some(mode_str) = demo {
return run_demo(&mode_str);
}
if json {
return print_json();
}
print_table();
Ok(())
}
fn print_table() {
let is_tty = std::io::stdout().is_terminal();
let sep = " ──────────────────────────────────────────────────────────────────────────";
println!();
if is_tty {
println!(" \x1b[1mbctx lens modes\x1b[0m — 10 named modes, one per use case");
} else {
println!(" bctx lens modes — 10 named modes, one per use case");
}
println!("{sep}");
println!(
" {:<13} {:<22} {:<14} USE CASE",
"MODE", "LENS STACK", "SAVINGS"
);
println!("{sep}");
for mode in ReadMode::all_named() {
let name = mode.name();
let stack = mode.lens_stack();
let savings = mode.savings_estimate();
let use_case = mode.use_case();
let name_col = if is_tty && name != "auto" {
format!("\x1b[36m{:<13}\x1b[0m", name)
} else {
format!("{:<13}", name)
};
println!(
" {} {:<22} {:<14} {}",
name_col, stack, savings, use_case
);
}
println!("{sep}");
println!(" + lines:N-M line-range extractor depends on range Focus on a known region of a file");
println!();
println!(" Usage:");
println!(" bctx read --mode signatures -- cat src/lib.rs");
println!(" bctx read --mode aggressive -- cargo test 2>&1");
println!(" bctx read --mode lines:10-40 -- cat main.rs");
println!(" BCTX_MODE=map bctx git log --oneline -30");
println!();
println!(" Demo a mode against sample input:");
println!(" bctx modes --demo signatures");
println!();
}
fn print_json() -> Result<()> {
let arr: Vec<serde_json::Value> = ReadMode::all_named()
.iter()
.map(|m| {
serde_json::json!({
"name": m.name(),
"description": m.description(),
"lens_stack": m.lens_stack(),
"savings_estimate": m.savings_estimate(),
"use_case": m.use_case()
})
})
.collect();
println!("{}", serde_json::to_string_pretty(&arr)?);
Ok(())
}
const DEMO_SOURCE: &str = r#"use std::collections::HashMap;
/// Counts word frequencies in text.
pub fn word_freq(text: &str) -> HashMap<String, usize> {
let mut map: HashMap<String, usize> = HashMap::new();
for word in text.split_whitespace() {
*map.entry(word.to_lowercase()).or_insert(0) += 1;
}
map
}
// TODO: add stemming support
// FIXME: doesn't handle punctuation properly
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn counts_single_word() {
let freq = word_freq("hello hello world");
assert_eq!(freq["hello"], 2);
assert_eq!(freq["world"], 1);
}
#[test]
fn empty_string_returns_empty_map() {
assert!(word_freq("").is_empty());
}
}
"#;
fn run_demo(mode_str: &str) -> Result<()> {
let mode = ReadMode::parse(mode_str).ok_or_else(|| {
anyhow::anyhow!("unknown mode '{mode_str}' — run `bctx modes` to list all")
})?;
let ctx = weave::LensContext::new(2000);
let out = mode.apply(DEMO_SOURCE, &ctx);
let is_tty = std::io::stdout().is_terminal();
let sep = " ─────────────────────────────────────────────────────";
println!();
if is_tty {
println!(" \x1b[1mbctx modes --demo {mode_str}\x1b[0m");
} else {
println!(" bctx modes --demo {mode_str}");
}
println!(" Mode: {}", mode.name());
println!(" Stack: {}", mode.lens_stack());
println!(" Savings: {}", mode.savings_estimate());
println!("{sep}");
println!(" INPUT ({} tokens):", out.tokens_before);
println!("{sep}");
for line in DEMO_SOURCE.lines() {
println!(" {line}");
}
println!("{sep}");
println!(
" OUTPUT ({} tokens — {} lenses applied):",
out.tokens_after,
out.applied.len()
);
println!("{sep}");
if out.content.is_empty() {
println!(" (empty — all content filtered)");
} else {
for line in out.content.lines() {
println!(" {line}");
}
}
println!("{sep}");
let saved = out.tokens_before.saturating_sub(out.tokens_after);
let pct = (saved * 100).checked_div(out.tokens_before).unwrap_or(0);
println!(" Saved {} tokens ({}%) via {:?}", saved, pct, out.applied);
println!();
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_named_modes_have_non_empty_metadata() {
for mode in ReadMode::all_named() {
assert!(
!mode.description().is_empty(),
"description empty for {}",
mode.name()
);
assert!(
!mode.use_case().is_empty(),
"use_case empty for {}",
mode.name()
);
assert!(
!mode.lens_stack().is_empty(),
"lens_stack empty for {}",
mode.name()
);
assert!(
!mode.savings_estimate().is_empty(),
"savings_estimate empty for {}",
mode.name()
);
}
}
#[test]
fn all_named_modes_have_unique_names() {
let names: Vec<_> = ReadMode::all_named().iter().map(|m| m.name()).collect();
let unique: std::collections::HashSet<_> = names.iter().collect();
assert_eq!(names.len(), unique.len(), "duplicate mode names: {names:?}");
}
#[test]
fn demo_unknown_mode_errors() {
assert!(run_demo("nonexistent").is_err());
}
#[test]
fn demo_signatures_reduces_tokens() {
let ctx = weave::LensContext::new(2000);
let out = ReadMode::Signatures.apply(DEMO_SOURCE, &ctx);
assert!(
out.tokens_after <= out.tokens_before,
"signatures mode must not expand output"
);
}
#[test]
fn demo_aggressive_reduces_tokens() {
let ctx = weave::LensContext::new(2000);
let out = ReadMode::Aggressive.apply(DEMO_SOURCE, &ctx);
assert!(
out.tokens_after <= out.tokens_before,
"aggressive mode must not expand output"
);
}
#[test]
fn demo_full_is_passthrough() {
let ctx = weave::LensContext::new(2000);
let out = ReadMode::Full.apply(DEMO_SOURCE, &ctx);
assert_eq!(out.content, DEMO_SOURCE);
}
#[test]
fn all_named_returns_nine_modes() {
assert_eq!(ReadMode::all_named().len(), 9);
}
#[test]
fn json_output_is_parseable_and_complete() {
let arr: Vec<serde_json::Value> = ReadMode::all_named()
.iter()
.map(|m| {
serde_json::json!({
"name": m.name(),
"description": m.description(),
"lens_stack": m.lens_stack(),
"savings_estimate": m.savings_estimate(),
"use_case": m.use_case()
})
})
.collect();
let text = serde_json::to_string_pretty(&arr).expect("serialise");
let parsed: Vec<serde_json::Value> = serde_json::from_str(&text).expect("parse");
assert_eq!(parsed.len(), 9);
for item in &parsed {
assert!(item["name"].is_string() && !item["name"].as_str().unwrap().is_empty());
assert!(item["description"].is_string());
assert!(item["lens_stack"].is_string());
assert!(item["savings_estimate"].is_string());
assert!(item["use_case"].is_string());
}
}
#[test]
fn all_modes_can_be_parsed_back_from_name() {
for mode in ReadMode::all_named() {
let name = mode.name();
assert!(
ReadMode::parse(&name).is_some(),
"ReadMode::parse failed for '{name}'"
);
}
}
#[test]
fn demo_source_is_non_empty_rust() {
assert!(
DEMO_SOURCE.contains("fn "),
"DEMO_SOURCE should contain a fn definition"
);
assert!(
DEMO_SOURCE.contains("#[test]"),
"DEMO_SOURCE should contain a test"
);
}
#[test]
fn every_mode_name_matches_all_named_index() {
let modes = ReadMode::all_named();
let names: Vec<_> = modes.iter().map(|m| m.name()).collect();
assert!(names.contains(&"auto".to_string()));
assert!(names.contains(&"aggressive".to_string()));
assert!(names.contains(&"signatures".to_string()));
}
}