summaryrefslogtreecommitdiff
path: root/src/socket/parser.rs
blob: e8dd9ec7ee5a70d11c04fcb0970f19461421e851 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// See LICENSE file for copyright and license details.

//! Parse the socket info.
//!
//! For now this module will have 2 methods. One for inmediate execution and
//! other for add a bindind.

use x11::xlib;
use x11::keysym;

use command::*;
use dotwm::DotWM;

use nom::{IResult,alpha,multispace};
use nom::IResult::*;
use std::str;

named!(token<&str>,
       map_res!(
           alpha, str::from_utf8));

fn slice2str(input: Vec<&[u8]>) -> Vec<&str> {
    let res: Vec<&str> = input.iter()
                              .map(|x| str::from_utf8(x).unwrap())
                              .collect();
    res
}

named!(args<Vec<&str> >,
       map!(
           separated_list!(
               multispace, alpha),
           slice2str));

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(()),
    }
}

fn str_to_key<'a>(s: &'a str) -> Result<u32, ()> {
    match s {
        "h" => Ok(keysym::XK_h),
        "j" => Ok(keysym::XK_j),
        "k" => Ok(keysym::XK_k),
        "l" => Ok(keysym::XK_l),
        "Tab" => Ok(keysym::XK_Tab),
        "p" => Ok(keysym::XK_p),
        "Return" => Ok(keysym::XK_Return),
        "q" => Ok(keysym::XK_q),
        _ => Err(()),
    }
}

fn str_to_func<'a>(s: &'a str) -> Result<ExecFn,()> {
    match s {
        "exec" => Ok(exec),
        "move_win" => Ok(move_win),
        "resize_win" => Ok(resize_win),
        _ => Err(()),
    }
}

pub fn parse<'a>(dotwm: &mut DotWM, bindings: &mut BindingHash, input: &'a str) -> &'a str {
    let args: Vec<&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..];

                     add_binding(dotwm, bindings, key, modifier, func, arguments);
                },
                &"exec" => { println!("exec"); },
                _ => { println!("anotherthing ._."); },
            }
        },
        None => println!("error"),
    }
    "ok"
}

#[test]
fn parse_test() {
    assert_eq!(token(&b"exec"[..]), IResult::Done(&b""[..], "exec"));
}

#[test]
fn parse_args() {
    assert_eq!(args(&b"hola chau"[..]),
               IResult::Done(&b""[..], vec!["hola", "chau"]));
}