1use crate::sys;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
12pub struct MaaStatus(pub i32);
13
14pub type MaaId = i64;
16
17impl MaaStatus {
18 pub const INVALID: Self = Self(sys::MaaStatusEnum_MaaStatus_Invalid as i32);
19 pub const PENDING: Self = Self(sys::MaaStatusEnum_MaaStatus_Pending as i32);
20 pub const RUNNING: Self = Self(sys::MaaStatusEnum_MaaStatus_Running as i32);
21 pub const SUCCEEDED: Self = Self(sys::MaaStatusEnum_MaaStatus_Succeeded as i32);
22 pub const FAILED: Self = Self(sys::MaaStatusEnum_MaaStatus_Failed as i32);
23
24 pub fn is_success(&self) -> bool {
26 *self == Self::SUCCEEDED
27 }
28
29 pub fn succeeded(&self) -> bool {
31 *self == Self::SUCCEEDED
32 }
33
34 pub fn is_failed(&self) -> bool {
36 *self == Self::FAILED
37 }
38
39 pub fn failed(&self) -> bool {
41 *self == Self::FAILED
42 }
43
44 pub fn done(&self) -> bool {
46 *self == Self::SUCCEEDED || *self == Self::FAILED
47 }
48
49 pub fn pending(&self) -> bool {
51 *self == Self::PENDING
52 }
53
54 pub fn running(&self) -> bool {
56 *self == Self::RUNNING
57 }
58}
59
60impl fmt::Display for MaaStatus {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 match *self {
63 Self::INVALID => write!(f, "Invalid"),
64 Self::PENDING => write!(f, "Pending"),
65 Self::RUNNING => write!(f, "Running"),
66 Self::SUCCEEDED => write!(f, "Succeeded"),
67 Self::FAILED => write!(f, "Failed"),
68 _ => write!(f, "Unknown({})", self.0),
69 }
70 }
71}
72
73pub fn check_bool(ret: sys::MaaBool) -> crate::MaaResult<()> {
74 if ret != 0 {
75 Ok(())
76 } else {
77 Err(crate::MaaError::FrameworkError(0))
78 }
79}
80
81impl From<i32> for MaaStatus {
82 fn from(value: i32) -> Self {
83 Self(value)
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Default)]
94#[serde(from = "RectDef")]
95pub struct Rect {
96 pub x: i32,
97 pub y: i32,
98 pub width: i32,
99 pub height: i32,
100}
101
102impl Serialize for Rect {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: serde::Serializer,
106 {
107 (self.x, self.y, self.width, self.height).serialize(serializer)
108 }
109}
110
111#[derive(Deserialize)]
113#[serde(untagged)]
114enum RectDef {
115 Map {
116 x: i32,
117 y: i32,
118 #[serde(alias = "w")]
119 width: i32,
120 #[serde(alias = "h")]
121 height: i32,
122 },
123 Array(i32, i32, i32, i32),
124}
125
126impl From<RectDef> for Rect {
127 fn from(def: RectDef) -> Self {
128 match def {
129 RectDef::Map {
130 x,
131 y,
132 width,
133 height,
134 } => Rect {
135 x,
136 y,
137 width,
138 height,
139 },
140 RectDef::Array(x, y, w, h) => Rect {
141 x,
142 y,
143 width: w,
144 height: h,
145 },
146 }
147 }
148}
149
150impl From<(i32, i32, i32, i32)> for Rect {
151 fn from(tuple: (i32, i32, i32, i32)) -> Self {
152 Self {
153 x: tuple.0,
154 y: tuple.1,
155 width: tuple.2,
156 height: tuple.3,
157 }
158 }
159}
160
161impl From<sys::MaaRect> for Rect {
162 fn from(r: sys::MaaRect) -> Self {
163 Self {
164 x: r.x,
165 y: r.y,
166 width: r.width,
167 height: r.height,
168 }
169 }
170}
171
172impl Rect {
173 pub fn to_tuple(&self) -> (i32, i32, i32, i32) {
174 (self.x, self.y, self.width, self.height)
175 }
176}
177
178impl PartialEq<(i32, i32, i32, i32)> for Rect {
179 fn eq(&self, other: &(i32, i32, i32, i32)) -> bool {
180 self.x == other.0 && self.y == other.1 && self.width == other.2 && self.height == other.3
181 }
182}
183
184impl PartialEq<Rect> for (i32, i32, i32, i32) {
185 fn eq(&self, other: &Rect) -> bool {
186 self.0 == other.x && self.1 == other.y && self.2 == other.width && self.3 == other.height
187 }
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
192pub struct Point {
193 pub x: i32,
194 pub y: i32,
195}
196
197impl Point {
198 pub fn new(x: i32, y: i32) -> Self {
199 Self { x, y }
200 }
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209#[repr(u64)]
210#[non_exhaustive]
211pub enum GamepadType {
212 Xbox360 = 0,
214 DualShock4 = 1,
216}
217
218#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
220#[repr(i32)]
221#[non_exhaustive]
222pub enum GamepadContact {
223 LeftStick = 0,
225 RightStick = 1,
227 LeftTrigger = 2,
229 RightTrigger = 3,
231}
232
233bitflags::bitflags! {
234 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
238 pub struct GamepadButton: u32 {
239 const DPAD_UP = 0x0001;
241 const DPAD_DOWN = 0x0002;
242 const DPAD_LEFT = 0x0004;
243 const DPAD_RIGHT = 0x0008;
244
245 const START = 0x0010;
247 const BACK = 0x0020;
248 const LEFT_THUMB = 0x0040; const RIGHT_THUMB = 0x0080; const LB = 0x0100; const RB = 0x0200; const GUIDE = 0x0400;
257
258 const A = 0x1000;
260 const B = 0x2000;
261 const X = 0x4000;
262 const Y = 0x8000;
263
264 const PS = 0x10000;
266 const TOUCHPAD = 0x20000;
267 }
268}
269
270impl GamepadButton {
271 pub const CROSS: Self = Self::A;
273 pub const CIRCLE: Self = Self::B;
274 pub const SQUARE: Self = Self::X;
275 pub const TRIANGLE: Self = Self::Y;
276 pub const L1: Self = Self::LB;
277 pub const R1: Self = Self::RB;
278 pub const L3: Self = Self::LEFT_THUMB;
279 pub const R3: Self = Self::RIGHT_THUMB;
280 pub const OPTIONS: Self = Self::START;
281 pub const SHARE: Self = Self::BACK;
282}
283
284bitflags::bitflags! {
289 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
293 pub struct ControllerFeature: u64 {
294 const USE_MOUSE_DOWN_UP_INSTEAD_OF_CLICK = 1;
298 const USE_KEY_DOWN_UP_INSTEAD_OF_CLICK = 1 << 1;
301 const NO_SCALING_TOUCH_POINTS = 1 << 2;
304 }
305}
306
307bitflags::bitflags! {
312 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
317 pub struct AdbScreencapMethod: u64 {
318 const ENCODE_TO_FILE_AND_PULL = 1;
319 const ENCODE = 1 << 1;
320 const RAW_WITH_GZIP = 1 << 2;
321 const RAW_BY_NETCAT = 1 << 3;
322 const MINICAP_DIRECT = 1 << 4;
323 const MINICAP_STREAM = 1 << 5;
324 const EMULATOR_EXTRAS = 1 << 6;
325 const ALL = !0;
326 }
327}
328
329impl AdbScreencapMethod {
330 pub const DEFAULT: Self = Self::from_bits_truncate(
332 Self::ALL.bits()
333 & !Self::RAW_BY_NETCAT.bits()
334 & !Self::MINICAP_DIRECT.bits()
335 & !Self::MINICAP_STREAM.bits(),
336 );
337}
338
339impl Default for AdbScreencapMethod {
340 fn default() -> Self {
341 Self::DEFAULT
342 }
343}
344
345bitflags::bitflags! {
346 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
351 pub struct AdbInputMethod: u64 {
352 const ADB_SHELL = 1;
353 const MINITOUCH_AND_ADB_KEY = 1 << 1;
354 const MAATOUCH = 1 << 2;
355 const EMULATOR_EXTRAS = 1 << 3;
356 const ALL = !0;
357 }
358}
359
360impl AdbInputMethod {
361 pub const DEFAULT: Self =
363 Self::from_bits_truncate(Self::ALL.bits() & !Self::EMULATOR_EXTRAS.bits());
364}
365
366impl Default for AdbInputMethod {
367 fn default() -> Self {
368 Self::DEFAULT
369 }
370}
371
372bitflags::bitflags! {
377 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
379 pub struct Win32ScreencapMethod: u64 {
380 const GDI = 1;
381 const FRAME_POOL = 1 << 1;
382 const DXGI_DESKTOP_DUP = 1 << 2;
383 const DXGI_DESKTOP_DUP_WINDOW = 1 << 3;
384 const PRINT_WINDOW = 1 << 4;
385 const SCREEN_DC = 1 << 5;
386 }
387}
388
389bitflags::bitflags! {
390 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
392 pub struct Win32InputMethod: u64 {
393 const SEIZE = 1;
394 const SEND_MESSAGE = 1 << 1;
395 const POST_MESSAGE = 1 << 2;
396 const LEGACY_EVENT = 1 << 3;
397 const POST_THREAD_MESSAGE = 1 << 4;
398 const SEND_MESSAGE_WITH_CURSOR_POS = 1 << 5;
399 const POST_MESSAGE_WITH_CURSOR_POS = 1 << 6;
400 const SEND_MESSAGE_WITH_WINDOW_POS = 1 << 7;
401 const POST_MESSAGE_WITH_WINDOW_POS = 1 << 8;
402 }
403}
404
405#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
407pub struct RecognitionDetail {
408 pub node_name: String,
410 pub algorithm: AlgorithmEnum,
412 pub hit: bool,
414 pub box_rect: Rect,
416 pub detail: serde_json::Value,
418 #[serde(skip)]
420 pub raw_image: Option<Vec<u8>>,
421 #[serde(skip)]
423 pub draw_images: Vec<Vec<u8>>,
424 #[serde(default)]
426 pub sub_details: Vec<RecognitionDetail>,
427}
428
429impl RecognitionDetail {
430 pub fn as_template_match_result(&self) -> Option<TemplateMatchResult> {
431 serde_json::from_value(self.detail.clone()).ok()
432 }
433
434 pub fn as_feature_match_result(&self) -> Option<FeatureMatchResult> {
435 serde_json::from_value(self.detail.clone()).ok()
436 }
437
438 pub fn as_color_match_result(&self) -> Option<ColorMatchResult> {
439 serde_json::from_value(self.detail.clone()).ok()
440 }
441
442 pub fn as_ocr_result(&self) -> Option<OCRResult> {
443 serde_json::from_value(self.detail.clone()).ok()
444 }
445
446 pub fn as_neural_network_result(&self) -> Option<NeuralNetworkResult> {
447 serde_json::from_value(self.detail.clone()).ok()
448 }
449
450 pub fn as_custom_result(&self) -> Option<CustomRecognitionResult> {
451 serde_json::from_value(self.detail.clone()).ok()
452 }
453}
454
455#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
457pub struct ActionDetail {
458 pub node_name: String,
460 pub action: ActionEnum,
462 pub box_rect: Rect,
464 pub success: bool,
466 pub detail: serde_json::Value,
468}
469
470impl ActionDetail {
471 pub fn as_click_result(&self) -> Option<ClickActionResult> {
472 serde_json::from_value(self.detail.clone()).ok()
473 }
474
475 pub fn as_long_press_result(&self) -> Option<LongPressActionResult> {
476 serde_json::from_value(self.detail.clone()).ok()
477 }
478
479 pub fn as_swipe_result(&self) -> Option<SwipeActionResult> {
480 serde_json::from_value(self.detail.clone()).ok()
481 }
482
483 pub fn as_multi_swipe_result(&self) -> Option<MultiSwipeActionResult> {
484 serde_json::from_value(self.detail.clone()).ok()
485 }
486
487 pub fn as_click_key_result(&self) -> Option<ClickKeyActionResult> {
488 serde_json::from_value(self.detail.clone()).ok()
489 }
490
491 pub fn as_input_text_result(&self) -> Option<InputTextActionResult> {
492 serde_json::from_value(self.detail.clone()).ok()
493 }
494
495 pub fn as_app_result(&self) -> Option<AppActionResult> {
496 serde_json::from_value(self.detail.clone()).ok()
497 }
498
499 pub fn as_scroll_result(&self) -> Option<ScrollActionResult> {
500 serde_json::from_value(self.detail.clone()).ok()
501 }
502
503 pub fn as_touch_result(&self) -> Option<TouchActionResult> {
504 serde_json::from_value(self.detail.clone()).ok()
505 }
506
507 pub fn as_shell_result(&self) -> Option<ShellActionResult> {
508 serde_json::from_value(self.detail.clone()).ok()
509 }
510}
511
512#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
518pub struct ClickActionResult {
519 pub point: Point,
520 pub contact: i32,
521}
522
523#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
525pub struct LongPressActionResult {
526 pub point: Point,
527 pub duration: i32,
528 pub contact: i32,
529}
530
531#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
533pub struct SwipeActionResult {
534 pub begin: Point,
535 pub end: Vec<Point>,
536 #[serde(default)]
537 pub end_hold: Vec<i32>,
538 #[serde(default)]
539 pub duration: Vec<i32>,
540 #[serde(default)]
541 pub only_hover: bool,
542 #[serde(default)]
543 pub starting: i32,
544 pub contact: i32,
545}
546
547#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
549pub struct MultiSwipeActionResult {
550 pub swipes: Vec<SwipeActionResult>,
551}
552
553#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
555pub struct ClickKeyActionResult {
556 pub keycode: Vec<i32>,
557}
558
559#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
561pub struct LongPressKeyActionResult {
562 pub keycode: Vec<i32>,
563 pub duration: i32,
564}
565
566#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
568pub struct InputTextActionResult {
569 pub text: String,
570}
571
572#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
574pub struct AppActionResult {
575 pub package: String,
576}
577
578#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
580pub struct ScrollActionResult {
581 pub dx: i32,
582 pub dy: i32,
583}
584
585#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
587pub struct TouchActionResult {
588 pub contact: i32,
589 pub point: Point,
590 #[serde(default)]
591 pub pressure: i32,
592}
593
594#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
596pub struct ShellActionResult {
597 pub cmd: String,
598 pub timeout: i32,
599 pub success: bool,
600 pub output: String,
601}
602
603#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
605pub struct NodeDetail {
606 pub node_name: String,
607 pub reco_id: MaaId,
609 pub act_id: MaaId,
611 #[serde(default)]
613 pub recognition: Option<RecognitionDetail>,
614 #[serde(default)]
616 pub action: Option<ActionDetail>,
617 pub completed: bool,
619}
620
621#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
623pub struct TaskDetail {
624 pub entry: String,
626 pub node_id_list: Vec<MaaId>,
628 pub status: MaaStatus,
630 #[serde(default)]
632 pub nodes: Vec<Option<NodeDetail>>,
633}
634
635#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
637#[serde(into = "String", from = "String")]
638pub enum AlgorithmEnum {
639 DirectHit,
640 TemplateMatch,
641 FeatureMatch,
642 ColorMatch,
643 OCR,
644 NeuralNetworkClassify,
645 NeuralNetworkDetect,
646 And,
647 Or,
648 Custom,
649 Other(String),
650}
651
652impl From<String> for AlgorithmEnum {
653 fn from(s: String) -> Self {
654 match s.as_str() {
655 "DirectHit" => Self::DirectHit,
656 "TemplateMatch" => Self::TemplateMatch,
657 "FeatureMatch" => Self::FeatureMatch,
658 "ColorMatch" => Self::ColorMatch,
659 "OCR" => Self::OCR,
660 "NeuralNetworkClassify" => Self::NeuralNetworkClassify,
661 "NeuralNetworkDetect" => Self::NeuralNetworkDetect,
662 "And" => Self::And,
663 "Or" => Self::Or,
664 "Custom" => Self::Custom,
665 _ => Self::Other(s),
666 }
667 }
668}
669
670impl From<AlgorithmEnum> for String {
671 fn from(algo: AlgorithmEnum) -> Self {
672 match algo {
673 AlgorithmEnum::DirectHit => "DirectHit".to_string(),
674 AlgorithmEnum::TemplateMatch => "TemplateMatch".to_string(),
675 AlgorithmEnum::FeatureMatch => "FeatureMatch".to_string(),
676 AlgorithmEnum::ColorMatch => "ColorMatch".to_string(),
677 AlgorithmEnum::OCR => "OCR".to_string(),
678 AlgorithmEnum::NeuralNetworkClassify => "NeuralNetworkClassify".to_string(),
679 AlgorithmEnum::NeuralNetworkDetect => "NeuralNetworkDetect".to_string(),
680 AlgorithmEnum::And => "And".to_string(),
681 AlgorithmEnum::Or => "Or".to_string(),
682 AlgorithmEnum::Custom => "Custom".to_string(),
683 AlgorithmEnum::Other(s) => s,
684 }
685 }
686}
687
688impl AlgorithmEnum {
689 pub fn as_str(&self) -> &str {
690 match self {
691 Self::DirectHit => "DirectHit",
692 Self::TemplateMatch => "TemplateMatch",
693 Self::FeatureMatch => "FeatureMatch",
694 Self::ColorMatch => "ColorMatch",
695 Self::OCR => "OCR",
696 Self::NeuralNetworkClassify => "NeuralNetworkClassify",
697 Self::NeuralNetworkDetect => "NeuralNetworkDetect",
698 Self::And => "And",
699 Self::Or => "Or",
700 Self::Custom => "Custom",
701 Self::Other(s) => s.as_str(),
702 }
703 }
704}
705
706#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
708#[serde(into = "String", from = "String")]
709pub enum ActionEnum {
710 DoNothing,
711 Click,
712 LongPress,
713 Swipe,
714 MultiSwipe,
715 TouchDown,
716 TouchMove,
717 TouchUp,
718 ClickKey,
719 LongPressKey,
720 KeyDown,
721 KeyUp,
722 InputText,
723 StartApp,
724 StopApp,
725 StopTask,
726 Scroll,
727 Command,
728 Shell,
729 Custom,
730 Other(String),
731}
732
733impl From<String> for ActionEnum {
734 fn from(s: String) -> Self {
735 match s.as_str() {
736 "DoNothing" => Self::DoNothing,
737 "Click" => Self::Click,
738 "LongPress" => Self::LongPress,
739 "Swipe" => Self::Swipe,
740 "MultiSwipe" => Self::MultiSwipe,
741 "TouchDown" => Self::TouchDown,
742 "TouchMove" => Self::TouchMove,
743 "TouchUp" => Self::TouchUp,
744 "ClickKey" => Self::ClickKey,
745 "LongPressKey" => Self::LongPressKey,
746 "KeyDown" => Self::KeyDown,
747 "KeyUp" => Self::KeyUp,
748 "InputText" => Self::InputText,
749 "StartApp" => Self::StartApp,
750 "StopApp" => Self::StopApp,
751 "StopTask" => Self::StopTask,
752 "Scroll" => Self::Scroll,
753 "Command" => Self::Command,
754 "Shell" => Self::Shell,
755 "Custom" => Self::Custom,
756 _ => Self::Other(s),
757 }
758 }
759}
760
761impl From<ActionEnum> for String {
762 fn from(act: ActionEnum) -> Self {
763 match act {
764 ActionEnum::DoNothing => "DoNothing".to_string(),
765 ActionEnum::Click => "Click".to_string(),
766 ActionEnum::LongPress => "LongPress".to_string(),
767 ActionEnum::Swipe => "Swipe".to_string(),
768 ActionEnum::MultiSwipe => "MultiSwipe".to_string(),
769 ActionEnum::TouchDown => "TouchDown".to_string(),
770 ActionEnum::TouchMove => "TouchMove".to_string(),
771 ActionEnum::TouchUp => "TouchUp".to_string(),
772 ActionEnum::ClickKey => "ClickKey".to_string(),
773 ActionEnum::LongPressKey => "LongPressKey".to_string(),
774 ActionEnum::KeyDown => "KeyDown".to_string(),
775 ActionEnum::KeyUp => "KeyUp".to_string(),
776 ActionEnum::InputText => "InputText".to_string(),
777 ActionEnum::StartApp => "StartApp".to_string(),
778 ActionEnum::StopApp => "StopApp".to_string(),
779 ActionEnum::StopTask => "StopTask".to_string(),
780 ActionEnum::Scroll => "Scroll".to_string(),
781 ActionEnum::Command => "Command".to_string(),
782 ActionEnum::Shell => "Shell".to_string(),
783 ActionEnum::Custom => "Custom".to_string(),
784 ActionEnum::Other(s) => s,
785 }
786 }
787}
788
789impl ActionEnum {
790 pub fn as_str(&self) -> &str {
791 match self {
792 Self::DoNothing => "DoNothing",
793 Self::Click => "Click",
794 Self::LongPress => "LongPress",
795 Self::Swipe => "Swipe",
796 Self::MultiSwipe => "MultiSwipe",
797 Self::TouchDown => "TouchDown",
798 Self::TouchMove => "TouchMove",
799 Self::TouchUp => "TouchUp",
800 Self::ClickKey => "ClickKey",
801 Self::LongPressKey => "LongPressKey",
802 Self::KeyDown => "KeyDown",
803 Self::KeyUp => "KeyUp",
804 Self::InputText => "InputText",
805 Self::StartApp => "StartApp",
806 Self::StopApp => "StopApp",
807 Self::StopTask => "StopTask",
808 Self::Scroll => "Scroll",
809 Self::Command => "Command",
810 Self::Shell => "Shell",
811 Self::Custom => "Custom",
812 Self::Other(s) => s.as_str(),
813 }
814 }
815}
816
817#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
819#[non_exhaustive]
820pub enum NotificationType {
821 Starting,
822 Succeeded,
823 Failed,
824 Unknown,
825}
826
827impl NotificationType {
828 pub fn from_message(msg: &str) -> Self {
829 if msg.ends_with(".Starting") {
830 Self::Starting
831 } else if msg.ends_with(".Succeeded") {
832 Self::Succeeded
833 } else if msg.ends_with(".Failed") {
834 Self::Failed
835 } else {
836 Self::Unknown
837 }
838 }
839}
840
841#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
844pub struct BoxAndScore {
845 #[serde(rename = "box")]
846 pub box_rect: (i32, i32, i32, i32),
847 pub score: f64,
848}
849
850#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
851pub struct BoxAndCount {
852 #[serde(rename = "box")]
853 pub box_rect: (i32, i32, i32, i32),
854 pub count: i32,
855}
856
857pub type TemplateMatchResult = BoxAndScore;
858pub type FeatureMatchResult = BoxAndCount;
859pub type ColorMatchResult = BoxAndCount;
860
861#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
862pub struct OCRResult {
863 #[serde(flatten)]
864 pub base: BoxAndScore,
865 pub text: String,
866}
867
868#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
869pub struct NeuralNetworkResult {
870 #[serde(flatten)]
871 pub base: BoxAndScore,
872 pub cls_index: i32,
873 pub label: String,
874}
875
876pub type NeuralNetworkClassifyResult = NeuralNetworkResult;
877pub type NeuralNetworkDetectResult = NeuralNetworkResult;
878
879#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
880pub struct CustomRecognitionResult {
881 #[serde(rename = "box")]
882 pub box_rect: (i32, i32, i32, i32),
883 pub detail: serde_json::Value,
884}