diff options
Diffstat (limited to 'src/socket/parser.rs')
-rw-r--r-- | src/socket/parser.rs | 215 |
1 files changed, 163 insertions, 52 deletions
diff --git a/src/socket/parser.rs b/src/socket/parser.rs index e8dd9ec..0de0248 100644 --- a/src/socket/parser.rs +++ b/src/socket/parser.rs @@ -9,94 +9,205 @@ use x11::xlib; use x11::keysym; use command::*; -use dotwm::DotWM; +use ::socket::ParsedCmd; +use ::socket::FnType; -use nom::{IResult,alpha,multispace}; -use nom::IResult::*; -use std::str; - -named!(token<&str>, - map_res!( - alpha, str::from_utf8)); +macro_rules! simple_try { + ($expr:expr) => (match $expr { + Ok(val) => val, + Err(err) => { + return Err(err) + } + }) +} -fn slice2str(input: Vec<&[u8]>) -> Vec<&str> { - let res: Vec<&str> = input.iter() - .map(|x| str::from_utf8(x).unwrap()) - .collect(); - res +fn modifier_from<'a>(s: &'a str) -> Result<u32, &'static str> { + match s { + "Mod1" => Ok(xlib::Mod4Mask), + "Mod2" => Ok(xlib::Mod4Mask), + "Mod3" => Ok(xlib::Mod4Mask), + "Mod4" => Ok(xlib::Mod4Mask), + "Control" => Ok(xlib::ControlMask), + "Shift" => Ok(xlib::ShiftMask), + _ => Err("unknown modifier"), + } } -named!(args<Vec<&str> >, - map!( - separated_list!( - multispace, alpha), - slice2str)); +fn modifiers<'a>(s: &'a str) -> Result<Vec<u32>, &'static str> { + let mut result = vec![]; -fn modifier<'a>(s: &'a str) -> Result<u32, ()> { - match s { - "Mod1Mask" => Ok(xlib::Mod4Mask), - "Mod2Mask" => Ok(xlib::Mod4Mask), - "Mod3Mask" => Ok(xlib::Mod4Mask), - "Mod4Mask" => Ok(xlib::Mod4Mask), - "ControlMask" => Ok(xlib::ControlMask), - "ShiftMask" => Ok(xlib::ShiftMask), - _ => Err(()), + for smod in s.split("-") { + let modifier = simple_try!(modifier_from(smod)); + result.push(modifier); } + + Ok(result) } -fn str_to_key<'a>(s: &'a str) -> Result<u32, ()> { +fn key<'a>(s: &'a str) -> Result<u32, &'static str> { match s { + "a" => Ok(keysym::XK_a), + "b" => Ok(keysym::XK_b), + "c" => Ok(keysym::XK_c), + "d" => Ok(keysym::XK_d), + "e" => Ok(keysym::XK_e), + "f" => Ok(keysym::XK_f), + "g" => Ok(keysym::XK_g), "h" => Ok(keysym::XK_h), + "i" => Ok(keysym::XK_i), "j" => Ok(keysym::XK_j), "k" => Ok(keysym::XK_k), "l" => Ok(keysym::XK_l), - "Tab" => Ok(keysym::XK_Tab), + "m" => Ok(keysym::XK_m), + "n" => Ok(keysym::XK_n), + "o" => Ok(keysym::XK_o), "p" => Ok(keysym::XK_p), - "Return" => Ok(keysym::XK_Return), "q" => Ok(keysym::XK_q), - _ => Err(()), + "r" => Ok(keysym::XK_r), + "s" => Ok(keysym::XK_s), + "t" => Ok(keysym::XK_t), + "u" => Ok(keysym::XK_u), + "v" => Ok(keysym::XK_v), + "w" => Ok(keysym::XK_w), + "x" => Ok(keysym::XK_x), + "y" => Ok(keysym::XK_y), + "z" => Ok(keysym::XK_z), + "A" => Ok(keysym::XK_A), + "B" => Ok(keysym::XK_B), + "C" => Ok(keysym::XK_C), + "D" => Ok(keysym::XK_D), + "E" => Ok(keysym::XK_E), + "F" => Ok(keysym::XK_F), + "G" => Ok(keysym::XK_G), + "H" => Ok(keysym::XK_H), + "I" => Ok(keysym::XK_I), + "J" => Ok(keysym::XK_J), + "K" => Ok(keysym::XK_K), + "L" => Ok(keysym::XK_L), + "M" => Ok(keysym::XK_M), + "N" => Ok(keysym::XK_N), + "O" => Ok(keysym::XK_O), + "P" => Ok(keysym::XK_P), + "Q" => Ok(keysym::XK_Q), + "R" => Ok(keysym::XK_R), + "S" => Ok(keysym::XK_S), + "T" => Ok(keysym::XK_T), + "U" => Ok(keysym::XK_U), + "V" => Ok(keysym::XK_V), + "W" => Ok(keysym::XK_W), + "X" => Ok(keysym::XK_X), + "Y" => Ok(keysym::XK_Y), + "Z" => Ok(keysym::XK_Z), + "Tab" => Ok(keysym::XK_Tab), + "Return" => Ok(keysym::XK_Return), + _ => Err("unknown key"), } } -fn str_to_func<'a>(s: &'a str) -> Result<ExecFn,()> { +fn func<'a>(s: &'a str) -> Result<ExecFn, &'static str> { match s { "exec" => Ok(exec), - "move_win" => Ok(move_win), - "resize_win" => Ok(resize_win), - _ => Err(()), + "move-win" => Ok(move_win), + "move-win-to" => Ok(move_win_to), + "resize-win" => Ok(resize_win), + "focus-next" => Ok(focus_next), + "quit" => Ok(quit_dotwm), + _ => Err("unknown function"), } } -pub fn parse<'a>(dotwm: &mut DotWM, bindings: &mut BindingHash, input: &'a str) -> &'a str { - let args: Vec<&str> = input.split_whitespace().collect(); +pub fn parse<'a>(input: &'a str) -> Result<ParsedCmd<'a>, &'static str> { + let args: Vec<&'a str> = input.split_whitespace().collect(); match args.first() { Some(cmd) => { match cmd { - &"add-binding" => { - let modifier = modifier(args[1]).unwrap(); - let key = str_to_key(args[2]).unwrap(); - let func = str_to_func(args[3]).unwrap(); - let arguments = &args[4..]; + &"bind" => { + if args.len() > 2 { + let modifiers = simple_try!(modifiers(args[1])); + let key = simple_try!(key(args[2])); + let func = simple_try!(func(args[3])); + let arguments: &[&'a str]= &args[4..]; - add_binding(dotwm, bindings, key, modifier, func, arguments); + Ok(ParsedCmd { + f: FnType::Bind, + modifiers: modifiers, + key: key, + args: arguments.to_vec(), + func: func, + }) + } else { + Err("missing arguments") + } + }, + &"exec" => { + Ok(ParsedCmd { + f: FnType::Exec, + modifiers: vec![], + key: 0, + args: vec![], + func: exec + }) + }, + _ => { + Err("unknown command") }, - &"exec" => { println!("exec"); }, - _ => { println!("anotherthing ._."); }, } }, - None => println!("error"), + None => Err("no input"), + } +} + +#[test] +fn parse_unknown() { + let res = parse("unknown"); + if let Err(e) = res { + assert_eq!(e, "unknown command"); + } else { + assert!(false); } - "ok" } #[test] -fn parse_test() { - assert_eq!(token(&b"exec"[..]), IResult::Done(&b""[..], "exec")); +fn parse_bind_modifier() { + let res = parse("bind modifier1 k exec "); + if let Err(e) = res { + assert_eq!(e, "unknown modifier"); + } else { + assert!(false); + } + + let res2 = parse("bind Mod4 k exec "); + if let Ok(modifier) = res2 { + assert_eq!(modifier.modifiers[0], xlib::Mod4Mask); + } else { + assert!(false); + } } #[test] -fn parse_args() { - assert_eq!(args(&b"hola chau"[..]), - IResult::Done(&b""[..], vec!["hola", "chau"])); +fn parse_bind_key() { + let res = parse("bind Mod4 ' exec "); + if let Err(e) = res { + assert_eq!(e, "unknown key"); + } else { + assert!(false); + } + + let res2 = parse("bind Mod4 k exec "); + if let Ok(modifier) = res2 { + assert_eq!(modifier.key, keysym::XK_k); + } else { + assert!(false); + } +} + +#[test] +fn parse_exec() { + let res = parse("exec Mod4 ' exec "); + if let Ok(pcmd) = res { + assert_eq!(pcmd.f, FnType::Exec); + } else { + assert!(false); + } } |