<commit_before>use std::f64::NAN;

use super::js_var::{JsPtrEnum, JsPtrTag, JsType, JsVar};
use super::js_var::JsType::*;
use super::native_var::NativeVar;

pub trait AsBool {
    fn as_bool(&self) -> bool;
}

impl AsBool for JsVar {
    fn as_bool(&self) -> bool {
        match self.t {
            JsBool(b) => b,
            JsUndef=> false,
            JsNull => false,
            JsNum(n) =>
                if n == 0.0f64 || n == -0.0f64 || n.is_nan() {
                    false
                } else {
                    true
                },
            JsPtr(_) => true, // TODO - this is incorrect
            //JsString(ref s) =>
            //    if s.len() == 0 {
            //        false
            //    } else {
            //        true
            //    },
            //JsSymbol(_) => true,
            //JsObject | JsError(_) | JsFunction(_, _, _) => true,
        }
    }
}

pub trait AsNumber {
    fn as_number(&self) -> f64;
}

impl AsNumber for JsVar {
    fn as_number(&self) -> f64 {
        match self.t {
            JsBool(b) => if b { 1f64 } else { 0f64 },
            JsUndef => NAN,
            JsNull => 0f64,
            JsNum(n) => n,
            JsPtr(_) => NAN,
            //JsString(ref s) =>
            //    if s.len() == 0 {
            //        JsNumber(0f64)
            //    } else {
            //        let num = s.parse();
            //        match num {
            //            Ok(n)  => JsNumber(n),
            //            Err(_) => JsNumber(NAN),
            //        }
            //    },
            //JsSymbol(_) => panic!("Cannot convert a Symbol to a number."),
            //JsObject | JsError(_) | JsFunction(_, _, _) => JsNumber(NAN),
        }
    }
}

pub trait AsString {
    fn as_string(&self) -> String;
}

impl AsString for JsType {
    fn as_string(&self) -> String {
        let s = match *self {
            JsBool(true) => "true",
            JsBool(false) => "false",
            JsUndef => "undefined",
            JsNull => "null",
            JsNum(n) => return format!("{}", n),

            // NOTE: These cases should never actually be used; in the case that the variable is
            // a JsPtr, the corresponding JsPtrEnum's string coercion should be used.
            JsPtr(JsPtrTag::JsSym) => "Symbol(...)",
            JsPtr(JsPtrTag::JsStr) => "\"...\"",
            JsPtr(JsPtrTag::JsObj) => "{ ... }",
            JsPtr(JsPtrTag::JsFn{..}) => "function() { ... }",
            JsPtr(JsPtrTag::NativeFn{..}) => "function() { [native code] }",
            JsPtr(JsPtrTag::NativeVar{..}) => "[native code]",
        };

        String::from(s)
    }
}

impl AsString for JsPtrEnum {
    fn as_string(&self) -> String {
        match *self {
            JsPtrEnum::JsSym(ref s) => format!("Symbol({})", s),
            JsPtrEnum::JsStr(ref s) => s.text.to_owned(),

            // TODO: Check object's `toString` method
            JsPtrEnum::JsObj(_) => String::from("[object Object]"),

            // TODO: A function's string representation is apparently the string of source code that
            // created it; the AST doesn't currently support this, so we'll need to do some
            // restructuring before we can support this.
            JsPtrEnum::JsFn(_) => String::from("[function]"),
            JsPtrEnum::NativeFn(_) => String::from("[native function]"),
            JsPtrEnum::NativeVar(NativeVar { ref var, ref ptr, ..}) => ptr.as_ref().map(|p| p.as_string()).unwrap_or(var.t.as_string()),
        }
    }
}
<commit_msg>add AsNumber coercion for JsPtrEnum<commit_after>use std::f64::NAN;

use super::js_str::JsStrStruct;
use super::js_var::{JsPtrEnum, JsPtrTag, JsType, JsVar};
use super::js_var::JsType::*;
use super::native_var::NativeVar;

pub trait AsBool {
    fn as_bool(&self) -> bool;
}

impl AsBool for JsVar {
    fn as_bool(&self) -> bool {
        match self.t {
            JsBool(b) => b,
            JsUndef=> false,
            JsNull => false,
            JsNum(n) =>
                if n == 0.0f64 || n == -0.0f64 || n.is_nan() {
                    false
                } else {
                    true
                },
            JsPtr(_) => true, // TODO - this is incorrect
            //JsString(ref s) =>
            //    if s.len() == 0 {
            //        false
            //    } else {
            //        true
            //    },
            //JsSymbol(_) => true,
            //JsObject | JsError(_) | JsFunction(_, _, _) => true,
        }
    }
}

pub trait AsNumber {
    fn as_number(&self) -> f64;
}

impl AsNumber for JsVar {
    fn as_number(&self) -> f64 {
        match self.t {
            JsBool(b) => if b { 1f64 } else { 0f64 },
            JsUndef => NAN,
            JsNull => 0f64,
            JsNum(n) => n,
            JsPtr(_) => NAN,
        }
    }
}

impl AsNumber for JsPtrEnum {
    fn as_number(&self) -> f64 {
        match self {
            // TODO: Change this to throw a TypeError
            &JsPtrEnum::JsSym(_) => panic!("Cannot convert a Symbol to a number."),
            &JsPtrEnum::JsStr(JsStrStruct { ref text }) => {
                if text.len() == 0 {
                    return 0.0
                }

                text.parse().unwrap_or(NAN)
            }
            &JsPtrEnum::NativeVar(NativeVar { ref var, ref ptr, .. }) => match (var, ptr) {
                (_, &Some(ref ptr)) => ptr.as_number(),
                (ref var, &None) => var.as_number(),
            },
            _ => NAN
        }
    }
}

pub trait AsString {
    fn as_string(&self) -> String;
}

impl AsString for JsType {
    fn as_string(&self) -> String {
        let s = match *self {
            JsBool(true) => "true",
            JsBool(false) => "false",
            JsUndef => "undefined",
            JsNull => "null",
            JsNum(n) => return format!("{}", n),

            // NOTE: These cases should never actually be used; in the case that the variable is
            // a JsPtr, the corresponding JsPtrEnum's string coercion should be used.
            JsPtr(JsPtrTag::JsSym) => "Symbol(...)",
            JsPtr(JsPtrTag::JsStr) => "\"...\"",
            JsPtr(JsPtrTag::JsObj) => "{ ... }",
            JsPtr(JsPtrTag::JsFn{..}) => "function() { ... }",
            JsPtr(JsPtrTag::NativeFn{..}) => "function() { [native code] }",
            JsPtr(JsPtrTag::NativeVar{..}) => "[native code]",
        };

        String::from(s)
    }
}

impl AsString for JsPtrEnum {
    fn as_string(&self) -> String {
        match *self {
            JsPtrEnum::JsSym(ref s) => format!("Symbol({})", s),
            JsPtrEnum::JsStr(ref s) => s.text.to_owned(),

            // TODO: Check object's `toString` method
            JsPtrEnum::JsObj(_) => String::from("[object Object]"),

            // TODO: A function's string representation is apparently the string of source code that
            // created it; the AST doesn't currently support this, so we'll need to do some
            // restructuring before we can support this.
            JsPtrEnum::JsFn(_) => String::from("[function]"),
            JsPtrEnum::NativeFn(_) => String::from("[native function]"),
            JsPtrEnum::NativeVar(NativeVar { ref var, ref ptr, ..}) => ptr.as_ref().map(|p| p.as_string()).unwrap_or(var.t.as_string()),
        }
    }
}
<|endoftext|>


<commit_before>extern crate ws;

use self::ws::{Handler, Sender, Result, Message, Handshake, CloseCode, Error, Settings};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

use std::rc::Rc;
use std::cell::Cell;

struct Server {
    clients:Arc<Mutex<HashMap<u32, Sender>>>,
    out: Sender,
    count: Rc<Cell<u32>>,
    id : u32,
}
trait HasBroadcast {
	fn broadcast(&self, msg: Message)->Result<()>;
}
impl HasBroadcast for Server {
	fn broadcast(&self, msg:Message)->Result<()> {
        for (key, client) in self.clients.lock().unwrap().iter(){
        	if *key != self.id {
	        	// println!("{:?} {:?}", *key, self.id);
	        	client.send(msg.clone());
	        	client.send(format!("hello {} from {}",key, &self.id));
       		}
        }
        return Ok(());
	}
}

pub fn create() {

  println!("0.0.0.0:3012");
  let count = Rc::new(Cell::new(0));
  let uuid = Rc::new(Cell::new(100));
  let map:HashMap<u32, Sender> = HashMap::new();
  let mutex_map = Arc::new(Mutex::new(map));
  ws::Settings.max_connections = 200;
  let ws = ws::listen("0.0.0.0:3012", |out| {
  	uuid.set(uuid.get()+1);
    let id = uuid.get();

  	 Server { out: out, count: count.clone(), clients:mutex_map.clone(), id:id }
  }).unwrap();

}

impl Handler for Server {

    fn on_open(&mut self, _: Handshake) -> Result<()> {
        self.clients.lock().unwrap().insert(self.id.clone(), self.out.clone());

        Ok(self.count.set(self.count.get() + 1))
    }

    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("The number of live connections is {}", self.count.get());
        self.broadcast(msg)?;
        return Ok(())
//        self.out.send(msg)
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        self.clients.lock().unwrap().remove(&self.id.clone());

        match code {
            CloseCode::Normal => println!("The client is done with the connection."),
            CloseCode::Away   => println!("The client is leaving the site."),
            CloseCode::Abnormal => println!(
                "Closing handshake failed! Unable to obtain closing status from client."),
            _ => println!("The client encountered an error: {}", reason),
        }

