1use serde::{Deserialize, Deserializer, Serialize, de::DeserializeOwned};
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 #[serde(default)]
327 pub color_filter: String,
328}
329
330#[derive(Serialize, Deserialize, Debug, Clone)]
334pub struct NeuralNetworkClassify {
335 pub model: String,
337 #[serde(default, deserialize_with = "scalar_or_vec")]
339 pub expected: Vec<i32>,
340 #[serde(default = "default_roi_zero")]
342 pub roi: Target,
343 #[serde(default)]
345 pub roi_offset: Rect,
346 #[serde(default)]
348 pub labels: Vec<String>,
349 #[serde(default = "default_order_by")]
351 pub order_by: String,
352 #[serde(default)]
354 pub index: i32,
355}
356
357#[derive(Serialize, Deserialize, Debug, Clone)]
361pub struct NeuralNetworkDetect {
362 pub model: String,
364 #[serde(default, deserialize_with = "scalar_or_vec")]
366 pub expected: Vec<i32>,
367 #[serde(default = "default_roi_zero")]
369 pub roi: Target,
370 #[serde(default)]
372 pub roi_offset: Rect,
373 #[serde(default)]
375 pub labels: Vec<String>,
376 #[serde(
378 default = "default_detect_threshold",
379 deserialize_with = "scalar_or_vec"
380 )]
381 pub threshold: Vec<f64>,
382 #[serde(default = "default_order_by")]
384 pub order_by: String,
385 #[serde(default)]
387 pub index: i32,
388}
389
390#[derive(Serialize, Deserialize, Debug, Clone)]
394pub struct CustomRecognition {
395 pub custom_recognition: String,
397 #[serde(default = "default_roi_zero")]
399 pub roi: Target,
400 #[serde(default)]
402 pub roi_offset: Rect,
403 #[serde(default)]
405 pub custom_recognition_param: Value,
406}
407
408#[derive(Serialize, Deserialize, Debug, Clone, Default)]
412pub struct And {
413 #[serde(default)]
415 pub all_of: Vec<RecognitionRef>,
416 #[serde(default)]
418 pub box_index: i32,
419}
420
421#[derive(Serialize, Deserialize, Debug, Clone, Default)]
425pub struct Or {
426 #[serde(default)]
428 pub any_of: Vec<RecognitionRef>,
429}
430
431#[derive(Serialize, Deserialize, Debug, Clone)]
450#[serde(tag = "type", content = "param")]
451pub enum Action {
452 DoNothing(DoNothing),
453 Click(Click),
454 LongPress(LongPress),
455 Swipe(Swipe),
456 MultiSwipe(MultiSwipe),
457 TouchDown(Touch),
458 TouchMove(Touch),
459 TouchUp(TouchUp),
460 ClickKey(KeyList),
461 LongPressKey(LongPressKey),
462 KeyDown(SingleKey),
463 KeyUp(SingleKey),
464 InputText(InputText),
465 StartApp(App),
466 StopApp(App),
467 StopTask(StopTask),
468 Scroll(Scroll),
469 Command(Command),
470 Shell(Shell),
471 Custom(CustomAction),
472}
473
474#[derive(Serialize, Deserialize, Debug, Clone, Default)]
478pub struct DoNothing {}
479
480#[derive(Serialize, Deserialize, Debug, Clone, Default)]
482pub struct StopTask {}
483
484#[derive(Serialize, Deserialize, Debug, Clone, Default)]
488pub struct Click {
489 #[serde(default)]
491 pub target: Target,
492 #[serde(default)]
494 pub target_offset: Rect,
495 #[serde(default)]
497 pub contact: i32,
498 #[serde(default = "default_pressure")]
500 pub pressure: i32,
501}
502
503#[derive(Serialize, Deserialize, Debug, Clone)]
507pub struct LongPress {
508 #[serde(default)]
510 pub target: Target,
511 #[serde(default)]
513 pub target_offset: Rect,
514 #[serde(default = "default_long_press_duration")]
516 pub duration: i32,
517 #[serde(default)]
519 pub contact: i32,
520 #[serde(default = "default_pressure")]
522 pub pressure: i32,
523}
524
525#[derive(Serialize, Deserialize, Debug, Clone)]
529pub struct Swipe {
530 #[serde(default)]
532 pub starting: i32,
533 #[serde(default)]
535 pub begin: Target,
536 #[serde(default)]
538 pub begin_offset: Rect,
539 #[serde(
541 default = "default_target_list_true",
542 deserialize_with = "scalar_or_vec"
543 )]
544 pub end: Vec<Target>,
545 #[serde(default = "default_rect_list_zero", deserialize_with = "scalar_or_vec")]
547 pub end_offset: Vec<Rect>,
548 #[serde(default = "default_i32_list_zero", deserialize_with = "scalar_or_vec")]
550 pub end_hold: Vec<i32>,
551 #[serde(default = "default_duration_list", deserialize_with = "scalar_or_vec")]
553 pub duration: Vec<i32>,
554 #[serde(default)]
556 pub only_hover: bool,
557 #[serde(default)]
559 pub contact: i32,
560 #[serde(default = "default_pressure")]
562 pub pressure: i32,
563}
564
565#[derive(Serialize, Deserialize, Debug, Clone)]
569pub struct MultiSwipe {
570 #[serde(default)]
572 pub swipes: Vec<Swipe>,
573}
574
575#[derive(Serialize, Deserialize, Debug, Clone)]
579pub struct Touch {
580 #[serde(default)]
582 pub contact: i32,
583 #[serde(default)]
585 pub target: Target,
586 #[serde(default)]
588 pub target_offset: Rect,
589 #[serde(default)]
591 pub pressure: i32,
592}
593
594#[derive(Serialize, Deserialize, Debug, Clone)]
596pub struct TouchUp {
597 #[serde(default)]
599 pub contact: i32,
600}
601
602#[derive(Serialize, Deserialize, Debug, Clone)]
604pub struct LongPressKey {
605 #[serde(deserialize_with = "scalar_or_vec")]
607 pub key: Vec<i32>,
608 #[serde(default = "default_long_press_duration")]
610 pub duration: i32,
611}
612
613#[derive(Serialize, Deserialize, Debug, Clone)]
615pub struct KeyList {
616 #[serde(deserialize_with = "scalar_or_vec")]
618 pub key: Vec<i32>,
619}
620
621#[derive(Serialize, Deserialize, Debug, Clone)]
623pub struct SingleKey {
624 pub key: i32,
626}
627
628#[derive(Serialize, Deserialize, Debug, Clone)]
630pub struct InputText {
631 pub input_text: String,
633}
634
635#[derive(Serialize, Deserialize, Debug, Clone)]
637pub struct App {
638 pub package: String,
640}
641
642#[derive(Serialize, Deserialize, Debug, Clone, Default)]
644pub struct Scroll {
645 #[serde(default)]
647 pub target: Target,
648 #[serde(default)]
650 pub target_offset: Rect,
651 #[serde(default)]
653 pub dx: i32,
654 #[serde(default)]
656 pub dy: i32,
657}
658
659#[derive(Serialize, Deserialize, Debug, Clone)]
661pub struct Command {
662 pub exec: String,
664 #[serde(default)]
666 pub args: Vec<String>,
667 #[serde(default)]
669 pub detach: bool,
670}
671
672#[derive(Serialize, Deserialize, Debug, Clone)]
674pub struct Shell {
675 pub cmd: String,
677 #[serde(default = "default_timeout")]
679 pub shell_timeout: i32,
680}
681
682#[derive(Serialize, Deserialize, Debug, Clone)]
686pub struct CustomAction {
687 pub custom_action: String,
689 #[serde(default)]
691 pub target: Target,
692 #[serde(default)]
694 pub custom_action_param: Value,
695 #[serde(default)]
697 pub target_offset: Rect,
698}
699
700#[derive(Serialize, Deserialize, Debug, Clone)]
706pub struct PipelineData {
707 pub recognition: Recognition,
709 pub action: Action,
711 #[serde(default)]
713 pub next: Vec<NodeAttr>,
714 #[serde(default = "default_rate_limit")]
716 pub rate_limit: i32,
717 #[serde(default = "default_timeout")]
719 pub timeout: i32,
720 #[serde(default)]
722 pub on_error: Vec<NodeAttr>,
723 #[serde(default)]
725 pub anchor: Anchor,
726 #[serde(default)]
728 pub inverse: bool,
729 #[serde(default = "default_enabled")]
731 pub enabled: bool,
732 #[serde(default = "default_pre_delay")]
734 pub pre_delay: i32,
735 #[serde(default = "default_post_delay")]
737 pub post_delay: i32,
738 #[serde(default)]
740 pub pre_wait_freezes: Option<WaitFreezes>,
741 #[serde(default)]
743 pub post_wait_freezes: Option<WaitFreezes>,
744 #[serde(default = "default_repeat")]
746 pub repeat: i32,
747 #[serde(default)]
749 pub repeat_delay: i32,
750 #[serde(default)]
752 pub repeat_wait_freezes: Option<WaitFreezes>,
753 #[serde(default = "default_max_hit")]
755 pub max_hit: u32,
756 #[serde(default)]
758 pub focus: Option<Value>,
759 #[serde(default)]
761 pub attach: Option<Value>,
762}
763
764fn default_wait_time() -> i32 {
767 1
768}
769fn default_wait_threshold() -> f64 {
770 0.95
771}
772fn default_wait_method() -> i32 {
773 5
774}
775fn default_rate_limit() -> i32 {
776 1000
777}
778fn default_timeout() -> i32 {
779 20000
780}
781fn default_threshold() -> Vec<f64> {
782 vec![0.7]
783}
784fn default_order_by() -> String {
785 "Horizontal".to_string()
786}
787fn default_template_method() -> i32 {
788 5
789}
790fn default_detector() -> String {
791 "SIFT".to_string()
792}
793fn default_feature_count() -> i32 {
794 4
795}
796fn default_feature_ratio() -> f64 {
797 0.6
798}
799fn default_color_method() -> i32 {
800 4
801} fn default_count_one() -> i32 {
803 1
804}
805fn default_ocr_threshold() -> f64 {
806 0.3
807}
808fn default_detect_threshold() -> Vec<f64> {
809 vec![0.3]
810}
811fn default_pressure() -> i32 {
812 1
813}
814fn default_long_press_duration() -> i32 {
815 1000
816}
817fn default_target_list_true() -> Vec<Target> {
818 vec![Target::Bool(true)]
819}
820fn default_rect_list_zero() -> Vec<Rect> {
821 vec![(0, 0, 0, 0).into()]
822}
823fn default_i32_list_zero() -> Vec<i32> {
824 vec![0]
825}
826fn default_duration_list() -> Vec<i32> {
827 vec![200]
828}
829fn default_enabled() -> bool {
830 true
831}
832fn default_pre_delay() -> i32 {
833 200
834}
835fn default_post_delay() -> i32 {
836 200
837}
838fn default_repeat() -> i32 {
839 1
840}
841fn default_max_hit() -> u32 {
842 u32::MAX
843}
844fn default_roi_zero() -> Target {
845 Target::Rect((0, 0, 0, 0).into())
846}