visual-cortex 0.1.0

Watch screen regions and receive typed events over async streams when patterns match: OCR, template matching, and pixel conditions on live captures.
Documentation
use visual_cortex_capture::CaptureError;

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error(transparent)]
    Capture(#[from] CaptureError),

    #[error("no capture configured; call SessionBuilder::source() or ::target()")]
    NoSource,

    #[error("watcher name already registered: {0}")]
    DuplicateWatcher(String),

    #[error("watcher {0} has no detector; call .detector() before .subscribe()")]
    MissingDetector(String),

    #[error("invalid template for watcher {0}: {1}")]
    InvalidTemplate(String, String),

    #[error("target-based capture is not supported on this platform yet")]
    UnsupportedPlatform,

    #[error("configure exactly one of .source() or .target(), not both")]
    AmbiguousSource,

    /// Failures from external engine construction (e.g. an OCR backend).
    /// Wraps arbitrary errors so applications returning `visual_cortex::Result` can
    /// use `?` on engine setup via [`Error::engine`].
    #[error("engine error: {0}")]
    Engine(#[source] Box<dyn std::error::Error + Send + Sync>),
}

impl Error {
    /// Wrap an external engine error (OCR backend construction, model
    /// loading, ...) so it flows through `visual_cortex::Result`.
    pub fn engine(err: impl std::error::Error + Send + Sync + 'static) -> Self {
        Error::Engine(Box::new(err))
    }
}

pub type Result<T> = std::result::Result<T, Error>;

#[cfg(test)]
mod tests {
    use super::*;

    #[derive(Debug, thiserror::Error)]
    #[error("model exploded")]
    struct FakeEngineError;

    #[test]
    fn engine_errors_wrap_and_display() {
        let err = Error::engine(FakeEngineError);
        assert_eq!(err.to_string(), "engine error: model exploded");
        assert!(std::error::Error::source(&err).is_some());
    }
}