1use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
4use serde_json::Value;
5use std::collections::HashMap;
6
7pub use crate::common::Rect;
8
9fn scalar_or_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
14where
15 D: Deserializer<'de>,
16 T: DeserializeOwned,
17{
18 let value = Value::deserialize(deserializer)?;
19
20 if let Ok(vec) = serde_json::from_value::<Vec<T>>(value.clone()) {
22 return Ok(vec);
23 }
24
25 if let Ok(single) = serde_json::from_value::<T>(value) {
27 return Ok(vec![single]);
28 }
29
30 Err(serde::de::Error::custom("Expected T or Vec<T>"))
31}
32
33pub type Roi = (i32, i32, i32, i32);
37
38#[derive(Serialize, Deserialize, Debug, Clone)]
44#[serde(untagged)]
45pub enum Target {
46 Bool(bool),
47 Name(String),
48 Point((i32, i32)),
49 Rect(Rect),
50}
51
52impl Default for Target {
53 fn default() -> Self {
54 Target::Bool(true)
55 }
56}
57
58#[derive(Serialize, Deserialize, Debug, Clone)]
65#[serde(untagged)]
66pub enum Anchor {
67 Name(String),
68 List(Vec<String>),
69 Map(HashMap<String, String>),
70}
71
72impl Default for Anchor {
73 fn default() -> Self {
74 Anchor::List(Vec::new())
75 }
76}
77
78#[derive(Serialize, Deserialize, Debug, Clone, Default)]
84pub struct NodeAttr {
85 #[serde(default)]
87 pub name: String,
88 #[serde(default)]
90 pub jump_back: bool,
91 #[serde(default)]
93 pub anchor: bool,
94}
95
96#[derive(Serialize, Deserialize, Debug, Clone)]
103pub struct WaitFreezes {
104 #[serde(default = "default_wait_time")]
106 pub time: i32,
107 #[serde(default)]
109 pub target: Target,
110 #[serde(default)]
112 pub target_offset: Rect,
113 #[serde(default = "default_wait_threshold")]
115 pub threshold: f64,
116 #[serde(default = "default_wait_method")]
118 pub method: i32,
119 #[serde(default = "default_rate_limit")]
121 pub rate_limit: i32,
122 #[serde(default = "default_timeout")]
124 pub timeout: i32,
125}
126
127impl Default for WaitFreezes {
128 fn default() -> Self {
129 Self {
130 time: default_wait_time(),
131 target: Target::default(),
132 target_offset: Rect::default(),
133 threshold: default_wait_threshold(),
134 method: default_wait_method(),
135 rate_limit: default_rate_limit(),
136 timeout: default_timeout(),
137 }
138 }
139}
140
141#[derive(Serialize, Deserialize, Debug, Clone)]
157#[serde(tag = "type", content = "param")]
158pub enum Recognition {
159 DirectHit(DirectHit),
160 TemplateMatch(TemplateMatch),
161 FeatureMatch(FeatureMatch),
162 ColorMatch(ColorMatch),
163 OCR(OCR),
164 NeuralNetworkClassify(NeuralNetworkClassify),
165 NeuralNetworkDetect(NeuralNetworkDetect),
166 And(And),
167 Or(Or),
168 Custom(CustomRecognition),
169}
170
171#[derive(Serialize, Deserialize, Debug, Clone)]
173#[serde(untagged)]
174pub enum RecognitionRef {
175 NodeName(String),
176 Inline(Recognition),
177}
178
179#[derive(Serialize, Deserialize, Debug, Clone, Default)]
185pub struct DirectHit {
186 #[serde(default = "default_roi_zero")]
188 pub roi: Target,
189 #[serde(default)]
191 pub roi_offset: Rect,
192}
193
194#[derive(Serialize, Deserialize, Debug, Clone)]
198pub struct TemplateMatch {
199 #[serde(deserialize_with = "scalar_or_vec")]
201 pub template: Vec<String>,
202 #[serde(default = "default_roi_zero")]
204 pub roi: Target,
205 #[serde(default)]
207 pub roi_offset: Rect,
208 #[serde(default = "default_threshold", deserialize_with = "scalar_or_vec")]
210 pub threshold: Vec<f64>,
211 #[serde(default = "default_order_by")]
213 pub order_by: String,
214 #[serde(default)]
216 pub index: i32,
217 #[serde(default = "default_template_method")]
219 pub method: i32,
220 #[serde(default)]
222 pub green_mask: bool,
223}
224
225#[derive(Serialize, Deserialize, Debug, Clone)]
229pub struct FeatureMatch {
230 #[serde(deserialize_with = "scalar_or_vec")]
232 pub template: Vec<String>,
233 #[serde(default = "default_roi_zero")]
235 pub roi: Target,
236 #[serde(default)]
238 pub roi_offset: Rect,
239 #[serde(default = "default_detector")]
241 pub detector: String,
242 #[serde(default = "default_order_by")]
244 pub order_by: String,
245 #[serde(default = "default_feature_count")]
247 pub count: i32,
248 #[serde(default)]
250 pub index: i32,
251 #[serde(default)]
253 pub green_mask: bool,
254 #[serde(default = "default_feature_ratio")]
256 pub ratio: f64,
257}
258
259#[derive(Serialize, Deserialize, Debug, Clone)]
263pub struct ColorMatch {
264 #[serde(deserialize_with = "scalar_or_vec")]
266 pub lower: Vec<Vec<i32>>,
267 #[serde(deserialize_with = "scalar_or_vec")]
269 pub upper: Vec<Vec<i32>>,
270 #[serde(default = "default_roi_zero")]
272 pub roi: Target,
273 #[serde(default)]
275 pub roi_offset: Rect,
276 #[serde(default = "default_order_by")]
278 pub order_by: String,
279 #[serde(default = "default_color_method")]
281 pub method: i32,
282 #[serde(default = "default_count_one")]
284 pub count: i32,
285 #[serde(default)]
287 pub index: i32,
288 #[serde(default)]
290 pub connected: bool,
291}
292
293#[derive(Serialize, Deserialize, Debug, Clone, Default)]
297pub struct OCR {
298 #[serde(default, deserialize_with = "scalar_or_vec")]
300 pub expected: Vec<String>,
301 #[serde(default = "default_roi_zero")]
303 pub roi: Target,
304 #[serde(default)]
306 pub roi_offset: Rect,
307 #[serde(default = "default_ocr_threshold")]
309 pub threshold: f64,
310 #[serde(default)]
312 pub replace: Vec<Vec<String>>,
313 #[serde(default = "default_order_by")]
315 pub order_by: String,
316 #[serde(default)]
318 pub index: i32,
319 #[serde(default)]
321 pub only_rec: bool,
322 #[serde(default)]
324 pub model: String,
325}
326
327#[derive(Serialize, Deserialize, Debug, Clone)]
331pub struct NeuralNetworkClassify {
332 pub model: String,
334 #[serde(default, deserialize_with = "scalar_or_vec")]
336 pub expected: Vec<i32>,
337 #[serde(default = "default_roi_zero")]
339 pub roi: Target,
340 #[serde(default)]
342 pub roi_offset: Rect,
343 #[serde(default)]
345 pub labels: Vec<String>,
346 #[serde(default = "default_order_by")]
348 pub order_by: String,
349 #[serde(default)]
351 pub index: i32,
352}
353
354#[derive(Serialize, Deserialize, Debug, Clone)]
358pub struct NeuralNetworkDetect {
359 pub model: String,
361 #[serde(default, deserialize_with = "scalar_or_vec")]
363 pub expected: Vec<i32>,
364 #[serde(default = "default_roi_zero")]
366 pub roi: Target,
367 #[serde(default)]
369 pub roi_offset: Rect,
370 #[serde(default)]
372 pub labels: Vec<String>,
373 #[serde(
375 default = "default_detect_threshold",
376 deserialize_with = "scalar_or_vec"
377 )]
378 pub threshold: Vec<f64>,
379 #[serde(default = "default_order_by")]
381 pub order_by: String,
382 #[serde(default)]
384 pub index: i32,
385}
386
387#[derive(Serialize, Deserialize, Debug, Clone)]
391pub struct CustomRecognition {
392 pub custom_recognition: String,
394 #[serde(default = "default_roi_zero")]
396 pub roi: Target,
397 #[serde(default)]
399 pub roi_offset: Rect,
400 #[serde(default)]
402 pub custom_recognition_param: Value,
403}
404
405#[derive(Serialize, Deserialize, Debug, Clone, Default)]
409pub struct And {
410 #[serde(default)]
412 pub all_of: Vec<RecognitionRef>,
413 #[serde(default)]
415 pub box_index: i32,
416}
417
418#[derive(Serialize, Deserialize, Debug, Clone, Default)]
422pub struct Or {
423 #[serde(default)]
425 pub any_of: Vec<RecognitionRef>,
426}
427
428#[derive(Serialize, Deserialize, Debug, Clone)]
447#[serde(tag = "type", content = "param")]
448pub enum Action {
449 DoNothing(DoNothing),
450 Click(Click),
451 LongPress(LongPress),
452 Swipe(Swipe),
453 MultiSwipe(MultiSwipe),
454 TouchDown(Touch),
455 TouchMove(Touch),
456 TouchUp(TouchUp),
457 ClickKey(KeyList),
458 LongPressKey(LongPressKey),
459 KeyDown(SingleKey),
460 KeyUp(SingleKey),
461 InputText(InputText),
462 StartApp(App),
463 StopApp(App),
464 StopTask(StopTask),
465 Scroll(Scroll),
466 Command(Command),
467 Shell(Shell),
468 Custom(CustomAction),
469}
470
471#[derive(Serialize, Deserialize, Debug, Clone, Default)]
475pub struct DoNothing {}
476
477#[derive(Serialize, Deserialize, Debug, Clone, Default)]
479pub struct StopTask {}
480
481#[derive(Serialize, Deserialize, Debug, Clone, Default)]
485pub struct Click {
486 #[serde(default)]
488 pub target: Target,
489 #[serde(default)]
491 pub target_offset: Rect,
492 #[serde(default)]
494 pub contact: i32,
495 #[serde(default = "default_pressure")]
497 pub pressure: i32,
498}
499
500#[derive(Serialize, Deserialize, Debug, Clone)]
504pub struct LongPress {
505 #[serde(default)]
507 pub target: Target,
508 #[serde(default)]
510 pub target_offset: Rect,
511 #[serde(default = "default_long_press_duration")]
513 pub duration: i32,
514 #[serde(default)]
516 pub contact: i32,
517 #[serde(default = "default_pressure")]
519 pub pressure: i32,
520}
521
522#[derive(Serialize, Deserialize, Debug, Clone)]
526pub struct Swipe {
527 #[serde(default)]
529 pub starting: i32,
530 #[serde(default)]
532 pub begin: Target,
533 #[serde(default)]
535 pub begin_offset: Rect,
536 #[serde(
538 default = "default_target_list_true",
539 deserialize_with = "scalar_or_vec"
540 )]
541 pub end: Vec<Target>,
542 #[serde(default = "default_rect_list_zero", deserialize_with = "scalar_or_vec")]
544 pub end_offset: Vec<Rect>,
545 #[serde(default = "default_i32_list_zero", deserialize_with = "scalar_or_vec")]
547 pub end_hold: Vec<i32>,
548 #[serde(default = "default_duration_list", deserialize_with = "scalar_or_vec")]
550 pub duration: Vec<i32>,
551 #[serde(default)]
553 pub only_hover: bool,
554 #[serde(default)]
556 pub contact: i32,
557 #[serde(default = "default_pressure")]
559 pub pressure: i32,
560}
561
562#[derive(Serialize, Deserialize, Debug, Clone)]
566pub struct MultiSwipe {
567 #[serde(default)]
569 pub swipes: Vec<Swipe>,
570}
571
572#[derive(Serialize, Deserialize, Debug, Clone)]
576pub struct Touch {
577 #[serde(default)]
579 pub contact: i32,
580 #[serde(default)]
582 pub target: Target,
583 #[serde(default)]
585 pub target_offset: Rect,
586 #[serde(default)]
588 pub pressure: i32,
589}
590
591#[derive(Serialize, Deserialize, Debug, Clone)]
593pub struct TouchUp {
594 #[serde(default)]
596 pub contact: i32,
597}
598
599#[derive(Serialize, Deserialize, Debug, Clone)]
601pub struct LongPressKey {
602 #[serde(deserialize_with = "scalar_or_vec")]
604 pub key: Vec<i32>,
605 #[serde(default = "default_long_press_duration")]
607 pub duration: i32,
608}
609
610#[derive(Serialize, Deserialize, Debug, Clone)]
612pub struct KeyList {
613 #[serde(deserialize_with = "scalar_or_vec")]
615 pub key: Vec<i32>,
616}
617
618#[derive(Serialize, Deserialize, Debug, Clone)]
620pub struct SingleKey {
621 pub key: i32,
623}
624
625#[derive(Serialize, Deserialize, Debug, Clone)]
627pub struct InputText {
628 pub input_text: String,
630}
631
632#[derive(Serialize, Deserialize, Debug, Clone)]
634pub struct App {
635 pub package: String,
637}
638
639#[derive(Serialize, Deserialize, Debug, Clone, Default)]
641pub struct Scroll {
642 #[serde(default)]
644 pub target: Target,
645 #[serde(default)]
647 pub target_offset: Rect,
648 #[serde(default)]
650 pub dx: i32,
651 #[serde(default)]
653 pub dy: i32,
654}
655
656#[derive(Serialize, Deserialize, Debug, Clone)]
658pub struct Command {
659 pub exec: String,
661 #[serde(default)]
663 pub args: Vec<String>,
664 #[serde(default)]
666 pub detach: bool,
667}
668
669#[derive(Serialize, Deserialize, Debug, Clone)]
671pub struct Shell {
672 pub cmd: String,
674 #[serde(default = "default_timeout")]
676 pub timeout: i32,
677}
678
679#[derive(Serialize, Deserialize, Debug, Clone)]
683pub struct CustomAction {
684 pub custom_action: String,
686 #[serde(default)]
688 pub target: Target,
689 #[serde(default)]
691 pub custom_action_param: Value,
692 #[serde(default)]
694 pub target_offset: Rect,
695}
696
697#[derive(Serialize, Deserialize, Debug, Clone)]
703pub struct PipelineData {
704 pub recognition: Recognition,
706 pub action: Action,
708 #[serde(default)]
710 pub next: Vec<NodeAttr>,
711 #[serde(default = "default_rate_limit")]
713 pub rate_limit: i32,
714 #[serde(default = "default_timeout")]
716 pub timeout: i32,
717 #[serde(default)]
719 pub on_error: Vec<NodeAttr>,
720 #[serde(default)]
722 pub anchor: Anchor,
723 #[serde(default)]
725 pub inverse: bool,
726 #[serde(default = "default_enabled")]
728 pub enabled: bool,
729 #[serde(default = "default_pre_delay")]
731 pub pre_delay: i32,
732 #[serde(default = "default_post_delay")]
734 pub post_delay: i32,
735 #[serde(default)]
737 pub pre_wait_freezes: Option<WaitFreezes>,
738 #[serde(default)]
740 pub post_wait_freezes: Option<WaitFreezes>,
741 #[serde(default = "default_repeat")]
743 pub repeat: i32,
744 #[serde(default)]
746 pub repeat_delay: i32,
747 #[serde(default)]
749 pub repeat_wait_freezes: Option<WaitFreezes>,
750 #[serde(default = "default_max_hit")]
752 pub max_hit: u32,
753 #[serde(default)]
755 pub focus: Option<Value>,
756 #[serde(default)]
758 pub attach: Option<Value>,
759}
760
761fn default_wait_time() -> i32 {
764 1
765}
766fn default_wait_threshold() -> f64 {
767 0.95
768}
769fn default_wait_method() -> i32 {
770 5
771}
772fn default_rate_limit() -> i32 {
773 1000
774}
775fn default_timeout() -> i32 {
776 20000
777}
778fn default_threshold() -> Vec<f64> {
779 vec![0.7]
780}
781fn default_order_by() -> String {
782 "Horizontal".to_string()
783}
784fn default_template_method() -> i32 {
785 5
786}
787fn default_detector() -> String {
788 "SIFT".to_string()
789}
790fn default_feature_count() -> i32 {
791 4
792}
793fn default_feature_ratio() -> f64 {
794 0.6
795}
796fn default_color_method() -> i32 {
797 4
798} fn default_count_one() -> i32 {
800 1
801}
802fn default_ocr_threshold() -> f64 {
803 0.3
804}
805fn default_detect_threshold() -> Vec<f64> {
806 vec![0.3]
807}
808fn default_pressure() -> i32 {
809 1
810}
811fn default_long_press_duration() -> i32 {
812 1000
813}
814fn default_target_list_true() -> Vec<Target> {
815 vec![Target::Bool(true)]
816}
817fn default_rect_list_zero() -> Vec<Rect> {
818 vec![(0, 0, 0, 0).into()]
819}
820fn default_i32_list_zero() -> Vec<i32> {
821 vec![0]
822}
823fn default_duration_list() -> Vec<i32> {
824 vec![200]
825}
826fn default_enabled() -> bool {
827 true
828}
829fn default_pre_delay() -> i32 {
830 200
831}
832fn default_post_delay() -> i32 {
833 200
834}
835fn default_repeat() -> i32 {
836 1
837}
838fn default_max_hit() -> u32 {
839 u32::MAX
840}
841fn default_roi_zero() -> Target {
842 Target::Rect((0, 0, 0, 0).into())
843}