Skip to content

Commit 6e1b26f

Browse files
committed
Small lib for fun and giggles.
0 parents  commit 6e1b26f

File tree

3 files changed

+265
-0
lines changed

3 files changed

+265
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "rdev"
3+
version = "0.1.0"
4+
authors = ["Nicolas Patry <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
serde = { version = "1.0", features = ["derive"] }
11+
serde_json = "1.0"

src/lib.rs

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
2+
mod rdev{
3+
use serde::{Deserialize, Serialize, Serializer, Deserializer};
4+
use serde::ser::{Error};
5+
use std::time::{SystemTime, Duration};
6+
7+
#[derive(Debug, Serialize, Deserialize)]
8+
#[serde(rename_all = "UPPERCASE")]
9+
pub enum EventType{
10+
Key,
11+
Button,
12+
}
13+
14+
#[derive(Debug, Clone, PartialEq)]
15+
pub enum EventError{
16+
InvalidCoordinates,
17+
InvalidName,
18+
InvalidTime,
19+
}
20+
21+
#[derive(Debug, Serialize, Deserialize)]
22+
pub struct Event{
23+
#[serde(rename = "keycode")]
24+
pub code: u8,
25+
#[serde(rename = "hasAlt")]
26+
has_alt: bool,
27+
#[serde(rename = "hasCapsLock")]
28+
has_capslock: bool,
29+
#[serde(rename = "hasCtrl")]
30+
has_ctrl: bool,
31+
#[serde(rename = "hasMeta")]
32+
has_meta: bool,
33+
#[serde(rename = "hasShift")]
34+
has_shift: bool,
35+
#[serde(serialize_with = "serialize_from_st", deserialize_with="deserialize_from_ts")]
36+
time: SystemTime,
37+
press: bool,
38+
event_type: EventType,
39+
x: f64,
40+
y: f64,
41+
name: Option<String>,
42+
}
43+
44+
fn serialize_from_st<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
45+
where
46+
S: Serializer,
47+
{
48+
match time.duration_since(SystemTime::UNIX_EPOCH){
49+
Ok(n) => serializer.serialize_f64(n.as_secs_f64()),
50+
Err(e) => Err(e).map_err(Error::custom)
51+
}
52+
53+
}
54+
fn deserialize_from_ts<'de, D>(deserializer: D) -> Result<SystemTime, D::Error>
55+
where
56+
D: Deserializer<'de>,
57+
{
58+
match f64::deserialize(deserializer){
59+
Ok(v) => {
60+
println!("Deserializing {}", v);
61+
let d = Duration::from_secs_f64(v);
62+
println!("Deserializing {:?}", d);
63+
let res = SystemTime::UNIX_EPOCH + d;
64+
println!("Result {:?}", res);
65+
Ok(res)
66+
},
67+
Err(e) => Err(e),
68+
}
69+
}
70+
71+
impl Event{
72+
pub fn new(code:u8, has_alt: bool, has_capslock: bool, has_ctrl: bool, has_meta: bool, has_shift: bool, time: SystemTime, press: bool, event_type: EventType, x: f64, y: f64, name: Option<String>) -> Result<Event, EventError>{
73+
74+
if x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0{
75+
return Err(EventError::InvalidCoordinates);
76+
}
77+
if let Some(ename) = &name{
78+
if ename == ""{
79+
return Err(EventError::InvalidName); // "Don't use empty string for events."
80+
}
81+
if ename != " " && ename.contains(" "){
82+
return Err(EventError::InvalidName); // "Don't use Spaces in complex event names"
83+
}
84+
}
85+
86+
return Ok(Event{
87+
code,
88+
has_alt,
89+
has_capslock,
90+
has_ctrl,
91+
has_meta,
92+
has_shift,
93+
time,
94+
press,
95+
event_type,
96+
x,
97+
y,
98+
name,
99+
});
100+
}
101+
}
102+
103+
pub fn format_events(events: Vec<Event>) -> String{
104+
let mut s = String::from("");
105+
for event in events{
106+
if !event.press{
107+
continue
108+
}
109+
if let Some(event_name) = event.name{
110+
s.push_str(&event_name);
111+
}
112+
113+
}
114+
return s
115+
}
116+
}
117+
118+
119+
120+
121+
#[cfg(test)]
122+
mod tests {
123+
use std::time::{SystemTime};
124+
use crate::rdev::{Event, EventError, EventType, format_events};
125+
126+
fn simple_key(code: u8, name: Option<String>) -> Event{
127+
Event::new(
128+
code,
129+
false,
130+
false,
131+
false,
132+
false,
133+
false,
134+
SystemTime::now(),
135+
true,
136+
EventType::Key,
137+
0.,
138+
0.,
139+
name,
140+
).unwrap()
141+
}
142+
143+
#[test]
144+
fn format_simple() {
145+
let event = simple_key(1, Some(String::from("H")));
146+
let event2 = simple_key(2, Some(String::from("e")));
147+
assert_eq!(format_events(vec![event, event2]), String::from("He"));
148+
}
149+
150+
#[test]
151+
fn event_out_of_boundary() {
152+
let event = Event::new(
153+
1,
154+
false,
155+
false,
156+
false,
157+
false,
158+
false,
159+
SystemTime::now(),
160+
true,
161+
EventType::Key,
162+
-1.,
163+
0.,
164+
Some(String::from("e")),
165+
);
166+
assert_eq!(event.err(), Some(EventError::InvalidCoordinates), "We should crash because x is negative");
167+
}
168+
169+
#[test]
170+
fn event_invalid_name() {
171+
let event = Event::new(
172+
1,
173+
false,
174+
false,
175+
false,
176+
false,
177+
false,
178+
SystemTime::now(),
179+
true,
180+
EventType::Key,
181+
0.,
182+
0.,
183+
Some(String::from("")),
184+
);
185+
assert_eq!(event.err(), Some(EventError::InvalidName), "We should not emit empty string names");
186+
}
187+
188+
#[test]
189+
fn event_invalid_name_with_space() {
190+
let event = Event::new(
191+
1,
192+
false,
193+
false,
194+
false,
195+
false,
196+
false,
197+
SystemTime::now(),
198+
true,
199+
EventType::Key,
200+
0.,
201+
0.,
202+
Some(String::from("Some event")),
203+
);
204+
assert_eq!(event.err(), Some(EventError::InvalidName), "We should not emit an event associated with a space");
205+
}
206+
207+
#[test]
208+
fn event_json_deserialization() {
209+
let data = r#"
210+
{
211+
"keycode": 1,
212+
"hasAlt": false,
213+
"hasCapsLock": false,
214+
"hasCtrl": false,
215+
"hasMeta": false,
216+
"hasShift": false,
217+
"time": 15806656262720,
218+
"press": true,
219+
"event_type": "KEY",
220+
"x":0.0,
221+
"y":0.0
222+
}"#;
223+
224+
// Parse the string of data into serde_json::Value.
225+
let event: Event = serde_json::from_str(data).unwrap();
226+
227+
assert_eq!(event.code, 1);
228+
}
229+
230+
#[test]
231+
fn event_json_serialization() {
232+
let event = Event::new(
233+
1,
234+
false,
235+
false,
236+
false,
237+
false,
238+
false,
239+
SystemTime::UNIX_EPOCH,
240+
true,
241+
EventType::Key,
242+
0.,
243+
0.,
244+
None,
245+
).unwrap();
246+
let data = r#"{"keycode":1,"hasAlt":false,"hasCapsLock":false,"hasCtrl":false,"hasMeta":false,"hasShift":false,"time":0.0,"press":true,"event_type":"KEY","x":0.0,"y":0.0,"name":null}"#;
247+
248+
// Parse the string of data into serde_json::Value.
249+
let output: String = serde_json::to_string(&event).unwrap();
250+
assert_eq!(output, data);
251+
}
252+
}

0 commit comments

Comments
 (0)