1
1
//! Parse linux rc keymaps
2
2
3
3
use super :: { Keymap , Raw } ;
4
+ use irp:: { Message , Pronto } ;
4
5
use std:: { collections:: HashMap , ffi:: OsStr , fmt:: Write , path:: Path } ;
5
6
use toml:: { Table , Value } ;
6
7
@@ -12,7 +13,8 @@ peg::parser! {
12
13
let mut scancodes = HashMap :: new( ) ;
13
14
14
15
for ( code, name) in lines. into_iter( ) . flatten( ) {
15
- scancodes. insert( code. to_owned( ) , name. to_owned( ) ) ;
16
+ let code = string_to_scancode( code) . unwrap( ) ;
17
+ scancodes. insert( code, name. to_owned( ) ) ;
16
18
}
17
19
18
20
let mut protocol = vec![ Keymap {
@@ -60,6 +62,13 @@ peg::parser! {
60
62
}
61
63
}
62
64
65
+ fn string_to_scancode ( s : & str ) -> Result < u64 , std:: num:: ParseIntError > {
66
+ if let Some ( hex) = s. strip_prefix ( "0x" ) {
67
+ u64:: from_str_radix ( hex, 16 )
68
+ } else {
69
+ str:: parse ( s)
70
+ }
71
+ }
63
72
impl Keymap {
64
73
/// Parse a rc keymap file, either toml or old text format. No validation is done of key codes or protocol names
65
74
pub fn parse ( contents : & str , filename : & Path ) -> Result < Vec < Keymap > , String > {
@@ -127,19 +136,22 @@ fn parse_toml(contents: &str, filename: &Path) -> Result<Vec<Keymap>, String> {
127
136
} ;
128
137
129
138
let raw = if let Some ( Value :: String ( raw) ) = e. get ( "raw" ) {
130
- Some ( raw. to_owned ( ) )
139
+ let raw = Message :: parse ( raw) ?;
140
+ Some ( raw)
131
141
} else {
132
142
None
133
143
} ;
134
144
135
145
let repeat = if let Some ( Value :: String ( repeat) ) = e. get ( "repeat" ) {
136
- Some ( repeat. to_owned ( ) )
146
+ let repeat = Message :: parse ( repeat) ?;
147
+ Some ( repeat)
137
148
} else {
138
149
None
139
150
} ;
140
151
141
152
let pronto = if let Some ( Value :: String ( pronto) ) = e. get ( "pronto" ) {
142
- Some ( pronto. to_owned ( ) )
153
+ let pronto = Pronto :: parse ( pronto) ?;
154
+ Some ( pronto)
143
155
} else {
144
156
None
145
157
} ;
@@ -182,12 +194,14 @@ fn parse_toml(contents: &str, filename: &Path) -> Result<Vec<Keymap>, String> {
182
194
if let Some ( Value :: Table ( codes) ) = entry. get ( "scancodes" ) {
183
195
let mut res = HashMap :: new ( ) ;
184
196
185
- for ( key, value) in codes {
186
- let Value :: String ( value) = value else {
187
- return Err ( format ! ( "{}: scancode should be string" , filename. display( ) ) ) ;
197
+ for ( scancode, keycode) in codes {
198
+ let scancode = string_to_scancode ( scancode)
199
+ . map_err ( |_| format ! ( "{scancode} is a not valid scancode" ) ) ?;
200
+ let Value :: String ( keycode) = keycode else {
201
+ return Err ( format ! ( "{}: keycode should be string" , filename. display( ) ) ) ;
188
202
} ;
189
203
190
- res. insert ( key . to_owned ( ) , value . to_owned ( ) ) ;
204
+ res. insert ( scancode , keycode . to_owned ( ) ) ;
191
205
}
192
206
193
207
scancodes = Some ( res) ;
@@ -407,8 +421,8 @@ fn parse_toml_test() {
407
421
assert_eq ! ( k[ 0 ] . variant, Some ( String :: from( "rc5" ) ) ) ;
408
422
if let Some ( scancodes) = & k[ 0 ] . scancodes {
409
423
for s in scancodes {
410
- match ( s. 0 . as_str ( ) , s. 1 . as_str ( ) ) {
411
- ( " 0x1e3b" , "KEY_SELECT" ) | ( " 0x1e3d" , "KEY_POWER2" ) | ( " 0x1e1c" , "KEY_TV" ) => { }
424
+ match ( s. 0 , s. 1 . as_str ( ) ) {
425
+ ( 0x1e3b , "KEY_SELECT" ) | ( 0x1e3d , "KEY_POWER2" ) | ( 0x1e1c , "KEY_TV" ) => { }
412
426
_ => panic ! ( "{s:?} not expected" ) ,
413
427
}
414
428
}
@@ -473,8 +487,8 @@ fn parse_text_test() {
473
487
assert_eq ! ( k[ 0 ] . variant, None ) ;
474
488
if let Some ( scancodes) = & k[ 0 ] . scancodes {
475
489
for s in scancodes {
476
- match ( s. 0 . as_str ( ) , s. 1 . as_str ( ) ) {
477
- ( " 0x1e3b" , "KEY_SELECT" ) | ( " 0x1e3d" , "KEY_POWER2" ) | ( " 0x1e1c" , "KEY_TV" ) => { }
490
+ match ( s. 0 , s. 1 . as_str ( ) ) {
491
+ ( 0x1e3b , "KEY_SELECT" ) | ( 0x1e3d , "KEY_POWER2" ) | ( 0x1e1c , "KEY_TV" ) => { }
478
492
_ => panic ! ( "{s:?} not expected" ) ,
479
493
}
480
494
}
@@ -498,11 +512,11 @@ fn parse_text_test() {
498
512
assert_eq ! ( k[ 0 ] . variant, None ) ;
499
513
if let Some ( scancodes) = & k[ 0 ] . scancodes {
500
514
for s in scancodes {
501
- match ( s. 0 . as_str ( ) , s. 1 . as_str ( ) ) {
502
- ( " 0x800f0400" , "KEY_NUMERIC_0" )
503
- | ( " 0x800f0401" , "KEY_NUMERIC_1" )
504
- | ( " 0x800f0402" , "KEY_NUMERIC_2" )
505
- | ( " 0x800f0403" , "KEY_NUMERIC_3" ) => { }
515
+ match ( s. 0 , s. 1 . as_str ( ) ) {
516
+ ( 0x800f0400 , "KEY_NUMERIC_0" )
517
+ | ( 0x800f0401 , "KEY_NUMERIC_1" )
518
+ | ( 0x800f0402 , "KEY_NUMERIC_2" )
519
+ | ( 0x800f0403 , "KEY_NUMERIC_3" ) => { }
506
520
_ => panic ! ( "{s:?} not expected" ) ,
507
521
}
508
522
}
@@ -522,10 +536,10 @@ fn parse_text_test() {
522
536
assert_eq ! ( k[ 0 ] . variant, None ) ;
523
537
if let Some ( scancodes) = & k[ 0 ] . scancodes {
524
538
for s in scancodes {
525
- match ( s. 0 . as_str ( ) , s. 1 . as_str ( ) ) {
526
- ( " 0x28c0" , "KEY_NUMERIC_0" )
527
- | ( " 0x28c1" , "KEY_NUMERIC_1" )
528
- | ( " 0x28c2" , "KEY_NUMERIC_2" ) => { }
539
+ match ( s. 0 , s. 1 . as_str ( ) ) {
540
+ ( 0x28c0 , "KEY_NUMERIC_0" )
541
+ | ( 0x28c1 , "KEY_NUMERIC_1" )
542
+ | ( 0x28c2 , "KEY_NUMERIC_2" ) => { }
529
543
_ => panic ! ( "{s:?} not expected" ) ,
530
544
}
531
545
}
0 commit comments