        // The connection is going down, so we need to decrement the count
        self.count.set(self.count.get() - 1)
    }

    fn on_error(&mut self, err: Error) {
        println!("The server encountered an error: {:?}", err);
    }
}
<commit_msg>clean up warnings<commit_after>extern crate ws;

use self::ws::{Handler, Sender, Result, Message, Handshake, CloseCode, Error};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

use std::rc::Rc;
use std::cell::Cell;

struct Server {
    clients:Arc<Mutex<HashMap<u32, Sender>>>,
    out: Sender,
    count: Rc<Cell<u32>>,
    id : u32,
}
trait HasBroadcast {
	fn broadcast(&self, msg: Message)->Result<()>;
}
impl HasBroadcast for Server {
	fn broadcast(&self, msg:Message)->Result<()> {
        for (key, client) in self.clients.lock().unwrap().iter(){
        	if *key != self.id {
	        	// println!("{:?} {:?}", *key, self.id);
	        	client.send(msg.clone()).unwrap();
	        	client.send(format!("hello {} from {}",key, &self.id)).unwrap();
       		}
        }
        return Ok(());
	}
}

pub fn create() {

  println!("0.0.0.0:3012");
  let count = Rc::new(Cell::new(0));
  let uuid = Rc::new(Cell::new(100));
  let map:HashMap<u32, Sender> = HashMap::new();
  let mutex_map = Arc::new(Mutex::new(map));

  let ws = ws::listen("0.0.0.0:3012", |out| {
  	uuid.set(uuid.get()+1);
    let id = uuid.get();

  	 Server { out: out, count: count.clone(), clients:mutex_map.clone(), id:id }
  }).unwrap();
  return ws;
}

impl Handler for Server {

    fn on_open(&mut self, _: Handshake) -> Result<()> {
        self.clients.lock().unwrap().insert(self.id.clone(), self.out.clone());

        Ok(self.count.set(self.count.get() + 1))
    }

    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("The number of live connections is {}", self.count.get());
        self.broadcast(msg)?;
        return Ok(())
//        self.out.send(msg)
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        self.clients.lock().unwrap().remove(&self.id.clone());

        match code {
            CloseCode::Normal => println!("The client is done with the connection."),
            CloseCode::Away   => println!("The client is leaving the site."),
            CloseCode::Abnormal => println!(
                "Closing handshake failed! Unable to obtain closing status from client."),
            _ => println!("The client encountered an error: {}", reason),
        }

        // The connection is going down, so we need to decrement the count
        self.count.set(self.count.get() - 1)
    }

    fn on_error(&mut self, err: Error) {
        println!("The server encountered an error: {:?}", err);
    }
}
<|endoftext|>


<commit_before>extern crate winapi;
extern crate user32;

use self::user32::*;
use self::winapi::*;

use ::{KeyboardControllable, Key, MouseControllable, MouseButton};
use win::keycodes::*;
use std::mem::*;

/// The main struct for handling the event emitting
pub struct Enigo {
    current_x: i32,
    current_y: i32,
}

impl Enigo {
    // TODO(dustin): do the right initialisation

    /// Constructs a new `Enigo` instance.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use enigo::*;
    /// let mut enigo = Enigo::new();
    /// ```
    pub fn new() -> Self {
        Enigo {
            current_x: 0,
            current_y: 0,
        }
    }
}

impl MouseControllable for Enigo {
    fn mouse_move_to(&mut self, x: i32, y: i32) {
        // TODO(dustin): use interior mutability
        self.current_x = x;
        self.current_y = y;
        unsafe { SetCursorPos(self.current_x, self.current_y) };
    }

    fn mouse_move_relative(&mut self, x: i32, y: i32) {
        // TODO(dustin): use interior mutability
        self.current_x += x;
        self.current_y += y;
        unsafe { SetCursorPos(self.current_x, self.current_y) };
    }

