Skip to main content

visual_cortex/
error.rs

1use visual_cortex_capture::CaptureError;
2
3#[derive(Debug, thiserror::Error)]
4pub enum Error {
5    #[error(transparent)]
6    Capture(#[from] CaptureError),
7
8    #[error("no capture configured; call SessionBuilder::source() or ::target()")]
9    NoSource,
10
11    #[error("watcher name already registered: {0}")]
12    DuplicateWatcher(String),
13
14    #[error("watcher {0} has no detector; call .detector() before .subscribe()")]
15    MissingDetector(String),
16
17    #[error("invalid template for watcher {0}: {1}")]
18    InvalidTemplate(String, String),
19
20    #[error("target-based capture is not supported on this platform yet")]
21    UnsupportedPlatform,
22
23    #[error("configure exactly one of .source() or .target(), not both")]
24    AmbiguousSource,
25
26    /// Failures from external engine construction (e.g. an OCR backend).
27    /// Wraps arbitrary errors so applications returning `visual_cortex::Result` can
28    /// use `?` on engine setup via [`Error::engine`].
29    #[error("engine error: {0}")]
30    Engine(#[source] Box<dyn std::error::Error + Send + Sync>),
31}
32
33impl Error {
34    /// Wrap an external engine error (OCR backend construction, model
35    /// loading, ...) so it flows through `visual_cortex::Result`.
36    pub fn engine(err: impl std::error::Error + Send + Sync + 'static) -> Self {
37        Error::Engine(Box::new(err))
38    }
39}
40
41pub type Result<T> = std::result::Result<T, Error>;
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[derive(Debug, thiserror::Error)]
48    #[error("model exploded")]
49    struct FakeEngineError;
50
51    #[test]
52    fn engine_errors_wrap_and_display() {
53        let err = Error::engine(FakeEngineError);
54        assert_eq!(err.to_string(), "engine error: model exploded");
55        assert!(std::error::Error::source(&err).is_some());
56    }
57}