2017-09-21 22:34:24 -04:00
use std ::fs ::File ;
use std ::io ::Read ;
use std ::collections ::HashMap ;
2019-10-06 13:51:01 -04:00
use std ::hash ::Hash ;
use std ::convert ::TryFrom ;
2017-09-21 22:34:24 -04:00
2019-09-29 23:49:23 -04:00
use crate ::{ Error , Result } ;
2017-11-15 01:08:38 -05:00
2017-09-21 22:34:24 -04:00
const INVERT_KEY_FLAG : char = '^' ;
const CAPS_MODIFY_KEY_FLAG : char = '*' ;
const HALF_KEY_SEPARATOR : char = ':' ;
2019-10-06 13:51:01 -04:00
// nightly only...
//pub trait KeyCode = Into<usize> + TryFrom<usize> + Copy + Clone + Eq + Hash + Default + 'static;
#[ derive(PartialEq) ]
pub enum KeyState {
DOWN ,
UP ,
OTHER ,
}
pub trait KeyEvent < T >
where
T : Into < usize > ,
{
fn code ( & self ) -> T ;
fn value ( & self ) -> KeyState ;
}
2017-09-21 22:34:24 -04:00
2019-10-06 13:51:01 -04:00
pub trait Keyboard < T , E , R = ( ) >
where
T : Into < usize > ,
E : KeyEvent < T > ,
{
fn send ( & self , event : & mut E ) -> Result < R > ;
fn send_mod_code ( & self , code : T , event : & mut E ) -> Result < R > ;
fn send_mod_code_value ( & self , code : T , up_not_down : bool , event : & mut E ) -> Result < R > ;
fn synchronize ( & self ) -> Result < R > ;
fn left_shift_code ( & self ) -> T ;
fn right_shift_code ( & self ) -> T ;
fn caps_lock_code ( & self ) -> T ;
fn block_key ( & self ) -> Result < R > ;
}
2017-09-21 22:34:24 -04:00
2019-10-06 13:51:01 -04:00
pub trait KeyMapper < K , T , E , R >
where
T : Into < usize > ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > ;
2017-09-21 22:34:24 -04:00
}
2019-10-06 13:51:01 -04:00
pub struct KeyMaps < K , T , E , R = ( ) >
where
T : Into < usize > + Copy + Clone + Eq + Hash ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
keymaps : Vec < Box < dyn KeyMapper < K , T , E , R > > > ,
keymap_index_keys : HashMap < T , usize > ,
2017-09-21 22:34:24 -04:00
switch_layout_keys : Vec < usize > ,
key_state : [ bool ; KEY_MAX ] ,
2019-10-06 13:51:01 -04:00
revert_default_key : T ,
2017-09-21 22:34:24 -04:00
revert_keymap_index : usize ,
// above do not change, below does
chosen_keymap_index : usize ,
current_keymap_index : usize ,
}
2019-10-06 13:51:01 -04:00
fn parse_key < T : Clone + Copy > ( key_map : & HashMap < & 'static str , T > , key : & str ) -> T {
2017-09-21 22:34:24 -04:00
match key_map . get ( key . trim_matches ( | c : char | c . is_whitespace ( ) | | c = = INVERT_KEY_FLAG | | c = = CAPS_MODIFY_KEY_FLAG ) ) {
2019-10-06 13:51:01 -04:00
Some ( key_code ) = > * key_code ,
2017-09-21 22:34:24 -04:00
None = > panic! ( " unknown key: {} " , key . trim ( ) )
}
}
2019-10-06 13:51:01 -04:00
fn parse_keymap_numeric < T : Clone + Copy > ( key_map : & HashMap < & 'static str , T > , keymap : & str ) -> Vec < T > {
2017-09-21 22:34:24 -04:00
keymap . split ( " , " ) . map ( | k | parse_key ( key_map , k ) ) . collect ( )
}
2019-10-06 13:51:01 -04:00
fn parse_key_half_inverted < T : Clone + Copy > ( key_map : & HashMap < & 'static str , T > , key : & str ) -> HalfInvertedKey < T > {
2017-09-21 22:34:24 -04:00
HalfInvertedKey {
code : parse_key ( key_map , key ) ,
invert_shift : key . contains ( INVERT_KEY_FLAG ) ,
capslock_nomodify : key . contains ( CAPS_MODIFY_KEY_FLAG ) ,
}
}
// maybe shortcut to this if not contains * or :
2019-10-06 13:51:01 -04:00
fn parse_keymap_u16 < T : Clone + Copy > ( key_map : & HashMap < & 'static str , T > , keymap : & str ) -> Vec < T > {
2017-09-23 01:29:23 -04:00
keymap . split ( " , " ) . map ( | k | parse_key ( key_map , k ) ) . collect ( )
}
// todo: how do I return an iterator here instead of .collect to Vec?
2019-10-06 13:51:01 -04:00
fn parse_keymap < T : Copy > ( key_map : & HashMap < & 'static str , T > , keymap : & str ) -> Vec < Key < T > > {
2017-09-23 01:29:23 -04:00
keymap . split ( " , " ) . map ( | k | {
2019-10-06 13:51:01 -04:00
let ret : Key < T > = if k . contains ( HALF_KEY_SEPARATOR ) {
2017-09-23 01:29:23 -04:00
let keys : Vec < & str > = k . split ( HALF_KEY_SEPARATOR ) . collect ( ) ;
if keys . len ( ) ! = 2 {
panic! ( " split key can only have 2 keys, 1 :, has {} keys " , keys . len ( ) ) ;
}
let mut shift_half = parse_key_half_inverted ( key_map , keys [ 1 ] ) ;
shift_half . invert_shift = ! shift_half . invert_shift ;
Key ::FullKey ( parse_key_half_inverted ( key_map , keys [ 0 ] ) , shift_half )
} else if k . contains ( INVERT_KEY_FLAG ) | | k . contains ( CAPS_MODIFY_KEY_FLAG ) {
Key ::HalfKey ( parse_key_half_inverted ( key_map , k ) )
} else {
Key ::Direct ( parse_key ( key_map , k ) )
} ;
ret
} ) . collect ( )
2017-09-21 22:34:24 -04:00
}
2019-10-06 13:51:01 -04:00
impl < K , T , E , R > KeyMaps < K , T , E , R >
where
T : Into < usize > + TryFrom < usize > + Copy + Clone + Eq + Hash + Default + 'static ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
pub fn from_cfg < P : AsRef < Path > > ( key_map : & HashMap < & 'static str , T > , path : P ) -> KeyMaps < K , T , E , R > {
2017-09-21 22:34:24 -04:00
let key_map_config = parse_cfg ( path ) . expect ( " provided config cannot be found/parsed " ) ;
KeyMaps ::new ( key_map , key_map_config )
}
2019-10-06 13:51:01 -04:00
pub fn new ( key_map : & HashMap < & 'static str , T > , config : KeymapConfig ) -> KeyMaps < K , T , E , R > {
2017-09-21 22:34:24 -04:00
if config . keymaps . len ( ) < 2 {
panic! ( " must have at least 2 keymaps (original and mapped) but only have {} , " , config . keymaps . len ( ) ) ;
}
if config . default_keymap_index > = config . keymaps . len ( ) | | config . revert_keymap_index > = config . keymaps . len ( ) {
panic! ( " default_keymap_index ( {} ) and revert_keymap_index ( {} ) must be less than keymaps length ( {} ), " , config . default_keymap_index , config . revert_keymap_index , config . keymaps . len ( ) ) ;
}
let base_keymap = parse_keymap_numeric ( key_map , & config . keymaps [ 0 ] ) ;
2017-09-22 00:30:56 -04:00
//println!("base_keymap : {:?}", base_keymap);
2019-10-06 13:51:01 -04:00
let mut keymaps : Vec < Box < dyn KeyMapper < K , T , E , R > > > = vec! ( Box ::new ( Key ::Noop ) ) ; // todo: can we share the box?
let mut keymap_index_keys : HashMap < T , usize > = HashMap ::new ( ) ;
2017-09-21 22:34:24 -04:00
for ( x , v ) in config . keymaps . iter ( ) . enumerate ( ) {
2019-10-06 13:51:01 -04:00
keymap_index_keys . insert ( * key_map . get ( & * x . to_string ( ) ) . unwrap ( ) , x ) ;
2017-09-21 22:34:24 -04:00
if x = = 0 {
continue ;
}
2017-09-23 01:29:23 -04:00
if v . contains ( HALF_KEY_SEPARATOR ) | | v . contains ( INVERT_KEY_FLAG ) | | v . contains ( CAPS_MODIFY_KEY_FLAG ) {
// we need KeyMap, the complicated more memory taking one
let v = parse_keymap ( key_map , v ) ;
let mut keymap = KeyMap ::new ( ) ;
let mut i : usize = 0 ;
for key_code in v {
// todo: if these are the same, do Noop instead
keymap . map ( base_keymap [ i ] , key_code ) ;
i = i + 1 ;
if i > base_keymap . len ( ) {
panic! ( " all keymaps must be the same length, keymap index 0 length: {} , index {} length: {} , " , base_keymap . len ( ) , x , i ) ;
2017-09-21 22:34:24 -04:00
}
}
2017-09-23 01:29:23 -04:00
keymaps . push ( Box ::new ( keymap ) ) ;
} else {
// this is a simple keymap
let v = parse_keymap_u16 ( key_map , v ) ;
let mut keymap = CodeKeyMap ::new ( ) ;
let mut i : usize = 0 ;
for key_code in v {
keymap . map ( base_keymap [ i ] , key_code ) ;
i = i + 1 ;
if i > base_keymap . len ( ) {
panic! ( " all keymaps must be the same length, keymap index 0 length: {} , index {} length: {} , " , base_keymap . len ( ) , x , i ) ;
}
2017-09-21 22:34:24 -04:00
}
2017-09-23 01:29:23 -04:00
keymaps . push ( Box ::new ( keymap ) ) ;
2017-09-21 22:34:24 -04:00
}
}
//println!("keymaps: {:?}", keymaps);
//println!("keymap_index_keys: {:?}", keymap_index_keys);
KeyMaps {
keymaps : keymaps ,
keymap_index_keys : keymap_index_keys ,
2019-10-06 13:51:01 -04:00
switch_layout_keys : config . switch_layout_keys . iter ( ) . map ( | k | parse_key ( key_map , k ) . into ( ) ) . collect ( ) ,
2017-09-21 22:34:24 -04:00
key_state : [ false ; KEY_MAX ] ,
// todo: detect key state? at least CAPSLOCK...
revert_default_key : parse_key ( key_map , & config . revert_default_key ) ,
revert_keymap_index : config . revert_keymap_index ,
chosen_keymap_index : config . default_keymap_index ,
current_keymap_index : config . default_keymap_index ,
}
}
2019-10-06 13:51:01 -04:00
//}
2017-09-21 22:34:24 -04:00
//impl KeyMapper for KeyMaps {
2019-10-06 13:51:01 -04:00
//impl KeyMaps {
pub fn send_event ( & mut self , mut event : & mut E , device : & K ) -> Result < R > {
2017-09-21 22:34:24 -04:00
//println!("type: {} code: {} value: {}", event.type_, event.code, event.value);
2019-10-06 13:51:01 -04:00
let value = event . value ( ) ;
if value ! = KeyState ::OTHER {
2017-09-21 22:34:24 -04:00
// todo: index check here...
2019-10-06 13:51:01 -04:00
if event . code ( ) = = device . caps_lock_code ( ) {
if value = = KeyState ::DOWN {
self . key_state [ device . caps_lock_code ( ) . into ( ) ] = ! self . key_state [ device . caps_lock_code ( ) . into ( ) ] ;
2017-09-21 22:34:24 -04:00
}
} else {
2019-10-06 13:51:01 -04:00
self . key_state [ event . code ( ) . into ( ) ] = value = = KeyState ::DOWN ;
2017-09-21 22:34:24 -04:00
}
let mut switch_layout_keys_pressed = true ;
for layout_switch_key in self . switch_layout_keys . iter_mut ( ) {
if ! self . key_state [ * layout_switch_key ] {
switch_layout_keys_pressed = false ;
break ;
}
}
//println!("switch_layout_keys_pressed: {}", self.switch_layout_keys_pressed);
if switch_layout_keys_pressed {
2019-10-06 13:51:01 -04:00
let new_index = self . keymap_index_keys . get ( & event . code ( ) ) ;
2017-09-21 22:34:24 -04:00
if new_index . is_some ( ) {
self . chosen_keymap_index = * new_index . unwrap ( ) ;
self . current_keymap_index = self . chosen_keymap_index ; // todo: what if revert_default_key is held? for now ignore
2019-10-06 13:51:01 -04:00
return device . block_key ( ) ; // we don't want to also send this keypress, so bail
2017-09-21 22:34:24 -04:00
}
}
2019-10-06 13:51:01 -04:00
if event . code ( ) = = self . revert_default_key {
match value {
2017-09-21 22:34:24 -04:00
// todo: ctrl+c will get c stuck because code c value 1 will be sent, but then we'll let go of ctrl, and code j value 0 is sent, so c is never released... fix that...
2019-10-06 13:51:01 -04:00
KeyState ::DOWN = > self . current_keymap_index = self . revert_keymap_index ,
KeyState ::UP = > self . current_keymap_index = self . chosen_keymap_index ,
2017-09-21 22:34:24 -04:00
_ = > ( ) // do nothing for 2
}
}
}
2017-11-15 01:08:38 -05:00
self . keymaps [ self . current_keymap_index ] . send_event ( & self . key_state , & mut event , device )
2017-09-21 22:34:24 -04:00
}
}
// 249 is one more than KEY_MICMUTE which is max key in uinput-sys event.rs
const KEY_MAX : usize = 249 ;
2019-10-06 13:51:01 -04:00
struct KeyMap < T : Into < usize > + Copy > {
2017-09-23 00:47:20 -04:00
//keymap: Vec<Key>,
2019-10-06 13:51:01 -04:00
keymap : [ Key < T > ; KEY_MAX ] ,
2017-09-21 22:34:24 -04:00
}
2019-10-06 13:51:01 -04:00
impl < T : Into < usize > + Copy > KeyMap < T > {
2017-09-21 22:34:24 -04:00
pub fn new ( ) -> Self {
//let mut keymap = [0u16; KEY_MAX];
//let mut keymap : [Box<KeyMapper>; KEY_MAX] = [Box::new(NOOP); KEY_MAX];
//let mut keymap : [Box<KeyMapper>; KEY_MAX] = [Box::new(0u16); KEY_MAX];
2019-10-06 13:51:01 -04:00
let keymap : [ Key < T > ; KEY_MAX ] = [ Key ::Noop ; KEY_MAX ] ;
2017-09-23 00:47:20 -04:00
/*
2017-09-23 00:46:42 -04:00
let mut keymap : Vec < Key > = Vec ::with_capacity ( KEY_MAX ) ;
2017-09-21 22:34:24 -04:00
#[ allow(unused_variables) ]
for x in 0 .. KEY_MAX {
2017-09-23 00:46:42 -04:00
keymap . push ( Key ::Noop ) ;
2017-09-21 22:34:24 -04:00
}
2017-09-23 00:47:20 -04:00
* /
2017-09-21 22:34:24 -04:00
// which is rustier
/*
for x in 0 .. KEY_MAX {
keymap [ x as usize ] = x as u16 ;
}
for ( x , v ) in keymap . iter_mut ( ) . enumerate ( ) {
* v = x as u16 ;
}
* /
//println!("keymap: {:?}", &keymap[..]);
KeyMap {
keymap : keymap
}
}
/*
pub fn map ( & mut self , from : u16 , to : u16 ) {
self . keymap [ from as usize ] = to ;
}
* /
2019-10-06 13:51:01 -04:00
pub fn map ( & mut self , from : T , to : Key < T > ) {
self . keymap [ from . into ( ) ] = to ;
2017-09-21 22:34:24 -04:00
}
}
2019-10-06 13:51:01 -04:00
impl < K , T , E , R > KeyMapper < K , T , E , R > for KeyMap < T >
where
T : Into < usize > + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
self . keymap [ event . code ( ) . into ( ) ] . send_event ( key_state , event , device )
2017-09-21 22:34:24 -04:00
}
}
2019-10-06 13:51:01 -04:00
struct CodeKeyMap < T : Into < usize > + TryFrom < usize > + Copy + Default > {
2017-09-23 01:29:23 -04:00
//keymap: Vec<Key>,
2019-10-06 13:51:01 -04:00
keymap : [ T ; KEY_MAX ] ,
2017-09-23 01:29:23 -04:00
}
2019-10-06 13:51:01 -04:00
impl < T : Into < usize > + TryFrom < usize > + Copy + Default > CodeKeyMap < T > {
2017-09-23 01:29:23 -04:00
pub fn new ( ) -> Self {
2019-10-06 13:51:01 -04:00
let mut keymap = [ T ::default ( ) ; KEY_MAX ] ;
2017-09-23 01:29:23 -04:00
// which is rustier
/*
for x in 0 .. KEY_MAX {
keymap [ x as usize ] = x as u16 ;
}
* /
for ( x , v ) in keymap . iter_mut ( ) . enumerate ( ) {
2019-10-06 13:51:01 -04:00
* v = T ::try_from ( x ) . unwrap_or_else ( | _ | panic! ( " cannot convert from usize to T ???? " ) ) ;
2017-09-23 01:29:23 -04:00
}
//println!("keymap: {:?}", &keymap[..]);
CodeKeyMap {
keymap : keymap
}
}
2019-10-06 13:51:01 -04:00
pub fn map ( & mut self , from : T , to : T ) {
self . keymap [ from . into ( ) ] = to ;
2017-09-23 01:29:23 -04:00
}
}
2019-10-06 13:51:01 -04:00
impl < K , T , E , R > KeyMapper < K , T , E , R > for CodeKeyMap < T >
where
T : Into < usize > + TryFrom < usize > + Copy + Default ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , _key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
device . send_mod_code ( self . keymap [ event . code ( ) . into ( ) ] , event )
//self.keymap[event.code().into()].send_event(key_state, event, device)
2017-09-21 22:34:24 -04:00
}
}
// todo:capslock_nomodify is like a whole-key thing, not a half-key thing, split code/invert_shift to own struct, send into send_key from *InvertedKey, maybe anyway, consider it, maybe 1 char for whole key and another for half?
2017-09-23 00:47:20 -04:00
#[ derive(Clone, Copy) ]
2019-10-06 13:51:01 -04:00
struct HalfInvertedKey < T : Clone + Copy > {
code : T ,
2017-09-21 22:34:24 -04:00
// code this is describing
invert_shift : bool ,
// true to invert shift for this code
capslock_nomodify : bool ,
// true means capslock does not normally modify this, but you would like it to
}
2019-10-06 13:51:01 -04:00
fn send_half_inverted_key < K , T , E , R > ( half_inverted_key : & HalfInvertedKey < T > , event : & mut E , device : & K , left_shift : bool , right_shift : bool , caps_lock : bool ) -> Result < R >
where
T : Into < usize > + Clone + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
let value = event . value ( ) ;
let mut invert_shift = half_inverted_key . invert_shift ;
if value = = KeyState ::DOWN {
if caps_lock & & half_inverted_key . capslock_nomodify {
invert_shift = ! invert_shift ;
2017-09-21 22:34:24 -04:00
}
2019-10-06 13:51:01 -04:00
if invert_shift {
let ( shift_code , up_not_down ) = if left_shift {
( device . left_shift_code ( ) , true )
} else if right_shift {
( device . right_shift_code ( ) , true )
} else {
( device . left_shift_code ( ) , false )
} ;
device . send_mod_code_value ( shift_code , up_not_down , event ) ? ;
// SYN_REPORT after, then key, then key's SYN_REPORT
device . synchronize ( ) ? ;
}
}
let ret = device . send_mod_code ( half_inverted_key . code , event ) ? ;
if value = = KeyState ::UP {
if caps_lock & & half_inverted_key . capslock_nomodify {
invert_shift = ! invert_shift ;
}
if invert_shift {
let ( shift_code , up_not_down ) = if left_shift {
( device . left_shift_code ( ) , false )
} else if right_shift {
( device . right_shift_code ( ) , false )
} else {
( device . left_shift_code ( ) , true )
} ;
// SYN_REPORT first after key, then shift, then key's SYN_REPORT which will be used for shift's
device . synchronize ( ) ? ;
device . send_mod_code_value ( shift_code , up_not_down , event ) ? ;
2017-09-21 22:34:24 -04:00
}
}
2019-10-06 13:51:01 -04:00
Ok ( ret )
2017-09-21 22:34:24 -04:00
}
2019-10-06 13:51:01 -04:00
impl < K , T , E , R > KeyMapper < K , T , E , R > for HalfInvertedKey < T >
where
T : Into < usize > + Clone + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
let left_shift = key_state [ device . left_shift_code ( ) . into ( ) ] ;
let right_shift = key_state [ device . right_shift_code ( ) . into ( ) ] ;
let caps_lock = key_state [ device . caps_lock_code ( ) . into ( ) ] ;
send_half_inverted_key ( self , event , device , left_shift , right_shift , caps_lock )
2017-09-21 22:34:24 -04:00
}
}
2017-09-23 00:47:20 -04:00
#[ derive(Clone, Copy) ]
2019-10-06 13:51:01 -04:00
enum Key < T >
where
T : Copy + Clone
{
2017-09-23 00:46:42 -04:00
Noop ,
2019-10-06 13:51:01 -04:00
Direct ( T ) ,
HalfKey ( HalfInvertedKey < T > ) ,
FullKey ( HalfInvertedKey < T > , HalfInvertedKey < T > ) ,
2017-09-21 22:34:24 -04:00
}
2019-10-06 13:51:01 -04:00
impl < K , T , E , R > KeyMapper < K , T , E , R > for Key < T >
where
T : Into < usize > + Copy ,
E : KeyEvent < T > ,
K : Keyboard < T , E , R > ,
{
fn send_event ( & self , key_state : & [ bool ] , event : & mut E , device : & K ) -> Result < R > {
2017-09-23 00:46:42 -04:00
match * self {
Key ::Noop = > {
2019-10-06 13:51:01 -04:00
device . send ( event )
2017-09-23 00:46:42 -04:00
} ,
Key ::Direct ( code ) = > {
2019-10-06 13:51:01 -04:00
device . send_mod_code ( code , event )
2017-09-23 00:46:42 -04:00
} ,
Key ::HalfKey ( ref key_half ) = > {
2017-11-15 01:08:38 -05:00
key_half . send_event ( key_state , event , device )
2017-09-23 00:46:42 -04:00
} ,
Key ::FullKey ( ref noshift_half , ref shift_half ) = > {
2019-10-06 13:51:01 -04:00
let left_shift = key_state [ device . left_shift_code ( ) . into ( ) ] ;
let right_shift = key_state [ device . right_shift_code ( ) . into ( ) ] ;
let caps_lock = key_state [ device . caps_lock_code ( ) . into ( ) ] ;
2017-09-23 00:46:42 -04:00
if caps_lock ! = ( left_shift | | right_shift ) {
2019-10-06 13:51:01 -04:00
send_half_inverted_key ( shift_half , event , device , left_shift , right_shift , caps_lock )
2017-09-23 00:46:42 -04:00
} else {
2019-10-06 13:51:01 -04:00
send_half_inverted_key ( noshift_half , event , device , left_shift , right_shift , caps_lock )
2017-09-23 00:46:42 -04:00
}
} ,
2017-09-21 22:34:24 -04:00
}
}
}
use std ::path ::Path ;
2019-09-30 22:55:16 -04:00
use serde ::Deserialize ;
2017-09-21 22:34:24 -04:00
#[ derive(Deserialize, Debug) ]
pub struct KeymapConfig {
switch_layout_keys : Vec < String > ,
revert_default_key : String ,
revert_keymap_index : usize ,
default_keymap_index : usize ,
keymaps : Vec < String >
}
2017-11-15 01:08:38 -05:00
fn parse_cfg < P : AsRef < Path > > ( path : P ) -> Result < KeymapConfig > {
2017-09-21 22:34:24 -04:00
let mut f = File ::open ( path ) ? ;
let mut input = String ::new ( ) ;
f . read_to_string ( & mut input ) ? ;
//toml::from_str(&input)?
match toml ::from_str ( & input ) {
Ok ( toml ) = > Ok ( toml ) ,
2017-11-15 01:08:38 -05:00
Err ( _ ) = > Err ( Error ::NotFound ) // todo: something better
2017-09-21 22:34:24 -04:00
}
}