<commit_before>//
extern crate termion;

//
use self::termion::event::{Event, Key, MouseEvent};
use self::termion::input::{TermRead, MouseTerminal};
use self::termion::raw::IntoRawMode;
use self::termion::terminal_size;

use std::io::{self, Write, stdin, Stdout};

//
use core::screen::Screen;
use core::codepointinfo::CodepointInfo;

use core::editor::Editor;

fn fill_screen(screen: &mut Screen, data: &[u8]) {

    screen.clear();

    let mut offset = 0;
    for c in data {

        let mut displayed_cp: char = *c as char;
        if *c as char == '\n' as char {
            displayed_cp = ' ';
        }

        let cpi = CodepointInfo {
            cp: *c as char,
            displayed_cp: displayed_cp,
            offset: offset,
        };

        let (ok, _) = screen.push(cpi);
        offset += 1;
        if ok == false {
            break;
        }
    }
}

fn draw_screen(screen: &Screen, stdout: &mut Stdout) {

    write!(stdout, "{}", termion::cursor::Goto(1, 1)).unwrap();

    for l in 0..screen.height {
        let line = &screen.line[l];
        if line.used == 0 {
            break;
        }

        for c in 0..line.width {
            let cpi = &line.chars[c];
            write!(stdout, "{}", cpi.displayed_cp).unwrap();
        }

        if l < screen.height - 1 {
            write!(stdout, "\r\n").unwrap();
        }
    }

    stdout.flush().unwrap();
}

fn draw_buffer(buf: &Option<&Box<::core::buffer::Buffer>>, mut scr: &mut Screen, mut stdout: &mut Stdout)
{
     match *buf {
            Some(ref b) => {
                match b.byte_buffer {

                    Some(ref byte_buf) => {
                        fill_screen(&mut scr, &byte_buf.data);
                        draw_screen(&scr, &mut stdout);
                    }
                    _ => {},
                }
            }
            _ => {},
        }
}