    fn mouse_down(&mut self, button: MouseButton) {
        unsafe {
            let mut input = INPUT {
                type_: INPUT_MOUSE,
                u: transmute_copy(&MOUSEINPUT {
                                      dx: 0,
                                      dy: 0,
                                      mouseData: 0,
                                      dwFlags: match button {
                                          MouseButton::Left => MOUSEEVENTF_LEFTDOWN,
                                          MouseButton::Middle => MOUSEEVENTF_MIDDLEDOWN,
                                          MouseButton::Right => MOUSEEVENTF_RIGHTDOWN,

                                          _ => unimplemented!(),
                                      },
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }
    }

    fn mouse_up(&mut self, button: MouseButton) {
        unsafe {
            let mut input = INPUT {
                type_: INPUT_MOUSE,
                u: transmute_copy(&MOUSEINPUT {
                                      dx: 0,
                                      dy: 0,
                                      mouseData: 0,
                                      dwFlags: match button {
                                          MouseButton::Left => MOUSEEVENTF_LEFTUP,
                                          MouseButton::Middle => MOUSEEVENTF_MIDDLEUP,
                                          MouseButton::Right => MOUSEEVENTF_RIGHTUP,

                                          _ => unimplemented!(),
                                      },
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }
    }

    fn mouse_click(&mut self, button: MouseButton) {
        self.mouse_down(button);
        self.mouse_up(button);
    }

    fn mouse_scroll_x(&mut self, length: i32) {
        let mut scroll_direction = 1 * 50; // 1 left -1 right
        let mut length = length;

        if length < 0 {
            length *= -1;
            scroll_direction *= -1;
        }

        for _ in 0..length {
            unsafe {
                let mut input = INPUT {
                    type_: INPUT_MOUSE,
                    u: transmute_copy(&MOUSEINPUT {
                                          dx: 0,
                                          dy: 0,
                                          mouseData: transmute_copy(&scroll_direction),
                                          dwFlags: MOUSEEVENTF_HWHEEL,
                                          time: 0,
                                          dwExtraInfo: 0,
                                      }),
                };

                SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
            }
        }
    }

    fn mouse_scroll_y(&mut self, length: i32) {
        let mut scroll_direction = -1 * 50; // 1 left -1 right
        let mut length = length;

        if length < 0 {
            length *= -1;
            scroll_direction *= -1;
        }

        for _ in 0..length {
            unsafe {
                let mut input = INPUT {
                    type_: INPUT_MOUSE,
                    u: transmute_copy(&MOUSEINPUT {
                                          dx: 0,
                                          dy: 0,
                                          mouseData: transmute_copy(&scroll_direction),
                                          dwFlags: MOUSEEVENTF_WHEEL,
                                          time: 0,
                                          dwExtraInfo: 0,
                                      }),
                };

                SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
            }
        }
    }
}

impl KeyboardControllable for Enigo {
    fn key_sequence(&mut self, sequence: &str) {
        let mut buffer = [0; 2];

        for c in sequence.chars() {
            //Windows uses uft-16 encoding. We need to check
            //for variable length characters. As such some
            //characters can be 32 bit long and those are
            //encoded in such called hight and low surrogates
            //each 16 bit wide that needs to be send after
            //another to the SendInput function without
            //being interrupted by "keyup"
            let result = c.encode_utf16(&mut buffer);
            if result.len() == 1 {
                self.unicode_key_click(result[0]);
            } else {
                for utf16_surrogate in result {
                    self.unicode_key_down(utf16_surrogate.clone());
                }
                //do i need to produce a keyup?
                //self.unicode_key_up(0);
            }
        }
    }

    fn key_click(&mut self, key: Key) {
        let keycode = self.key_to_keycode(key);

        use std::{thread, time};
        thread::sleep(time::Duration::from_millis(20));

        unsafe {
            let mut input = INPUT {
                type_: INPUT_KEYBOARD,
                u: transmute_copy(&KEYBDINPUT {
                                      wVk: keycode,
                                      wScan: 0,
                                      dwFlags: 0,
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }

        thread::sleep(time::Duration::from_millis(20));

        unsafe {
            let mut input = INPUT {
                type_: INPUT_KEYBOARD,
                u: transmute_copy(&KEYBDINPUT {
                                      wVk: keycode,
                                      wScan: 0,
                                      dwFlags: KEYEVENTF_KEYUP,
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }

        thread::sleep(time::Duration::from_millis(20));
    }

    fn key_down(&mut self, key: Key) {
        unsafe {
            let mut input = INPUT {
                type_: INPUT_KEYBOARD,
                u: transmute_copy(&KEYBDINPUT {
                                      wVk: self.key_to_keycode(key),
                                      wScan: 0,
                                      dwFlags: 0,
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }
    }

    fn key_up(&mut self, key: Key) {
        unsafe {
            let mut input = INPUT {
                type_: INPUT_KEYBOARD,
                u: transmute_copy(&KEYBDINPUT {
                                      wVk: self.key_to_keycode(key),
                                      wScan: 0,
                                      dwFlags: KEYEVENTF_KEYUP,
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }
    }
}

impl Enigo {
    fn unicode_key_click(&self, unicode_char: u16) {
        use std::{thread, time};
        thread::sleep(time::Duration::from_millis(20));
        self.unicode_key_down(unicode_char);
        self.unicode_key_up(unicode_char);
        thread::sleep(time::Duration::from_millis(20));
    }

    fn unicode_key_down(&self, unicode_char: u16) {
        unsafe {
            let mut input = INPUT {
                type_: INPUT_KEYBOARD,
                u: transmute_copy(&KEYBDINPUT {
                                      wVk: 0,
                                      wScan: unicode_char,
                                      dwFlags: KEYEVENTF_UNICODE,
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }
    }

    fn unicode_key_up(&self, unicode_char: u16) {
        unsafe {
            let mut input = INPUT {
                type_: INPUT_KEYBOARD,
                u: transmute_copy(&KEYBDINPUT {
                                      wVk: 0,
                                      wScan: unicode_char,
                                      dwFlags: KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
                                      time: 0,
                                      dwExtraInfo: 0,
                                  }),
            };

            SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int);
        }
    }

    fn key_to_keycode(&self, key: Key) -> u16 {
        //do not use the codes from crate winapi they're
        //wrongly typed with i32 instead of i16 use the
        //ones provided by win/keycodes.rs that are prefixed
        //with an 'E' infront of the original name
        match key {
            Key::Return => EVK_RETURN,
            Key::Tab => EVK_TAB,
            Key::Space => EVK_SPACE,
            Key::Backspace => EVK_BACK,
            Key::Escape => EVK_ESCAPE,
            Key::Super => EVK_LWIN,
            Key::Command => EVK_LWIN,
            Key::Windows => EVK_LWIN,
            Key::Shift => EVK_SHIFT,
            Key::CapsLock => EVK_CAPITAL,
            Key::Alt => EVK_MENU,
            Key::Option => EVK_MENU,
            Key::Control => EVK_LCONTROL,
            Key::Home => EVK_HOME,
            Key::PageUp => EVK_PRIOR,
            Key::PageDown => EVK_NEXT,
            Key::LeftArrow => EVK_LEFT,
            Key::RightArrow => EVK_RIGHT,
            Key::DownArrow => EVK_DOWN,
            Key::UpArrow => EVK_UP,
            Key::F1 => EVK_F1,
            Key::F2 => EVK_F2,
            Key::F3 => EVK_F3,
            Key::F4 => EVK_F4,
            Key::F5 => EVK_F5,
            Key::F6 => EVK_F6,
            Key::F7 => EVK_F7,
            Key::F8 => EVK_F8,
            Key::F9 => EVK_F9,
            Key::F10 => EVK_F10,
            Key::F11 => EVK_F11,
            Key::F12 => EVK_F12,

            Key::Raw(raw_keycode) => raw_keycode,
            Key::Layout(string) => self.get_layoutdependent_keycode(string),
            //_ => 0,
        }
    }

    fn get_layoutdependent_keycode(&self, string: String) -> u16 {
        let mut buffer = [0; 2];
        //get the first char from the string ignore the rest
        //ensure its not a multybyte char
        let utf16 = string
            .chars()
            .nth(0)
            .expect("no valid input") //TODO(dustin): no panic here make an error
            .encode_utf16(&mut buffer);
        if utf16.len() != 1 {
            //TODO(dustin) don't panic here use an apropriate errors
            panic!("this char is not allowd");
        }
        //NOTE VkKeyScanW uses the current keyboard layout
        //to specify a layout use VkKeyScanExW and GetKeyboardLayout
        //or load one with LoadKeyboardLayoutW
        let keycode_and_shiftstate = unsafe { VkKeyScanW(utf16[0]) };
        //0x41 as u16 //key that has the letter 'a' on it on english like keylayout
        keycode_and_shiftstate as u16
    }
}
<commit_msg>win impl refactor<commit_after>extern crate winapi;
extern crate user32;

use self::user32::*;
use self::winapi::*;

use ::{KeyboardControllable, Key, MouseControllable, MouseButton};
use win::keycodes::*;
use std::mem::*;

/// The main struct for handling the event emitting
pub struct Enigo {}

impl Enigo {
    /// Constructs a new `Enigo` instance.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use enigo::*;
    /// let mut enigo = Enigo::new();
    /// ```
    pub fn new() -> Self {
        Enigo {}
    }
}

fn mouse_event(flags: u32, data: u32, dx: i32, dy: i32) {
    let mut input = INPUT {
        type_: INPUT_MOUSE,
        u: unsafe{transmute(MOUSEINPUT {
            dx: dx,
            dy: dy,
            mouseData: data,
            dwFlags: flags,
            time: 0,
            dwExtraInfo: 0,
        })},
    };
    unsafe{SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int)};
}

fn keybd_event(flags: u32, vk: u16, scan: u16) {
    let mut input = INPUT {
        type_: INPUT_KEYBOARD,
        u: unsafe{transmute_copy(&KEYBDINPUT {
            wVk: vk,
            wScan: scan,
            dwFlags: flags,
            time: 0,
            dwExtraInfo: 0,
        })}
    };
    unsafe{SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int)};
}

impl MouseControllable for Enigo {
    fn mouse_move_to(&mut self, x: i32, y: i32) {
        mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, 0,
            x*65335/unsafe{GetSystemMetrics(78)},
            y*65335/unsafe{GetSystemMetrics(79)}
        );
    }

    fn mouse_move_relative(&mut self, x: i32, y: i32) {
        mouse_event(MOUSEEVENTF_MOVE, 0, x, y);
    }

    fn mouse_down(&mut self, button: MouseButton) {
        mouse_event(MOUSEEVENTF_MOVE, match button {
            MouseButton::Left => MOUSEEVENTF_LEFTDOWN,
            MouseButton::Middle => MOUSEEVENTF_MIDDLEDOWN,
            MouseButton::Right => MOUSEEVENTF_RIGHTDOWN,
            _ => unimplemented!()
        }, 0, 0);
    }

    fn mouse_up(&mut self, button: MouseButton) {
        mouse_event(MOUSEEVENTF_MOVE, match button {
            MouseButton::Left => MOUSEEVENTF_LEFTUP,
            MouseButton::Middle => MOUSEEVENTF_MIDDLEUP,
            MouseButton::Right => MOUSEEVENTF_RIGHTUP,
            _ => unimplemented!()
        }, 0, 0);
    }

    fn mouse_click(&mut self, button: MouseButton) {
        self.mouse_down(button);
        self.mouse_up(button);
    }

    fn mouse_scroll_x(&mut self, length: i32) {
        mouse_event(MOUSEEVENTF_HWHEEL, unsafe{transmute(length*120)}, 0, 0);
    }

    fn mouse_scroll_y(&mut self, length: i32) {
        mouse_event(MOUSEEVENTF_WHEEL, unsafe{transmute(length*120)}, 0, 0);
    }
}

impl KeyboardControllable for Enigo {
    fn key_sequence(&mut self, sequence: &str) {
        let mut buffer = [0; 2];

        for c in sequence.chars() {
            //Windows uses uft-16 encoding. We need to check
            //for variable length characters. As such some
            //characters can be 32 bit long and those are
            //encoded in such called hight and low surrogates
            //each 16 bit wide that needs to be send after
            //another to the SendInput function without
            //being interrupted by "keyup"
            let result = c.encode_utf16(&mut buffer);
            if result.len() == 1 {
                self.unicode_key_click(result[0]);
            } else {
                for utf16_surrogate in result {
                    self.unicode_key_down(utf16_surrogate.clone());
                }
                //do i need to produce a keyup?
                //self.unicode_key_up(0);
            }
        }
    }

    fn key_click(&mut self, key: Key) {
        let keycode = self.key_to_keycode(key);
        use std::{thread, time};
        keybd_event(0, keycode, 0);
        thread::sleep(time::Duration::from_millis(20));
        keybd_event(KEYEVENTF_KEYUP, keycode, 0);
    }

    fn key_down(&mut self, key: Key) {
        keybd_event(0, self.key_to_keycode(key), 0);
    }

    fn key_up(&mut self, key: Key) {
        keybd_event(KEYEVENTF_KEYUP, self.key_to_keycode(key), 0);
    }
}

impl Enigo {
    fn unicode_key_click(&self, unicode_char: u16) {
        use std::{thread, time};
        self.unicode_key_down(unicode_char);
        thread::sleep(time::Duration::from_millis(20));
        self.unicode_key_up(unicode_char);
    }

    fn unicode_key_down(&self, unicode_char: u16) {
        keybd_event(KEYEVENTF_UNICODE, 0, unicode_char);
    }

    fn unicode_key_up(&self, unicode_char: u16) {
        keybd_event(KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, 0, unicode_char);
    }

    fn key_to_keycode(&self, key: Key) -> u16 {
        //do not use the codes from crate winapi they're
        //wrongly typed with i32 instead of i16 use the
        //ones provided by win/keycodes.rs that are prefixed
        //with an 'E' infront of the original name
        match key {
            Key::Return => EVK_RETURN,
            Key::Tab => EVK_TAB,
            Key::Space => EVK_SPACE,
            Key::Backspace => EVK_BACK,
            Key::Escape => EVK_ESCAPE,
            Key::Super => EVK_LWIN,
            Key::Command => EVK_LWIN,
            Key::Windows => EVK_LWIN,
            Key::Shift => EVK_SHIFT,
            Key::CapsLock => EVK_CAPITAL,
            Key::Alt => EVK_MENU,
            Key::Option => EVK_MENU,
            Key::Control => EVK_LCONTROL,
            Key::Home => EVK_HOME,
            Key::PageUp => EVK_PRIOR,
            Key::PageDown => EVK_NEXT,
            Key::LeftArrow => EVK_LEFT,
            Key::RightArrow => EVK_RIGHT,
            Key::DownArrow => EVK_DOWN,
            Key::UpArrow => EVK_UP,
            Key::F1 => EVK_F1,
            Key::F2 => EVK_F2,
            Key::F3 => EVK_F3,
            Key::F4 => EVK_F4,
            Key::F5 => EVK_F5,
            Key::F6 => EVK_F6,
            Key::F7 => EVK_F7,
            Key::F8 => EVK_F8,
            Key::F9 => EVK_F9,
            Key::F10 => EVK_F10,
            Key::F11 => EVK_F11,
            Key::F12 => EVK_F12,

            Key::Raw(raw_keycode) => raw_keycode,
            Key::Layout(string) => self.get_layoutdependent_keycode(string),
            //_ => 0,
        }
    }

    fn get_layoutdependent_keycode(&self, string: String) -> u16 {
        let mut buffer = [0; 2];
        //get the first char from the string ignore the rest
        //ensure its not a multybyte char
        let utf16 = string
            .chars()
            .nth(0)
            .expect("no valid input") //TODO(dustin): no panic here make an error
            .encode_utf16(&mut buffer);
        if utf16.len() != 1 {
            //TODO(dustin) don't panic here use an apropriate errors
            panic!("this char is not allowd");
        }
        //NOTE VkKeyScanW uses the current keyboard layout
        //to specify a layout use VkKeyScanExW and GetKeyboardLayout
        //or load one with LoadKeyboardLayoutW
        let keycode_and_shiftstate = unsafe { VkKeyScanW(utf16[0]) };
        //0x41 as u16 //key that has the letter 'a' on it on english like keylayout
        keycode_and_shiftstate as u16
    }
}<|endoftext|>


<commit_before>use super::{NativeSqlType, FromSql};
use {Queriable, Table, Column, QuerySource};
use query_source::SelectableColumn;
use row::Row;

// FIXME(https://github.com/rust-lang/rust/issues/19630) Remove this work-around
macro_rules! e {
    ($e:expr) => { $e }
}

macro_rules! tuple_impls {
    ($(
        $Tuple:ident {
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
        }
    )+) => {
        $(
            impl<$($T:NativeSqlType),+> NativeSqlType for ($($T,)+) {}

            impl<$($T),+,$($ST),+> FromSql<($($ST),+)> for ($($T),+) where
                $($T: FromSql<$ST>),+,
                $($ST: NativeSqlType),+
            {
                #[allow(unused_assignments)]
                fn from_sql<T: Row>(row: &mut T) -> Self {
                    ($($T::from_sql(row)),+)
                }
            }

            impl<$($T),+,$($ST),+> Queriable<($($ST),+)> for ($($T),+) where
                $($T: FromSql<$ST>),+,
                $($ST: NativeSqlType),+
            {
                type Row = Self;

                fn build(row: Self::Row) -> Self {
                    row
                }
            }

            impl<$($T),+, $($ST),+, $($TT),+>
                Column<($($ST),+), ($($TT),+)> for ($($T),+) where
                $($T: Column<$ST, $TT>),+,
            {
                #[allow(non_snake_case)]
                fn name(&self) -> String {
                    let parts: &[String] = e!(&[$(self.$idx.name()),*]);
                    parts.join(", ")
                }
            }

            impl<$($T),+, $($ST),+, $($TT),+, QS>
                SelectableColumn<($($ST),+), ($($TT),+), QS>
                for ($($T),+) where
                $($T: SelectableColumn<$ST, $TT, QS>),+,
                QS: QuerySource,
            {}
        )+
    }
}

tuple_impls! {
    T2 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
    }
    T3 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
    }
    T4 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
    }
    T5 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
    }
    T6 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
    }
    T7 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
    }
    T8 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
    }
    T9 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
    }
    T10 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
        (9) -> J, SJ, TJ,
    }
    T11 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
        (9) -> J, SJ, TJ,
        (10) -> K, SK, TK,
    }
    T12 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
        (9) -> J, SJ, TJ,
        (10) -> K, SK, TK,
        (11) -> L, SL, TL,
    }
}
<commit_msg>Remove an unnecessary lint skip<commit_after>use super::{NativeSqlType, FromSql};
use {Queriable, Table, Column, QuerySource};
use query_source::SelectableColumn;
use row::Row;

// FIXME(https://github.com/rust-lang/rust/issues/19630) Remove this work-around
macro_rules! e {
    ($e:expr) => { $e }
}

macro_rules! tuple_impls {
    ($(
        $Tuple:ident {
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
        }
    )+) => {
        $(
            impl<$($T:NativeSqlType),+> NativeSqlType for ($($T,)+) {}

            impl<$($T),+,$($ST),+> FromSql<($($ST),+)> for ($($T),+) where
                $($T: FromSql<$ST>),+,
                $($ST: NativeSqlType),+
            {
                fn from_sql<T: Row>(row: &mut T) -> Self {
                    ($($T::from_sql(row)),+)
                }
            }

            impl<$($T),+,$($ST),+> Queriable<($($ST),+)> for ($($T),+) where
                $($T: FromSql<$ST>),+,
                $($ST: NativeSqlType),+
            {
                type Row = Self;

                fn build(row: Self::Row) -> Self {
                    row
                }
            }

            impl<$($T),+, $($ST),+, $($TT),+>
                Column<($($ST),+), ($($TT),+)> for ($($T),+) where
                $($T: Column<$ST, $TT>),+,
            {
                #[allow(non_snake_case)]
                fn name(&self) -> String {
                    let parts: &[String] = e!(&[$(self.$idx.name()),*]);
                    parts.join(", ")
                }
            }

            impl<$($T),+, $($ST),+, $($TT),+, QS>
                SelectableColumn<($($ST),+), ($($TT),+), QS>
                for ($($T),+) where
                $($T: SelectableColumn<$ST, $TT, QS>),+,
                QS: QuerySource,
            {}
        )+
    }
}

tuple_impls! {
    T2 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
    }
    T3 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
    }
    T4 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
    }
    T5 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
    }
    T6 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
    }
    T7 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
    }
    T8 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
    }
    T9 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
    }
    T10 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
        (9) -> J, SJ, TJ,
    }
    T11 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
        (9) -> J, SJ, TJ,
        (10) -> K, SK, TK,
    }
    T12 {
        (0) -> A, SA, TA,
        (1) -> B, SB, TB,
        (2) -> C, SC, TC,
        (3) -> D, SD, TD,
        (4) -> E, SE, TE,
        (5) -> F, SF, TF,
        (6) -> G, SG, TG,
        (7) -> H, SH, TH,
        (8) -> I, SI, TI,
        (9) -> J, SJ, TJ,
        (10) -> K, SK, TK,
        (11) -> L, SL, TL,
    }
}
<|endoftext|>


