Skip to main content

codefold_core/
lib.rs

1//! codefold — structural code reader for LLM agents.
2//!
3//! `Read`, with zoom levels.
4
5pub mod error;
6mod go;
7mod language;
8mod level;
9mod options;
10mod parse;
11mod python;
12mod result;
13mod rust;
14mod tokens;
15mod typescript;
16
17pub use error::Error;
18pub use language::Language;
19pub use level::Level;
20pub use options::Options;
21pub use result::{FoldResult, Symbol, SymbolKind};
22
23use std::fs;
24use std::path::Path;
25
26pub type Result<T> = std::result::Result<T, Error>;
27
28/// Read `path` at the requested zoom `level`.
29pub fn read(path: &Path, level: Level) -> Result<FoldResult> {
30    read_opts(path, Options::new(level))
31}
32
33/// Read `path` with full options (level + focus).
34pub fn read_opts(path: &Path, opts: Options) -> Result<FoldResult> {
35    let language = Language::detect(path)?;
36    let source = fs::read_to_string(path).map_err(|source| Error::Io {
37        path: path.into(),
38        source,
39    })?;
40
41    if opts.level == Level::Full {
42        let tokens_est = tokens::estimate(&source);
43        return Ok(FoldResult {
44            content: source,
45            symbols: Vec::new(),
46            hidden_ranges: Vec::new(),
47            language: language.name().to_string(),
48            tokens_est,
49        });
50    }
51
52    let tree = parse::parse(language, &source).map_err(|_| Error::Parse { path: path.into() })?;
53
54    let (content, symbols, hidden_ranges) = match language {
55        Language::Python => {
56            let out = python::render(&source, &tree, opts.level, &opts.focus);
57            (out.content, out.symbols, out.hidden_ranges)
58        }
59        Language::TypeScript => {
60            let out = typescript::render(&source, &tree, opts.level, &opts.focus);
61            (out.content, out.symbols, out.hidden_ranges)
62        }
63        Language::Rust => {
64            let out = rust::render(&source, &tree, opts.level, &opts.focus);
65            (out.content, out.symbols, out.hidden_ranges)
66        }
67        Language::Go => {
68            let out = go::render(&source, &tree, opts.level, &opts.focus);
69            (out.content, out.symbols, out.hidden_ranges)
70        }
71    };
72
73    let tokens_est = tokens::estimate(&content);
74    Ok(FoldResult {
75        content,
76        symbols,
77        hidden_ranges,
78        language: language.name().to_string(),
79        tokens_est,
80    })
81}