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)]
389 pub struct Win32ScreencapMethod: u64 {
390 const GDI = 1;
391 const FRAME_POOL = 1 << 1;
392 const DXGI_DESKTOP_DUP = 1 << 2;
393 const DXGI_DESKTOP_DUP_WINDOW = 1 << 3;
394 const PRINT_WINDOW = 1 << 4;
395 const SCREEN_DC = 1 << 5;
396 const ALL = !0;
397 const FOREGROUND = Self::DXGI_DESKTOP_DUP_WINDOW.bits() | Self::SCREEN_DC.bits();
398 const BACKGROUND = Self::FRAME_POOL.bits() | Self::PRINT_WINDOW.bits();
399 }
400}
401
402bitflags::bitflags! {
403 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
405 pub struct Win32InputMethod: u64 {
406 const SEIZE = 1;
407 const SEND_MESSAGE = 1 << 1;
408 const POST_MESSAGE = 1 << 2;
409 const LEGACY_EVENT = 1 << 3;
410 const POST_THREAD_MESSAGE = 1 << 4;
411 const SEND_MESSAGE_WITH_CURSOR_POS = 1 << 5;
412 const POST_MESSAGE_WITH_CURSOR_POS = 1 << 6;
413 const SEND_MESSAGE_WITH_WINDOW_POS = 1 << 7;
414 const POST_MESSAGE_WITH_WINDOW_POS = 1 << 8;
415 }
416}
417
418#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
420pub struct RecognitionDetail {
421 pub node_name: String,
423 pub algorithm: AlgorithmEnum,
425 pub hit: bool,
427 pub box_rect: Rect,
429 pub detail: serde_json::Value,
431 #[serde(skip)]
433 pub raw_image: Option<Vec<u8>>,
434 #[serde(skip)]
436 pub draw_images: Vec<Vec<u8>>,
437 #[serde(default)]
439 pub sub_details: Vec<RecognitionDetail>,
440}
441
442impl RecognitionDetail {
443 pub fn as_template_match_result(&self) -> Option<TemplateMatchResult> {
444 serde_json::from_value(self.detail.clone()).ok()
445 }
446
447 pub fn as_feature_match_result(&self) -> Option<FeatureMatchResult> {
448 serde_json::from_value(self.detail.clone()).ok()
449 }
450
451 pub fn as_color_match_result(&self) -> Option<ColorMatchResult> {
452 serde_json::from_value(self.detail.clone()).ok()
453 }
454
455 pub fn as_ocr_result(&self) -> Option<OCRResult> {
456 serde_json::from_value(self.detail.clone()).ok()
457 }
458
459 pub fn as_neural_network_result(&self) -> Option<NeuralNetworkResult> {
460 serde_json::from_value(self.detail.clone()).ok()
461 }
462
463 pub fn as_custom_result(&self) -> Option<CustomRecognitionResult> {
464 serde_json::from_value(self.detail.clone()).ok()
465 }
466}
467
468#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
470pub struct ActionDetail {
471 pub node_name: String,
473 pub action: ActionEnum,
475 pub box_rect: Rect,
477 pub success: bool,
479 pub detail: serde_json::Value,
481}
482
483impl ActionDetail {
484 pub fn as_click_result(&self) -> Option<ClickActionResult> {
485 serde_json::from_value(self.detail.clone()).ok()
486 }
487
488 pub fn as_long_press_result(&self) -> Option<LongPressActionResult> {
489 serde_json::from_value(self.detail.clone()).ok()
490 }
491
492 pub fn as_swipe_result(&self) -> Option<SwipeActionResult> {
493 serde_json::from_value(self.detail.clone()).ok()
494 }
495
496 pub fn as_multi_swipe_result(&self) -> Option<MultiSwipeActionResult> {
497 serde_json::from_value(self.detail.clone()).ok()
498 }
499
500 pub fn as_click_key_result(&self) -> Option<ClickKeyActionResult> {
501 serde_json::from_value(self.detail.clone()).ok()
502 }
503
504 pub fn as_input_text_result(&self) -> Option<InputTextActionResult> {
505 serde_json::from_value(self.detail.clone()).ok()
506 }
507
508 pub fn as_app_result(&self) -> Option<AppActionResult> {
509 serde_json::from_value(self.detail.clone()).ok()
510 }
511
512 pub fn as_scroll_result(&self) -> Option<ScrollActionResult> {
513 serde_json::from_value(self.detail.clone()).ok()
514 }
515
516 pub fn as_touch_result(&self) -> Option<TouchActionResult> {
517 serde_json::from_value(self.detail.clone()).ok()
518 }
519
520 pub fn as_shell_result(&self) -> Option<ShellActionResult> {
521 serde_json::from_value(self.detail.clone()).ok()
522 }
523}
524
525#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
531pub struct ClickActionResult {
532 pub point: Point,
533 pub contact: i32,
534 #[serde(default)]
535 pub pressure: i32,
536}
537
538#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
540pub struct LongPressActionResult {
541 pub point: Point,
542 pub duration: i32,
543 pub contact: i32,
544 #[serde(default)]
545 pub pressure: i32,
546}
547
548#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
550pub struct SwipeActionResult {
551 pub begin: Point,
552 pub end: Vec<Point>,
553 #[serde(default)]
554 pub end_hold: Vec<i32>,
555 #[serde(default)]
556 pub duration: Vec<i32>,
557 #[serde(default)]
558 pub only_hover: bool,
559 #[serde(default)]
560 pub starting: i32,
561 pub contact: i32,
562 #[serde(default)]
563 pub pressure: i32,
564}
565
566#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
568pub struct MultiSwipeActionResult {
569 pub swipes: Vec<SwipeActionResult>,
570}
571
572#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
574pub struct ClickKeyActionResult {
575 pub keycode: Vec<i32>,
576}
577
578#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
580pub struct LongPressKeyActionResult {
581 pub keycode: Vec<i32>,
582 pub duration: i32,
583}
584
585#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
587pub struct InputTextActionResult {
588 pub text: String,
589}
590
591#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
593pub struct AppActionResult {
594 pub package: String,
595}
596
597#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
599pub struct ScrollActionResult {
600 #[serde(default)]
601 pub point: Point,
602 pub dx: i32,
603 pub dy: i32,
604}
605
606#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
608pub struct TouchActionResult {
609 pub contact: i32,
610 pub point: Point,
611 #[serde(default)]
612 pub pressure: i32,
613}
614
615#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
617pub struct ShellActionResult {
618 pub cmd: String,
619 pub shell_timeout: i32,
620 pub success: bool,
621 pub output: String,
622}
623
624#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
626pub struct NodeDetail {
627 pub node_name: String,
628 pub reco_id: MaaId,
630 pub act_id: MaaId,
632 #[serde(default)]
634 pub recognition: Option<RecognitionDetail>,
635 #[serde(default)]
637 pub action: Option<ActionDetail>,
638 pub completed: bool,
640}
641
642#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
644pub struct TaskDetail {
645 pub entry: String,
647 pub node_id_list: Vec<MaaId>,
649 pub status: MaaStatus,
651 #[serde(default)]
653 pub nodes: Vec<Option<NodeDetail>>,
654}
655
656#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
658#[serde(into = "String", from = "String")]
659pub enum AlgorithmEnum {
660 DirectHit,
661 TemplateMatch,
662 FeatureMatch,
663 ColorMatch,
664 OCR,
665 NeuralNetworkClassify,
666 NeuralNetworkDetect,
667 And,
668 Or,
669 Custom,
670 Other(String),
671}
672
673impl From<String> for AlgorithmEnum {
674 fn from(s: String) -> Self {
675 match s.as_str() {
676 "DirectHit" => Self::DirectHit,
677 "TemplateMatch" => Self::TemplateMatch,
678 "FeatureMatch" => Self::FeatureMatch,
679 "ColorMatch" => Self::ColorMatch,
680 "OCR" => Self::OCR,
681 "NeuralNetworkClassify" => Self::NeuralNetworkClassify,
682 "NeuralNetworkDetect" => Self::NeuralNetworkDetect,
683 "And" => Self::And,
684 "Or" => Self::Or,
685 "Custom" => Self::Custom,
686 _ => Self::Other(s),
687 }
688 }
689}
690
691impl From<AlgorithmEnum> for String {
692 fn from(algo: AlgorithmEnum) -> Self {
693 match algo {
694 AlgorithmEnum::DirectHit => "DirectHit".to_string(),
695 AlgorithmEnum::TemplateMatch => "TemplateMatch".to_string(),
696 AlgorithmEnum::FeatureMatch => "FeatureMatch".to_string(),
697 AlgorithmEnum::ColorMatch => "ColorMatch".to_string(),
698 AlgorithmEnum::OCR => "OCR".to_string(),
699 AlgorithmEnum::NeuralNetworkClassify => "NeuralNetworkClassify".to_string(),
700 AlgorithmEnum::NeuralNetworkDetect => "NeuralNetworkDetect".to_string(),
701 AlgorithmEnum::And => "And".to_string(),
702 AlgorithmEnum::Or => "Or".to_string(),
703 AlgorithmEnum::Custom => "Custom".to_string(),
704 AlgorithmEnum::Other(s) => s,
705 }
706 }
707}
708
709impl AlgorithmEnum {
710 pub fn as_str(&self) -> &str {
711 match self {
712 Self::DirectHit => "DirectHit",
713 Self::TemplateMatch => "TemplateMatch",
714 Self::FeatureMatch => "FeatureMatch",
715 Self::ColorMatch => "ColorMatch",
716 Self::OCR => "OCR",
717 Self::NeuralNetworkClassify => "NeuralNetworkClassify",
718 Self::NeuralNetworkDetect => "NeuralNetworkDetect",
719 Self::And => "And",
720 Self::Or => "Or",
721 Self::Custom => "Custom",
722 Self::Other(s) => s.as_str(),
723 }
724 }
725}
726
727#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
729#[serde(into = "String", from = "String")]
730pub enum ActionEnum {
731 DoNothing,
732 Click,
733 LongPress,
734 Swipe,
735 MultiSwipe,
736 TouchDown,
737 TouchMove,
738 TouchUp,
739 ClickKey,
740 LongPressKey,
741 KeyDown,
742 KeyUp,
743 InputText,
744 StartApp,
745 StopApp,
746 StopTask,
747 Scroll,
748 Command,
749 Shell,
750 Custom,
751 Other(String),
752}
753
754impl From<String> for ActionEnum {
755 fn from(s: String) -> Self {
756 match s.as_str() {
757 "DoNothing" => Self::DoNothing,
758 "Click" => Self::Click,
759 "LongPress" => Self::LongPress,
760 "Swipe" => Self::Swipe,
761 "MultiSwipe" => Self::MultiSwipe,
762 "TouchDown" => Self::TouchDown,
763 "TouchMove" => Self::TouchMove,
764 "TouchUp" => Self::TouchUp,
765 "ClickKey" => Self::ClickKey,
766 "LongPressKey" => Self::LongPressKey,
767 "KeyDown" => Self::KeyDown,
768 "KeyUp" => Self::KeyUp,
769 "InputText" => Self::InputText,
770 "StartApp" => Self::StartApp,
771 "StopApp" => Self::StopApp,
772 "StopTask" => Self::StopTask,
773 "Scroll" => Self::Scroll,
774 "Command" => Self::Command,
775 "Shell" => Self::Shell,
776 "Custom" => Self::Custom,
777 _ => Self::Other(s),
778 }
779 }
780}
781
782impl From<ActionEnum> for String {
783 fn from(act: ActionEnum) -> Self {
784 match act {
785 ActionEnum::DoNothing => "DoNothing".to_string(),
786 ActionEnum::Click => "Click".to_string(),
787 ActionEnum::LongPress => "LongPress".to_string(),
788 ActionEnum::Swipe => "Swipe".to_string(),
789 ActionEnum::MultiSwipe => "MultiSwipe".to_string(),
790 ActionEnum::TouchDown => "TouchDown".to_string(),
791 ActionEnum::TouchMove => "TouchMove".to_string(),
792 ActionEnum::TouchUp => "TouchUp".to_string(),
793 ActionEnum::ClickKey => "ClickKey".to_string(),
794 ActionEnum::LongPressKey => "LongPressKey".to_string(),
795 ActionEnum::KeyDown => "KeyDown".to_string(),
796 ActionEnum::KeyUp => "KeyUp".to_string(),
797 ActionEnum::InputText => "InputText".to_string(),
798 ActionEnum::StartApp => "StartApp".to_string(),
799 ActionEnum::StopApp => "StopApp".to_string(),
800 ActionEnum::StopTask => "StopTask".to_string(),
801 ActionEnum::Scroll => "Scroll".to_string(),
802 ActionEnum::Command => "Command".to_string(),
803 ActionEnum::Shell => "Shell".to_string(),
804 ActionEnum::Custom => "Custom".to_string(),
805 ActionEnum::Other(s) => s,
806 }
807 }
808}
809
810impl ActionEnum {
811 pub fn as_str(&self) -> &str {
812 match self {
813 Self::DoNothing => "DoNothing",
814 Self::Click => "Click",
815 Self::LongPress => "LongPress",
816 Self::Swipe => "Swipe",
817 Self::MultiSwipe => "MultiSwipe",
818 Self::TouchDown => "TouchDown",
819 Self::TouchMove => "TouchMove",
820 Self::TouchUp => "TouchUp",
821 Self::ClickKey => "ClickKey",
822 Self::LongPressKey => "LongPressKey",
823 Self::KeyDown => "KeyDown",
824 Self::KeyUp => "KeyUp",
825 Self::InputText => "InputText",
826 Self::StartApp => "StartApp",
827 Self::StopApp => "StopApp",
828 Self::StopTask => "StopTask",
829 Self::Scroll => "Scroll",
830 Self::Command => "Command",
831 Self::Shell => "Shell",
832 Self::Custom => "Custom",
833 Self::Other(s) => s.as_str(),
834 }
835 }
836}
837
838#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
840#[non_exhaustive]
841pub enum NotificationType {
842 Starting,
843 Succeeded,
844 Failed,
845 Unknown,
846}
847
848impl NotificationType {
849 pub fn from_message(msg: &str) -> Self {
850 if msg.ends_with(".Starting") {
851 Self::Starting
852 } else if msg.ends_with(".Succeeded") {
853 Self::Succeeded
854 } else if msg.ends_with(".Failed") {
855 Self::Failed
856 } else {
857 Self::Unknown
858 }
859 }
860}
861
862#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
865pub struct BoxAndScore {
866 #[serde(rename = "box")]
867 pub box_rect: (i32, i32, i32, i32),
868 pub score: f64,
869}
870
871#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
872pub struct BoxAndCount {
873 #[serde(rename = "box")]
874 pub box_rect: (i32, i32, i32, i32),
875 pub count: i32,
876}
877
878pub type TemplateMatchResult = BoxAndScore;
879pub type FeatureMatchResult = BoxAndCount;
880pub type ColorMatchResult = BoxAndCount;
881
882#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
883pub struct OCRResult {
884 #[serde(flatten)]
885 pub base: BoxAndScore,
886 pub text: String,
887}
888
889#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
890pub struct NeuralNetworkResult {
891 #[serde(flatten)]
892 pub base: BoxAndScore,
893 pub cls_index: i32,
894 pub label: String,
895}
896
897pub type NeuralNetworkClassifyResult = NeuralNetworkResult;
898pub type NeuralNetworkDetectResult = NeuralNetworkResult;
899
900#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
901pub struct CustomRecognitionResult {
902 #[serde(rename = "box")]
903 pub box_rect: (i32, i32, i32, i32),
904 pub detail: serde_json::Value,
905}