<commit_before>use std::str;
use rustc_serialize::hex::FromHex;
use std::path::PathBuf;

use rex_utils;
use rex_utils::rect::Rect;
use super::super::frontend::{Frontend, Style, KeyPress};
use super::input::Input;
use super::widget::Widget;

use super::common::Canceled;

pub enum BaseInputLineActions {
    Edit(char),
    Ctrl(char),
    MoveLeft,
    MoveRight,
    DeleteWithMove,
    Ok,
    Cancel
}

pub trait InputLineBehavior {
    fn get_prefix(&mut self) -> String;
    fn do_enter(&mut self, data: &[u8]);
    fn do_cancel(&mut self);
    fn do_shortcut(&mut self, shortcut: char) {

    }
}

pub struct InputLine<T:InputLineBehavior> {
    behavior: T,
    data: Vec<u8>,
    input_pos: isize,
}

impl<T:InputLineBehavior> InputLine<T> {
    pub fn new(behavior: T) -> InputLine<T> {
        InputLine {
            behavior: behavior,
            data: vec![],
            input_pos: 0,
        }
    }
}

impl<T:InputLineBehavior> Widget for InputLine<T> {
    fn input(&mut self, input: &Input, key: KeyPress) -> bool {
        let action = if let Some(action) = input.inputline_input(key) { action } else {
            return false;
        };

        match action {
            BaseInputLineActions::Ok => {
                self.behavior.do_enter(&self.data)
            }
            BaseInputLineActions::Cancel => {
                self.behavior.do_cancel()
            }
            BaseInputLineActions::MoveLeft => {
                if self.input_pos > 0 {
                    self.input_pos -= 1;
                }
            }
            BaseInputLineActions::MoveRight => {
                if self.input_pos < self.data.len() as isize {
                    self.input_pos += 1;
                }
            }
            BaseInputLineActions::Edit(ch) => {
                if ch.len_utf8() == 1 {
                    self.data.insert(self.input_pos as usize, ch as u8);
                    self.input_pos += 1;
                } else {
                    // TODO: Make it printable rather than alphanumeric
                }
            }
            BaseInputLineActions::Ctrl(ch) => {
                self.behavior.do_shortcut(ch)
            }
            BaseInputLineActions::DeleteWithMove => {
                if self.input_pos > 0 {
                    self.input_pos -= 1;
                    self.data.remove(self.input_pos as usize);
                }
            }
        };

        return true;
    }

    fn draw(&mut self, rb: &mut Frontend, area: Rect<isize>, has_focus: bool) {
        let prefix = self.behavior.get_prefix();
        rb.print_style(area.left as usize, area.top as usize, Style::InputLine,
                 &rex_utils::string_with_repeat(' ', area.width as usize));
        rb.print_style(area.left as usize, area.top as usize, Style::InputLine,
                 &format!("{}{}", prefix, str::from_utf8(&self.data).unwrap()));
        if has_focus {
            rb.set_cursor(prefix.len() as isize + self.input_pos, (area.top as isize));
        }
    }
}

enum RadixType {
    DecRadix,
    HexRadix,
    OctRadix,
}

signal_decl!{GotoEvent(isize)}

pub struct GotoInputLineBehavior {
    radix: RadixType,
    pub on_done: GotoEvent,
    pub on_cancel: Canceled,
}

impl GotoInputLineBehavior {
    pub fn new() -> GotoInputLineBehavior {
        GotoInputLineBehavior {
            radix: RadixType::DecRadix,
            on_done: Default::default(),
            on_cancel: Default::default(),
        }
    }

    fn set_radix(&mut self, r: RadixType) {
        self.radix = r;
    }

    fn do_goto(&mut self, data: &[u8]) {
        let radix = match self.radix {
            RadixType::DecRadix => 10,
            RadixType::HexRadix => 16,
            RadixType::OctRadix => 8,
        };

        let pos: Option<isize> = match str::from_utf8(&data) {
            Ok(gs) => isize::from_str_radix(&gs, radix).ok(),
            Err(_) => None
        };

        match pos {
            Some(pos) => {
                self.on_done.signal(pos)
            }
            None => {
                self.on_cancel.signal(Some(format!("Bad position!")));
            }
        };

    }
}

