1use core::fmt;
4
5macro_rules! vision_string_enum {
6 (
7 $(#[$meta:meta])*
8 pub enum $name:ident {
9 $( $variant:ident => $value:literal ),+ $(,)?
10 }
11 ) => {
12 $(#[$meta])*
13 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14 pub enum $name {
15 $( $variant ),+
16 }
17
18 impl $name {
19 pub const ALL: &'static [Self] = &[
21 $( Self::$variant ),+
22 ];
23
24 #[must_use]
26 pub const fn as_str(self) -> &'static str {
27 match self {
28 $( Self::$variant => $value ),+
29 }
30 }
31
32 #[allow(clippy::should_implement_trait)]
34 #[must_use]
35 pub fn from_str(value: &str) -> Option<Self> {
36 match value {
37 $( $value => Some(Self::$variant), )+
38 _ => None,
39 }
40 }
41 }
42
43 impl AsRef<str> for $name {
44 fn as_ref(&self) -> &str {
45 self.as_str()
46 }
47 }
48
49 impl fmt::Display for $name {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 f.write_str(self.as_str())
52 }
53 }
54 };
55}
56
57vision_string_enum! {
58 pub enum AnimalIdentifier {
60 Dog => "Dog",
61 Cat => "Cat",
62 }
63}
64
65vision_string_enum! {
66 pub enum BarcodeSymbology {
68 Aztec => "VNBarcodeSymbologyAztec",
69 Codabar => "VNBarcodeSymbologyCodabar",
70 Code128 => "VNBarcodeSymbologyCode128",
71 Code39 => "VNBarcodeSymbologyCode39",
72 Code39Checksum => "VNBarcodeSymbologyCode39Checksum",
73 Code39FullAscii => "VNBarcodeSymbologyCode39FullASCII",
74 Code39FullAsciiChecksum => "VNBarcodeSymbologyCode39FullASCIIChecksum",
75 Code93 => "VNBarcodeSymbologyCode93",
76 Code93i => "VNBarcodeSymbologyCode93i",
77 DataMatrix => "VNBarcodeSymbologyDataMatrix",
78 Ean13 => "VNBarcodeSymbologyEAN13",
79 Ean8 => "VNBarcodeSymbologyEAN8",
80 Gs1DataBar => "VNBarcodeSymbologyGS1DataBar",
81 Gs1DataBarExpanded => "VNBarcodeSymbologyGS1DataBarExpanded",
82 Gs1DataBarLimited => "VNBarcodeSymbologyGS1DataBarLimited",
83 I2of5 => "VNBarcodeSymbologyI2of5",
84 I2of5Checksum => "VNBarcodeSymbologyI2of5Checksum",
85 Itf14 => "VNBarcodeSymbologyITF14",
86 MsiPlessey => "VNBarcodeSymbologyMSIPlessey",
87 MicroPdf417 => "VNBarcodeSymbologyMicroPDF417",
88 MicroQr => "VNBarcodeSymbologyMicroQR",
89 Pdf417 => "VNBarcodeSymbologyPDF417",
90 Qr => "VNBarcodeSymbologyQR",
91 Upce => "VNBarcodeSymbologyUPCE",
92 }
93}
94
95vision_string_enum! {
96 pub enum ComputeStage {
98 Main => "VNComputeStageMain",
99 PostProcessing => "VNComputeStagePostProcessing",
100 }
101}
102
103vision_string_enum! {
104 pub enum ImageOption {
106 Properties => "VNImageOptionProperties",
107 CameraIntrinsics => "VNImageOptionCameraIntrinsics",
108 CiContext => "VNImageOptionCIContext",
109 }
110}
111
112vision_string_enum! {
113 pub enum RecognizedPointGroupKey {
115 All => "VNIPOAll",
116 }
117}
118
119vision_string_enum! {
120 pub enum RecognizedPoint3DGroupKey {
122 All => "VNIPOAll",
123 }
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
128#[repr(usize)]
129pub enum ImageCropAndScaleOption {
130 CenterCrop = 0,
131 ScaleFit = 1,
132 ScaleFill = 2,
133 ScaleFitRotate90Ccw = 0x101,
134 ScaleFillRotate90Ccw = 0x102,
135}
136
137impl ImageCropAndScaleOption {
138 pub const ALL: &'static [Self] = &[
140 Self::CenterCrop,
141 Self::ScaleFit,
142 Self::ScaleFill,
143 Self::ScaleFitRotate90Ccw,
144 Self::ScaleFillRotate90Ccw,
145 ];
146
147 #[must_use]
148 pub const fn as_raw(self) -> usize {
149 self as usize
150 }
151
152 #[must_use]
153 pub const fn from_raw(raw: usize) -> Option<Self> {
154 match raw {
155 0 => Some(Self::CenterCrop),
156 1 => Some(Self::ScaleFit),
157 2 => Some(Self::ScaleFill),
158 0x101 => Some(Self::ScaleFitRotate90Ccw),
159 0x102 => Some(Self::ScaleFillRotate90Ccw),
160 _ => None,
161 }
162 }
163}
164
165#[cfg(feature = "coreml")]
166impl From<ImageCropAndScaleOption> for crate::coreml::CoreMLImageCropAndScaleOption {
167 fn from(value: ImageCropAndScaleOption) -> Self {
168 match value {
169 ImageCropAndScaleOption::CenterCrop => Self::CenterCrop,
170 ImageCropAndScaleOption::ScaleFit => Self::ScaleFit,
171 ImageCropAndScaleOption::ScaleFill => Self::ScaleFill,
172 ImageCropAndScaleOption::ScaleFitRotate90Ccw => Self::ScaleFitRotate90CCW,
173 ImageCropAndScaleOption::ScaleFillRotate90Ccw => Self::ScaleFillRotate90CCW,
174 }
175 }
176}
177
178#[cfg(feature = "coreml")]
179impl From<crate::coreml::CoreMLImageCropAndScaleOption> for ImageCropAndScaleOption {
180 fn from(value: crate::coreml::CoreMLImageCropAndScaleOption) -> Self {
181 match value {
182 crate::coreml::CoreMLImageCropAndScaleOption::CenterCrop => Self::CenterCrop,
183 crate::coreml::CoreMLImageCropAndScaleOption::ScaleFit => Self::ScaleFit,
184 crate::coreml::CoreMLImageCropAndScaleOption::ScaleFill => Self::ScaleFill,
185 crate::coreml::CoreMLImageCropAndScaleOption::ScaleFitRotate90CCW => {
186 Self::ScaleFitRotate90Ccw
187 }
188 crate::coreml::CoreMLImageCropAndScaleOption::ScaleFillRotate90CCW => {
189 Self::ScaleFillRotate90Ccw
190 }
191 }
192 }
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
197#[repr(usize)]
198pub enum ElementType {
199 Unknown = 0,
200 Float32 = 1,
201 Float64 = 2,
202}
203
204impl ElementType {
205 pub const ALL: &'static [Self] = &[Self::Unknown, Self::Float32, Self::Float64];
206
207 #[must_use]
208 pub const fn as_raw(self) -> usize {
209 self as usize
210 }
211
212 #[must_use]
213 pub const fn from_raw(raw: usize) -> Option<Self> {
214 match raw {
215 0 => Some(Self::Unknown),
216 1 => Some(Self::Float32),
217 2 => Some(Self::Float64),
218 _ => None,
219 }
220 }
221
222 #[must_use]
223 pub const fn size_in_bytes(self) -> usize {
224 match self {
225 Self::Unknown => 0,
226 Self::Float32 => 4,
227 Self::Float64 => 8,
228 }
229 }
230}
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
234#[repr(i32)]
235pub enum PointsClassification {
236 Disconnected = 0,
237 OpenPath = 1,
238 ClosedPath = 2,
239}
240
241impl PointsClassification {
242 pub const ALL: &'static [Self] = &[Self::Disconnected, Self::OpenPath, Self::ClosedPath];
243
244 #[must_use]
245 pub const fn as_raw(self) -> i32 {
246 self as i32
247 }
248
249 #[must_use]
250 pub const fn from_raw(raw: i32) -> Option<Self> {
251 match raw {
252 0 => Some(Self::Disconnected),
253 1 => Some(Self::OpenPath),
254 2 => Some(Self::ClosedPath),
255 _ => None,
256 }
257 }
258}
259
260#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
262#[repr(i32)]
263pub enum BarcodeCompositeType {
264 None = 0,
265 Linked = 1,
266 Gs1TypeA = 2,
267 Gs1TypeB = 3,
268 Gs1TypeC = 4,
269}
270
271impl BarcodeCompositeType {
272 pub const ALL: &'static [Self] = &[
273 Self::None,
274 Self::Linked,
275 Self::Gs1TypeA,
276 Self::Gs1TypeB,
277 Self::Gs1TypeC,
278 ];
279
280 #[must_use]
281 pub const fn as_raw(self) -> i32 {
282 self as i32
283 }
284
285 #[must_use]
286 pub const fn from_raw(raw: i32) -> Option<Self> {
287 match raw {
288 0 => Some(Self::None),
289 1 => Some(Self::Linked),
290 2 => Some(Self::Gs1TypeA),
291 3 => Some(Self::Gs1TypeB),
292 4 => Some(Self::Gs1TypeC),
293 _ => None,
294 }
295 }
296}
297
298#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
300#[repr(i32)]
301pub enum VisionErrorCode {
302 TuriCore = -1,
303 Success = 0,
304 RequestCancelled = 1,
305 InvalidFormat = 2,
306 OperationFailed = 3,
307 OutOfBounds = 4,
308 InvalidOption = 5,
309 Io = 6,
310 MissingOption = 7,
311 NotImplemented = 8,
312 Internal = 9,
313 OutOfMemory = 10,
314 Unknown = 11,
315 InvalidOperation = 12,
316 InvalidImage = 13,
317 InvalidArgument = 14,
318 InvalidModel = 15,
319 UnsupportedRevision = 16,
320 DataUnavailable = 17,
321 TimeStampNotFound = 18,
322 UnsupportedRequest = 19,
323 Timeout = 20,
324 UnsupportedComputeStage = 21,
325 UnsupportedComputeDevice = 22,
326}
327
328impl VisionErrorCode {
329 pub const ALL: &'static [Self] = &[
330 Self::TuriCore,
331 Self::Success,
332 Self::RequestCancelled,
333 Self::InvalidFormat,
334 Self::OperationFailed,
335 Self::OutOfBounds,
336 Self::InvalidOption,
337 Self::Io,
338 Self::MissingOption,
339 Self::NotImplemented,
340 Self::Internal,
341 Self::OutOfMemory,
342 Self::Unknown,
343 Self::InvalidOperation,
344 Self::InvalidImage,
345 Self::InvalidArgument,
346 Self::InvalidModel,
347 Self::UnsupportedRevision,
348 Self::DataUnavailable,
349 Self::TimeStampNotFound,
350 Self::UnsupportedRequest,
351 Self::Timeout,
352 Self::UnsupportedComputeStage,
353 Self::UnsupportedComputeDevice,
354 ];
355
356 #[must_use]
357 pub const fn as_raw(self) -> i32 {
358 self as i32
359 }
360
361 #[must_use]
362 pub const fn from_raw(raw: i32) -> Option<Self> {
363 match raw {
364 -1 => Some(Self::TuriCore),
365 0 => Some(Self::Success),
366 1 => Some(Self::RequestCancelled),
367 2 => Some(Self::InvalidFormat),
368 3 => Some(Self::OperationFailed),
369 4 => Some(Self::OutOfBounds),
370 5 => Some(Self::InvalidOption),
371 6 => Some(Self::Io),
372 7 => Some(Self::MissingOption),
373 8 => Some(Self::NotImplemented),
374 9 => Some(Self::Internal),
375 10 => Some(Self::OutOfMemory),
376 11 => Some(Self::Unknown),
377 12 => Some(Self::InvalidOperation),
378 13 => Some(Self::InvalidImage),
379 14 => Some(Self::InvalidArgument),
380 15 => Some(Self::InvalidModel),
381 16 => Some(Self::UnsupportedRevision),
382 17 => Some(Self::DataUnavailable),
383 18 => Some(Self::TimeStampNotFound),
384 19 => Some(Self::UnsupportedRequest),
385 20 => Some(Self::Timeout),
386 21 => Some(Self::UnsupportedComputeStage),
387 22 => Some(Self::UnsupportedComputeDevice),
388 _ => None,
389 }
390 }
391}
392
393pub const VISION_ERROR_DOMAIN: &str = "com.apple.Vision";
395
396extern "C" {
397 static VNVisionVersionNumber: f64;
398}
399
400#[must_use]
402pub fn vision_version_number() -> f64 {
403 unsafe { VNVisionVersionNumber }
405}