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)]
451#[serde(tag = "type", content = "param")]
452pub enum Action {
453 DoNothing(DoNothing),
454 Click(Click),
455 LongPress(LongPress),
456 Swipe(Swipe),
457 MultiSwipe(MultiSwipe),
458 TouchDown(Touch),
459 TouchMove(Touch),
460 TouchUp(TouchUp),
461 ClickKey(KeyList),
462 LongPressKey(LongPressKey),
463 KeyDown(SingleKey),
464 KeyUp(SingleKey),
465 InputText(InputText),
466 StartApp(App),
467 StopApp(App),
468 StopTask(StopTask),
469 Scroll(Scroll),
470 Command(Command),
471 Shell(Shell),
472 Screencap(Screencap),
473 Custom(CustomAction),
474}
475
476#[derive(Serialize, Deserialize, Debug, Clone, Default)]
480pub struct DoNothing {}
481
482#[derive(Serialize, Deserialize, Debug, Clone, Default)]
484pub struct StopTask {}
485
486#[derive(Serialize, Deserialize, Debug, Clone, Default)]
490pub struct Click {
491 #[serde(default)]
493 pub target: Target,
494 #[serde(default)]
496 pub target_offset: Rect,
497 #[serde(default)]
499 pub contact: i32,
500 #[serde(default = "default_pressure")]
502 pub pressure: i32,
503}
504
505#[derive(Serialize, Deserialize, Debug, Clone)]
509pub struct LongPress {
510 #[serde(default)]
512 pub target: Target,
513 #[serde(default)]
515 pub target_offset: Rect,
516 #[serde(default = "default_long_press_duration")]
518 pub duration: i32,
519 #[serde(default)]
521 pub contact: i32,
522 #[serde(default = "default_pressure")]
524 pub pressure: i32,
525}
526
527#[derive(Serialize, Deserialize, Debug, Clone)]
531pub struct Swipe {
532 #[serde(default)]
534 pub starting: i32,
535 #[serde(default)]
537 pub begin: Target,
538 #[serde(default)]
540 pub begin_offset: Rect,
541 #[serde(
543 default = "default_target_list_true",
544 deserialize_with = "scalar_or_vec"
545 )]
546 pub end: Vec<Target>,
547 #[serde(default = "default_rect_list_zero", deserialize_with = "scalar_or_vec")]
549 pub end_offset: Vec<Rect>,
550 #[serde(default = "default_i32_list_zero", deserialize_with = "scalar_or_vec")]
552 pub end_hold: Vec<i32>,
553 #[serde(default = "default_duration_list", deserialize_with = "scalar_or_vec")]
555 pub duration: Vec<i32>,
556 #[serde(default)]
558 pub only_hover: bool,
559 #[serde(default)]
561 pub contact: i32,
562 #[serde(default = "default_pressure")]
564 pub pressure: i32,
565}
566
567#[derive(Serialize, Deserialize, Debug, Clone)]
571pub struct MultiSwipe {
572 #[serde(default)]
574 pub swipes: Vec<Swipe>,
575}
576
577#[derive(Serialize, Deserialize, Debug, Clone)]
581pub struct Touch {
582 #[serde(default)]
584 pub contact: i32,
585 #[serde(default)]
587 pub target: Target,
588 #[serde(default)]
590 pub target_offset: Rect,
591 #[serde(default)]
593 pub pressure: i32,
594}
595
596#[derive(Serialize, Deserialize, Debug, Clone)]
598pub struct TouchUp {
599 #[serde(default)]
601 pub contact: i32,
602}
603
604#[derive(Serialize, Deserialize, Debug, Clone)]
606pub struct LongPressKey {
607 #[serde(deserialize_with = "scalar_or_vec")]
609 pub key: Vec<i32>,
610 #[serde(default = "default_long_press_duration")]
612 pub duration: i32,
613}
614
615#[derive(Serialize, Deserialize, Debug, Clone)]
617pub struct KeyList {
618 #[serde(deserialize_with = "scalar_or_vec")]
620 pub key: Vec<i32>,
621}
622
623#[derive(Serialize, Deserialize, Debug, Clone)]
625pub struct SingleKey {
626 pub key: i32,
628}
629
630#[derive(Serialize, Deserialize, Debug, Clone)]
632pub struct InputText {
633 pub input_text: String,
635}
636
637#[derive(Serialize, Deserialize, Debug, Clone)]
639pub struct App {
640 pub package: String,
642}
643
644#[derive(Serialize, Deserialize, Debug, Clone, Default)]
646pub struct Scroll {
647 #[serde(default)]
649 pub target: Target,
650 #[serde(default)]
652 pub target_offset: Rect,
653 #[serde(default)]
655 pub dx: i32,
656 #[serde(default)]
658 pub dy: i32,
659}
660
661#[derive(Serialize, Deserialize, Debug, Clone)]
663pub struct Command {
664 pub exec: String,
666 #[serde(default)]
668 pub args: Vec<String>,
669 #[serde(default)]
671 pub detach: bool,
672}
673
674#[derive(Serialize, Deserialize, Debug, Clone)]
676pub struct Shell {
677 pub cmd: String,
679 #[serde(default = "default_timeout")]
681 pub shell_timeout: i32,
682}
683
684#[derive(Serialize, Deserialize, Debug, Clone, Default)]
686pub struct Screencap {
687 #[serde(default)]
689 pub filename: String,
690 #[serde(default = "default_screencap_format")]
692 pub format: String,
693 #[serde(default = "default_screencap_quality")]
695 pub quality: i32,
696}
697
698#[derive(Serialize, Deserialize, Debug, Clone)]
702pub struct CustomAction {
703 pub custom_action: String,
705 #[serde(default)]
707 pub target: Target,
708 #[serde(default)]
710 pub custom_action_param: Value,
711 #[serde(default)]
713 pub target_offset: Rect,
714}
715
716#[derive(Serialize, Deserialize, Debug, Clone)]
722pub struct PipelineData {
723 pub recognition: Recognition,
725 pub action: Action,
727 #[serde(default)]
729 pub next: Vec<NodeAttr>,
730 #[serde(default = "default_rate_limit")]
732 pub rate_limit: i32,
733 #[serde(default = "default_timeout")]
735 pub timeout: i32,
736 #[serde(default)]
738 pub on_error: Vec<NodeAttr>,
739 #[serde(default)]
741 pub anchor: Anchor,
742 #[serde(default)]
744 pub inverse: bool,
745 #[serde(default = "default_enabled")]
747 pub enabled: bool,
748 #[serde(default = "default_pre_delay")]
750 pub pre_delay: i32,
751 #[serde(default = "default_post_delay")]
753 pub post_delay: i32,
754 #[serde(default)]
756 pub pre_wait_freezes: Option<WaitFreezes>,
757 #[serde(default)]
759 pub post_wait_freezes: Option<WaitFreezes>,
760 #[serde(default = "default_repeat")]
762 pub repeat: i32,
763 #[serde(default)]
765 pub repeat_delay: i32,
766 #[serde(default)]
768 pub repeat_wait_freezes: Option<WaitFreezes>,
769 #[serde(default = "default_max_hit")]
771 pub max_hit: u32,
772 #[serde(default)]
774 pub focus: Option<Value>,
775 #[serde(default)]
777 pub attach: Option<Value>,
778}
779
780fn default_wait_time() -> i32 {
783 1
784}
785fn default_wait_threshold() -> f64 {
786 0.95
787}
788fn default_wait_method() -> i32 {
789 5
790}
791fn default_rate_limit() -> i32 {
792 1000
793}
794fn default_timeout() -> i32 {
795 20000
796}
797fn default_threshold() -> Vec<f64> {
798 vec![0.7]
799}
800fn default_order_by() -> String {
801 "Horizontal".to_string()
802}
803fn default_template_method() -> i32 {
804 5
805}
806fn default_detector() -> String {
807 "SIFT".to_string()
808}
809fn default_feature_count() -> i32 {
810 4
811}
812fn default_feature_ratio() -> f64 {
813 0.6
814}
815fn default_color_method() -> i32 {
816 4
817} fn default_count_one() -> i32 {
819 1
820}
821fn default_ocr_threshold() -> f64 {
822 0.3
823}
824fn default_detect_threshold() -> Vec<f64> {
825 vec![0.3]
826}
827fn default_pressure() -> i32 {
828 1
829}
830fn default_long_press_duration() -> i32 {
831 1000
832}
833fn default_target_list_true() -> Vec<Target> {
834 vec![Target::Bool(true)]
835}
836fn default_rect_list_zero() -> Vec<Rect> {
837 vec![(0, 0, 0, 0).into()]
838}
839fn default_i32_list_zero() -> Vec<i32> {
840 vec![0]
841}
842fn default_duration_list() -> Vec<i32> {
843 vec![200]
844}
845fn default_enabled() -> bool {
846 true
847}
848fn default_pre_delay() -> i32 {
849 200
850}
851fn default_post_delay() -> i32 {
852 200
853}
854fn default_repeat() -> i32 {
855 1
856}
857fn default_max_hit() -> u32 {
858 u32::MAX
859}
860fn default_screencap_format() -> String {
861 "png".to_string()
862}
863fn default_screencap_quality() -> i32 {
864 100
865}
866fn default_roi_zero() -> Target {
867 Target::Rect((0, 0, 0, 0).into())
868}