impl InputLineBehavior for GotoInputLineBehavior {
    fn get_prefix(&mut self) -> String {
        match self.radix {
            RadixType::DecRadix => "Goto (Dec):".to_string(),
            RadixType::HexRadix => "Goto (Hex):".to_string(),
            RadixType::OctRadix => "Goto (Oct):".to_string(),
        }
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.do_goto(data);
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }

    fn do_shortcut(&mut self, shortcut: char) {
        match shortcut {
            'd' => {
                self.set_radix(RadixType::DecRadix);
            }
            'h' => {
                self.set_radix(RadixType::HexRadix);
            }
            'o' => {
                self.set_radix(RadixType::OctRadix);
            }
            _ => ()
        }
    }
}

enum DataType {
    AsciiStr,
    UnicodeStr,
    HexStr,
}

signal_decl!{FindEvent(Vec<u8>)}

pub struct FindInputLine {
    data_type: DataType,
    pub on_find: FindEvent,
    pub on_cancel: Canceled,
}

impl FindInputLine {
    pub fn new() -> FindInputLine {
        FindInputLine {
            data_type: DataType::AsciiStr,
            on_find: Default::default(),
            on_cancel: Default::default(),
        }
    }

    fn set_search_data_type(&mut self, dt: DataType) {
        self.data_type = dt;
    }

    fn do_find(&mut self, data: &[u8]) {
        let ll = str::from_utf8(data).unwrap().from_hex();

        let needle: Vec<u8> = match self.data_type {
            DataType::AsciiStr => data.clone().into(),
            DataType::UnicodeStr => data.clone().into(),
            DataType::HexStr => {
                match ll {
                    Ok(n) => n,
                    Err(_) => {
                        self.on_cancel.signal(Some(format!("Bad hex value")));
                        return;
                    }
                }
            }
        };

        self.on_find.signal(needle);
    }
}

impl InputLineBehavior for FindInputLine {
    fn get_prefix(&mut self) -> String {
        match self.data_type {
            DataType::AsciiStr => "Find(Ascii): ".to_string(),
            DataType::UnicodeStr => "Find(Uni): ".to_string(),
            DataType::HexStr => "Find(Hex): ".to_string(),
        }
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.do_find(data);
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }

    fn do_shortcut(&mut self, shortcut: char) {
        match shortcut {
            'a' => {
                self.set_search_data_type(DataType::AsciiStr);
            }
            'u' => {
                self.set_search_data_type(DataType::UnicodeStr);
            }
            'h' => {
                self.set_search_data_type(DataType::HexStr);
            }
            _ => ()
        }
    }
}

signal_decl!{PathEvent(PathBuf)}

pub struct PathInputLine {
    pub on_done: PathEvent,
    pub on_cancel: Canceled,
    prefix: String,
}

impl PathInputLine {
    pub fn new(prefix: String) -> PathInputLine {
        PathInputLine {
            prefix: prefix,
            on_done: Default::default(),
            on_cancel: Default::default()
        }
    }
}

impl InputLineBehavior for PathInputLine {
    fn get_prefix(&mut self) -> String {
        self.prefix.clone()
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.on_done.signal(PathBuf::from(str::from_utf8(data).unwrap()));
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }
}

signal_decl!{ConfigSetEvent(String)}

pub struct ConfigSetLine {
    pub on_done: ConfigSetEvent,
    pub on_cancel: Canceled,
    prefix: String,
}

impl ConfigSetLine {
    pub fn new(prefix: String) -> ConfigSetLine {
        ConfigSetLine {
            prefix: prefix,
            on_done: Default::default(),
            on_cancel: Default::default(),
        }
    }
}

impl InputLineBehavior for ConfigSetLine {
    fn get_prefix(&mut self) -> String {
        self.prefix.clone()
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.on_done.signal(str::from_utf8(&data).unwrap().to_owned());
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }
}
<commit_msg>Change the InputLine behavior to pass a reference to a string<commit_after>use std::str;
use rustc_serialize::hex::FromHex;
use std::path::PathBuf;

use rex_utils;
use rex_utils::rect::Rect;
use super::super::frontend::{Frontend, Style, KeyPress};
use super::input::Input;
use super::widget::Widget;

use super::common::Canceled;

pub enum BaseInputLineActions {
    Edit(char),
    Ctrl(char),
    MoveLeft,
    MoveRight,
    DeleteWithMove,
    Ok,
    Cancel
}

pub trait InputLineBehavior {
    fn get_prefix(&mut self) -> &str;
    fn do_enter(&mut self, data: &[u8]);
    fn do_cancel(&mut self);
    fn do_shortcut(&mut self, shortcut: char) {

    }
}

pub struct InputLine<T:InputLineBehavior> {
    behavior: T,
    data: Vec<u8>,
    input_pos: isize,
}

impl<T:InputLineBehavior> InputLine<T> {
    pub fn new(behavior: T) -> InputLine<T> {
        InputLine {
            behavior: behavior,
            data: vec![],
            input_pos: 0,
        }
    }
}

impl<T:InputLineBehavior> Widget for InputLine<T> {
    fn input(&mut self, input: &Input, key: KeyPress) -> bool {
        let action = if let Some(action) = input.inputline_input(key) { action } else {
            return false;
        };

        match action {
            BaseInputLineActions::Ok => {
                self.behavior.do_enter(&self.data)
            }
            BaseInputLineActions::Cancel => {
                self.behavior.do_cancel()
            }
            BaseInputLineActions::MoveLeft => {
                if self.input_pos > 0 {
                    self.input_pos -= 1;
                }
            }
            BaseInputLineActions::MoveRight => {
                if self.input_pos < self.data.len() as isize {
                    self.input_pos += 1;
                }
            }
            BaseInputLineActions::Edit(ch) => {
                if ch.len_utf8() == 1 {
                    self.data.insert(self.input_pos as usize, ch as u8);
                    self.input_pos += 1;
                } else {
                    // TODO: Make it printable rather than alphanumeric
                }
            }
            BaseInputLineActions::Ctrl(ch) => {
                self.behavior.do_shortcut(ch)
            }
            BaseInputLineActions::DeleteWithMove => {
                if self.input_pos > 0 {
                    self.input_pos -= 1;
                    self.data.remove(self.input_pos as usize);
                }
            }
        };

        return true;
    }

    fn draw(&mut self, rb: &mut Frontend, area: Rect<isize>, has_focus: bool) {
        let prefix = self.behavior.get_prefix();
        rb.print_style(area.left as usize, area.top as usize, Style::InputLine,
                 &rex_utils::string_with_repeat(' ', area.width as usize));
        rb.print_style(area.left as usize, area.top as usize, Style::InputLine,
                 &format!("{}{}", prefix, str::from_utf8(&self.data).unwrap()));
        if has_focus {
            rb.set_cursor(prefix.len() as isize + self.input_pos, (area.top as isize));
        }
    }
}

enum RadixType {
    DecRadix,
    HexRadix,
    OctRadix,
}

signal_decl!{GotoEvent(isize)}

pub struct GotoInputLineBehavior {
    radix: RadixType,
    pub on_done: GotoEvent,
    pub on_cancel: Canceled,
}

impl GotoInputLineBehavior {
    pub fn new() -> GotoInputLineBehavior {
        GotoInputLineBehavior {
            radix: RadixType::DecRadix,
            on_done: Default::default(),
            on_cancel: Default::default(),
        }
    }

    fn set_radix(&mut self, r: RadixType) {
        self.radix = r;
    }

    fn do_goto(&mut self, data: &[u8]) {
        let radix = match self.radix {
            RadixType::DecRadix => 10,
            RadixType::HexRadix => 16,
            RadixType::OctRadix => 8,
        };

        let pos: Option<isize> = match str::from_utf8(&data) {
            Ok(gs) => isize::from_str_radix(&gs, radix).ok(),
            Err(_) => None
        };

        match pos {
            Some(pos) => {
                self.on_done.signal(pos)
            }
            None => {
                self.on_cancel.signal(Some(format!("Bad position!")));
            }
        };

    }
}

impl InputLineBehavior for GotoInputLineBehavior {
    fn get_prefix(&mut self) -> &str {
        match self.radix {
            RadixType::DecRadix => "Goto (Dec):",
            RadixType::HexRadix => "Goto (Hex):",
            RadixType::OctRadix => "Goto (Oct):",
        }
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.do_goto(data);
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }

    fn do_shortcut(&mut self, shortcut: char) {
        match shortcut {
            'd' => {
                self.set_radix(RadixType::DecRadix);
            }
            'h' => {
                self.set_radix(RadixType::HexRadix);
            }
            'o' => {
                self.set_radix(RadixType::OctRadix);
            }
            _ => ()
        }
    }
}

enum DataType {
    AsciiStr,
    UnicodeStr,
    HexStr,
}

signal_decl!{FindEvent(Vec<u8>)}

pub struct FindInputLine {
    data_type: DataType,
    pub on_find: FindEvent,
    pub on_cancel: Canceled,
}

impl FindInputLine {
    pub fn new() -> FindInputLine {
        FindInputLine {
            data_type: DataType::AsciiStr,
            on_find: Default::default(),
            on_cancel: Default::default(),
        }
    }

    fn set_search_data_type(&mut self, dt: DataType) {
        self.data_type = dt;
    }

    fn do_find(&mut self, data: &[u8]) {
        let ll = str::from_utf8(data).unwrap().from_hex();

        let needle: Vec<u8> = match self.data_type {
            DataType::AsciiStr => data.clone().into(),
            DataType::UnicodeStr => data.clone().into(),
            DataType::HexStr => {
                match ll {
                    Ok(n) => n,
                    Err(_) => {
                        self.on_cancel.signal(Some(format!("Bad hex value")));
                        return;
                    }
                }
            }
        };

        self.on_find.signal(needle);
    }
}

