1pub 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
28pub fn read(path: &Path, level: Level) -> Result<FoldResult> {
30 read_opts(path, Options::new(level))
31}
32
33pub 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}