Skip to main content

visionkit/
image_analysis.rs

1use core::ffi::{c_char, c_void};
2use core::ptr;
3
4use crate::error::VisionKitError;
5use crate::ffi;
6use crate::image_analyzer::ImageAnalysisTypes;
7use crate::private::{error_from_status, string_from_ptr};
8
9/// Wraps the VisionKit ImageAnalysis counterpart.
10pub struct ImageAnalysis {
11    pub(crate) token: *mut c_void,
12}
13
14impl Drop for ImageAnalysis {
15    fn drop(&mut self) {
16        if !self.token.is_null() {
17            unsafe { ffi::image_analysis::vk_image_analysis_release(self.token) };
18            self.token = ptr::null_mut();
19        }
20    }
21}
22
23impl ImageAnalysis {
24    pub(crate) fn from_token(token: *mut c_void) -> Self {
25        Self { token }
26    }
27
28    pub(crate) fn raw_token(&self) -> *mut c_void {
29        self.token
30    }
31
32    /// Returns the transcript generated by VisionKit.
33    pub fn transcript(&self) -> Result<String, VisionKitError> {
34        let mut transcript: *mut c_char = ptr::null_mut();
35        let mut err_msg: *mut c_char = ptr::null_mut();
36        let status = unsafe {
37            ffi::image_analysis::vk_image_analysis_transcript(
38                self.token,
39                &mut transcript,
40                &mut err_msg,
41            )
42        };
43        if status == ffi::status::OK {
44            unsafe { string_from_ptr(transcript, "image analysis transcript") }
45        } else {
46            Err(unsafe { error_from_status(status, err_msg) })
47        }
48    }
49
50    /// Returns whether VisionKit found results for the requested analysis types.
51    pub fn has_results(&self, analysis_types: ImageAnalysisTypes) -> Result<bool, VisionKitError> {
52        let mut has_results = 0;
53        let mut err_msg: *mut c_char = ptr::null_mut();
54        let status = unsafe {
55            ffi::image_analysis::vk_image_analysis_has_results(
56                self.token,
57                analysis_types.bits(),
58                &mut has_results,
59                &mut err_msg,
60            )
61        };
62        if status == ffi::status::OK {
63            Ok(has_results != 0)
64        } else {
65            Err(unsafe { error_from_status(status, err_msg) })
66        }
67    }
68}