impl InputLineBehavior for FindInputLine {
    fn get_prefix(&mut self) -> &str {
        match self.data_type {
            DataType::AsciiStr => "Find(Ascii): ",
            DataType::UnicodeStr => "Find(Uni): ",
            DataType::HexStr => "Find(Hex): ",
        }
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.do_find(data);
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }

    fn do_shortcut(&mut self, shortcut: char) {
        match shortcut {
            'a' => {
                self.set_search_data_type(DataType::AsciiStr);
            }
            'u' => {
                self.set_search_data_type(DataType::UnicodeStr);
            }
            'h' => {
                self.set_search_data_type(DataType::HexStr);
            }
            _ => ()
        }
    }
}

signal_decl!{PathEvent(PathBuf)}

pub struct PathInputLine {
    pub on_done: PathEvent,
    pub on_cancel: Canceled,
    prefix: String,
}

impl PathInputLine {
    pub fn new(prefix: String) -> PathInputLine {
        PathInputLine {
            prefix: prefix,
            on_done: Default::default(),
            on_cancel: Default::default()
        }
    }
}

impl InputLineBehavior for PathInputLine {
    fn get_prefix(&mut self) -> &str {
        &self.prefix
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.on_done.signal(PathBuf::from(str::from_utf8(data).unwrap()));
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }
}

signal_decl!{ConfigSetEvent(String)}

pub struct ConfigSetLine {
    pub on_done: ConfigSetEvent,
    pub on_cancel: Canceled,
    prefix: String,
}

impl ConfigSetLine {
    pub fn new(prefix: String) -> ConfigSetLine {
        ConfigSetLine {
            prefix: prefix,
            on_done: Default::default(),
            on_cancel: Default::default(),
        }
    }
}

impl InputLineBehavior for ConfigSetLine {
    fn get_prefix(&mut self) -> &str {
        &self.prefix
    }

    fn do_enter(&mut self, data: &[u8]) {
        self.on_done.signal(str::from_utf8(&data).unwrap().to_owned());
    }

    fn do_cancel(&mut self) {
        self.on_cancel.signal(None);
    }
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::ast::*;
use syntax::visit::{self, FnKind};
use utils::{span_lint_and_then, in_macro, span_lint};

/// **What it does:** This lint warns about names that are very similar and thus confusing
///
/// **Why is this bad?** It's hard to distinguish between names that differ only by a single character
///
/// **Known problems:** None?
///
/// **Example:** `checked_exp` and `checked_expr`
declare_lint! {
    pub SIMILAR_NAMES,
    Warn,
    "similarly named items and bindings"
}

/// **What it does:** This lint warns about having too many variables whose name consists of a single character
///
/// **Why is this bad?** It's hard to memorize what a variable means without a descriptive name.
///
/// **Known problems:** None?
///
/// **Example:** let (a, b, c, d, e, f, g) = (...);
declare_lint! {
    pub MANY_SINGLE_CHAR_NAMES,
    Warn,
    "too many single character bindings"
}

pub struct NonExpressiveNames {
    pub max_single_char_names: u64,
}

impl LintPass for NonExpressiveNames {
    fn get_lints(&self) -> LintArray {
        lint_array!(SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES)
    }
}

struct SimilarNamesLocalVisitor<'a, 'b: 'a> {
    names: Vec<(InternedString, Span, usize)>,
    cx: &'a EarlyContext<'b>,
    lint: &'a NonExpressiveNames,
    single_char_names: Vec<char>,
}

const WHITELIST: &'static [&'static str] = &[
    "lhs", "rhs",
];

struct SimilarNamesNameVisitor<'a, 'b: 'a, 'c: 'b>(&'a mut SimilarNamesLocalVisitor<'b, 'c>);

impl<'v, 'a, 'b, 'c> visit::Visitor<'v> for SimilarNamesNameVisitor<'a, 'b, 'c> {
    fn visit_pat(&mut self, pat: &'v Pat) {
        if let PatKind::Ident(_, id, _) = pat.node {
            self.check_name(id.span, id.node.name);
        }
        visit::walk_pat(self, pat);
    }
}

fn whitelisted(interned_name: &str) -> bool {
    for &allow in WHITELIST {
        if interned_name == allow {
            return true;
        }
        if interned_name.len() <= allow.len() {
            continue;
        }
        // allow_*
        let allow_start = allow.chars().chain(Some('_'));
        if interned_name.chars().zip(allow_start).all(|(l, r)| l == r) {
            return true;
        }
        // *_allow
        let allow_end = Some('_').into_iter().chain(allow.chars());
        if interned_name.chars().rev().zip(allow_end.rev()).all(|(l, r)| l == r) {
            return true;
        }
    }
    false
}

impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
    fn check_short_name(&mut self, c: char, span: Span) {
        // make sure we ignore shadowing
        if self.0.single_char_names.contains(&c) {
            return;
        }
        self.0.single_char_names.push(c);
        if self.0.single_char_names.len() as u64 >= self.0.lint.max_single_char_names {
            span_lint(self.0.cx,
                      MANY_SINGLE_CHAR_NAMES,
                      span,
                      &format!("{}th binding whose name is just one char",
                               self.0.single_char_names.len()));
        }
    }
    fn check_name(&mut self, span: Span, name: Name) {
        if in_macro(self.0.cx, span) {
            return;
        }
        let interned_name = name.as_str();
        if interned_name.chars().any(char::is_uppercase) {
            return;
        }
        let count = interned_name.chars().count();
        if count < 3 {
            if count != 1 {
                return;
            }
            let c = interned_name.chars().next().expect("already checked");
            self.check_short_name(c, span);
            return;
        }
        if whitelisted(&interned_name) {
            return;
        }
        for &(ref existing_name, sp, existing_len) in &self.0.names {
            let mut split_at = None;
            if existing_len > count {
                if existing_len - count != 1 {
                    continue;
                }
                if levenstein_not_1(&interned_name, &existing_name) {
                    continue;
                }
            } else if existing_len < count {
                if count - existing_len != 1 {
                    continue;
                }
                if levenstein_not_1(&existing_name, &interned_name) {
                    continue;
                }
            } else {
                let mut interned_chars = interned_name.chars();
                let mut existing_chars = existing_name.chars();

                if interned_chars.next() != existing_chars.next() {
                    let i = interned_chars.next().expect("we know we have more than 1 char");
                    let e = existing_chars.next().expect("we know we have more than 1 char");
                    if i == e {
                        if i == '_' {
                            // allowed similarity x_foo, y_foo
                            // or too many chars differ (x_foo, y_boo)
                            continue;
                        } else if interned_chars.ne(existing_chars) {
                            // too many chars differ
                            continue
                        }
                    } else {
                        // too many chars differ
                        continue;
                    }
                    split_at = interned_name.chars().next().map(|c| c.len_utf8());
                } else if interned_chars.next_back() == existing_chars.next_back() {
                    if interned_chars.zip(existing_chars).filter(|&(i, e)| i != e).count() != 1 {
                        // too many chars differ, or none differ (aka shadowing)
                        continue;
                    }
                } else {
                    let i = interned_chars.next_back().expect("we know we have more than 2 chars");
                    let e = existing_chars.next_back().expect("we know we have more than 2 chars");
                    if i == e {
                        if i == '_' {
                            // allowed similarity foo_x, foo_x
                            // or too many chars differ (foo_x, boo_x)
                            continue;
                        } else if interned_chars.ne(existing_chars) {
                            // too many chars differ
                            continue
                        }
                    } else {
                        // too many chars differ
                        continue;
                    }
                    split_at = interned_name.char_indices().rev().next().map(|(i, _)| i);
                }
            }
            span_lint_and_then(self.0.cx,
                               SIMILAR_NAMES,
                               span,
                               "binding's name is too similar to existing binding",
                               |diag| {
                                   diag.span_note(sp, "existing binding defined here");
                                   if let Some(split) = split_at {
                                       diag.span_help(span, &format!("separate the discriminating character \
                                                                      by an underscore like: `{}_{}`",
                                                                     &interned_name[..split],
                                                                     &interned_name[split..]));
                                   }
                               });
            return;
        }
        self.0.names.push((interned_name, span, count));
    }
}

impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
    /// ensure scoping rules work
    fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {
        let n = self.names.len();
        let single_char_count = self.single_char_names.len();
        f(self);
        self.names.truncate(n);
        self.single_char_names.truncate(single_char_count);
    }
}

impl<'v, 'a, 'b> visit::Visitor<'v> for SimilarNamesLocalVisitor<'a, 'b> {
    fn visit_local(&mut self, local: &'v Local) {
        if let Some(ref init) = local.init {
            self.apply(|this| visit::walk_expr(this, &**init));
        }
        // add the pattern after the expression because the bindings aren't available yet in the init expression
        SimilarNamesNameVisitor(self).visit_pat(&*local.pat);
    }
    fn visit_block(&mut self, blk: &'v Block) {
        self.apply(|this| visit::walk_block(this, blk));
    }
    fn visit_arm(&mut self, arm: &'v Arm) {
        self.apply(|this| {
            // just go through the first pattern, as either all patterns bind the same bindings or rustc would have errored much earlier
            SimilarNamesNameVisitor(this).visit_pat(&arm.pats[0]);
            this.apply(|this| visit::walk_expr(this, &arm.body));
        });
    }
    fn visit_item(&mut self, _: &'v Item) {
        // do nothing
    }
}

impl EarlyLintPass for NonExpressiveNames {
    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, blk: &Block, _: Span, _: NodeId) {
        let mut visitor = SimilarNamesLocalVisitor {
            names: Vec::new(),
            cx: cx,
            lint: &self,
            single_char_names: Vec::new(),
        };
        // initialize with function arguments
        for arg in &decl.inputs {
            visit::walk_pat(&mut SimilarNamesNameVisitor(&mut visitor), &arg.pat);
        }
        // walk all other bindings
        visit::walk_block(&mut visitor, blk);
    }
}

