tfc/command/
execute.rs

1use super::Command;
2use std::{thread, time::Duration};
3use crate::{GenericError, traits::*};
4
5impl Command {
6    fn execute_core<C>(&self, ctx: &mut C) -> Result<bool, GenericError<C::PlatformError>>
7        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext
8    {
9        use Command::*;
10        match self {
11            KeyDown(key) => ctx.key_down(*key),
12            KeyUp(key) => ctx.key_up(*key),
13            KeyClick(key) => ctx.key_click(*key),
14            MouseMoveRel(dx, dy) => ctx.mouse_move_rel(*dx, *dy),
15            MouseMoveAbs(x, y) => ctx.mouse_move_abs(*x, *y),
16            MouseScroll(dx, dy) => ctx.mouse_scroll(*dx, *dy),
17            MouseDown(button) => ctx.mouse_down(*button),
18            MouseUp(button) => ctx.mouse_up(*button),
19            MouseClick(button) => ctx.mouse_click(*button),
20            AsciiCharDown(ch) => ctx.ascii_char_down(*ch),
21            AsciiCharUp(ch) => ctx.ascii_char_up(*ch),
22            AsciiChar(ch) => ctx.ascii_char(*ch),
23            AsciiString(s) => ctx.ascii_string(s.as_slice()),
24            _ => return Ok(false)
25        }?;
26        Ok(true)
27    }
28
29    #[cfg(not(all(
30        not(feature = "ascii-fallback"),
31        target_os = "linux",
32        not(x11)
33    )))]
34    fn execute_unicode<C>(&self, ctx: &mut C) -> Result<bool, GenericError<C::PlatformError>>
35        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext + UnicodeKeyboardContext
36    {
37        if self.execute_core(ctx)? {
38            return Ok(true);
39        }
40
41        use Command::*;
42        match self {
43            UnicodeCharDown(ch) => ctx.unicode_char_down(*ch),
44            UnicodeCharUp(ch) => ctx.unicode_char_up(*ch),
45            UnicodeChar(ch) => ctx.unicode_char(*ch),
46            UnicodeString(s) => ctx.unicode_string(s.as_str()),
47            _ => return Ok(false)
48        }?;
49
50        Ok(true)
51    }
52
53    #[cfg(all(
54        not(feature = "ascii-fallback"),
55        target_os = "linux",
56        not(x11)
57    ))]
58    pub fn execute_unicode<C>(&self, ctx: &mut C) -> Result<bool, GenericError<C::PlatformError>>
59        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext
60    {
61        if self.execute_core(ctx)? {
62            return Ok(true);
63        }
64
65        use Command::*;
66        match self {
67            UnicodeCharDown(_) => panic!("UnicodeKeyboardContext is not implemented"),
68            UnicodeCharUp(_) => panic!("UnicodeKeyboardContext is not implemented"),
69            UnicodeChar(_) => panic!("UnicodeKeyboardContext is not implemented"),
70            UnicodeString(_) => panic!("UnicodeKeyboardContext is not implemented"),
71            _ => Ok(false)
72        }
73    }
74
75    /// Execute a [`Command`] by calling the corresponding method on
76    /// one of the [`traits`](crate::traits).
77    ///
78    /// [`Delay`](Command::Delay) is treated as being synchronous and is
79    /// executed using [`std::thread::sleep`].
80    #[cfg(not(all(
81        not(feature = "ascii-fallback"),
82        target_os = "linux",
83        not(x11)
84    )))]
85    pub fn execute<C>(&self, ctx: &mut C) -> Result<(), GenericError<C::PlatformError>>
86        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext + UnicodeKeyboardContext
87    {
88        if self.execute_unicode(ctx)? {
89            return Ok(());
90        }
91
92        use Command::*;
93        match self {
94            Delay(millis) => {
95                thread::sleep(Duration::from_millis(*millis as u64));
96                Ok(())
97            }
98            _ => std::unreachable!()
99        }
100    }
101
102    /// Execute a [`Command`] by calling the corresponding method on
103    /// one of the [`traits`](crate::traits).
104    ///
105    /// [`Delay`](Command::Delay) is treated as being asynchronous and is
106    /// executed using [`tokio::time::sleep`].
107    #[cfg(all(
108        not(all(
109            not(feature = "ascii-fallback"),
110            target_os = "linux",
111            not(x11)
112        )),
113        feature = "tokio"
114    ))]
115    pub async fn execute_async<C>(&self, ctx: &mut C) -> Result<(), GenericError<C::PlatformError>>
116        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext + UnicodeKeyboardContext
117    {
118        if self.execute_unicode(ctx)? {
119            return Ok(());
120        }
121
122        use Command::*;
123        match self {
124            Delay(millis) => {
125                tokio::time::sleep(Duration::from_millis(*millis as u64)).await;
126                Ok(())
127            }
128            _ => std::unreachable!()
129        }
130    }
131
132    /// Execute a [`Command`] by calling the corresponding method on
133    /// one of the [`traits`](crate::traits).
134    ///
135    /// [`Delay`](Command::Delay) is treated as being synchronous and is
136    /// executed using [`std::thread::sleep`].
137    #[cfg(all(
138        not(feature = "ascii-fallback"),
139        target_os = "linux",
140        not(x11)
141    ))]
142    pub fn execute<C>(&self, ctx: &mut C) -> Result<(), GenericError<C::PlatformError>>
143        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext
144    {
145        if self.execute_unicode(ctx)? {
146            return Ok(());
147        }
148
149        use Command::*;
150        match self {
151            Delay(millis) => {
152                thread::sleep(Duration::from_millis(*millis as u64));
153                Ok(())
154            }
155            _ => std::unreachable!()
156        }
157    }
158
159    /// Execute a [`Command`] by calling the corresponding method on
160    /// one of the [`traits`](crate::traits).
161    ///
162    /// [`Delay`](Command::Delay) is treated as being asynchronous and is
163    /// executed using [`tokio::time::sleep`].
164    #[cfg(all(
165        not(feature = "ascii-fallback"),
166        target_os = "linux",
167        not(x11),
168        feature = "tokio"
169    ))]
170    pub async fn execute_async<C>(&self, ctx: &mut C) -> Result<(), GenericError<C::PlatformError>>
171        where C: FallibleContext + KeyboardContext + MouseContext + AsciiKeyboardContext
172    {
173        if self.execute_unicode(ctx)? {
174            return Ok(());
175        }
176
177        use Command::*;
178        match self {
179            Delay(millis) => {
180                tokio::time::sleep(Duration::from_millis(*millis as u64)).await;
181                Ok(())
182            }
183            _ => std::unreachable!()
184        }
185    }
186}