pub fn main_loop(editor: &mut Editor) {

    let mut stdout = MouseTerminal::from(io::stdout().into_raw_mode().unwrap());

    write!(stdout, "{}{}", termion::cursor::Hide, termion::clear::All).unwrap();

    stdout.flush().unwrap();

    let mut keys: Vec<Event> = Vec::new();

    let mut quit = false;
    let mut clear_screen = true;

    // select file
    let mut bid = 2;
    let mut buf = editor.buffer_map.get(&bid);

    while !quit {
        let (width, height) = terminal_size().unwrap();
        let mut scr = Screen::new(width as usize, height as usize);

        if clear_screen == true {
            clear_screen = false;
            write!(stdout, "{}", termion::clear::All).unwrap();
            stdout.flush().unwrap();
        }

        draw_buffer(&buf, &mut scr, &mut stdout);
        for evt in stdin().events() {

            draw_buffer(&buf, &mut scr, &mut stdout);

            write!(stdout, "{}", termion::cursor::Goto(1, 1)).unwrap();

            keys.push(evt.unwrap());

            let evt = keys[keys.len() - 1].clone();

            // Print recieved Events...
            match evt {

                Event::Key(k) => {
                    match k {
                        // Exit.
                        Key::Ctrl('r') => {
                            keys.clear();
                        }

                        Key::Ctrl('c') => {
                            if keys.len() > 1 {
                                if let Event::Key(prev_event) = keys[keys.len() - 2] {
                                    if let Key::Ctrl(prev_char) = prev_event {
                                        if prev_char == 'x' {
                                            quit = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        Key::Char(c) => print!("'{}'", c),
                        Key::Alt(c) => print!("Alt-{}", c),
                        Key::Ctrl(c) => print!("Ctrl-{}", c),

                        Key::F(1) => {
                            if bid > 0 {
                                bid -= 1;
                            }
                            buf = editor.buffer_map.get(&bid);
                            clear_screen = true;
                        },

                        Key::F(2) => {
                            bid += 1;
                            buf = editor.buffer_map.get(&bid);
                            clear_screen = true;
                        },

                        Key::F(f) => print!("F{:?}", f),
                        Key::Left => print!("<left>"),
                        Key::Right => print!("<right>"),
                        Key::Up => print!("<up>"),
                        Key::Down => print!("<down>"),
                        Key::Backspace => print!("<backspace>"),
                        Key::Home => print!("<Home>"),
                        Key::End => print!("<End>"),
                        Key::PageUp => print!("<PageUp>"),
                        Key::PageDown => print!("<PageDown>"),
                        Key::Delete => print!("<Delete>"),
                        Key::Insert => print!("<Insert>"),
                        Key::Esc => print!("<Esc>"),
                        _ => print!("Other"),

                    }
                }

                Event::Mouse(m) => {
                    match m {
                        MouseEvent::Press(mb, x, y) => {
                            print!("MouseEvent::Press => MouseButton {:?} @ ({}, {})", mb, x, y);
                        }

                        MouseEvent::Release(x, y) => {
                            print!("MouseEvent::Release => @ ({}, {})", x, y);
                        }

                        MouseEvent::Hold(x, y) => {
                            print!("MouseEvent::Hold => @ ({}, {})", x, y);
                        }
                    }
                }

                Event::Unsupported(_) => {}
            }

            // Flush again.
            print!("        ");
            stdout.flush().unwrap();
        }
    }

    write!(stdout, "{}{}", termion::clear::All, termion::cursor::Show).unwrap();
    stdout.flush().unwrap();
}
<commit_msg>force screen clearing on buffer change<commit_after>//
extern crate termion;

//
use self::termion::event::{Event, Key, MouseEvent};
use self::termion::input::{TermRead, MouseTerminal};
use self::termion::raw::IntoRawMode;
use self::termion::terminal_size;

use std::io::{self, Write, stdin, Stdout};

//
use core::screen::Screen;
use core::codepointinfo::CodepointInfo;

use core::editor::Editor;

fn fill_screen(screen: &mut Screen, data: &[u8]) {

    screen.clear();

    let mut offset = 0;
    for c in data {

        let mut displayed_cp: char = *c as char;
        if *c as char == '\n' as char {
            displayed_cp = ' ';
        }

        let cpi = CodepointInfo {
            cp: *c as char,
            displayed_cp: displayed_cp,
            offset: offset,
        };

        let (ok, _) = screen.push(cpi);
        offset += 1;
        if ok == false {
            break;
        }
    }
}

fn draw_screen(screen: &Screen, stdout: &mut Stdout) {

    write!(stdout, "{}", termion::cursor::Goto(1, 1)).unwrap();

    for l in 0..screen.height {
        let line = &screen.line[l];
        if line.used == 0 {
            break;
        }

        for c in 0..line.width {
            let cpi = &line.chars[c];
            write!(stdout, "{}", cpi.displayed_cp).unwrap();
        }

        if l < screen.height - 1 {
            write!(stdout, "\r\n").unwrap();
        }
    }

    stdout.flush().unwrap();
}

fn draw_buffer(buf: &Option<&Box<::core::buffer::Buffer>>, mut scr: &mut Screen, mut stdout: &mut Stdout)
{
     match *buf {
            Some(ref b) => {
                match b.byte_buffer {

                    Some(ref byte_buf) => {
                        fill_screen(&mut scr, &byte_buf.data);
                        draw_screen(&scr, &mut stdout);
                    }
                    _ => {},
                }
            }
            _ => {},
        }
}

pub fn main_loop(editor: &mut Editor) {

    let mut stdout = MouseTerminal::from(io::stdout().into_raw_mode().unwrap());

    write!(stdout, "{}{}", termion::cursor::Hide, termion::clear::All).unwrap();

    stdout.flush().unwrap();

    let mut keys: Vec<Event> = Vec::new();

    let mut quit = false;
    let mut clear_screen = true;

    // select file
    let mut bid = 2;
    let mut buf = editor.buffer_map.get(&bid);

    while !quit {
        let (width, height) = terminal_size().unwrap();
        let mut scr = Screen::new(width as usize, height as usize);

        if clear_screen == true {
            clear_screen = false;
            write!(stdout, "{}", termion::clear::All).unwrap();
            stdout.flush().unwrap();
        }

        draw_buffer(&buf, &mut scr, &mut stdout);
        for evt in stdin().events() {

            draw_buffer(&buf, &mut scr, &mut stdout);

            write!(stdout, "{}", termion::cursor::Goto(1, 1)).unwrap();

            keys.push(evt.unwrap());

            let evt = keys[keys.len() - 1].clone();

            // Print recieved Events...
            match evt {

                Event::Key(k) => {
                    match k {
                        // Exit.
                        Key::Ctrl('r') => {
                            keys.clear();
                        }

                        Key::Ctrl('c') => {
                            if keys.len() > 1 {
                                if let Event::Key(prev_event) = keys[keys.len() - 2] {
                                    if let Key::Ctrl(prev_char) = prev_event {
                                        if prev_char == 'x' {
                                            quit = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        Key::Char(c) => print!("'{}'", c),
                        Key::Alt(c) => print!("Alt-{}", c),
                        Key::Ctrl(c) => print!("Ctrl-{}", c),

                        Key::F(1) => {
                            if bid > 0 {
                                bid -= 1;
                            }
                            buf = editor.buffer_map.get(&bid);
                            clear_screen = true;
                            break
                        },

                        Key::F(2) => {
                            bid += 1;
                            buf = editor.buffer_map.get(&bid);
                            clear_screen = true;
                            break
                        },

                        Key::F(f) => print!("F{:?}", f),
                        Key::Left => print!("<left>"),
                        Key::Right => print!("<right>"),
                        Key::Up => print!("<up>"),
                        Key::Down => print!("<down>"),
                        Key::Backspace => print!("<backspace>"),
                        Key::Home => print!("<Home>"),
                        Key::End => print!("<End>"),
                        Key::PageUp => print!("<PageUp>"),
                        Key::PageDown => print!("<PageDown>"),
                        Key::Delete => print!("<Delete>"),
                        Key::Insert => print!("<Insert>"),
                        Key::Esc => print!("<Esc>"),
                        _ => print!("Other"),

                    }
                }

                Event::Mouse(m) => {
                    match m {
                        MouseEvent::Press(mb, x, y) => {
                            print!("MouseEvent::Press => MouseButton {:?} @ ({}, {})", mb, x, y);
                        }

                        MouseEvent::Release(x, y) => {
                            print!("MouseEvent::Release => @ ({}, {})", x, y);
                        }

                        MouseEvent::Hold(x, y) => {
                            print!("MouseEvent::Hold => @ ({}, {})", x, y);
                        }
                    }
                }

                Event::Unsupported(_) => {}
            }

            // Flush again.
            print!("        ");
            stdout.flush().unwrap();
        }
    }

    write!(stdout, "{}{}", termion::clear::All, termion::cursor::Show).unwrap();
    stdout.flush().unwrap();
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error;
use std::fmt;
use std::io;
use std::sync::Mutex;
use std::time::{Duration, Instant};
use std::sync::atomic::{AtomicBool, Ordering};
use std::net::{ToSocketAddrs, SocketAddr, UdpSocket};

use cadence::prelude::*;
use cadence::{MetricSink, MetricResult, ErrorKind};

#[macro_use]
pub mod macros;

static mut CLIENT: Option<*const Metric> = None;
// IS_INITIALIZED indicates the state of CLIENT,
// `false` for uninitialized, `true` for initialized.
static IS_INITIALIZED: AtomicBool = AtomicBool::new(false);

pub trait Metric: Counted + Gauged + Metered + Timed {}

impl<T: Counted + Gauged + Metered + Timed> Metric for T {}

/// The type returned by `set_metric_client` if `set_metric_client` has already been called.
#[derive(Debug)]
pub struct SetMetricError;

impl fmt::Display for SetMetricError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt,
               "attempted to set a metric client after the metric system was already initialized")
    }
}

impl error::Error for SetMetricError {
    fn description(&self) -> &str {
        "set_metric_client() called multiple times"
    }
}

pub fn set_metric_client(client: Box<Metric + Send + Sync>) -> Result<(), SetMetricError> {
    unsafe {
        if IS_INITIALIZED.compare_and_swap(false, true, Ordering::SeqCst) != false {
            return Err(SetMetricError);
        }

        CLIENT = Some(Box::into_raw(client));
        Ok(())
    }
}

#[doc(hidden)]
pub fn client() -> Option<&'static Metric> {
    if IS_INITIALIZED.load(Ordering::SeqCst) != true {
        return None;
    }

    unsafe { CLIENT.map(|c| &*c) }
}

static BUFFER_SIZE: usize = 1024;

pub struct BufferedUdpMetricSink {
    sink_addr: SocketAddr,
    socket: UdpSocket,

    buffer: Mutex<Vec<u8>>,
    last_flush_time: Mutex<Instant>,
    flush_period: Duration,
}

impl BufferedUdpMetricSink {
    pub fn from<A>(sink_addr: A,
                   socket: UdpSocket,
                   flush_period: Duration)
                   -> MetricResult<BufferedUdpMetricSink>
        where A: ToSocketAddrs
    {
        let mut addr_iter = try!(sink_addr.to_socket_addrs());
        let addr = try!(addr_iter.next()
            .ok_or((ErrorKind::InvalidInput, "No socket addresses yielded")));

        // Moves this UDP stream into nonblocking mode.
        try!(socket.set_nonblocking(true));

        Ok(BufferedUdpMetricSink {
            sink_addr: addr,
            socket: socket,

            buffer: Mutex::new(Vec::with_capacity(BUFFER_SIZE)),
            flush_period: flush_period,
            last_flush_time: Mutex::new(Instant::now()),
        })
    }

    fn append_to_buffer(&self, metric: &str) -> io::Result<usize> {
        let mut buffer = self.buffer.lock().unwrap();
        let mut last_flush_time = self.last_flush_time.lock().unwrap();

        // +1 for '\n'
        if (buffer.len() + metric.len() + 1) > buffer.capacity() ||
           (last_flush_time.elapsed() >= self.flush_period) {
            self.flush(&mut buffer);
            *last_flush_time = Instant::now();
        }

        buffer.extend_from_slice(metric.as_bytes());
        buffer.push(b'\n');
        Ok(metric.len())
    }

    fn flush(&self, buffer: &mut Vec<u8>) {
        if let Err(e) = self.socket.send_to(buffer.as_slice(), &self.sink_addr) {
            warn!("send metric failed {:?}", e);
        }

        buffer.clear();
    }
}

impl MetricSink for BufferedUdpMetricSink {
    fn emit(&self, metric: &str) -> io::Result<usize> {
        self.append_to_buffer(metric)
    }
}
<commit_msg>util: send metrics in a background thread (#787)<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error;
use std::fmt;
use std::io;
use std::sync::Mutex;
use std::time::{Duration, Instant};
use std::sync::atomic::{AtomicBool, Ordering};
use std::net::{ToSocketAddrs, SocketAddr, UdpSocket};

use super::worker::{Worker, Runnable};

use cadence::prelude::*;
use cadence::{MetricSink, MetricResult, ErrorKind};

#[macro_use]
pub mod macros;

static mut CLIENT: Option<*const Metric> = None;
// IS_INITIALIZED indicates the state of CLIENT,
// `false` for uninitialized, `true` for initialized.
static IS_INITIALIZED: AtomicBool = AtomicBool::new(false);

pub trait Metric: Counted + Gauged + Metered + Timed {}

impl<T: Counted + Gauged + Metered + Timed> Metric for T {}

/// The type returned by `set_metric_client` if `set_metric_client` has already been called.
#[derive(Debug)]
pub struct SetMetricError;

impl fmt::Display for SetMetricError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt,
               "attempted to set a metric client after the metric system was already initialized")
    }
}

impl error::Error for SetMetricError {
    fn description(&self) -> &str {
        "set_metric_client() called multiple times"
    }
}

pub fn set_metric_client(client: Box<Metric + Send + Sync>) -> Result<(), SetMetricError> {
    unsafe {
        if IS_INITIALIZED.compare_and_swap(false, true, Ordering::SeqCst) != false {
            return Err(SetMetricError);
        }

        CLIENT = Some(Box::into_raw(client));
        Ok(())
    }
}

#[doc(hidden)]
pub fn client() -> Option<&'static Metric> {
    if IS_INITIALIZED.load(Ordering::SeqCst) != true {
        return None;
    }

    unsafe { CLIENT.map(|c| &*c) }
}

const BUFFER_SIZE: usize = 1024;

struct MetricBuffer(Vec<u8>);

impl fmt::Display for MetricBuffer {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "MetricBuffer")
    }
}

struct BufferSender {
    sink_addr: SocketAddr,
    socket: UdpSocket,
}

impl Runnable<MetricBuffer> for BufferSender {
    fn run(&mut self, buffer: MetricBuffer) {
        if let Err(e) = self.socket.send_to(buffer.0.as_slice(), &self.sink_addr) {
            warn!("send metric failed {:?}", e);
        }
    }
}

struct MutexBundle {
    buffer: MetricBuffer,
    last_flush_time: Instant,
    worker: Worker<MetricBuffer>,
}

pub struct BufferedUdpMetricSink {
    buffer: Mutex<MutexBundle>,
    flush_period: Duration,
}

impl BufferedUdpMetricSink {
    pub fn from<A>(sink_addr: A,
                   socket: UdpSocket,
                   flush_period: Duration)
                   -> MetricResult<BufferedUdpMetricSink>
        where A: ToSocketAddrs
    {
        let mut addr_iter = try!(sink_addr.to_socket_addrs());
        let addr = try!(addr_iter.next()
            .ok_or((ErrorKind::InvalidInput, "No socket addresses yielded")));

        let sender = BufferSender {
            sink_addr: addr,
            socket: socket,
        };

        let mut worker = Worker::new("mteric-worker");
        worker.start(sender).unwrap();

        let mb = MutexBundle {
            buffer: MetricBuffer(Vec::with_capacity(BUFFER_SIZE)),
            last_flush_time: Instant::now(),
            worker: worker,
        };

        Ok(BufferedUdpMetricSink {
            buffer: Mutex::new(mb),
            flush_period: flush_period,
        })
    }

    fn append_to_buffer(&self, metric: &str) -> io::Result<usize> {
        let mut mb = self.buffer.lock().unwrap();

        // +1 for '\n'
        if (mb.buffer.0.len() + metric.len() + 1) > mb.buffer.0.capacity() ||
           (mb.last_flush_time.elapsed() >= self.flush_period) {
            mb.last_flush_time = Instant::now();
            mb.worker.schedule(MetricBuffer(mb.buffer.0.clone())).unwrap();
            mb.buffer.0.clear()
        }

        mb.buffer.0.extend_from_slice(metric.as_bytes());
        mb.buffer.0.push(b'\n');
        Ok(metric.len())
    }
}

impl MetricSink for BufferedUdpMetricSink {
    fn emit(&self, metric: &str) -> io::Result<usize> {
        self.append_to_buffer(metric)
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::panic::{self, PanicInfo};
use std::cell::RefCell;
use std::sync::StaticRwLock;
use std::process;

/// A simple panic hook that allows skiping printing stacktrace conditionaly.

static HOOK_LOCK: StaticRwLock = StaticRwLock::new();
// store the default panic hook defined in std.
static mut DEFAULT_HOOK: Option<*mut (Fn(&PanicInfo) + 'static + Sync + Send)> = None;

thread_local! {
    static MUTED: RefCell<bool> = RefCell::new(false)
}

/// Replace the default hook if we haven't.
fn initialize() {
    unsafe {
        let rl = HOOK_LOCK.read().unwrap();
        if let Some(_) = DEFAULT_HOOK {
            return;
        }
        drop(rl);
        let wl = HOOK_LOCK.write().unwrap();
        // in case multiple thread is waiting for the wl.
        if let Some(_) = DEFAULT_HOOK {
            return;
        }
        DEFAULT_HOOK = Some(Box::into_raw(panic::take_hook()));
        panic::set_hook(box track_hook);
        // mute unused warning.
        drop(wl);
    }
}

/// Skip printing the stacktrace if panic.
pub fn mute() {
    initialize();
    MUTED.with(|m| *m.borrow_mut() = true);
}

/// Print the stacktrace if panic.
pub fn unmute() {
    MUTED.with(|m| *m.borrow_mut() = false);
}

/// Print the stacktrace according to the static MUTED.
fn track_hook(p: &PanicInfo) {
    MUTED.with(|m| {
        if *m.borrow() {
            return;
        }
        unsafe {
            if let Some(hook) = DEFAULT_HOOK {
                (*hook)(p);
            }
        }
    });
}

/// Exit the whole process when panic.
pub fn set_exit_hook() {
    let orig_hook = panic::take_hook();
    panic::set_hook(box move |info: &PanicInfo| {
        orig_hook(info);
        process::exit(1);
    })
}
<commit_msg>util: use Once to initialize panic hook (#599)<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::panic::{self, PanicInfo};
use std::cell::RefCell;
use std::sync::{Once, ONCE_INIT};
use std::process;

/// A simple panic hook that allows skiping printing stacktrace conditionaly.

static INIT: Once = ONCE_INIT;
// store the default panic hook defined in std.
static mut DEFAULT_HOOK: Option<*mut (Fn(&PanicInfo) + 'static + Sync + Send)> = None;

thread_local! {
    static MUTED: RefCell<bool> = RefCell::new(false)
}

/// Replace the default hook if we haven't.
fn initialize() {
    unsafe {
        DEFAULT_HOOK = Some(Box::into_raw(panic::take_hook()));
        panic::set_hook(box track_hook);
    }
}

/// Skip printing the stacktrace if panic.
pub fn mute() {
    INIT.call_once(initialize);
    MUTED.with(|m| *m.borrow_mut() = true);
}

/// Print the stacktrace if panic.
pub fn unmute() {
    MUTED.with(|m| *m.borrow_mut() = false);
}

/// Print the stacktrace according to the static MUTED.
fn track_hook(p: &PanicInfo) {
    MUTED.with(|m| {
        if *m.borrow() {
            return;
        }
        unsafe {
            if let Some(hook) = DEFAULT_HOOK {
                (*hook)(p);
            }
        }
    });
}

/// Exit the whole process when panic.
pub fn set_exit_hook() {
    let orig_hook = panic::take_hook();
    panic::set_hook(box move |info: &PanicInfo| {
        orig_hook(info);
        process::exit(1);
    })
}
<|endoftext|>


<commit_before>use util::units::AsTuple;

#[derive(Copy, Debug, PartialEq)]
pub struct Size {
    pub x: i32,
    pub y: i32
}

impl Size {

    pub fn new(x: i32, y: i32) -> Size {
        Size { x: x, y: y }
    }

}

impl AsTuple<i32> for Size {
    fn as_tuple(&self) -> (i32, i32) {
        (self.x, self.y)
    }
}
<commit_msg>Implement Add and Sub for Size<commit_after>use util::units::AsTuple;

use std::ops::{Add, Sub};

#[derive(Copy, Debug, PartialEq)]
pub struct Size {
    pub x: i32,
    pub y: i32
}

impl Size {

    pub fn new(x: i32, y: i32) -> Size {
        Size { x: x, y: y }
    }

}

impl Add for Size {
    type Output = Size;

    fn add(self, other: Size) -> Size {
        let (ox, oy) = other.as_tuple();
        Size { x: self.x + ox, y: self.y + oy }
    }
}

impl Add<(i32, i32)> for Size {
    type Output = Size;

    fn add(self, other: (i32, i32)) -> Size {
        let (ox, oy) = other;
        Size { x: self.x + ox, y: self.y + oy }
    }
}

impl Sub for Size {
    type Output = Size;

    fn sub(self, other: Size) -> Size {
        let (ox, oy) = other.as_tuple();
        Size { x: self.x - ox, y: self.y - oy }
    }
}

impl Sub<(i32, i32)> for Size {
    type Output = Size;

    fn sub(self, other: (i32, i32)) -> Size {
        let (ox, oy) = other;
        Size { x: self.x - ox, y: self.y - oy }
    }
}

impl AsTuple<i32> for Size {
    fn as_tuple(&self) -> (i32, i32) {
        (self.x, self.y)
    }
}
<|endoftext|>


<commit_before>use std::io::fs;
use std::io::fs::PathExtensions;
use std::str::StrExt;

struct Index {
    path: Path,
    entries: Vec<Path>,
}

impl Index {
    fn new(path: &str) -> Index {
        return Index { path: Path::new(path.to_string()), entries: vec![] }
    }

    // Finds all files inside and beneath the index path
    // and adds them to the index entries vector.
    fn populate(&mut self) {
        // The entries listed by readdir include the root index path; we want
        // relative paths, so we get this length so that we can strip it.
        let prefix_length = self.path.as_str().unwrap().len()+1;

        // Start by getting any files in the root path. Since
        // read_directory_entries is already borrowing a mutable
        // reference to the index, so we can't also lend out a
        // reference to its path field, hence the clone.
        let path = self.path.clone();
        self.index_directory_files(path, prefix_length);

        // Get an iterator that'll let us walk all of the subdirectories
        // of the index path, bailing out if there's an error of any kind.
        let mut subdirectories = match fs::walk_dir(&self.path) {
            Ok(iterator) => iterator,
            Err(e) => return,
        };

        // Index any other files beneath the root directory.
        for directory in subdirectories {
            self.index_directory_files(directory, prefix_length);
        }
    }

    // Helper method for populate.
    // Finds files for a particular directory, strips prefix_length leading
    // characters from their path, and adds them to the index entries vector.
    fn index_directory_files(&mut self, directory: Path, prefix_length: uint) {
        match fs::readdir(&directory) {
            Ok(entries) => {
                // Put all of the file-based Path entries into the index.
                for file in entries.iter().filter(|entry| entry.is_file()) {
                    // Make the file path relative to the index path by stripping it from its string.
                    let file_path = Path::new(file.as_str().unwrap().slice_from(prefix_length));

                    self.entries.push(file_path);
                }
            },
            Err(e) => (),
        }
    }
}

#[test]
fn new_creates_index_with_passed_path() {
    let path = "my path";
    let index = Index::new(path);

    // Get the index path as a string.
    let index_path = match index.path.as_str() {
        Some(value) => value,
        None => ""
    };

    assert_eq!(index_path, path);
}

#[test]
fn new_creates_index_with_empty_array() {
    let path = "my path";
    let index = Index::new(path);
    let empty_array: Vec<Path> = vec![];

    assert!(index.entries == empty_array);
}

#[test]
fn populate_adds_all_files_to_entries() {
    let path = "tests/sample";
    let index = &mut Index::new(path);
    let expected_array = vec![Path::new("root_file"), Path::new("directory/nested_file")];
    index.populate();

    assert!(index.entries == expected_array);
}
<commit_msg>Replace uint reference with usize.<commit_after>use std::io::fs;
use std::io::fs::PathExtensions;
use std::str::StrExt;

struct Index {
    path: Path,
    entries: Vec<Path>,
}

impl Index {
    fn new(path: &str) -> Index {
        return Index { path: Path::new(path.to_string()), entries: vec![] }
    }

    // Finds all files inside and beneath the index path
    // and adds them to the index entries vector.
    fn populate(&mut self) {
        // The entries listed by readdir include the root index path; we want
        // relative paths, so we get this length so that we can strip it.
        let prefix_length = self.path.as_str().unwrap().len()+1;

        // Start by getting any files in the root path. Since
        // read_directory_entries is already borrowing a mutable
        // reference to the index, so we can't also lend out a
        // reference to its path field, hence the clone.
        let path = self.path.clone();
        self.index_directory_files(path, prefix_length);

        // Get an iterator that'll let us walk all of the subdirectories
        // of the index path, bailing out if there's an error of any kind.
        let mut subdirectories = match fs::walk_dir(&self.path) {
            Ok(iterator) => iterator,
            Err(e) => return,
        };

        // Index any other files beneath the root directory.
        for directory in subdirectories {
            self.index_directory_files(directory, prefix_length);
        }
    }

    // Helper method for populate.
    // Finds files for a particular directory, strips prefix_length leading
    // characters from their path, and adds them to the index entries vector.
    fn index_directory_files(&mut self, directory: Path, prefix_length: usize) {
        match fs::readdir(&directory) {
            Ok(entries) => {
                // Put all of the file-based Path entries into the index.
                for file in entries.iter().filter(|entry| entry.is_file()) {
                    // Make the file path relative to the index path by stripping it from its string.
                    let file_path = Path::new(file.as_str().unwrap().slice_from(prefix_length));

                    self.entries.push(file_path);
                }
            },
            Err(e) => (),
        }
    }
}

#[test]
fn new_creates_index_with_passed_path() {
    let path = "my path";
    let index = Index::new(path);

    // Get the index path as a string.
    let index_path = match index.path.as_str() {
        Some(value) => value,
        None => ""
    };

    assert_eq!(index_path, path);
}

#[test]
fn new_creates_index_with_empty_array() {
    let path = "my path";
    let index = Index::new(path);
    let empty_array: Vec<Path> = vec![];

    assert!(index.entries == empty_array);
}

#[test]
fn populate_adds_all_files_to_entries() {
    let path = "tests/sample";
    let index = &mut Index::new(path);
    let expected_array = vec![Path::new("root_file"), Path::new("directory/nested_file")];
    index.populate();

    assert!(index.entries == expected_array);
}
<|endoftext|>


<commit_before>#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    LParen,
    RParen,
    Symbol(String),
    Number(i32),
    EOF,
}

pub struct LexerState {
    pub s: String,
    pub pos: usize,
    pub col: usize,
    pub line_num: usize,
    pub tok_buf: Option<Token>,
}

fn is_valid_symbol_start(c: char) -> bool {
    // TODO: avoid allocatiing this in each call
    let symbol_start_chars = vec!['+', '-', '*', '/', '#'];

    let mut ret = false;
    if c.is_alphabetic() { ret = true; }
    else {
        for s in symbol_start_chars {
            if c == s { ret = true; break; }
            else { continue; }
        }
    }

    return ret;
}

pub fn get_token(ls: &mut LexerState) -> Token {
    if let Some(tok) = ls.tok_buf.clone() {
        ls.tok_buf = None;
        return tok;
    }
    else {
        let mut iter = ls.s[ls.pos..].chars().peekable();
        while let Some(&c) = iter.peek() {
            if c.is_numeric() {
                let mut acc = String::new();
                let mut n = c;
                while n.is_numeric() {
                    acc.push(n);
                    iter.next();
                    ls.pos += 1;
                    ls.col += 1;
                    n = match iter.peek() {
                        Some(&x) => x,
                        None => break,
                    };
                }
                return Token::Number(acc.parse().unwrap());
            }
            else if is_valid_symbol_start(c) {
                let mut acc = String::new();
                let mut s = c;
                while (s.is_alphanumeric() ||
                       is_valid_symbol_start(s)) {
                    acc.push(s);
                    iter.next();
                    ls.pos += 1;
                    ls.col += 1;
                    s = match iter.peek() {
                        Some(&x) => x,
                        None => break,
                    };
                }
                return Token::Symbol(acc);
            }
            else {
                match c {
                    '\n' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col = 0;
                        ls.line_num += 1;
                        continue;
                    },
                    ' ' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        continue
                    },
                    '(' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        return Token::LParen
                    },
                    ')' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        return Token::RParen
                    },
                    _ => panic!("line {}:{} unexpected char: {}", ls.line_num, ls.col, c),
                }
            }
        }
        return Token::EOF;
    }
}
<commit_msg>Remove parens around while cond<commit_after>#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    LParen,
    RParen,
    Symbol(String),
    Number(i32),
    EOF,
}

pub struct LexerState {
    pub s: String,
    pub pos: usize,
    pub col: usize,
    pub line_num: usize,
    pub tok_buf: Option<Token>,
}

fn is_valid_symbol_start(c: char) -> bool {
    // TODO: avoid allocatiing this in each call
    let symbol_start_chars = vec!['+', '-', '*', '/', '#'];

    let mut ret = false;
    if c.is_alphabetic() { ret = true; }
    else {
        for s in symbol_start_chars {
            if c == s { ret = true; break; }
            else { continue; }
        }
    }

    return ret;
}

pub fn get_token(ls: &mut LexerState) -> Token {
    if let Some(tok) = ls.tok_buf.clone() {
        ls.tok_buf = None;
        return tok;
    }
    else {
        let mut iter = ls.s[ls.pos..].chars().peekable();
        while let Some(&c) = iter.peek() {
            if c.is_numeric() {
                let mut acc = String::new();
                let mut n = c;
                while n.is_numeric() {
                    acc.push(n);
                    iter.next();
                    ls.pos += 1;
                    ls.col += 1;
                    n = match iter.peek() {
                        Some(&x) => x,
                        None => break,
                    };
                }
                return Token::Number(acc.parse().unwrap());
            }
            else if is_valid_symbol_start(c) {
                let mut acc = String::new();
                let mut s = c;
                while s.is_alphanumeric() || is_valid_symbol_start(s) {
                    acc.push(s);
                    iter.next();
                    ls.pos += 1;
                    ls.col += 1;
                    s = match iter.peek() {
                        Some(&x) => x,
                        None => break,
                    };
                }
                return Token::Symbol(acc);
            }
            else {
                match c {
                    '\n' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col = 0;
                        ls.line_num += 1;
                        continue;
                    },
                    ' ' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        continue
                    },
                    '(' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        return Token::LParen
                    },
                    ')' => {
                        iter.next();
                        ls.pos += 1;
                        ls.col += 1;
                        return Token::RParen
                    },
                    _ => panic!("line {}:{} unexpected char: {}", ls.line_num, ls.col, c),
                }
            }
        }
        return Token::EOF;
    }
}
<|endoftext|>