/// Precondition: `a_name.chars().count() < b_name.chars().count()`.
fn levenstein_not_1(a_name: &str, b_name: &str) -> bool {
    debug_assert!(a_name.chars().count() < b_name.chars().count());
    let mut a_chars = a_name.chars();
    let mut b_chars = b_name.chars();
    while let (Some(a), Some(b)) = (a_chars.next(), b_chars.next()) {
        if a == b {
            continue;
        }
        if let Some(b2) = b_chars.next() {
            // check if there's just one character inserted
            return a != b2 || a_chars.ne(b_chars);
        } else {
            // tuple
            // ntuple
            return true;
        }
    }
    // for item in items
    true
}
<commit_msg>minor code readability improvements<commit_after>use rustc::lint::*;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::ast::*;
use syntax::visit::{self, FnKind};
use utils::{span_lint_and_then, in_macro, span_lint};

/// **What it does:** This lint warns about names that are very similar and thus confusing
///
/// **Why is this bad?** It's hard to distinguish between names that differ only by a single character
///
/// **Known problems:** None?
///
/// **Example:** `checked_exp` and `checked_expr`
declare_lint! {
    pub SIMILAR_NAMES,
    Warn,
    "similarly named items and bindings"
}

/// **What it does:** This lint warns about having too many variables whose name consists of a single character
///
/// **Why is this bad?** It's hard to memorize what a variable means without a descriptive name.
///
/// **Known problems:** None?
///
/// **Example:** let (a, b, c, d, e, f, g) = (...);
declare_lint! {
    pub MANY_SINGLE_CHAR_NAMES,
    Warn,
    "too many single character bindings"
}

pub struct NonExpressiveNames {
    pub max_single_char_names: u64,
}

impl LintPass for NonExpressiveNames {
    fn get_lints(&self) -> LintArray {
        lint_array!(SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES)
    }
}

struct SimilarNamesLocalVisitor<'a, 'b: 'a> {
    names: Vec<(InternedString, Span, usize)>,
    cx: &'a EarlyContext<'b>,
    lint: &'a NonExpressiveNames,
    single_char_names: Vec<char>,
}

const WHITELIST: &'static [&'static str] = &[
    "lhs", "rhs",
];

struct SimilarNamesNameVisitor<'a, 'b: 'a, 'c: 'b>(&'a mut SimilarNamesLocalVisitor<'b, 'c>);

impl<'v, 'a, 'b, 'c> visit::Visitor<'v> for SimilarNamesNameVisitor<'a, 'b, 'c> {
    fn visit_pat(&mut self, pat: &'v Pat) {
        if let PatKind::Ident(_, id, _) = pat.node {
            self.check_name(id.span, id.node.name);
        }
        visit::walk_pat(self, pat);
    }
}

fn whitelisted(interned_name: &str) -> bool {
    for &allow in WHITELIST {
        if interned_name == allow {
            return true;
        }
        if interned_name.len() <= allow.len() {
            continue;
        }
        // allow_*
        let allow_start = allow.chars().chain(Some('_'));
        if interned_name.chars().zip(allow_start).all(|(l, r)| l == r) {
            return true;
        }
        // *_allow
        let allow_end = Some('_').into_iter().chain(allow.chars());
        if interned_name.chars().rev().zip(allow_end.rev()).all(|(l, r)| l == r) {
            return true;
        }
    }
    false
}

impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
    fn check_short_name(&mut self, c: char, span: Span) {
        // make sure we ignore shadowing
        if self.0.single_char_names.contains(&c) {
            return;
        }
        self.0.single_char_names.push(c);
        if self.0.single_char_names.len() as u64 >= self.0.lint.max_single_char_names {
            span_lint(self.0.cx,
                      MANY_SINGLE_CHAR_NAMES,
                      span,
                      &format!("{}th binding whose name is just one char",
                               self.0.single_char_names.len()));
        }
    }
    fn check_name(&mut self, span: Span, name: Name) {
        if in_macro(self.0.cx, span) {
            return;
        }
        let interned_name = name.as_str();
        if interned_name.chars().any(char::is_uppercase) {
            return;
        }
        let count = interned_name.chars().count();
        if count < 3 {
            if count != 1 {
                return;
            }
            let c = interned_name.chars().next().expect("already checked");
            self.check_short_name(c, span);
            return;
        }
        if whitelisted(&interned_name) {
            return;
        }
        for &(ref existing_name, sp, existing_len) in &self.0.names {
            let mut split_at = None;
            if existing_len > count {
                if existing_len - count != 1 || levenstein_not_1(&interned_name, &existing_name) {
                    continue;
                }
            } else if existing_len < count {
                if count - existing_len != 1 || levenstein_not_1(&existing_name, &interned_name) {
                    continue;
                }
            } else {
                let mut interned_chars = interned_name.chars();
                let mut existing_chars = existing_name.chars();

                if interned_chars.next() != existing_chars.next() {
                    let i = interned_chars.next().expect("we know we have more than 1 char");
                    let e = existing_chars.next().expect("we know we have more than 1 char");
                    if i == e {
                        if i == '_' {
                            // allowed similarity x_foo, y_foo
                            // or too many chars differ (x_foo, y_boo)
                            continue;
                        } else if interned_chars.ne(existing_chars) {
                            // too many chars differ
                            continue
                        }
                    } else {
                        // too many chars differ
                        continue;
                    }
                    split_at = interned_name.chars().next().map(|c| c.len_utf8());
                } else if interned_chars.next_back() == existing_chars.next_back() {
                    if interned_chars.zip(existing_chars).filter(|&(i, e)| i != e).count() != 1 {
                        // too many chars differ, or none differ (aka shadowing)
                        continue;
                    }
                } else {
                    let i = interned_chars.next_back().expect("we know we have more than 2 chars");
                    let e = existing_chars.next_back().expect("we know we have more than 2 chars");
                    if i == e {
                        if i == '_' {
                            // allowed similarity foo_x, foo_x
                            // or too many chars differ (foo_x, boo_x)
                            continue;
                        } else if interned_chars.ne(existing_chars) {
                            // too many chars differ
                            continue
                        }
                    } else {
                        // too many chars differ
                        continue;
                    }
                    split_at = interned_name.char_indices().rev().next().map(|(i, _)| i);
                }
            }
            span_lint_and_then(self.0.cx,
                               SIMILAR_NAMES,
                               span,
                               "binding's name is too similar to existing binding",
                               |diag| {
                                   diag.span_note(sp, "existing binding defined here");
                                   if let Some(split) = split_at {
                                       diag.span_help(span, &format!("separate the discriminating character \
                                                                      by an underscore like: `{}_{}`",
                                                                     &interned_name[..split],
                                                                     &interned_name[split..]));
                                   }
                               });
            return;
        }
        self.0.names.push((interned_name, span, count));
    }
}

impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
    /// ensure scoping rules work
    fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {
        let n = self.names.len();
        let single_char_count = self.single_char_names.len();
        f(self);
        self.names.truncate(n);
        self.single_char_names.truncate(single_char_count);
    }
}

impl<'v, 'a, 'b> visit::Visitor<'v> for SimilarNamesLocalVisitor<'a, 'b> {
    fn visit_local(&mut self, local: &'v Local) {
        if let Some(ref init) = local.init {
            self.apply(|this| visit::walk_expr(this, &**init));
        }
        // add the pattern after the expression because the bindings aren't available yet in the init expression
        SimilarNamesNameVisitor(self).visit_pat(&*local.pat);
    }
    fn visit_block(&mut self, blk: &'v Block) {
        self.apply(|this| visit::walk_block(this, blk));
    }
    fn visit_arm(&mut self, arm: &'v Arm) {
        self.apply(|this| {
            // just go through the first pattern, as either all patterns bind the same bindings or rustc would have errored much earlier
            SimilarNamesNameVisitor(this).visit_pat(&arm.pats[0]);
            this.apply(|this| visit::walk_expr(this, &arm.body));
        });
    }
    fn visit_item(&mut self, _: &'v Item) {
        // do nothing
    }
}

impl EarlyLintPass for NonExpressiveNames {
    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, blk: &Block, _: Span, _: NodeId) {
        let mut visitor = SimilarNamesLocalVisitor {
            names: Vec::new(),
            cx: cx,
            lint: &self,
            single_char_names: Vec::new(),
        };
        // initialize with function arguments
        for arg in &decl.inputs {
            visit::walk_pat(&mut SimilarNamesNameVisitor(&mut visitor), &arg.pat);
        }
        // walk all other bindings
        visit::walk_block(&mut visitor, blk);
    }
}

/// Precondition: `a_name.chars().count() < b_name.chars().count()`.
fn levenstein_not_1(a_name: &str, b_name: &str) -> bool {
    debug_assert!(a_name.chars().count() < b_name.chars().count());
    let mut a_chars = a_name.chars();
    let mut b_chars = b_name.chars();
    while let (Some(a), Some(b)) = (a_chars.next(), b_chars.next()) {
        if a == b {
            continue;
        }
        if let Some(b2) = b_chars.next() {
            // check if there's just one character inserted
            return a != b2 || a_chars.ne(b_chars);
        } else {
            // tuple
            // ntuple
            return true;
        }
    }
    // for item in items
    true
}
<|endoftext|>


<commit_before>use std::fs;
use std::fs::File;
use std::path::{ Path, PathBuf };

use download;
use extract;
use verify;
use find_package;
use find_package::Package;

