Skip to main content

smix_input/
lib.rs

1#![doc = include_str!("../README.md")]
2#![deny(missing_docs)]
3#![deny(rustdoc::broken_intra_doc_links)]
4#![doc(html_root_url = "https://docs.smix.dev/smix-input")]
5
6//! Ported from now-retired TS source: `src/driver/types.ts:8-19`. Small wire-only types
7//! shared by smix-driver / smix-recorder-ir / smix-runner-client. Kept as
8//! a separate crate so cement (CLI / MCP / SDK / recorder) can depend on
9//! them without dragging in heavier driver / runner deps.
10
11use serde::{Deserialize, Serialize};
12
13/// Maestro yaml `direction:` semantic (per
14/// [[smix-must-be-superset-of-maestro]]): the direction names what
15/// content the caller wants to **see** (navigation through content),
16/// NOT the finger gesture direction. `Down` = "navigate down through
17/// content" = reveal what's BELOW the current viewport (visually content
18/// moves up, finger gestures up). Mirrors maestro CLI `direction: DOWN`
19/// semantics.
20///
21/// v6.11 c1 — name "SwipeDirection" predates the convention pin and now
22/// reads as a slight misnomer (the value is the *navigation* direction,
23/// not the *swipe gesture* direction). Renaming the enum would ripple
24/// across every adapter/driver/runner crate without semantic gain;
25/// instead the docstring carries the contract. Both runners (swift
26/// XCUITest + Kotlin UiAutomator) map this enum's wire string to the
27/// inverse finger gesture (e.g. `Down` → finger up via swipeUp / coord
28/// y 70→30) so the same yaml flow yields the same visual behavior on
29/// both platforms.
30#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
31#[serde(rename_all = "camelCase")]
32pub enum SwipeDirection {
33    /// Navigate up = see what's above (content moves down; finger gestures down).
34    Up,
35    /// Navigate down = see what's below (content moves up; finger gestures up).
36    Down,
37    /// Navigate left = see what's to the left (content moves right; finger gestures right).
38    Left,
39    /// Navigate right = see what's to the right (content moves left; finger gestures left).
40    Right,
41}
42
43impl SwipeDirection {
44    /// camelCase wire string (mirrors `roleSchema` style).
45    #[must_use]
46    pub fn as_str(self) -> &'static str {
47        match self {
48            SwipeDirection::Up => "up",
49            SwipeDirection::Down => "down",
50            SwipeDirection::Left => "left",
51            SwipeDirection::Right => "right",
52        }
53    }
54}
55
56impl std::fmt::Display for SwipeDirection {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        f.write_str(self.as_str())
59    }
60}
61
62/// Keyboard key name for `press_key` / `record` (camelCase serde 1:1 跟 TS).
63///
64/// Subset is intentional — these are the keys SDK users reliably exercise
65/// in iOS-sim contexts. Adding more is a c{N} discussion: arrow keys are
66/// here because focus-traversal flows need them (v1.5 c5g'').
67#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
68#[serde(rename_all = "camelCase")]
69pub enum KeyName {
70    /// Return / Enter key — submits a form or confirms an action.
71    Return,
72    /// Delete / Backspace key — deletes the character before the cursor.
73    Delete,
74    /// Tab key — moves focus to the next focusable element.
75    Tab,
76    /// Space key — inserts a space character.
77    Space,
78    /// Escape key — dismisses a modal or cancels an action.
79    Escape,
80    /// Up-arrow key — moves selection / focus / caret upward.
81    ArrowUp,
82    /// Down-arrow key — moves selection / focus / caret downward.
83    ArrowDown,
84    /// Left-arrow key — moves selection / focus / caret leftward.
85    ArrowLeft,
86    /// Right-arrow key — moves selection / focus / caret rightward.
87    ArrowRight,
88    /// iOS hardware Home button — XCUIDevice.shared.perform(.homeButton).
89    /// v5.2 c2 — maestro `pressKey: home` ↔ smix core KeyName 平铺。
90    Home,
91    /// iOS hardware Lock button — XCUIDevice.shared.perform(.lockButton).
92    /// v5.2 c2 — maestro `pressKey: lock` ↔ smix core KeyName 平铺。
93    Lock,
94    /// iOS hardware Volume Up button — XCUIDevice.Button.volumeUp.
95    /// v5.2 c2 — maestro `pressKey: volume up` ↔ smix core KeyName 平铺。
96    VolumeUp,
97    /// iOS hardware Volume Down button — XCUIDevice.Button.volumeDown.
98    /// v5.2 c2 — maestro `pressKey: volume down` ↔ smix core KeyName 平铺。
99    VolumeDown,
100}
101
102impl KeyName {
103    /// camelCase wire string.
104    #[must_use]
105    pub fn as_str(self) -> &'static str {
106        match self {
107            KeyName::Return => "return",
108            KeyName::Delete => "delete",
109            KeyName::Tab => "tab",
110            KeyName::Space => "space",
111            KeyName::Escape => "escape",
112            KeyName::ArrowUp => "arrowUp",
113            KeyName::ArrowDown => "arrowDown",
114            KeyName::ArrowLeft => "arrowLeft",
115            KeyName::ArrowRight => "arrowRight",
116            KeyName::Home => "home",
117            KeyName::Lock => "lock",
118            KeyName::VolumeUp => "volumeUp",
119            KeyName::VolumeDown => "volumeDown",
120        }
121    }
122}
123
124impl std::fmt::Display for KeyName {
125    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126        f.write_str(self.as_str())
127    }
128}