<commit_before>use libc;

use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};

use self::libc::{c_char, c_int, c_void, useconds_t};
use std::{borrow::Cow, ffi::CString, ptr};

const CURRENT_WINDOW: c_int = 0;
const DEFAULT_DELAY: u64 = 12000;
type Window = c_int;
type Xdo = *const c_void;

#[link(name = "xdo")]
extern "C" {
    fn xdo_free(xdo: Xdo);
    fn xdo_new(display: *const c_char) -> Xdo;

    fn xdo_click_window(xdo: Xdo, window: Window, button: c_int) -> c_int;
    fn xdo_mouse_down(xdo: Xdo, window: Window, button: c_int) -> c_int;
    fn xdo_mouse_up(xdo: Xdo, window: Window, button: c_int) -> c_int;
    fn xdo_move_mouse(xdo: Xdo, x: c_int, y: c_int, screen: c_int) -> c_int;
    fn xdo_move_mouse_relative(xdo: Xdo, x: c_int, y: c_int) -> c_int;

    fn xdo_enter_text_window(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
    fn xdo_send_keysequence_window(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
    fn xdo_send_keysequence_window_down(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
    fn xdo_send_keysequence_window_up(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
}

fn mousebutton(button: MouseButton) -> c_int {
    match button {
        MouseButton::Left => 1,
        MouseButton::Middle => 2,
        MouseButton::Right => 3,
        MouseButton::ScrollUp => 4,
        MouseButton::ScrollDown => 5,
        MouseButton::ScrollLeft => 6,
        MouseButton::ScrollRight => 7,
    }
}

/// The main struct for handling the event emitting
pub struct Enigo {
    xdo: Xdo,
    delay: u64,
}
// This is safe, we have a unique pointer.
// TODO: use Unique<c_char> once stable.
unsafe impl Send for Enigo {}

impl Default for Enigo {
    /// Create a new Enigo instance
    fn default() -> Self {
        Self {
            xdo: unsafe { xdo_new(ptr::null()) },
            delay: DEFAULT_DELAY,
        }
    }
}
impl Enigo {
    /// Get the delay per keypress.
    /// Default value is 12000.
    /// This is Linux-specific.
    pub fn delay(&self) -> u64 {
        self.delay
    }
    /// Set the delay per keypress.
    /// This is Linux-specific.
    pub fn set_delay(&mut self, delay: u64) {
        self.delay = delay;
    }
}
impl Drop for Enigo {
    fn drop(&mut self) {
        unsafe {
            xdo_free(self.xdo);
        }
    }
}
impl MouseControllable for Enigo {
    fn mouse_move_to(&mut self, x: i32, y: i32) {
        unsafe {
            xdo_move_mouse(self.xdo, x as c_int, y as c_int, 0);
        }
    }
    fn mouse_move_relative(&mut self, x: i32, y: i32) {
        unsafe {
            xdo_move_mouse_relative(self.xdo, x as c_int, y as c_int);
        }
    }
    fn mouse_down(&mut self, button: MouseButton) {
        unsafe {
            xdo_mouse_down(self.xdo, CURRENT_WINDOW, mousebutton(button));
        }
    }
    fn mouse_up(&mut self, button: MouseButton) {
        unsafe {
            xdo_mouse_up(self.xdo, CURRENT_WINDOW, mousebutton(button));
        }
    }
    fn mouse_click(&mut self, button: MouseButton) {
        unsafe {
            xdo_click_window(self.xdo, CURRENT_WINDOW, mousebutton(button));
        }
    }
    fn mouse_scroll_x(&mut self, length: i32) {
        let button;
        let mut length = length;

        if length < 0 {
            button = MouseButton::ScrollLeft;
        } else {
            button = MouseButton::ScrollRight;
        }

        if length < 0 {
            length = -length;
        }

        for _ in 0..length {
            self.mouse_click(button);
        }
    }
    fn mouse_scroll_y(&mut self, length: i32) {
        let button;
        let mut length = length;

        if length < 0 {
            button = MouseButton::ScrollUp;
        } else {
            button = MouseButton::ScrollDown;
        }

        if length < 0 {
            length = -length;
        }

        for _ in 0..length {
            self.mouse_click(button);
        }
    }
}
fn keysequence<'a>(key: Key) -> Cow<'a, str> {
    if let Key::Layout(c) = key {
        return Cow::Owned(format!("U{:X}", c as u32));
    }
    #[allow(deprecated)]
    // I mean duh, we still need to support deprecated keys until they're removed
    Cow::Borrowed(match key {
        Key::Alt => "Alt",
        Key::Backspace => "BackSpace",
        Key::CapsLock => "CapsLock",
        Key::Control => "Control",
        Key::Delete => "Delete",
        Key::DownArrow => "Down",
        Key::End => "End",
        Key::Escape => "Escape",
        Key::F1 => "F1",
        Key::F10 => "F10",
        Key::F11 => "F11",
        Key::F12 => "F12",
        Key::F2 => "F2",
        Key::F3 => "F3",
        Key::F4 => "F4",
        Key::F5 => "F5",
        Key::F6 => "F6",
        Key::F7 => "F7",
        Key::F8 => "F8",
        Key::F9 => "F9",
        Key::Home => "Home",
        Key::Layout(_) => unreachable!(),
        Key::LeftArrow => "Left",
        Key::Option => "Option",
        Key::PageDown => "Page_Down",
        Key::PageUp => "Page_Up",
        Key::Raw(_) => unimplemented!(),
        Key::Return => "Return",
        Key::RightArrow => "Right",
        Key::Shift => "Shift",
        Key::Space => "space",
        Key::Tab => "Tab",
        Key::UpArrow => "Up",

        Key::Command | Key::Super | Key::Windows | Key::Meta => "Super",
    })
}
impl KeyboardControllable for Enigo {
    fn key_sequence(&mut self, sequence: &str) {
        let string = CString::new(sequence).unwrap();
        unsafe {
            xdo_enter_text_window(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
    fn key_down(&mut self, key: Key) {
        let string = CString::new(&*keysequence(key)).unwrap();
        unsafe {
            xdo_send_keysequence_window_down(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
    fn key_up(&mut self, key: Key) {
        let string = CString::new(&*keysequence(key)).unwrap();
        unsafe {
            xdo_send_keysequence_window_up(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
    fn key_click(&mut self, key: Key) {
        let string = CString::new(&*keysequence(key)).unwrap();
        unsafe {
            xdo_send_keysequence_window(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
}
<commit_msg>Implement Raw keycodes for Linux (#85)<commit_after>use libc;

use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};

use self::libc::{c_char, c_int, c_void, useconds_t};
use std::{borrow::Cow, ffi::CString, ptr};

const CURRENT_WINDOW: c_int = 0;
const DEFAULT_DELAY: u64 = 12000;
type Window = c_int;
type Xdo = *const c_void;

#[link(name = "xdo")]
extern "C" {
    fn xdo_free(xdo: Xdo);
    fn xdo_new(display: *const c_char) -> Xdo;

    fn xdo_click_window(xdo: Xdo, window: Window, button: c_int) -> c_int;
    fn xdo_mouse_down(xdo: Xdo, window: Window, button: c_int) -> c_int;
    fn xdo_mouse_up(xdo: Xdo, window: Window, button: c_int) -> c_int;
    fn xdo_move_mouse(xdo: Xdo, x: c_int, y: c_int, screen: c_int) -> c_int;
    fn xdo_move_mouse_relative(xdo: Xdo, x: c_int, y: c_int) -> c_int;

    fn xdo_enter_text_window(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
    fn xdo_send_keysequence_window(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
    fn xdo_send_keysequence_window_down(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
    fn xdo_send_keysequence_window_up(
        xdo: Xdo,
        window: Window,
        string: *const c_char,
        delay: useconds_t,
    ) -> c_int;
}

fn mousebutton(button: MouseButton) -> c_int {
    match button {
        MouseButton::Left => 1,
        MouseButton::Middle => 2,
        MouseButton::Right => 3,
        MouseButton::ScrollUp => 4,
        MouseButton::ScrollDown => 5,
        MouseButton::ScrollLeft => 6,
        MouseButton::ScrollRight => 7,
    }
}

/// The main struct for handling the event emitting
pub struct Enigo {
    xdo: Xdo,
    delay: u64,
}
// This is safe, we have a unique pointer.
// TODO: use Unique<c_char> once stable.
unsafe impl Send for Enigo {}

impl Default for Enigo {
    /// Create a new Enigo instance
    fn default() -> Self {
        Self {
            xdo: unsafe { xdo_new(ptr::null()) },
            delay: DEFAULT_DELAY,
        }
    }
}
impl Enigo {
    /// Get the delay per keypress.
    /// Default value is 12000.
    /// This is Linux-specific.
    pub fn delay(&self) -> u64 {
        self.delay
    }
    /// Set the delay per keypress.
    /// This is Linux-specific.
    pub fn set_delay(&mut self, delay: u64) {
        self.delay = delay;
    }
}
impl Drop for Enigo {
    fn drop(&mut self) {
        unsafe {
            xdo_free(self.xdo);
        }
    }
}
impl MouseControllable for Enigo {
    fn mouse_move_to(&mut self, x: i32, y: i32) {
        unsafe {
            xdo_move_mouse(self.xdo, x as c_int, y as c_int, 0);
        }
    }
    fn mouse_move_relative(&mut self, x: i32, y: i32) {
        unsafe {
            xdo_move_mouse_relative(self.xdo, x as c_int, y as c_int);
        }
    }
    fn mouse_down(&mut self, button: MouseButton) {
        unsafe {
            xdo_mouse_down(self.xdo, CURRENT_WINDOW, mousebutton(button));
        }
    }
    fn mouse_up(&mut self, button: MouseButton) {
        unsafe {
            xdo_mouse_up(self.xdo, CURRENT_WINDOW, mousebutton(button));
        }
    }
    fn mouse_click(&mut self, button: MouseButton) {
        unsafe {
            xdo_click_window(self.xdo, CURRENT_WINDOW, mousebutton(button));
        }
    }
    fn mouse_scroll_x(&mut self, length: i32) {
        let button;
        let mut length = length;

        if length < 0 {
            button = MouseButton::ScrollLeft;
        } else {
            button = MouseButton::ScrollRight;
        }

        if length < 0 {
            length = -length;
        }

        for _ in 0..length {
            self.mouse_click(button);
        }
    }
    fn mouse_scroll_y(&mut self, length: i32) {
        let button;
        let mut length = length;

        if length < 0 {
            button = MouseButton::ScrollUp;
        } else {
            button = MouseButton::ScrollDown;
        }

        if length < 0 {
            length = -length;
        }

        for _ in 0..length {
            self.mouse_click(button);
        }
    }
}
fn keysequence<'a>(key: Key) -> Cow<'a, str> {
    if let Key::Layout(c) = key {
        return Cow::Owned(format!("U{:X}", c as u32));
    }
    if let Key::Raw(k) = key {
        return Cow::Owned(format!("{}", k as u16))
    }
    #[allow(deprecated)]
    // I mean duh, we still need to support deprecated keys until they're removed
    Cow::Borrowed(match key {
        Key::Alt => "Alt",
        Key::Backspace => "BackSpace",
        Key::CapsLock => "CapsLock",
        Key::Control => "Control",
        Key::Delete => "Delete",
        Key::DownArrow => "Down",
        Key::End => "End",
        Key::Escape => "Escape",
        Key::F1 => "F1",
        Key::F10 => "F10",
        Key::F11 => "F11",
        Key::F12 => "F12",
        Key::F2 => "F2",
        Key::F3 => "F3",
        Key::F4 => "F4",
        Key::F5 => "F5",
        Key::F6 => "F6",
        Key::F7 => "F7",
        Key::F8 => "F8",
        Key::F9 => "F9",
        Key::Home => "Home",
        Key::Layout(_) => unreachable!(),
        Key::LeftArrow => "Left",
        Key::Option => "Option",
        Key::PageDown => "Page_Down",
        Key::PageUp => "Page_Up",
        Key::Raw(_) => unreachable!(),
        Key::Return => "Return",
        Key::RightArrow => "Right",
        Key::Shift => "Shift",
        Key::Space => "space",
        Key::Tab => "Tab",
        Key::UpArrow => "Up",

        Key::Command | Key::Super | Key::Windows | Key::Meta => "Super",
    })
}
impl KeyboardControllable for Enigo {
    fn key_sequence(&mut self, sequence: &str) {
        let string = CString::new(sequence).unwrap();
        unsafe {
            xdo_enter_text_window(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
    fn key_down(&mut self, key: Key) {
        let string = CString::new(&*keysequence(key)).unwrap();
        unsafe {
            xdo_send_keysequence_window_down(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
    fn key_up(&mut self, key: Key) {
        let string = CString::new(&*keysequence(key)).unwrap();
        unsafe {
            xdo_send_keysequence_window_up(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
    fn key_click(&mut self, key: Key) {
        let string = CString::new(&*keysequence(key)).unwrap();
        unsafe {
            xdo_send_keysequence_window(
                self.xdo,
                CURRENT_WINDOW,
                string.as_ptr(),
                self.delay as useconds_t,
            );
        }
    }
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct VariableName {
    pub id: i32,
    pub name: String,
}

pub fn table_create_variable_name(conn: &Connection) -> &Connection {
    conn.execute(
        "CREATE TABLE VARIABLE_NAME (
                  id            INTEGER PRIMARY KEY ASC,
                  name      TEXT NOT NULL UNIQUE
                  )",
        &[],
    ).unwrap();
    return conn;
}

pub fn insert_variable_name(conn: &Connection, name: &String) -> Result<i32, &'static str> {
    let me = VariableName {
        id: 0,
        name: name.clone(),
    };
    let variable_name_instance = conn.execute(
        "INSERT INTO VARIABLE_NAME (name)
                  VALUES (?1)",
        &[&me.name],
    );
    if variable_name_instance.is_err() {
        return Err("Insert failed");
    }
    variable_name_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_name(conn: &Connection) -> Vec<VariableName> {
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<VariableName>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_name_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name, fk_provider, sq_order FROM VARIABLE_NAME")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found variable_name {:?}", person.unwrap());
    }
}

pub fn pk_variable_name_by_name(conn: &Connection, name: &str) -> Result<i32, &'static str> {
    let mut output = 0;
    let bill = String::from(name);
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME WHERE name = ?1")
        .unwrap();
    let variable_name_iter = stmt.query_map(&[&name], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    if variable_name_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_name_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<commit_msg>Use Logging<commit_after>use rusqlite::Connection;
use std::result;
use log;

#[derive(Debug)]
pub struct VariableName {
    pub id: i32,
    pub name: String,
}

pub fn table_create_variable_name(conn: &Connection) -> &Connection {
    conn.execute(
        "CREATE TABLE VARIABLE_NAME (
                  id            INTEGER PRIMARY KEY ASC,
                  name      TEXT NOT NULL UNIQUE
                  )",
        &[],
    ).unwrap();
    return conn;
}

pub fn insert_variable_name(conn: &Connection, name: &String) -> Result<i32, &'static str> {
    let me = VariableName {
        id: 0,
        name: name.clone(),
    };
    let variable_name_instance = conn.execute(
        "INSERT INTO VARIABLE_NAME (name)
                  VALUES (?1)",
        &[&me.name],
    );
    if variable_name_instance.is_err() {
        return Err("Insert failed");
    }
    variable_name_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_name(conn: &Connection) -> Vec<VariableName> {
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<VariableName>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_name_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name, fk_provider, sq_order FROM VARIABLE_NAME")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();

    for person in person_iter {
        info!("Found variable_name {:?}", person.unwrap());
    }
}

pub fn pk_variable_name_by_name(conn: &Connection, name: &str) -> Result<i32, &'static str> {
    let mut output = 0;
    let bill = String::from(name);
    let mut stmt = conn.prepare("SELECT id, name  FROM VARIABLE_NAME WHERE name = ?1")
        .unwrap();
    let variable_name_iter = stmt.query_map(&[&name], |row| {
        VariableName {
            id: row.get(0),
            name: row.get(1),
        }
    });
    if variable_name_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_name_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>///! Allocating pages of memory from the OS and carving them into individual allocations.

use std::{mem, ptr};
use bit_vec::BitVec;
use traits::{mark_entry_point, GCThing, gcthing_type_id};
use heap::Heap;

/// Total number of objects that can be allocated in a single page at once.
///
/// XXX BOGUS: At present, this is number is carefully selected (with insider
/// knowledge of both `size_of::<PairStorage>()` on my platform and the `Vec`
/// allocator's behavior) so that a TypedPage object fits in a page and thus
/// the assertions below about PAGE_ALIGN pass.
pub const HEAP_SIZE: usize = 124;

const PAGE_SIZE: usize = 0x1000;

/// We rely on all bits to the right of this bit being 0 in addresses of
/// TypedPage instances.
const PAGE_ALIGN: usize = 0x1000;

fn is_aligned(ptr: *const ()) -> bool {
    ptr as usize & (PAGE_ALIGN - 1) == 0
}

pub struct PageHeader<'a> {
    pub heap: *mut Heap<'a>,
    mark_bits: BitVec,
    allocated_bits: BitVec,
    mark_fn: unsafe fn(*mut ()),
    sweep_fn: unsafe fn(*mut PageHeader<'a>),
    freelist: *mut ()
}

impl<'a> PageHeader<'a> {
    pub fn find(ptr: *mut ()) -> *mut PageHeader<'a> {
        let header_addr = ptr as usize & !(PAGE_ALIGN - 1);
        header_addr as *mut PageHeader<'a>
    }

    pub fn clear_mark_bits(&mut self) {
        self.mark_bits.clear();
    }

    /// True if nothing on this page is allocated.
    pub fn is_empty(&self) -> bool {
        self.allocated_bits.none()
    }

    pub unsafe fn mark(&self, ptr: *mut ()) {
        (self.mark_fn)(ptr);
    }

    pub unsafe fn sweep(&mut self) {
        (self.sweep_fn)(self);
    }

    pub fn type_id(&self) -> usize {
        self.mark_fn as usize
    }
}

pub struct TypedPage<'a, T: GCThing<'a>> {
    pub header: PageHeader<'a>,
    objects: [T; HEAP_SIZE]
}

impl<'a, T: GCThing<'a>> Drop for TypedPage<'a, T> {
    fn drop(&mut self) {
        // All the memory in self.objects is uninitialized at this point. Rust
        // will drop each of those objects, which would crash. So we have this
        // super lame hack: initialize all the objects with innocuous values so
        // they can be safely destroyed.
        for i in 0 .. HEAP_SIZE {
            unsafe {
                ptr::write(
                    &mut self.objects[i] as *mut T,
                    T::default());
            }
        }
    }
}

impl<'a, T: GCThing<'a>> TypedPage<'a, T> {
    unsafe fn init(&mut self) {
        for i in 0 .. HEAP_SIZE {
            let p = &mut self.objects[i] as *mut T;
            self.add_to_free_list(p);
        }
    }

    pub fn find(ptr: *const T) -> *mut TypedPage<'a, T> {
        let page_addr = ptr as usize & !(PAGE_ALIGN - 1);
        let page = page_addr as *mut TypedPage<'a, T>;
        assert_eq!(gcthing_type_id::<T>(), unsafe { (*page).header.type_id() });
        page
    }

    unsafe fn add_to_free_list(&mut self, p: *mut T) {
        let listp = p as *mut *mut ();
        *listp = self.header.freelist;
        assert_eq!(*listp, self.header.freelist);
        self.header.freelist = p as *mut ();
    }

    unsafe fn allocation_index(&self, ptr: *const T) -> usize {
        let base = &self.objects[0] as *const T;

        // Check that ptr is in range.
        assert!(ptr >= base);
        assert!(ptr < base.offset(HEAP_SIZE as isize));

        let index = (ptr as usize - base as usize) / mem::size_of::<T>();
        assert_eq!(&self.objects[index] as *const T, ptr);
        index
    }

    pub unsafe fn get_mark_bit(&mut self, ptr: *const T) -> bool {
        let index = self.allocation_index(ptr);
        self.header.mark_bits[index]
    }

    pub unsafe fn set_mark_bit(&mut self, ptr: *const T) {
        let index = self.allocation_index(ptr);
        self.header.mark_bits.set(index, true);
    }

    pub unsafe fn try_alloc(&mut self) -> Option<*mut T> {
        let p = self.header.freelist;
        if p.is_null() {
            None
        } else {
            let listp = p as *mut *mut ();
            self.header.freelist = *listp;
            let ap = p as *mut T;
            let index = self.allocation_index(ap);
            assert!(!self.header.allocated_bits[index]);
            self.header.allocated_bits.set(index, true);
            Some(ap)
        }
    }

    unsafe fn sweep(&mut self) {
        for i in 0 .. HEAP_SIZE {
            let p = &mut self.objects[i] as *mut T;
            if self.header.allocated_bits[i] && !self.header.mark_bits[i] {
                // The next statement has the effect of calling p's destructor.
                ptr::read(p);
                self.header.allocated_bits.set(i, false);
                self.add_to_free_list(p);
            }
        }
    }
}

unsafe fn sweep_entry_point<'a, T: GCThing<'a>>(header: *mut PageHeader<'a>) {
    // little reinterpret_cast as downcast, no worries
    let typed_page = header as *mut TypedPage<'a, T>;
    (*typed_page).sweep();
}

pub struct PageBox<'a>(*mut PageHeader<'a>);

impl<'a> PageBox<'a> {
    pub fn new<T: GCThing<'a>>(heap: &mut Heap<'a>) -> PageBox<'a> {
        assert!(mem::size_of::<TypedPage<'a, T>>() <= PAGE_SIZE);
        let raw_page: *mut () = {
            let mut vec: Vec<u8> = Vec::with_capacity(PAGE_SIZE);
            let page = vec.as_mut_ptr() as *mut ();

            // Rust makes no guarantee whatsoever that this will work.
            // If it doesn't, panic.
            assert!(is_aligned(page));

            mem::forget(vec);
            page
        };

        let page: *mut TypedPage<'a, T> = raw_page as *mut TypedPage<'a, T>;
        unsafe {
            ptr::write(page, TypedPage {
                header: PageHeader {
                    heap: heap as *mut Heap<'a>,
                    mark_bits: BitVec::from_elem(HEAP_SIZE, false),
                    allocated_bits: BitVec::from_elem(HEAP_SIZE, false),
                    mark_fn: mark_entry_point::<T>,
                    sweep_fn: sweep_entry_point::<T>,
                    freelist: ptr::null_mut()
                },
                objects: mem::uninitialized()
            });
            TypedPage::<'a, T>::init(&mut *page);
            PageBox(&mut (*page).header as *mut PageHeader<'a>)
        }
    }

    pub fn downcast_mut<T: GCThing<'a>>(&mut self) -> Option<&mut TypedPage<'a, T>> {
        if gcthing_type_id::<T>() == unsafe { (*self.0).type_id() } {
            let ptr = self.0 as *mut TypedPage<'a, T>;
            Some(unsafe { &mut *ptr })
        } else {
            None
        }
    }

    pub fn header(&self) -> &PageHeader<'a> {
        unsafe { &*self.0 }
    }

    pub fn header_mut(&mut self) -> &mut PageHeader<'a> {
        unsafe { &mut *self.0 }
    }

    pub fn sweep(&mut self) {
        unsafe { (*self.0).sweep(); }
    }
}

impl<'a> Drop for PageBox<'a> {
    fn drop(&mut self) {
        unsafe {
            assert!((*self.0).is_empty());

            // Call the header's destructor. (ptr::read returns a temporary copy of
            // the header. Since we don't store it anywhere, it is then dropped.)
            ptr::read(self.0);

            // Deallocate the memory.
            Vec::from_raw_parts(self.0 as *mut u8, 0, PAGE_SIZE);
        }
    }
}

impl<'a> ::std::hash::Hash for PageBox<'a> {
    fn hash<H: ::std::hash::Hasher>(&self, hasher: &mut H) {
        hasher.write_usize(self.header().type_id());
    }
}
<commit_msg>Delete dead impl of Drop for TypedPage. PageBox::drop is specially written to avoid calling this horrible code, so there is no point still having it.<commit_after>///! Allocating pages of memory from the OS and carving them into individual allocations.

use std::{mem, ptr};
use bit_vec::BitVec;
use traits::{mark_entry_point, GCThing, gcthing_type_id};
use heap::Heap;

/// Total number of objects that can be allocated in a single page at once.
///
/// XXX BOGUS: At present, this is number is carefully selected (with insider
/// knowledge of both `size_of::<PairStorage>()` on my platform and the `Vec`
/// allocator's behavior) so that a TypedPage object fits in a page and thus
/// the assertions below about PAGE_ALIGN pass.
pub const HEAP_SIZE: usize = 124;

const PAGE_SIZE: usize = 0x1000;

/// We rely on all bits to the right of this bit being 0 in addresses of
/// TypedPage instances.
const PAGE_ALIGN: usize = 0x1000;

fn is_aligned(ptr: *const ()) -> bool {
    ptr as usize & (PAGE_ALIGN - 1) == 0
}

pub struct PageHeader<'a> {
    pub heap: *mut Heap<'a>,
    mark_bits: BitVec,
    allocated_bits: BitVec,
    mark_fn: unsafe fn(*mut ()),
    sweep_fn: unsafe fn(*mut PageHeader<'a>),
    freelist: *mut ()
}

impl<'a> PageHeader<'a> {
    pub fn find(ptr: *mut ()) -> *mut PageHeader<'a> {
        let header_addr = ptr as usize & !(PAGE_ALIGN - 1);
        header_addr as *mut PageHeader<'a>
    }

    pub fn clear_mark_bits(&mut self) {
        self.mark_bits.clear();
    }

    /// True if nothing on this page is allocated.
    pub fn is_empty(&self) -> bool {
        self.allocated_bits.none()
    }

    pub unsafe fn mark(&self, ptr: *mut ()) {
        (self.mark_fn)(ptr);
    }

    pub unsafe fn sweep(&mut self) {
        (self.sweep_fn)(self);
    }

    pub fn type_id(&self) -> usize {
        self.mark_fn as usize
    }
}

pub struct TypedPage<'a, T: GCThing<'a>> {
    pub header: PageHeader<'a>,
    objects: [T; HEAP_SIZE]
}

impl<'a, T: GCThing<'a>> TypedPage<'a, T> {
    unsafe fn init(&mut self) {
        for i in 0 .. HEAP_SIZE {
            let p = &mut self.objects[i] as *mut T;
            self.add_to_free_list(p);
        }
    }

    pub fn find(ptr: *const T) -> *mut TypedPage<'a, T> {
        let page_addr = ptr as usize & !(PAGE_ALIGN - 1);
        let page = page_addr as *mut TypedPage<'a, T>;
        assert_eq!(gcthing_type_id::<T>(), unsafe { (*page).header.type_id() });
        page
    }

    unsafe fn add_to_free_list(&mut self, p: *mut T) {
        let listp = p as *mut *mut ();
        *listp = self.header.freelist;
        assert_eq!(*listp, self.header.freelist);
        self.header.freelist = p as *mut ();
    }

    unsafe fn allocation_index(&self, ptr: *const T) -> usize {
        let base = &self.objects[0] as *const T;

        // Check that ptr is in range.
        assert!(ptr >= base);
        assert!(ptr < base.offset(HEAP_SIZE as isize));

        let index = (ptr as usize - base as usize) / mem::size_of::<T>();
        assert_eq!(&self.objects[index] as *const T, ptr);
        index
    }

    pub unsafe fn get_mark_bit(&mut self, ptr: *const T) -> bool {
        let index = self.allocation_index(ptr);
        self.header.mark_bits[index]
    }

    pub unsafe fn set_mark_bit(&mut self, ptr: *const T) {
        let index = self.allocation_index(ptr);
        self.header.mark_bits.set(index, true);
    }

    pub unsafe fn try_alloc(&mut self) -> Option<*mut T> {
        let p = self.header.freelist;
        if p.is_null() {
            None
        } else {
            let listp = p as *mut *mut ();
            self.header.freelist = *listp;
            let ap = p as *mut T;
            let index = self.allocation_index(ap);
            assert!(!self.header.allocated_bits[index]);
            self.header.allocated_bits.set(index, true);
            Some(ap)
        }
    }

    unsafe fn sweep(&mut self) {
        for i in 0 .. HEAP_SIZE {
            let p = &mut self.objects[i] as *mut T;
            if self.header.allocated_bits[i] && !self.header.mark_bits[i] {
                // The next statement has the effect of calling p's destructor.
                ptr::read(p);
                self.header.allocated_bits.set(i, false);
                self.add_to_free_list(p);
            }
        }
    }
}

unsafe fn sweep_entry_point<'a, T: GCThing<'a>>(header: *mut PageHeader<'a>) {
    // little reinterpret_cast as downcast, no worries
    let typed_page = header as *mut TypedPage<'a, T>;
    (*typed_page).sweep();
}

pub struct PageBox<'a>(*mut PageHeader<'a>);

impl<'a> PageBox<'a> {
    pub fn new<T: GCThing<'a>>(heap: &mut Heap<'a>) -> PageBox<'a> {
        assert!(mem::size_of::<TypedPage<'a, T>>() <= PAGE_SIZE);
        let raw_page: *mut () = {
            let mut vec: Vec<u8> = Vec::with_capacity(PAGE_SIZE);
            let page = vec.as_mut_ptr() as *mut ();

            // Rust makes no guarantee whatsoever that this will work.
            // If it doesn't, panic.
            assert!(is_aligned(page));

            mem::forget(vec);
            page
        };

        let page: *mut TypedPage<'a, T> = raw_page as *mut TypedPage<'a, T>;
        unsafe {
            ptr::write(page, TypedPage {
                header: PageHeader {
                    heap: heap as *mut Heap<'a>,
                    mark_bits: BitVec::from_elem(HEAP_SIZE, false),
                    allocated_bits: BitVec::from_elem(HEAP_SIZE, false),
                    mark_fn: mark_entry_point::<T>,
                    sweep_fn: sweep_entry_point::<T>,
                    freelist: ptr::null_mut()
                },
                objects: mem::uninitialized()
            });
            TypedPage::<'a, T>::init(&mut *page);
            PageBox(&mut (*page).header as *mut PageHeader<'a>)
        }
    }

    pub fn downcast_mut<T: GCThing<'a>>(&mut self) -> Option<&mut TypedPage<'a, T>> {
        if gcthing_type_id::<T>() == unsafe { (*self.0).type_id() } {
            let ptr = self.0 as *mut TypedPage<'a, T>;
            Some(unsafe { &mut *ptr })
        } else {
            None
        }
    }

    pub fn header(&self) -> &PageHeader<'a> {
        unsafe { &*self.0 }
    }

    pub fn header_mut(&mut self) -> &mut PageHeader<'a> {
        unsafe { &mut *self.0 }
    }

    pub fn sweep(&mut self) {
        unsafe { (*self.0).sweep(); }
    }
}

impl<'a> Drop for PageBox<'a> {
    fn drop(&mut self) {
        unsafe {
            assert!((*self.0).is_empty());

            // Call the header's destructor. (ptr::read returns a temporary copy of
            // the header. Since we don't store it anywhere, it is then dropped.)
            ptr::read(self.0);

            // Deallocate the memory.
            Vec::from_raw_parts(self.0 as *mut u8, 0, PAGE_SIZE);
        }
    }
}

impl<'a> ::std::hash::Hash for PageBox<'a> {
    fn hash<H: ::std::hash::Hasher>(&self, hasher: &mut H) {
        hasher.write_usize(self.header().type_id());
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::any::Any;
use std::cell::RefCell;
use std::panic::{UnwindSafe, catch_unwind, resume_unwind};

thread_local!(static PANIC_RESULT: RefCell<Option<Box<Any + Send>>> = RefCell::new(None));

/// If there is a pending panic, resume unwinding.
pub fn maybe_resume_unwind() {
    if let Some(error) = PANIC_RESULT.with(|result| result.borrow_mut().take()) {
        resume_unwind(error);
    }
}

/// Generic wrapper for JS engine callbacks panic-catching
pub fn wrap_panic<F, R>(function: F, generic_return_type: R) -> R
    where F: FnMut() -> R + UnwindSafe
{
    let result = catch_unwind(function);
    match result {
        Ok(result) => result,
        Err(error) => {
            PANIC_RESULT.with(|result| {
                assert!(result.borrow().is_none());
                *result.borrow_mut() = Some(error);
            });
            generic_return_type
        }
    }
}
<commit_msg>Auto merge of #317 - servo:fnonce, r=nox<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::any::Any;
use std::cell::RefCell;
use std::panic::{UnwindSafe, catch_unwind, resume_unwind};

thread_local!(static PANIC_RESULT: RefCell<Option<Box<Any + Send>>> = RefCell::new(None));

/// If there is a pending panic, resume unwinding.
pub fn maybe_resume_unwind() {
    if let Some(error) = PANIC_RESULT.with(|result| result.borrow_mut().take()) {
        resume_unwind(error);
    }
}

/// Generic wrapper for JS engine callbacks panic-catching
pub fn wrap_panic<F, R>(function: F, generic_return_type: R) -> R
    where F: FnOnce() -> R + UnwindSafe
{
    let result = catch_unwind(function);
    match result {
        Ok(result) => result,
        Err(error) => {
            PANIC_RESULT.with(|result| {
                assert!(result.borrow().is_none());
                *result.borrow_mut() = Some(error);
            });
            generic_return_type
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::{Sub, Div};

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Point {
    pub x: f64,
    pub y: f64,
}

impl Point {
    pub fn new(x: f64, y: f64) -> Self {
        Point { x: x, y: y }
    }

    pub fn cross(self, other: Point) -> f64 {
        return self.x * other.y - other.x * self.y;
    }

    pub fn dot(self, other: Point) -> f64 {
        return self.x * other.x + self.y * other.y;
    }
}

impl Sub<Point> for Point {
    type Output = Point;

    fn sub(self, other: Point) -> Self::Output {
        return Point {
            x: self.x - other.x,
            y: self.y - other.y,
        };
    }
}

impl Div<f64> for Point {
    type Output = Point;

    fn div(self, other: f64) -> Self::Output {
        return Point {
            x: self.x / other,
            y: self.y / other,
        };
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use expectest::prelude::*;

    const P1: Point = Point { x: 2.0, y: 3.0 };
    const P2: Point = Point { x: 5.0, y: 7.0 };

    #[test]
    fn test_new() {
        expect!(Point::new(2.0, 3.0)).to(be_equal_to(P1));
    }

    #[test]
    fn test_cross() {
        expect!(P1.cross(P2)).to(be_equal_to(-1.0));
    }

    #[test]
    fn test_dot() {
        expect!(P1.dot(P2)).to(be_equal_to(31.0));
    }
}
<commit_msg>Add test for Point ops<commit_after>use std::ops::{Sub, Div};

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Point {
    pub x: f64,
    pub y: f64,
}

impl Point {
    pub fn new(x: f64, y: f64) -> Self {
        Point { x: x, y: y }
    }

    pub fn cross(self, other: Point) -> f64 {
        return self.x * other.y - other.x * self.y;
    }

    pub fn dot(self, other: Point) -> f64 {
        return self.x * other.x + self.y * other.y;
    }
}

impl Sub<Point> for Point {
    type Output = Point;

    fn sub(self, other: Point) -> Self::Output {
        return Point {
            x: self.x - other.x,
            y: self.y - other.y,
        };
    }
}

impl Div<f64> for Point {
    type Output = Point;

    fn div(self, other: f64) -> Self::Output {
        return Point {
            x: self.x / other,
            y: self.y / other,
        };
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use expectest::prelude::*;

    const P1: Point = Point { x: 2.0, y: 3.0 };
    const P1_TIMES_2: Point = Point { x: 4.0, y: 6.0 };
    const P2: Point = Point { x: 5.0, y: 7.0 };

    #[test]
    fn test_new() {
        expect!(Point::new(2.0, 3.0)).to(be_equal_to(P1));
    }

    #[test]
    fn test_cross() {
        expect!(P1.cross(P2)).to(be_equal_to(-1.0));
    }

    #[test]
    fn test_dot() {
        expect!(P1.dot(P2)).to(be_equal_to(31.0));
    }

    #[test]
    fn test_ops() {
        expect!(P1_TIMES_2 - P1).to(be_equal_to(P1));
        expect!(P1_TIMES_2 / 2.0).to(be_equal_to(P1));
    }
}
<|endoftext|>


<commit_before>//
//// #What is the largest prime factor of the number 600851475143 ?
//
//// pub fn exe(x:i32)->i32{
////     let a = 4;
////     a
//// }
//
////pub fn prime(i:u32)->Vec<u32>{
////    for x in (2..i){
////    }
////    (2..i).filter(|x|i%x==0).collect::<Vec<u32>>()
////}
//
//pub fn divide(i:u32,x:u32)->(u32,u32){
//    if x%i==0 {
//        (i,divide(i,x%i).1)
//    }else{
//        (i,x)
//    }
//}
//
//#[cfg(test)]
//mod tests {
//    use super::*;
//    //use super::test::Bencher;
//
////    #[test]
////    fn test_prime1(){
////        assert_eq!(prime(10),[2,5]);
////    }
////    //13195 are 5, 7, 13 and 29.
////    #[test]
////    fn test_prime2(){
////        assert_eq!(prime(13195),[5, 7, 13, 29]);
////    }
//
//    // #[test]
//    // fn test_exe() {
//    //     assert_eq!([], exe(600_851_475_143u32));
//    // }
//    //
//    // #[test]
//    // fn test_exe() {
//    //     assert_eq!([5, 7, 13,29], exe(13_195u32));
//    // }
//    //
//    // #[bench]
//    // fn bench_fib_30(b: &mut Bencher) {
//    //     b.iter(|| super::fib(30));
//    // }
//    //
//    // #[bench]
//    // fn bench_exe(b: &mut Bencher) {
//    //     b.iter(||exe(600_851_475_143u32));
//    // }
//}
<commit_msg>euler3の実装完了<commit_after>extern crate test;
pub fn exe(x:u64)->u64{
    search_largest_prime(2,x)
}

fn search_largest_prime(x:u64,y:u64)->(u64){
    if x>=y{
        return x;
    }else if y%x==0 {
        return search_largest_prime(x,y/x);
    }else {
        return search_largest_prime(x+1,y);
    }
}

#[cfg(test)]
mod tests {
   use super::*;
   use super::test::Bencher;

   #[test]
   fn test_divide(){
       assert_eq!(super::search_largest_prime(2,10),5);
   }
   #[test]
   fn test_divide2(){
       assert_eq!(super::search_largest_prime(2,13195),29);
   }
   #[test]
   fn test_exe() {
       assert_eq!(6857, exe(600_851_475_143));
   }

   #[bench]
   fn bench_exe(b: &mut Bencher) {
       b.iter(||exe(600_851_475_143));
   }
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
use std::process::Command;

pub use rustc_version::version_meta as version;

use serde_json::Value;
use serde_json;
use walkdir::WalkDir;

use CurrentDirectory;
use errors::*;
use extensions::CommandExt;
use {rustc, util};

fn command() -> Command {
    env::var_os("RUSTC")
        .map(Command::new)
        .unwrap_or_else(|| Command::new("rustc"))
}

/// `rustc --print target-list`
pub fn targets(verbose: bool) -> Result<Vec<String>> {
    command()
        .args(&["--print", "target-list"])
        .run_and_get_stdout(verbose)
        .map(|t| t.lines().map(|l| l.to_owned()).collect())
}

/// `rustc --print sysroot`
pub fn sysroot(verbose: bool) -> Result<Sysroot> {
    command()
        .args(&["--print", "sysroot"])
        .run_and_get_stdout(verbose)
        .map(|l| {
            Sysroot {
                path: PathBuf::from(l.trim()),
            }
        })
}
/// Path to Rust source
pub struct Src {
    path: PathBuf,
}

impl Src {
    pub fn from_env() -> Option<Self> {
        env::var_os("XARGO_RUST_SRC").map(|s| {
            Src {
                path: PathBuf::from(s),
            }
        })
    }

    pub fn path(&self) -> &Path {
        &self.path
    }
}

/// Path to `rustc`'s sysroot
pub struct Sysroot {
    path: PathBuf,
}

impl Sysroot {
    pub fn path(&self) -> &Path {
        &self.path
    }

    /// Returns the path to Rust source, `$SRC`, where `$SRC/libstd/Carg.toml`
    /// exists
    pub fn src(&self) -> Result<Src> {
        let src = self.path().join("lib").join("rustlib").join("src");

        if src.join("rust").join("src").join("libstd").join("Cargo.toml").is_file() {
            return Ok(Src {
                path: src.join("rust").join("src"),
            });
        }

        if src.exists() {
            for e in WalkDir::new(src) {
                let e = e.chain_err(|| "couldn't walk the sysroot")?;

                // Looking for $SRC/libstd/Cargo.toml
                if e.file_type().is_file() && e.file_name() == "Cargo.toml" {
                    let toml = e.path();

                    if let Some(std) = toml.parent() {
                        if let Some(src) = std.parent() {
                            if std.file_name() == Some(OsStr::new("libstd")) {
                                return Ok(Src {
                                    path: src.to_owned(),
                                });
                            }
                        }
                    }
                }
            }
        }

        Err(
            "`rust-src` component not found. Run `rustup component add \
             rust-src`.",
        )?
    }
}

#[derive(Debug)]
pub enum Target {
    Builtin { triple: String },
    Custom { json: PathBuf, triple: String },
}

impl Target {
    pub fn new(triple: &str, cd: &CurrentDirectory, verbose: bool) -> Result<Option<Target>> {
        let triple = triple.to_owned();

        if rustc::targets(verbose)?.iter().any(|t| t == &triple) {
            Ok(Some(Target::Builtin { triple: triple }))
        } else {
            let mut json = cd.path().join(&triple);
            json.set_extension("json");

            if json.exists() {
                return Ok(Some(Target::Custom {
                    json: json,
                    triple: triple,
                }));
            } else {
                if let Some(p) = env::var_os("RUST_TARGET_PATH") {
                    let mut json = PathBuf::from(p);
                    json.push(&triple);
                    json.set_extension("json");

                    if json.exists() {
                        return Ok(Some(Target::Custom {
                            json: json,
                            triple: triple,
                        }));
                    }
                }
            }

            Ok(None)
        }
    }

    pub fn triple(&self) -> &str {
        match *self {
            Target::Builtin { ref triple } => triple,
            Target::Custom { ref triple, .. } => triple,
        }
    }

    pub fn hash<H>(&self, hasher: &mut H) -> Result<()>
    where
        H: Hasher,
    {
        if let Target::Custom { ref json, .. } = *self {
            // Here we roundtrip to/from JSON to get the same hash when some
            // fields of the JSON file has been shuffled around
            serde_json::from_str::<Value>(&util::read(json)?)
                .chain_err(|| format!("{} is not valid JSON", json.display()))?
                .to_string()
                .hash(hasher);
        }

        Ok(())
    }
}
<commit_msg>support relative XARGO_RUST_SRC<commit_after>use std::env;
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
use std::process::Command;

pub use rustc_version::version_meta as version;

use serde_json::Value;
use serde_json;
use walkdir::WalkDir;

use CurrentDirectory;
use errors::*;
use extensions::CommandExt;
use {rustc, util};

fn command() -> Command {
    env::var_os("RUSTC")
        .map(Command::new)
        .unwrap_or_else(|| Command::new("rustc"))
}

/// `rustc --print target-list`
pub fn targets(verbose: bool) -> Result<Vec<String>> {
    command()
        .args(&["--print", "target-list"])
        .run_and_get_stdout(verbose)
        .map(|t| t.lines().map(|l| l.to_owned()).collect())
}

/// `rustc --print sysroot`
pub fn sysroot(verbose: bool) -> Result<Sysroot> {
    command()
        .args(&["--print", "sysroot"])
        .run_and_get_stdout(verbose)
        .map(|l| {
            Sysroot {
                path: PathBuf::from(l.trim()),
            }
        })
}
/// Path to Rust source
pub struct Src {
    path: PathBuf,
}

impl Src {
    pub fn from_env() -> Option<Self> {
        env::var_os("XARGO_RUST_SRC").map(|s| {
            let path = PathBuf::from(s);
            // To support relative paths, we have to make sure we canonicalize
            // before changing the working directory.
            let path = path.canonicalize().unwrap_or(path);
            Src { path }
        })
    }

    pub fn path(&self) -> &Path {
        &self.path
    }
}

/// Path to `rustc`'s sysroot
pub struct Sysroot {
    path: PathBuf,
}

impl Sysroot {
    pub fn path(&self) -> &Path {
        &self.path
    }

    /// Returns the path to Rust source, `$SRC`, where `$SRC/libstd/Carg.toml`
    /// exists
    pub fn src(&self) -> Result<Src> {
        let src = self.path().join("lib").join("rustlib").join("src");

        if src.join("rust").join("src").join("libstd").join("Cargo.toml").is_file() {
            return Ok(Src {
                path: src.join("rust").join("src"),
            });
        }

        if src.exists() {
            for e in WalkDir::new(src) {
                let e = e.chain_err(|| "couldn't walk the sysroot")?;

                // Looking for $SRC/libstd/Cargo.toml
                if e.file_type().is_file() && e.file_name() == "Cargo.toml" {
                    let toml = e.path();

                    if let Some(std) = toml.parent() {
                        if let Some(src) = std.parent() {
                            if std.file_name() == Some(OsStr::new("libstd")) {
                                return Ok(Src {
                                    path: src.to_owned(),
                                });
                            }
                        }
                    }
                }
            }
        }

        Err(
            "`rust-src` component not found. Run `rustup component add \
             rust-src`.",
        )?
    }
}

#[derive(Debug)]
pub enum Target {
    Builtin { triple: String },
    Custom { json: PathBuf, triple: String },
}

impl Target {
    pub fn new(triple: &str, cd: &CurrentDirectory, verbose: bool) -> Result<Option<Target>> {
        let triple = triple.to_owned();

        if rustc::targets(verbose)?.iter().any(|t| t == &triple) {
            Ok(Some(Target::Builtin { triple: triple }))
        } else {
            let mut json = cd.path().join(&triple);
            json.set_extension("json");

            if json.exists() {
                return Ok(Some(Target::Custom {
                    json: json,
                    triple: triple,
                }));
            } else {
                if let Some(p) = env::var_os("RUST_TARGET_PATH") {
                    let mut json = PathBuf::from(p);
                    json.push(&triple);
                    json.set_extension("json");

                    if json.exists() {
                        return Ok(Some(Target::Custom {
                            json: json,
                            triple: triple,
                        }));
                    }
                }
            }

            Ok(None)
        }
    }

    pub fn triple(&self) -> &str {
        match *self {
            Target::Builtin { ref triple } => triple,
            Target::Custom { ref triple, .. } => triple,
        }
    }

    pub fn hash<H>(&self, hasher: &mut H) -> Result<()>
    where
        H: Hasher,
    {
        if let Target::Custom { ref json, .. } = *self {
            // Here we roundtrip to/from JSON to get the same hash when some
            // fields of the JSON file has been shuffled around
            serde_json::from_str::<Value>(&util::read(json)?)
                .chain_err(|| format!("{} is not valid JSON", json.display()))?
                .to_string()
                .hash(hasher);
        }

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