fn _install_package(package: &Package, path: &Path) -> Result<bool, String> {
    let mut download_path = PathBuf::new();
        download_path.push(path);
        download_path.push(format!("download/{}", package.name));

    if !download_path.exists() {
        download::download_file(&package.url, download_path.as_path())?;

        let target = match File::open(download_path.as_path()) {
            Ok(x) => x,
            Err(why) => return Err(format!("{}", why))
        };

        if verify::verify_file_crc32(&target) != package.crc32 {
            fs::remove_file(download_path.as_path())
                .ok()
                .expect(
                    &format!(
                        "Failed to remove file: {}",
                        download_path.as_path().to_str().unwrap_or("Invalid File")
                    )
                );
            return Err(String::from("The downloaded file is corrupted.\nwiz will delete the file now."))
        }
    }

    let mut tar_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("download/{}.tar", package.name));

    if !tar_path.exists() {
        extract::extract_gz(download_path.as_path(), tar_path.as_path())?;
    }

    let mut install_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("install/{}", package.name));

    if !install_path.exists() {
        extract::extract_tar(tar_path.as_path(), install_path.as_path())?;
    } else {
        return Ok(false)
    }

    return Ok(true)
}

pub fn install_package(name: &str, path: &Path) -> Result<bool, String> {
    let package = find_package::select_package(name, path).unwrap();
    for dep in package.dependencies {
        install_package(&dep.name, path)?;
    }
    return install_package(name, path)
}<commit_msg>Bugfix<commit_after>use std::fs;
use std::fs::File;
use std::path::{ Path, PathBuf };

use download;
use extract;
use verify;
use find_package;
use find_package::Package;

fn _install_package(package: &Package, path: &Path) -> Result<bool, String> {
    let mut download_path = PathBuf::new();
        download_path.push(path);
        download_path.push(format!("download/{}", package.name));

    if !download_path.exists() {
        download::download_file(&package.url, download_path.as_path())?;

        let target = match File::open(download_path.as_path()) {
            Ok(x) => x,
            Err(why) => return Err(format!("{}", why))
        };

        if verify::verify_file_crc32(&target) != package.crc32 {
            fs::remove_file(download_path.as_path())
                .ok()
                .expect(
                    &format!(
                        "Failed to remove file: {}",
                        download_path.as_path().to_str().unwrap_or("Invalid File")
                    )
                );
            return Err(String::from("The downloaded file is corrupted.\nwiz will delete the file now."))
        }
    }

    let mut tar_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("download/{}.tar", package.name));

    if !tar_path.exists() {
        extract::extract_gz(download_path.as_path(), tar_path.as_path())?;
    }

    let mut install_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("install/{}", package.name));

    if !install_path.exists() {
        extract::extract_tar(tar_path.as_path(), install_path.as_path())?;
    } else {
        return Ok(false)
    }

    return Ok(true)
}

pub fn install_package(name: &str, path: &Path) -> Result<bool, String> {
    let package = find_package::select_package(name, path)?;
    for dep in &package.dependencies {
        install_package(&dep.name, path)?;
    }
    return _install_package(&package, path)
}<|endoftext|>


<commit_before>//! The `image` element.

use cairo;
use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::allowed_url::Href;
use crate::aspect_ratio::AspectRatio;
use crate::bbox::BoundingBox;
use crate::drawing_ctx::{ClipMode, DrawingCtx};
use crate::error::*;
use crate::float_eq_cairo::ApproxEqCairo;
use crate::length::*;
use crate::node::*;
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;
use crate::rect::Rect;
use crate::viewbox::ViewBox;

#[derive(Default)]
pub struct Image {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    w: Length<Horizontal>,
    h: Length<Vertical>,
    aspect: AspectRatio,
    href: Option<Href>,
}

impl NodeTrait for Image {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!(svg "x") => self.x = attr.parse(value)?,
                expanded_name!(svg "y") => self.y = attr.parse(value)?,
                expanded_name!(svg "width") => {
                    self.w = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "height") => {
                    self.h = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                expanded_name!(xlink "href") | expanded_name!(svg "path") => {
                    let href = Href::parse(value)
                        .map_err(|_| ValueErrorKind::parse_error("could not parse href"))
                        .attribute(attr)?;

                    self.href = Some(href);
                }

                _ => (),
            }
        }

        Ok(())
    }

    fn overflow_hidden(&self) -> bool {
        true
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let values = cascaded.get();
        let params = draw_ctx.get_view_params();

        let x = self.x.normalize(values, &params);
        let y = self.y.normalize(values, &params);
        let w = self.w.normalize(values, &params);
        let h = self.h.normalize(values, &params);

        if w.approx_eq_cairo(0.0) || h.approx_eq_cairo(0.0) {
            return Ok(draw_ctx.empty_bbox());
        }

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            let surface = if let Some(Href::PlainUrl(ref url)) = self.href {
                dc.lookup_image(&url)?
            } else {
                return Ok(dc.empty_bbox());
            };

            let clip_mode = if !values.is_overflow() && self.aspect.is_slice() {
                Some(ClipMode::ClipToViewport)
            } else {
                None
            };

            let image_width = surface.width();
            let image_height = surface.height();
            if clipping || image_width == 0 || image_height == 0 {
                return Ok(dc.empty_bbox());
            }

            // The bounding box for <image> is decided by the values of x, y, w, h and not by
            // the final computed image bounds.
            let rect = Rect::new(x, y, x + w, y + h);
            let bbox = dc.empty_bbox().with_rect(rect);

            dc.with_saved_cr(&mut |dc| {
                let cr = dc.get_cairo_context();

                let image_width = f64::from(image_width);
                let image_height = f64::from(image_height);

                if let Some(_params) = dc.push_new_viewport(
                    Some(ViewBox(Rect::from_size(image_width, image_height))),
                    Rect::new(x, y, x + w, y + h),
                    self.aspect,
                    clip_mode,
                ) {
                    // We need to set extend appropriately, so can't use cr.set_source_surface().
                    //
                    // If extend is left at its default value (None), then bilinear scaling uses
                    // transparency outside of the image producing incorrect results.
                    // For example, in svg1.1/filters-blend-01-b.svgthere's a completely
                    // opaque 100×1 image of a gradient scaled to 100×98 which ends up
                    // transparent almost everywhere without this fix (which it shouldn't).
                    let ptn = surface.to_cairo_pattern();
                    ptn.set_extend(cairo::Extend::Pad);
                    cr.set_source(&ptn);

                    // Clip is needed due to extend being set to pad.
                    cr.rectangle(0.0, 0.0, image_width, image_height);
                    cr.clip();

                    cr.paint();
                }

                Ok(bbox)
            })
        })
    }
}
<commit_msg>image: reduce scope of cairo context<commit_after>//! The `image` element.

use cairo;
use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::allowed_url::Href;
use crate::aspect_ratio::AspectRatio;
use crate::bbox::BoundingBox;
use crate::drawing_ctx::{ClipMode, DrawingCtx};
use crate::error::*;
use crate::float_eq_cairo::ApproxEqCairo;
use crate::length::*;
use crate::node::*;
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;
use crate::rect::Rect;
use crate::viewbox::ViewBox;

#[derive(Default)]
pub struct Image {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    w: Length<Horizontal>,
    h: Length<Vertical>,
    aspect: AspectRatio,
    href: Option<Href>,
}

impl NodeTrait for Image {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!(svg "x") => self.x = attr.parse(value)?,
                expanded_name!(svg "y") => self.y = attr.parse(value)?,
                expanded_name!(svg "width") => {
                    self.w = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "height") => {
                    self.h = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                expanded_name!(xlink "href") | expanded_name!(svg "path") => {
                    let href = Href::parse(value)
                        .map_err(|_| ValueErrorKind::parse_error("could not parse href"))
                        .attribute(attr)?;

                    self.href = Some(href);
                }

                _ => (),
            }
        }

        Ok(())
    }

    fn overflow_hidden(&self) -> bool {
        true
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let values = cascaded.get();
        let params = draw_ctx.get_view_params();

        let x = self.x.normalize(values, &params);
        let y = self.y.normalize(values, &params);
        let w = self.w.normalize(values, &params);
        let h = self.h.normalize(values, &params);

        if w.approx_eq_cairo(0.0) || h.approx_eq_cairo(0.0) {
            return Ok(draw_ctx.empty_bbox());
        }

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            let surface = if let Some(Href::PlainUrl(ref url)) = self.href {
                dc.lookup_image(&url)?
            } else {
                return Ok(dc.empty_bbox());
            };

            let clip_mode = if !values.is_overflow() && self.aspect.is_slice() {
                Some(ClipMode::ClipToViewport)
            } else {
                None
            };

            let image_width = surface.width();
            let image_height = surface.height();
            if clipping || image_width == 0 || image_height == 0 {
                return Ok(dc.empty_bbox());
            }

            // The bounding box for <image> is decided by the values of x, y, w, h and not by
            // the final computed image bounds.
            let rect = Rect::new(x, y, x + w, y + h);
            let bbox = dc.empty_bbox().with_rect(rect);

            dc.with_saved_cr(&mut |dc| {
                let image_width = f64::from(image_width);
                let image_height = f64::from(image_height);

                if let Some(_params) = dc.push_new_viewport(
                    Some(ViewBox(Rect::from_size(image_width, image_height))),
                    Rect::new(x, y, x + w, y + h),
                    self.aspect,
                    clip_mode,
                ) {
                    let cr = dc.get_cairo_context();

                    // We need to set extend appropriately, so can't use cr.set_source_surface().
                    //
                    // If extend is left at its default value (None), then bilinear scaling uses
                    // transparency outside of the image producing incorrect results.
                    // For example, in svg1.1/filters-blend-01-b.svgthere's a completely
                    // opaque 100×1 image of a gradient scaled to 100×98 which ends up
                    // transparent almost everywhere without this fix (which it shouldn't).
                    let ptn = surface.to_cairo_pattern();
                    ptn.set_extend(cairo::Extend::Pad);
                    cr.set_source(&ptn);

                    // Clip is needed due to extend being set to pad.
                    cr.rectangle(0.0, 0.0, image_width, image_height);
                    cr.clip();

                    cr.paint();
                }

                Ok(bbox)
            })
        })
    }
}
<|endoftext|>