Skip to main content

tess/
open.rs

1//! Helper to open a file source, applying the live-mode wrapper and/or
2//! preprocessor as configured. Factored out of `main.rs` so that `app.rs`
3//! can also call it when switching files via colon-prompt commands.
4
5use crate::cli::Args;
6use crate::error::{Error, Result};
7use crate::source::{FileSource, LiveFileSource, MemorySource, Source};
8
9/// Open a single source file using the same pipeline as startup:
10/// preprocessor (if configured), live-mode wrapper (if --live).
11///
12/// Returns the boxed Source, the user-facing label, and any preprocess
13/// stderr that should be surfaced in the status line.
14///
15/// Content-type detection and the prettify wrapper are NOT applied here —
16/// they are handled at startup (or not at all on file-switch).
17pub fn open_source_for_path(
18    path: &std::path::Path,
19    args: &Args,
20    preprocessor: Option<&crate::preprocess::Preprocessor>,
21) -> Result<(Box<dyn Source>, String, Option<String>)> {
22    let label = path.display().to_string();
23    if args.live {
24        let lfs = LiveFileSource::open(path).map_err(|source| {
25            if let std::io::ErrorKind::InvalidInput = source.kind() {
26                Error::NotAFile { path: path.to_path_buf() }
27            } else {
28                Error::OpenFile { path: path.to_path_buf(), source }
29            }
30        })?;
31        return Ok((Box::new(lfs), label, None));
32    }
33    if let Some(p) = preprocessor {
34        match crate::preprocess::run(p, path) {
35            crate::preprocess::PreprocessResult::Bytes(bytes) => {
36                return Ok((Box::new(MemorySource::new(bytes)), label, None));
37            }
38            crate::preprocess::PreprocessResult::Failed { stderr } => {
39                let fs = FileSource::open(path).map_err(|source| {
40                    if let std::io::ErrorKind::InvalidInput = source.kind() {
41                        Error::NotAFile { path: path.to_path_buf() }
42                    } else {
43                        Error::OpenFile { path: path.to_path_buf(), source }
44                    }
45                })?;
46                return Ok((Box::new(fs), label, Some(stderr)));
47            }
48        }
49    }
50    let fs = FileSource::open(path).map_err(|source| {
51        if let std::io::ErrorKind::InvalidInput = source.kind() {
52            Error::NotAFile { path: path.to_path_buf() }
53        } else {
54            Error::OpenFile { path: path.to_path_buf(), source }
55        }
56    })?;
57    Ok((Box::new(fs), label, None))
58}