Skip to main content

apple_vision/
error.rs

1//! Errors from the Vision bridge.
2
3use core::fmt;
4
5use crate::ffi;
6
7/// Top-level error type returned by Vision APIs in this crate.
8#[derive(Debug, Clone, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum VisionError {
11    /// Image at the supplied path could not be loaded.
12    ImageLoadFailed(String),
13    /// `VNImageRequestHandler.perform` returned an error.
14    RequestFailed(String),
15    /// Caller supplied an invalid argument (NUL byte in path, etc.).
16    InvalidArgument(String),
17    /// Catch-all for unmapped statuses from the Swift bridge.
18    Unknown { code: i32, message: String },
19}
20
21impl fmt::Display for VisionError {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        match self {
24            Self::ImageLoadFailed(m) => write!(f, "image load failed: {m}"),
25            Self::RequestFailed(m) => write!(f, "Vision request failed: {m}"),
26            Self::InvalidArgument(m) => write!(f, "invalid argument: {m}"),
27            Self::Unknown { code, message } => write!(f, "vision error {code}: {message}"),
28        }
29    }
30}
31
32impl std::error::Error for VisionError {}
33
34pub(crate) unsafe fn from_swift(status: i32, error_str: *mut core::ffi::c_char) -> VisionError {
35    let message = if error_str.is_null() {
36        String::new()
37    } else {
38        let s = core::ffi::CStr::from_ptr(error_str)
39            .to_string_lossy()
40            .into_owned();
41        ffi::vn_string_free(error_str);
42        s
43    };
44    match status {
45        ffi::status::IMAGE_LOAD_FAILED => VisionError::ImageLoadFailed(message),
46        ffi::status::REQUEST_FAILED => VisionError::RequestFailed(message),
47        ffi::status::INVALID_ARGUMENT => VisionError::InvalidArgument(message),
48        code => VisionError::Unknown { code, message },
49    }
50}