<commit_before>//! The `event` module contains traits and structs to actually run your game mainloop
//! and handle top-level state, as well as handle input events such as keyboard
//! and mouse.
//!
//! If you don't want to do this, you can write your own mainloop and
//! get the necessary event machinery by calling
//! `context.sdl_context.event_pump()` on your `Context`.  You can
//! then call whatever SDL event methods you want on that.  This is
//! not particularly elegant and is not guaranteed to be stable across
//! different versions of ggez (for instance, we may someday get rid of SDL2),
//! but trying to wrap it
//! up more conveniently really ends up with the exact same interface.
//!
//! See the `eventloop` example for an implementation.

use winit;

/// A key code.
pub use winit::VirtualKeyCode as Keycode;

/// A struct that holds the state of keyboard modifier buttons such as ctrl or shift.
pub use winit::ModifiersState as KeyboardModifiers;
/// A mouse button.
pub use winit::MouseButton;

/// An analog axis of some device (controller, joystick...).
pub use winit::AxisId as Axis;
/// A button of some device (controller, joystick...).
pub use winit::ButtonId as Button;

/// `winit` events; nested in a module for re-export neatness.
pub mod winit_event {
    pub use super::winit::{Event, WindowEvent, DeviceEvent, KeyboardInput, ElementState};
}
use self::winit_event::*;
/// `winit` event loop.
pub use winit::EventsLoop;

use GameResult;
use context::Context;

/// A trait defining event callbacks; your primary interface with
/// `ggez`'s event loop.  Have a type implement this trait and
/// override at least the update() and draw() methods, then pass it to
/// `event::run()` to run the game's mainloop.
///
/// The default event handlers do nothing, apart from
/// `key_down_event()`, which will by default exit the game if escape
/// is pressed.  Just override the methods you want to do things with.
pub trait EventHandler {
    /// Called upon each physics update to the game.
    /// This should be where the game's logic takes place.
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()>;

    /// Called to do the drawing of your game.
    /// You probably want to start this with
    /// `graphics::clear()` and end it with
    /// `graphics::present()` and `timer::yield_now()`
    fn draw(&mut self, _ctx: &mut Context) -> GameResult<()>;

    /// A mouse button was pressed
    fn mouse_button_down_event(
        &mut self,
        _ctx: &mut Context,
        _button: MouseButton,
        _x: i32,
        _y: i32,
    ) {
    }

    /// A mouse button was released
    fn mouse_button_up_event(
        &mut self,
        _ctx: &mut Context,
        _button: MouseButton,
        _x: i32,
        _y: i32,
    ) {
    }

    /// The mouse was moved; it provides both absolute x and y coordinates in the window,
    /// and relative x and y coordinates compared to its last position.
    fn mouse_motion_event(&mut self, _ctx: &mut Context, _x: i32, _y: i32, _xrel: i32, _yrel: i32) {
    }

    /// The mousewheel was scrolled, vertically (y, positive away from and negative toward the user)
    /// or horizontally (x, positive to the right and negative to the left).
    fn mouse_wheel_event(&mut self, _ctx: &mut Context, _x: i32, _y: i32) {}

    /// A keyboard button was pressed.
    fn key_down_event(
        &mut self,
        ctx: &mut Context,
        keycode: Keycode,
        _keymods: KeyboardModifiers,
        _repeat: bool,
    ) {
        if keycode == Keycode::Escape {
            ctx.quit().expect("Should never fail");
        }
    }

    /// A keyboard button was released.
    fn key_up_event(&mut self, _ctx: &mut Context, _keycode: Keycode, _keymods: KeyboardModifiers) {
    }

    /// Candidate text is passed by the OS (via Input Method Editor).
    /// Refer to:
    /// <https://wiki.libsdl.org/SDL_TextEditingEvent>
    /// <https://wiki.libsdl.org/SDL_TextInputEvent>
    /// <https://wiki.libsdl.org/Tutorials/TextInput>
    fn text_editing_event(&mut self, _ctx: &mut Context, _text: String, _start: i32, _length: i32) {
    }

    /// Resulting text (usually a unicode character) is passed by the OS (via Input Method Editor).
    /// Refer to:
    /// <https://wiki.libsdl.org/SDL_TextEditingEvent>
    /// <https://wiki.libsdl.org/SDL_TextInputEvent>
    /// <https://wiki.libsdl.org/Tutorials/TextInput>
    fn text_input_event(&mut self, _ctx: &mut Context, _text: String) {}

    /// A controller button was pressed; instance_id identifies which controller.
    fn controller_button_down_event(
        &mut self,
        _ctx: &mut Context,
        _btn: Button,
        _instance_id: i32,
    ) {
    }
    /// A controller button was released.
    fn controller_button_up_event(&mut self, _ctx: &mut Context, _btn: Button, _instance_id: i32) {}
    /// A controller axis moved.
    fn controller_axis_event(
        &mut self,
        _ctx: &mut Context,
        _axis: Axis,
        _value: i16,
        _instance_id: i32,
    ) {
    }

    /// Called when the window is shown or hidden.
    fn focus_event(&mut self, _ctx: &mut Context, _gained: bool) {}

    /// Called upon a quit event.  If it returns true,
    /// the game does not exit.
    fn quit_event(&mut self, _ctx: &mut Context) -> bool {
        debug!("quit_event() callback called, quitting...");
        false
    }

    /// Called when the user resizes the window.
    /// Is not called when you resize it yourself with
    /// `graphics::set_mode()` though.
    fn resize_event(&mut self, _ctx: &mut Context, _width: u32, _height: u32) {}
}

/// A handle to access the OS's event pump.
// TODO: Do we need this?..
pub struct Events<'a>(&'a EventsLoop);

/*use std::fmt;
impl fmt::Debug for Events {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Events: {:p}>", self)
    }
}

impl Events {
    /// Create a new Events object.
    pub fn new(ctx: &Context) -> GameResult<Events> {
        let e = ctx.sdl_context.event_pump()?;
        Ok(Events(e))
    }

    /// Get an iterator for all events.
    pub fn poll(&mut self) -> EventPollIterator {
        self.0.poll_iter()
    }
}*/

/// Runs the game's main loop, calling event callbacks on the given state
/// object as events occur.
///
/// It does not try to do any type of framerate limiting.  See the
/// documentation for the `timer` module for more info.
pub fn run<S>(ctx: &mut Context, state: &mut S) -> GameResult<()>
where
    S: EventHandler,
{
    let mut events_loop = EventsLoop::new();
    let mut continuing = true;

    let mut mouse_delta = (0, 0);
    let mut cursor_location = (0, 0);
    // Tracks last pressed key to figure out if it's a repeated keystroke.
    let mut last_pressed = None;

    while continuing {
        ctx.timer_context.tick();

        events_loop.poll_events(|event| {
            ctx.process_event(&event);
            match event {
                Event::WindowEvent { event, .. } => {
                    match event {
                        WindowEvent::CloseRequested => {
                            continuing = state.quit_event(ctx);
                        }
                        WindowEvent::KeyboardInput {
                            input: winit::KeyboardInput {
                                state,
                                virtual_keycode,
                                modifiers,
                                ..
                            },
                            ..
                        } => {
                            if let Some(keycode) = virtual_keycode {
                                match state {
                                    Pressed => {
                                        let repeat = last_pressed == Some(keycode);
                                        state.key_down_event(ctx, keycode, modifiers, repeat);
                                        last_pressed = Some(keycode);
                                    }
                                    Released => {
                                        if last_pressed == Some(keycode) {
                                            last_pressed = None;
                                        }
                                        state.key_up_event(ctx, keycode, modifiers);
                                    }
                                }
                            }
                        }
                        WindowEvent::MouseInput { state, button, .. } => {
                            match state {
                                Pressed => {
                                    state.mouse_button_down_event(
                                        ctx,
                                        button,
                                        cursor_location.0,
                                        cursor_location.1,
                                    )
                                }
                                Released => {
                                    state.mouse_button_up_event(
                                        ctx,
                                        button,
                                        cursor_location.0,
                                        cursor_location.1,
                                    )
                                }
                            }
                        }
                        WindowEvent::CursorMoved { position, .. } => {
                            cursor_location = position as (i32, i32);
                            state.mouse_motion_event(
                                ctx,
                                cursor_location.0,
                                cursor_location.1,
                                mouse_delta.0,
                                mouse_delta.1,
                            );
                        }
                    }
                }
                Event::DeviceEvent { event, .. } => {
                    match event {
                        DeviceEvent::MouseMotion { delta } => {
                            mouse_delta = delta as (i32, i32);
                        }
                        _ => (),
                    }
                }
                Event::Awakened => unimplemented!(),
                Event::Suspended(_) => unimplemented!(),
            }
        });
        /*{
                TextEditing {
                    text,
                    start,
                    length,
                    ..
                } => state.text_editing_event(ctx, text, start, length),
                TextInput { text, .. } => state.text_input_event(ctx, text),
                MouseWheel { x, y, .. } => state.mouse_wheel_event(ctx, x, y),
                ControllerButtonDown { button, which, .. } => {
                    state.controller_button_down_event(ctx, button, which)
                }
                ControllerButtonUp { button, which, .. } => {
                    state.controller_button_up_event(ctx, button, which)
                }
                ControllerAxisMotion {
                    axis, value, which, ..
                } => state.controller_axis_event(ctx, axis, value, which),
                Window {
                    win_event: event::WindowEvent::FocusGained,
                    ..
                } => state.focus_event(ctx, true),
                Window {
                    win_event: event::WindowEvent::FocusLost,
                    ..
                } => state.focus_event(ctx, false),
                Window {
                    win_event: event::WindowEvent::Resized(w, h),
                    ..
                } => {
                    state.resize_event(ctx, w as u32, h as u32);
                }
                _ => {}
            }*/
        state.update(ctx)?;
        state.draw(ctx)?;
    }

    Ok(())
}
<commit_msg>`WindowEvent::Focused`; notes so far: (totally didn't forget to add them a commit earlier)<commit_after>//! The `event` module contains traits and structs to actually run your game mainloop
//! and handle top-level state, as well as handle input events such as keyboard
//! and mouse.
//!
//! If you don't want to do this, you can write your own mainloop and
//! get the necessary event machinery by calling
//! `context.sdl_context.event_pump()` on your `Context`.  You can
//! then call whatever SDL event methods you want on that.  This is
//! not particularly elegant and is not guaranteed to be stable across
//! different versions of ggez (for instance, we may someday get rid of SDL2),
//! but trying to wrap it
//! up more conveniently really ends up with the exact same interface.
//!
//! See the `eventloop` example for an implementation.

use winit;

/// A key code.
pub use winit::VirtualKeyCode as Keycode;

/// A struct that holds the state of keyboard modifier buttons such as ctrl or shift.
pub use winit::ModifiersState as KeyboardModifiers;
/// A mouse button.
pub use winit::MouseButton;

/// An analog axis of some device (controller, joystick...).
pub use winit::AxisId as Axis;
/// A button of some device (controller, joystick...).
pub use winit::ButtonId as Button;

/// `winit` events; nested in a module for re-export neatness.
pub mod winit_event {
    pub use super::winit::{Event, WindowEvent, DeviceEvent, KeyboardInput, ElementState};
}
use self::winit_event::*;
/// `winit` event loop.
pub use winit::EventsLoop;

use GameResult;
use context::Context;

/// A trait defining event callbacks; your primary interface with
/// `ggez`'s event loop.  Have a type implement this trait and
/// override at least the update() and draw() methods, then pass it to
/// `event::run()` to run the game's mainloop.
///
/// The default event handlers do nothing, apart from
/// `key_down_event()`, which will by default exit the game if escape
/// is pressed.  Just override the methods you want to do things with.
pub trait EventHandler {
    /// Called upon each physics update to the game.
    /// This should be where the game's logic takes place.
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()>;

    /// Called to do the drawing of your game.
    /// You probably want to start this with
    /// `graphics::clear()` and end it with
    /// `graphics::present()` and `timer::yield_now()`
    fn draw(&mut self, _ctx: &mut Context) -> GameResult<()>;

    /// A mouse button was pressed
    fn mouse_button_down_event(
        &mut self,
        _ctx: &mut Context,
        _button: MouseButton,
        _x: i32,
        _y: i32,
    ) {
    }

    /// A mouse button was released
    fn mouse_button_up_event(
        &mut self,
        _ctx: &mut Context,
        _button: MouseButton,
        _x: i32,
        _y: i32,
    ) {
    }

    /// The mouse was moved; it provides both absolute x and y coordinates in the window,
    /// and relative x and y coordinates compared to its last position.
    fn mouse_motion_event(&mut self, _ctx: &mut Context, _x: i32, _y: i32, _xrel: i32, _yrel: i32) {
    }

    /// The mousewheel was scrolled, vertically (y, positive away from and negative toward the user)
    /// or horizontally (x, positive to the right and negative to the left).
    fn mouse_wheel_event(&mut self, _ctx: &mut Context, _x: i32, _y: i32) {}

    /// A keyboard button was pressed.
    fn key_down_event(
        &mut self,
        ctx: &mut Context,
        keycode: Keycode,
        _keymods: KeyboardModifiers,
        _repeat: bool,
    ) {
        if keycode == Keycode::Escape {
            ctx.quit().expect("Should never fail");
        }
    }

    /// A keyboard button was released.
    fn key_up_event(&mut self, _ctx: &mut Context, _keycode: Keycode, _keymods: KeyboardModifiers) {
    }

    /// Candidate text is passed by the OS (via Input Method Editor).
    /// Refer to:
    /// <https://wiki.libsdl.org/SDL_TextEditingEvent>
    /// <https://wiki.libsdl.org/SDL_TextInputEvent>
    /// <https://wiki.libsdl.org/Tutorials/TextInput>
    fn text_editing_event(&mut self, _ctx: &mut Context, _text: String, _start: i32, _length: i32) {
    }

    /// Resulting text (usually a unicode character) is passed by the OS (via Input Method Editor).
    /// Refer to:
    /// <https://wiki.libsdl.org/SDL_TextEditingEvent>
    /// <https://wiki.libsdl.org/SDL_TextInputEvent>
    /// <https://wiki.libsdl.org/Tutorials/TextInput>
    fn text_input_event(&mut self, _ctx: &mut Context, _text: String) {}

    /// A controller button was pressed; instance_id identifies which controller.
    fn controller_button_down_event(
        &mut self,
        _ctx: &mut Context,
        _btn: Button,
        _instance_id: i32,
    ) {
    }
    /// A controller button was released.
    fn controller_button_up_event(&mut self, _ctx: &mut Context, _btn: Button, _instance_id: i32) {}
    /// A controller axis moved.
    fn controller_axis_event(
        &mut self,
        _ctx: &mut Context,
        _axis: Axis,
        _value: i16,
        _instance_id: i32,
    ) {
    }

    /// Called when the window is shown or hidden.
    fn focus_event(&mut self, _ctx: &mut Context, _gained: bool) {}

    /// Called upon a quit event.  If it returns true,
    /// the game does not exit.
    fn quit_event(&mut self, _ctx: &mut Context) -> bool {
        debug!("quit_event() callback called, quitting...");
        false
    }

    /// Called when the user resizes the window.
    /// Is not called when you resize it yourself with
    /// `graphics::set_mode()` though.
    fn resize_event(&mut self, _ctx: &mut Context, _width: u32, _height: u32) {}
}

/// A handle to access the OS's event pump.
// TODO: Do we need this?..
pub struct Events<'a>(&'a EventsLoop);

/*use std::fmt;
impl fmt::Debug for Events {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Events: {:p}>", self)
    }
}

impl Events {
    /// Create a new Events object.
    pub fn new(ctx: &Context) -> GameResult<Events> {
        let e = ctx.sdl_context.event_pump()?;
        Ok(Events(e))
    }

    /// Get an iterator for all events.
    pub fn poll(&mut self) -> EventPollIterator {
        self.0.poll_iter()
    }
}*/

/// Runs the game's main loop, calling event callbacks on the given state
/// object as events occur.
///
/// It does not try to do any type of framerate limiting.  See the
/// documentation for the `timer` module for more info.
pub fn run<S>(ctx: &mut Context, state: &mut S) -> GameResult<()>
where
    S: EventHandler,
{
    let mut events_loop = EventsLoop::new();
    let mut continuing = true;

    let mut mouse_delta = (0, 0);
    let mut cursor_location = (0, 0);
    // Tracks last pressed key to figure out if it's a repeated keystroke.
    let mut last_pressed = None;

    while continuing {
        ctx.timer_context.tick();

        events_loop.poll_events(|event| {
            ctx.process_event(&event);
            match event {
                Event::WindowEvent { event, .. } => {
                    match event {
                        WindowEvent::CloseRequested => {
                            continuing = state.quit_event(ctx);
                        }
                        WindowEvent::Focused(gained) => {
                            state.focus_event(ctx, gained);
                        }
                        WindowEvent::KeyboardInput {
                            input: winit::KeyboardInput {
                                state,
                                virtual_keycode: Some(keycode),
                                modifiers,
                                ..
                            },
                            ..
                        } => {
                            match state {
                                ElementState::Pressed => {
                                    let repeat = last_pressed == Some(keycode);
                                    state.key_down_event(ctx, keycode, modifiers, repeat);
                                    last_pressed = Some(keycode);
                                }
                                ElementState::Released => {
                                    if last_pressed == Some(keycode) {
                                        last_pressed = None;
                                    }
                                    state.key_up_event(ctx, keycode, modifiers);
                                }
                            }
                        }
                        WindowEvent::MouseInput { state, button, .. } => {
                            match state {
                                ElementState::Pressed => {
                                    state.mouse_button_down_event(
                                        ctx,
                                        button,
                                        cursor_location.0,
                                        cursor_location.1,
                                    )
                                }
                                ElementState::Released => {
                                    state.mouse_button_up_event(
                                        ctx,
                                        button,
                                        cursor_location.0,
                                        cursor_location.1,
                                    )
                                }
                            }
                        }
                        WindowEvent::CursorMoved { position, .. } => {
                            cursor_location = position as (i32, i32);
                            state.mouse_motion_event(
                                ctx,
                                cursor_location.0,
                                cursor_location.1,
                                mouse_delta.0,
                                mouse_delta.1,
                            );
                        }
                        _ => (),
                    }
                }
                Event::DeviceEvent { event, .. } => {
                    match event {
                        DeviceEvent::MouseMotion { delta } => {
                            mouse_delta = delta as (i32, i32);
                        }
                        _ => (),
                    }
                }
                Event::Awakened => unimplemented!(),
                Event::Suspended(_) => unimplemented!(),
            }
        });
        /*{
                TextEditing {
                    text,
                    start,
                    length,
                    ..
                } => state.text_editing_event(ctx, text, start, length),
                TextInput { text, .. } => state.text_input_event(ctx, text),
                MouseWheel { x, y, .. } => state.mouse_wheel_event(ctx, x, y),
                ControllerButtonDown { button, which, .. } => {
                    state.controller_button_down_event(ctx, button, which)
                }
                ControllerButtonUp { button, which, .. } => {
                    state.controller_button_up_event(ctx, button, which)
                }
                ControllerAxisMotion {
                    axis, value, which, ..
                } => state.controller_axis_event(ctx, axis, value, which),
                Window {
                    win_event: event::WindowEvent::Resized(w, h),
                    ..
                } => {
                    state.resize_event(ctx, w as u32, h as u32);
                }
                _ => {}
            }*/
        state.update(ctx)?;
        state.draw(ctx)?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

use std::cmp::min;
use std::io;
use std::num::Float;

const LINE_LENGTH: usize = 60;
const IM: u32 = 139968;

struct MyRandom {
    last: u32
}
impl MyRandom {
    fn new() -> MyRandom { MyRandom { last: 42 } }
    fn normalize(p: f32) -> u32 {(p * IM as f32).floor() as u32}
    fn gen(&mut self) -> u32 {
        self.last = (self.last * 3877 + 29573) % IM;
        self.last
    }
}

struct AAGen<'a> {
    rng: &'a mut MyRandom,
    data: Vec<(u32, u8)>
}
impl<'a> AAGen<'a> {
    fn new<'b>(rng: &'b mut MyRandom, aa: &[(char, f32)]) -> AAGen<'b> {
        let mut cum = 0.;
        let data = aa.iter()
            .map(|&(ch, p)| { cum += p; (MyRandom::normalize(cum), ch as u8) })
            .collect();
        AAGen { rng: rng, data: data }
    }
}
impl<'a> Iterator for AAGen<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let r = self.rng.gen();
        self.data.iter()
            .skip_while(|pc| pc.0 < r)
            .map(|&(_, c)| c)
            .next()
    }
}

fn make_fasta<W: io::Write, I: Iterator<Item=u8>>(
    wr: &mut W, header: &str, mut it: I, mut n: usize)
    -> io::Result<()>
{
    try!(wr.write_all(header.as_bytes()));
    let mut line = [0u8; LINE_LENGTH + 1];
    while n > 0 {
        let nb = min(LINE_LENGTH, n);
        for i in (0..nb) {
            line[i] = it.next().unwrap();
        }
        n -= nb;
        line[nb] = '\n' as u8;
        try!(wr.write_all(&line[..(nb+1)]));
    }
    Ok(())
}

fn run<W: io::Write>(writer: &mut W) -> io::Result<()> {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(1000);

    let rng = &mut MyRandom::new();
    let alu =
        "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\
        GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\
        CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\
        ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\
        GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\
        AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\
        AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
    let iub = &[('a', 0.27), ('c', 0.12), ('g', 0.12),
                ('t', 0.27), ('B', 0.02), ('D', 0.02),
                ('H', 0.02), ('K', 0.02), ('M', 0.02),
                ('N', 0.02), ('R', 0.02), ('S', 0.02),
                ('V', 0.02), ('W', 0.02), ('Y', 0.02)];
    let homosapiens = &[('a', 0.3029549426680),
                        ('c', 0.1979883004921),
                        ('g', 0.1975473066391),
                        ('t', 0.3015094502008)];

    try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
    try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                    AAGen::new(rng, iub), n * 3));
    try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
                    AAGen::new(rng, homosapiens), n * 5));

    writer.flush()
}

fn main() {
    run(&mut io::stdout()).unwrap()
}
<commit_msg>remove warning<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

use std::cmp::min;
use std::io;

const LINE_LENGTH: usize = 60;
const IM: u32 = 139968;

struct MyRandom {
    last: u32
}
impl MyRandom {
    fn new() -> MyRandom { MyRandom { last: 42 } }
    fn normalize(p: f32) -> u32 {(p * IM as f32).floor() as u32}
    fn gen(&mut self) -> u32 {
        self.last = (self.last * 3877 + 29573) % IM;
        self.last
    }
}

struct AAGen<'a> {
    rng: &'a mut MyRandom,
    data: Vec<(u32, u8)>
}
impl<'a> AAGen<'a> {
    fn new<'b>(rng: &'b mut MyRandom, aa: &[(char, f32)]) -> AAGen<'b> {
        let mut cum = 0.;
        let data = aa.iter()
            .map(|&(ch, p)| { cum += p; (MyRandom::normalize(cum), ch as u8) })
            .collect();
        AAGen { rng: rng, data: data }
    }
}
impl<'a> Iterator for AAGen<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let r = self.rng.gen();
        self.data.iter()
            .skip_while(|pc| pc.0 < r)
            .map(|&(_, c)| c)
            .next()
    }
}

fn make_fasta<W: io::Write, I: Iterator<Item=u8>>(
    wr: &mut W, header: &str, mut it: I, mut n: usize)
    -> io::Result<()>
{
    try!(wr.write_all(header.as_bytes()));
    let mut line = [0u8; LINE_LENGTH + 1];
    while n > 0 {
        let nb = min(LINE_LENGTH, n);
        for i in (0..nb) {
            line[i] = it.next().unwrap();
        }
        n -= nb;
        line[nb] = '\n' as u8;
        try!(wr.write_all(&line[..(nb+1)]));
    }
    Ok(())
}

fn run<W: io::Write>(writer: &mut W) -> io::Result<()> {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(1000);

    let rng = &mut MyRandom::new();
    let alu =
        "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\
        GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\
        CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\
        ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\
        GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\
        AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\
        AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
    let iub = &[('a', 0.27), ('c', 0.12), ('g', 0.12),
                ('t', 0.27), ('B', 0.02), ('D', 0.02),
                ('H', 0.02), ('K', 0.02), ('M', 0.02),
                ('N', 0.02), ('R', 0.02), ('S', 0.02),
                ('V', 0.02), ('W', 0.02), ('Y', 0.02)];
    let homosapiens = &[('a', 0.3029549426680),
                        ('c', 0.1979883004921),
                        ('g', 0.1975473066391),
                        ('t', 0.3015094502008)];

    try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
    try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                    AAGen::new(rng, iub), n * 3));
    try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
                    AAGen::new(rng, homosapiens), n * 5));

    writer.flush()
}

fn main() {
    run(&mut io::stdout()).unwrap()
}
<|endoftext|>


<commit_before>use std::fmt;
use std::io::{Cursor, ErrorKind, Read, Write};
use std::default::Default;

use rand;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

use result::{Error, Kind, Result};
use protocol::{CloseCode, OpCode};
use stream::TryReadBuf;

fn apply_mask(buf: &mut [u8], mask: &[u8; 4]) {
    let iter = buf.iter_mut().zip(mask.iter().cycle());
    for (byte, &key) in iter {
        *byte ^= key
    }
}

/// A struct representing a WebSocket frame.
#[derive(Debug, Clone)]
pub struct Frame {
    finished: bool,
    rsv1: bool,
    rsv2: bool,
    rsv3: bool,
    opcode: OpCode,

    mask: Option<[u8; 4]>,

    payload: Vec<u8>,
}

impl Frame {
    /// Get the length of the frame.
    /// This is the length of the header + the length of the payload.
    #[inline]
    pub fn len(&self) -> usize {
        let mut header_length = 2;
        let payload_len = self.payload().len();
        if payload_len > 125 {
            if payload_len <= u16::max_value() as usize {
                header_length += 2;
            } else {
                header_length += 8;
            }
        }

        if self.is_masked() {
            header_length += 4;
        }

        header_length + payload_len
    }

    /// Test whether the frame is a final frame.
    #[inline]
    pub fn is_final(&self) -> bool {
        self.finished
    }

    /// Test whether the first reserved bit is set.
    #[inline]
    pub fn has_rsv1(&self) -> bool {
        self.rsv1
    }

    /// Test whether the second reserved bit is set.
    #[inline]
    pub fn has_rsv2(&self) -> bool {
        self.rsv2
    }

    /// Test whether the third reserved bit is set.
    #[inline]
    pub fn has_rsv3(&self) -> bool {
        self.rsv3
    }

    /// Get the OpCode of the frame.
    #[inline]
    pub fn opcode(&self) -> OpCode {
        self.opcode
    }

    /// Test whether this is a control frame.
    #[inline]
    pub fn is_control(&self) -> bool {
        self.opcode.is_control()
    }

    /// Get a reference to the frame's payload.
    #[inline]
    pub fn payload(&self) -> &Vec<u8> {
        &self.payload
    }

    // Test whether the frame is masked.
    #[doc(hidden)]
    #[inline]
    pub fn is_masked(&self) -> bool {
        self.mask.is_some()
    }

    // Get an optional reference to the frame's mask.
    #[doc(hidden)]
    #[allow(dead_code)]
    #[inline]
    pub fn mask(&self) -> Option<&[u8; 4]> {
        self.mask.as_ref()
    }

    /// Make this frame a final frame.
    #[allow(dead_code)]
    #[inline]
    pub fn set_final(&mut self, is_final: bool) -> &mut Frame {
        self.finished = is_final;
        self
    }

    /// Set the first reserved bit.
    #[inline]
    pub fn set_rsv1(&mut self, has_rsv1: bool) -> &mut Frame {
        self.rsv1 = has_rsv1;
        self
    }

    /// Set the second reserved bit.
    #[inline]
    pub fn set_rsv2(&mut self, has_rsv2: bool) -> &mut Frame {
        self.rsv2 = has_rsv2;
        self
    }

    /// Set the third reserved bit.
    #[inline]
    pub fn set_rsv3(&mut self, has_rsv3: bool) -> &mut Frame {
        self.rsv3 = has_rsv3;
        self
    }

    /// Set the OpCode.
    #[allow(dead_code)]
    #[inline]
    pub fn set_opcode(&mut self, opcode: OpCode) -> &mut Frame {
        self.opcode = opcode;
        self
    }

    /// Edit the frame's payload.
    #[allow(dead_code)]
    #[inline]
    pub fn payload_mut(&mut self) -> &mut Vec<u8> {
        &mut self.payload
    }

    // Generate a new mask for this frame.
    //
    // This method simply generates and stores the mask. It does not change the payload data.
    // Instead, the payload data will be masked with the generated mask when the frame is sent
    // to the other endpoint.
    #[doc(hidden)]
    #[inline]
    pub fn set_mask(&mut self) -> &mut Frame {
        self.mask = Some(rand::random());
        self
    }

    // This method unmasks the payload and should only be called on frames that are actually
    // masked. In other words, those frames that have just been received from a client endpoint.
    #[doc(hidden)]
    #[inline]
    pub fn remove_mask(&mut self) -> &mut Frame {
        self.mask
            .take()
            .map(|mask| apply_mask(&mut self.payload, &mask));
        self
    }

    /// Consume the frame into its payload.
    pub fn into_data(self) -> Vec<u8> {
        self.payload
    }

    /// Create a new data frame.
    #[inline]
    pub fn message(data: Vec<u8>, code: OpCode, finished: bool) -> Frame {
        debug_assert!(
            match code {
                OpCode::Text | OpCode::Binary | OpCode::Continue => true,
                _ => false,
            },
            "Invalid opcode for data frame."
        );

        Frame {
            finished: finished,
            opcode: code,
            payload: data,
            ..Frame::default()
        }
    }

    /// Create a new Pong control frame.
    #[inline]
    pub fn pong(data: Vec<u8>) -> Frame {
        Frame {
            opcode: OpCode::Pong,
            payload: data,
            ..Frame::default()
        }
    }

    /// Create a new Ping control frame.
    #[inline]
    pub fn ping(data: Vec<u8>) -> Frame {
        Frame {
            opcode: OpCode::Ping,
            payload: data,
            ..Frame::default()
        }
    }

    /// Create a new Close control frame.
    #[inline]
    pub fn close(code: CloseCode, reason: &str) -> Frame {
        let payload = if let CloseCode::Empty = code {
            Vec::new()
        } else {
            let u: u16 = code.into();
            let raw = [(u >> 8) as u8, u as u8];
            [&raw, reason.as_bytes()].concat()
        };

        Frame {
            payload: payload,
            ..Frame::default()
        }
    }

    /// Parse the input stream into a frame.
    pub fn parse(cursor: &mut Cursor<Vec<u8>>) -> Result<Option<Frame>> {
        let size = cursor.get_ref().len() as u64 - cursor.position();
        let initial = cursor.position();
        trace!("Position in buffer {}", initial);

        let mut head = [0u8; 2];
        if cursor.read(&mut head)? != 2 {
            cursor.set_position(initial);
            return Ok(None);
        }

        trace!("Parsed headers {:?}", head);

        let first = head[0];
        let second = head[1];
        trace!("First: {:b}", first);
        trace!("Second: {:b}", second);

        let finished = first & 0x80 != 0;

        let rsv1 = first & 0x40 != 0;
        let rsv2 = first & 0x20 != 0;
        let rsv3 = first & 0x10 != 0;

        let opcode = OpCode::from(first & 0x0F);
        trace!("Opcode: {:?}", opcode);

        let masked = second & 0x80 != 0;
        trace!("Masked: {:?}", masked);

        let mut header_length = 2;

        let mut length = u64::from(second & 0x7F);

        if let Some(length_nbytes) = match length {
            126 => Some(2),
            127 => Some(8),
            _ => None,
        } {
            match cursor.read_uint::<BigEndian>(length_nbytes) {
                Err(ref err) if err.kind() == ErrorKind::UnexpectedEof => {
                    cursor.set_position(initial);
                    return Ok(None);
                }
                Err(err) => {
                    return Err(Error::from(err));
                }
                Ok(read) => {
                    length = read;
                }
            };
            header_length += length_nbytes as u64;
        }
        trace!("Payload length: {}", length);

        let mask = if masked {
            let mut mask_bytes = [0u8; 4];
            if cursor.read(&mut mask_bytes)? != 4 {
                cursor.set_position(initial);
                return Ok(None);
            } else {
                header_length += 4;
                Some(mask_bytes)
            }
        } else {
            None
        };

        match length.checked_add(header_length) {
            Some(l) if size < l => {
                cursor.set_position(initial);
                return Ok(None);
            }
            Some(_) => (),
            None => return Ok(None),
        };

        let mut data = Vec::with_capacity(length as usize);
        if length > 0 {
            if let Some(read) = cursor.try_read_buf(&mut data)? {
                debug_assert!(read == length as usize, "Read incorrect payload length!");
            }
        }

        // Disallow bad opcode
        if let OpCode::Bad = opcode {
            return Err(Error::new(
                Kind::Protocol,
                format!("Encountered invalid opcode: {}", first & 0x0F),
            ));
        }

        // control frames must have length <= 125
        match opcode {
            OpCode::Ping | OpCode::Pong if length > 125 => {
                return Err(Error::new(
                    Kind::Protocol,
                    format!(
                        "Rejected WebSocket handshake.Received control frame with length: {}.",
                        length
                    ),
                ))
            }
            OpCode::Close if length > 125 => {
                debug!("Received close frame with payload length exceeding 125. Morphing to protocol close frame.");
                return Ok(Some(Frame::close(
                    CloseCode::Protocol,
                    "Received close frame with payload length exceeding 125.",
                )));
            }
            _ => (),
        }

        let frame = Frame {
            finished: finished,
            rsv1: rsv1,
            rsv2: rsv2,
            rsv3: rsv3,
            opcode: opcode,
            mask: mask,
            payload: data,
        };

        Ok(Some(frame))
    }

    /// Write a frame out to a buffer
    pub fn format<W>(&mut self, w: &mut W) -> Result<()>
    where
        W: Write,
    {
        let mut one = 0u8;
        let code: u8 = self.opcode.into();
        if self.is_final() {
            one |= 0x80;
        }
        if self.has_rsv1() {
            one |= 0x40;
        }
        if self.has_rsv2() {
            one |= 0x20;
        }
        if self.has_rsv3() {
            one |= 0x10;
        }
        one |= code;

        let mut two = 0u8;
        if self.is_masked() {
            two |= 0x80;
        }

        match self.payload.len() {
            len if len < 126 => {
                two |= len as u8;
            }
            len if len <= 65535 => {
                two |= 126;
            }
            _ => {
                two |= 127;
            }
        }
        w.write_all(&[one, two])?;

        if let Some(length_bytes) = match self.payload.len() {
            len if len < 126 => None,
            len if len <= 65535 => Some(2),
            _ => Some(8),
        } {
            w.write_uint::<BigEndian>(self.payload.len() as u64, length_bytes)?;
        }

        if self.is_masked() {
            let mask = self.mask.take().unwrap();
            apply_mask(&mut self.payload, &mask);
            w.write_all(&mask)?;
        }

        w.write_all(&self.payload)?;
        Ok(())
    }
}

impl Default for Frame {
    fn default() -> Frame {
        Frame {
            finished: true,
            rsv1: false,
            rsv2: false,
            rsv3: false,
            opcode: OpCode::Close,
            mask: None,
            payload: Vec::new(),
        }
    }
}

impl fmt::Display for Frame {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "
<FRAME>
final: {}
reserved: {} {} {}
opcode: {}
length: {}
payload length: {}
payload: 0x{}
            ",
            self.finished,
            self.rsv1,
            self.rsv2,
            self.rsv3,
            self.opcode,
            // self.mask.map(|mask| format!("{:?}", mask)).unwrap_or("NONE".into()),
            self.len(),
            self.payload.len(),
            self.payload
                .iter()
                .map(|byte| format!("{:x}", byte))
                .collect::<String>()
        )
    }
}

mod test {
    #![allow(unused_imports, unused_variables, dead_code)]
    use super::*;
    use protocol::OpCode;

    #[test]
    fn display_frame() {
        let f = Frame::message("hi there".into(), OpCode::Text, true);
        let view = format!("{}", f);
        view.contains("payload:");
    }
}
<commit_msg>clippy: len_without_is_empty<commit_after>use std::fmt;
use std::io::{Cursor, ErrorKind, Read, Write};
use std::default::Default;

use rand;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

use result::{Error, Kind, Result};
use protocol::{CloseCode, OpCode};
use stream::TryReadBuf;

fn apply_mask(buf: &mut [u8], mask: &[u8; 4]) {
    let iter = buf.iter_mut().zip(mask.iter().cycle());
    for (byte, &key) in iter {
        *byte ^= key
    }
}

/// A struct representing a WebSocket frame.
#[derive(Debug, Clone)]
pub struct Frame {
    finished: bool,
    rsv1: bool,
    rsv2: bool,
    rsv3: bool,
    opcode: OpCode,

    mask: Option<[u8; 4]>,

    payload: Vec<u8>,
}

impl Frame {
    /// Get the length of the frame.
    /// This is the length of the header + the length of the payload.
    #[inline]
    pub fn len(&self) -> usize {
        let mut header_length = 2;
        let payload_len = self.payload().len();
        if payload_len > 125 {
            if payload_len <= u16::max_value() as usize {
                header_length += 2;
            } else {
                header_length += 8;
            }
        }

        if self.is_masked() {
            header_length += 4;
        }

        header_length + payload_len
    }

    /// Return `false`: a frame is never empty since it has a header.
    #[inline]
    pub fn is_empty(&self) -> bool {
        false
    }

    /// Test whether the frame is a final frame.
    #[inline]
    pub fn is_final(&self) -> bool {
        self.finished
    }

    /// Test whether the first reserved bit is set.
    #[inline]
    pub fn has_rsv1(&self) -> bool {
        self.rsv1
    }

    /// Test whether the second reserved bit is set.
    #[inline]
    pub fn has_rsv2(&self) -> bool {
        self.rsv2
    }

    /// Test whether the third reserved bit is set.
    #[inline]
    pub fn has_rsv3(&self) -> bool {
        self.rsv3
    }

    /// Get the OpCode of the frame.
    #[inline]
    pub fn opcode(&self) -> OpCode {
        self.opcode
    }

    /// Test whether this is a control frame.
    #[inline]
    pub fn is_control(&self) -> bool {
        self.opcode.is_control()
    }

    /// Get a reference to the frame's payload.
    #[inline]
    pub fn payload(&self) -> &Vec<u8> {
        &self.payload
    }

    // Test whether the frame is masked.
    #[doc(hidden)]
    #[inline]
    pub fn is_masked(&self) -> bool {
        self.mask.is_some()
    }

    // Get an optional reference to the frame's mask.
    #[doc(hidden)]
    #[allow(dead_code)]
    #[inline]
    pub fn mask(&self) -> Option<&[u8; 4]> {
        self.mask.as_ref()
    }

    /// Make this frame a final frame.
    #[allow(dead_code)]
    #[inline]
    pub fn set_final(&mut self, is_final: bool) -> &mut Frame {
        self.finished = is_final;
        self
    }

    /// Set the first reserved bit.
    #[inline]
    pub fn set_rsv1(&mut self, has_rsv1: bool) -> &mut Frame {
        self.rsv1 = has_rsv1;
        self
    }

    /// Set the second reserved bit.
    #[inline]
    pub fn set_rsv2(&mut self, has_rsv2: bool) -> &mut Frame {
        self.rsv2 = has_rsv2;
        self
    }

    /// Set the third reserved bit.
    #[inline]
    pub fn set_rsv3(&mut self, has_rsv3: bool) -> &mut Frame {
        self.rsv3 = has_rsv3;
        self
    }

    /// Set the OpCode.
    #[allow(dead_code)]
    #[inline]
    pub fn set_opcode(&mut self, opcode: OpCode) -> &mut Frame {
        self.opcode = opcode;
        self
    }

    /// Edit the frame's payload.
    #[allow(dead_code)]
    #[inline]
    pub fn payload_mut(&mut self) -> &mut Vec<u8> {
        &mut self.payload
    }

    // Generate a new mask for this frame.
    //
    // This method simply generates and stores the mask. It does not change the payload data.
    // Instead, the payload data will be masked with the generated mask when the frame is sent
    // to the other endpoint.
    #[doc(hidden)]
    #[inline]
    pub fn set_mask(&mut self) -> &mut Frame {
        self.mask = Some(rand::random());
        self
    }

    // This method unmasks the payload and should only be called on frames that are actually
    // masked. In other words, those frames that have just been received from a client endpoint.
    #[doc(hidden)]
    #[inline]
    pub fn remove_mask(&mut self) -> &mut Frame {
        self.mask
            .take()
            .map(|mask| apply_mask(&mut self.payload, &mask));
        self
    }

    /// Consume the frame into its payload.
    pub fn into_data(self) -> Vec<u8> {
        self.payload
    }

    /// Create a new data frame.
    #[inline]
    pub fn message(data: Vec<u8>, code: OpCode, finished: bool) -> Frame {
        debug_assert!(
            match code {
                OpCode::Text | OpCode::Binary | OpCode::Continue => true,
                _ => false,
            },
            "Invalid opcode for data frame."
        );

        Frame {
            finished: finished,
            opcode: code,
            payload: data,
            ..Frame::default()
        }
    }

    /// Create a new Pong control frame.
    #[inline]
    pub fn pong(data: Vec<u8>) -> Frame {
        Frame {
            opcode: OpCode::Pong,
            payload: data,
            ..Frame::default()
        }
    }

    /// Create a new Ping control frame.
    #[inline]
    pub fn ping(data: Vec<u8>) -> Frame {
        Frame {
            opcode: OpCode::Ping,
            payload: data,
            ..Frame::default()
        }
    }

    /// Create a new Close control frame.
    #[inline]
    pub fn close(code: CloseCode, reason: &str) -> Frame {
        let payload = if let CloseCode::Empty = code {
            Vec::new()
        } else {
            let u: u16 = code.into();
            let raw = [(u >> 8) as u8, u as u8];
            [&raw, reason.as_bytes()].concat()
        };

        Frame {
            payload: payload,
            ..Frame::default()
        }
    }

    /// Parse the input stream into a frame.
    pub fn parse(cursor: &mut Cursor<Vec<u8>>) -> Result<Option<Frame>> {
        let size = cursor.get_ref().len() as u64 - cursor.position();
        let initial = cursor.position();
        trace!("Position in buffer {}", initial);

        let mut head = [0u8; 2];
        if cursor.read(&mut head)? != 2 {
            cursor.set_position(initial);
            return Ok(None);
        }

        trace!("Parsed headers {:?}", head);

        let first = head[0];
        let second = head[1];
        trace!("First: {:b}", first);
        trace!("Second: {:b}", second);

        let finished = first & 0x80 != 0;

        let rsv1 = first & 0x40 != 0;
        let rsv2 = first & 0x20 != 0;
        let rsv3 = first & 0x10 != 0;

        let opcode = OpCode::from(first & 0x0F);
        trace!("Opcode: {:?}", opcode);

        let masked = second & 0x80 != 0;
        trace!("Masked: {:?}", masked);

        let mut header_length = 2;

        let mut length = u64::from(second & 0x7F);

        if let Some(length_nbytes) = match length {
            126 => Some(2),
            127 => Some(8),
            _ => None,
        } {
            match cursor.read_uint::<BigEndian>(length_nbytes) {
                Err(ref err) if err.kind() == ErrorKind::UnexpectedEof => {
                    cursor.set_position(initial);
                    return Ok(None);
                }
                Err(err) => {
                    return Err(Error::from(err));
                }
                Ok(read) => {
                    length = read;
                }
            };
            header_length += length_nbytes as u64;
        }
        trace!("Payload length: {}", length);

        let mask = if masked {
            let mut mask_bytes = [0u8; 4];
            if cursor.read(&mut mask_bytes)? != 4 {
                cursor.set_position(initial);
                return Ok(None);
            } else {
                header_length += 4;
                Some(mask_bytes)
            }
        } else {
            None
        };

        match length.checked_add(header_length) {
            Some(l) if size < l => {
                cursor.set_position(initial);
                return Ok(None);
            }
            Some(_) => (),
            None => return Ok(None),
        };

        let mut data = Vec::with_capacity(length as usize);
        if length > 0 {
            if let Some(read) = cursor.try_read_buf(&mut data)? {
                debug_assert!(read == length as usize, "Read incorrect payload length!");
            }
        }

        // Disallow bad opcode
        if let OpCode::Bad = opcode {
            return Err(Error::new(
                Kind::Protocol,
                format!("Encountered invalid opcode: {}", first & 0x0F),
            ));
        }

        // control frames must have length <= 125
        match opcode {
            OpCode::Ping | OpCode::Pong if length > 125 => {
                return Err(Error::new(
                    Kind::Protocol,
                    format!(
                        "Rejected WebSocket handshake.Received control frame with length: {}.",
                        length
                    ),
                ))
            }
            OpCode::Close if length > 125 => {
                debug!("Received close frame with payload length exceeding 125. Morphing to protocol close frame.");
                return Ok(Some(Frame::close(
                    CloseCode::Protocol,
                    "Received close frame with payload length exceeding 125.",
                )));
            }
            _ => (),
        }

        let frame = Frame {
            finished: finished,
            rsv1: rsv1,
            rsv2: rsv2,
            rsv3: rsv3,
            opcode: opcode,
            mask: mask,
            payload: data,
        };

        Ok(Some(frame))
    }

    /// Write a frame out to a buffer
    pub fn format<W>(&mut self, w: &mut W) -> Result<()>
    where
        W: Write,
    {
        let mut one = 0u8;
        let code: u8 = self.opcode.into();
        if self.is_final() {
            one |= 0x80;
        }
        if self.has_rsv1() {
            one |= 0x40;
        }
        if self.has_rsv2() {
            one |= 0x20;
        }
        if self.has_rsv3() {
            one |= 0x10;
        }
        one |= code;

        let mut two = 0u8;
        if self.is_masked() {
            two |= 0x80;
        }

        match self.payload.len() {
            len if len < 126 => {
                two |= len as u8;
            }
            len if len <= 65535 => {
                two |= 126;
            }
            _ => {
                two |= 127;
            }
        }
        w.write_all(&[one, two])?;

        if let Some(length_bytes) = match self.payload.len() {
            len if len < 126 => None,
            len if len <= 65535 => Some(2),
            _ => Some(8),
        } {
            w.write_uint::<BigEndian>(self.payload.len() as u64, length_bytes)?;
        }

        if self.is_masked() {
            let mask = self.mask.take().unwrap();
            apply_mask(&mut self.payload, &mask);
            w.write_all(&mask)?;
        }

        w.write_all(&self.payload)?;
        Ok(())
    }
}

impl Default for Frame {
    fn default() -> Frame {
        Frame {
            finished: true,
            rsv1: false,
            rsv2: false,
            rsv3: false,
            opcode: OpCode::Close,
            mask: None,
            payload: Vec::new(),
        }
    }
}

impl fmt::Display for Frame {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "
<FRAME>
final: {}
reserved: {} {} {}
opcode: {}
length: {}
payload length: {}
payload: 0x{}
            ",
            self.finished,
            self.rsv1,
            self.rsv2,
            self.rsv3,
            self.opcode,
            // self.mask.map(|mask| format!("{:?}", mask)).unwrap_or("NONE".into()),
            self.len(),
            self.payload.len(),
            self.payload
                .iter()
                .map(|byte| format!("{:x}", byte))
                .collect::<String>()
        )
    }
}

mod test {
    #![allow(unused_imports, unused_variables, dead_code)]
    use super::*;
    use protocol::OpCode;

    #[test]
    fn display_frame() {
        let f = Frame::message("hi there".into(), OpCode::Text, true);
        let view = format!("{}", f);
        view.contains("payload:");
    }
}
<|endoftext|>


<commit_before>//! Hooks interface
extern crate serde_json;

use self::super::{Github, Result};
use rep::{Hook, HookCreateOptions};

/// Interface for mangaing repository hooks
pub struct Hooks<'a> {
    github: &'a Github,
    owner: String,
    repo: String,
}

impl<'a> Hooks<'a> {
    /// Create a new deployments instance
    pub fn new<O, R>(github: &'a Github, owner: O, repo: R) -> Hooks<'a>
        where O: Into<String>,
              R: Into<String>
    {
        Hooks {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
        }
    }

    /// lists hook associated with a repoistory
    pub fn list(&self) -> Result<Vec<Hook>> {
        self.github.get(&format!("/repos/{}/{}/hooks", self.owner, self.repo))
    }

    /// creates a new repository hook
    /// Repository service hooks (like email or Campfire) can have at most one configured at a time.
    /// Creating hooks for a service that already has one configured will update the existing hook.
    /// see [github docs](https://developer.github.com/v3/repos/hooks/)
    /// for more information
    pub fn create(&self, options: &HookCreateOptions) -> Result<Hook> {
        let data = try!(serde_json::to_string(&options));
        self.github.post::<Hook>(&format!("/repos/{}/{}/hooks", self.owner, self.repo),
                                 data.as_bytes())
    }

    /// deletes a repoistory hook by id
    pub fn delete(&self, id: u64) -> Result<()> {
        self.github.delete(&format!("/repos/{}/{}/hooks/{}", self.owner, self.repo, id))
    }
}
<commit_msg>make webhook content type a type<commit_after>//! Hooks interface
extern crate serde_json;

use self::super::{Github, Result};
use rep::{Hook, HookCreateOptions};
use std::fmt;

/// Content-Type web hooks will recieve
/// deliveries in
#[derive(Debug, PartialEq)]
pub enum WebHookContentType {
    /// application/json
    Json,
    /// application/x-form-url-encoded
    Form,
}

impl Default for WebHookContentType {
    fn default() -> WebHookContentType {
        WebHookContentType::Form
    }
}

impl fmt::Display for WebHookContentType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{}",
               match *self {
                   WebHookContentType::Form => "form",
                   WebHookContentType::Json => "json",
               })
    }
}

/// Interface for mangaing repository hooks
pub struct Hooks<'a> {
    github: &'a Github,
    owner: String,
    repo: String,
}

impl<'a> Hooks<'a> {
    /// Create a new deployments instance
    pub fn new<O, R>(github: &'a Github, owner: O, repo: R) -> Hooks<'a>
        where O: Into<String>,
              R: Into<String>
    {
        Hooks {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
        }
    }

    /// lists hook associated with a repoistory
    pub fn list(&self) -> Result<Vec<Hook>> {
        self.github.get(&format!("/repos/{}/{}/hooks", self.owner, self.repo))
    }

    /// creates a new repository hook
    /// Repository service hooks (like email or Campfire) can have at most one configured at a time.
    /// Creating hooks for a service that already has one configured will update the existing hook.
    /// see [github docs](https://developer.github.com/v3/repos/hooks/)
    /// for more information
    pub fn create(&self, options: &HookCreateOptions) -> Result<Hook> {
        let data = try!(serde_json::to_string(&options));
        self.github.post::<Hook>(&format!("/repos/{}/{}/hooks", self.owner, self.repo),
                                 data.as_bytes())
    }

    /// deletes a repoistory hook by id
    pub fn delete(&self, id: u64) -> Result<()> {
        self.github.delete(&format!("/repos/{}/{}/hooks/{}", self.owner, self.repo, id))
    }
}

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

    #[test]
    fn webhook_content_type_display() {
        for (ct, expect) in vec![(WebHookContentType::Form, "form"),
                                 (WebHookContentType::Json, "json")] {
            assert_eq!(ct.to_string(), expect)
        }
    }

    #[test]
    fn webhook_content_type_default() {
        let default: WebHookContentType = Default::default();
        assert_eq!(default, WebHookContentType::Form)
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014-2015 Mathias Hällman
 *
 * 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/.
 */

extern crate libc;
extern crate termkey;

use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
use std::thread::Thread;

use self::termkey::{TermKeyEvent, TermKeyResult};
use self::termkey::c::TermKeySym;

use keymap;

#[cfg(not(test))]
const STDIN_FILENO: libc::c_int = 0;

/*
 * TermInput is returned when starting listening for key events on a file
 * descriptor. It controls the life time of the terminal input loop. When the
 * TermInput is dropped, the terminal input loop will finish.
 */
pub struct TermInput {
  kill_tx: Sender<()>,
  died_rx: Receiver<()>,
}

impl Drop for TermInput {
  fn drop(&mut self) {
    self.kill_tx.send(()).unwrap();
    self.died_rx.recv().unwrap();
  }
}

// start listening for terminal input on stdin
#[cfg(not(test))]
pub fn start(key_tx: Sender<keymap::Key>) -> TermInput {
  start_on_fd(STDIN_FILENO, key_tx)
}

// start listening for terminal input on the specified file descriptor
pub fn start_on_fd(fd: libc::c_int, key_tx: Sender<keymap::Key>) -> TermInput {
  let (kill_tx, kill_rx) = channel();
  let (died_tx, died_rx) = channel();
  Thread::spawn(move || { input_loop(kill_rx, died_tx, key_tx, fd); });
  TermInput { kill_tx: kill_tx, died_rx: died_rx }
}

/*
 * Helper module for detecting available bytes on the file descriptor being
 * listened to.
 */
mod libc_poll {
  use super::libc::{c_int, c_long, c_short};

  #[repr(C)]
  struct Pollfd {
    fd: c_int,
    events: c_short,
    revents: c_short
  }

  extern {
    fn poll(fds: *mut Pollfd, nfds: c_long, timeout: c_int) -> c_int;
  }

  #[derive(PartialEq)]
  pub enum PollResult {
    Ready,
    Timeout,
  }

  pub fn poll_fd(fd: c_int, timeout_ms: int) -> PollResult {
    const POLLIN: c_short = 1;
    let mut pollfd = Pollfd { fd: fd, events: POLLIN, revents: 0 };
    let num_fds = 1;
    let poll_result = unsafe {
      poll(&mut pollfd, num_fds, timeout_ms as c_int)
    };
    if poll_result < 0      { panic!("Unable to poll stdin."); }
    else if poll_result > 0 { PollResult::Ready }
    else                    { PollResult::Timeout }
  }
}

fn input_loop(kill_rx: Receiver<()>, died_tx: Sender<()>,
              key_tx: Sender<keymap::Key>, fd: libc::c_int) {
  let is_alive = |&:| kill_rx.try_recv() == Err(TryRecvError::Empty);
  let mut tk = termkey::TermKey::new(fd, termkey::c::TERMKEY_FLAG_CTRLC);

  while is_alive() {
    // check for available input
    let poll_timeout_ms = 10;
    if libc_poll::poll_fd(fd, poll_timeout_ms) == libc_poll::PollResult::Ready {
      // tell termkey that there's input available
      tk.advisereadable();
    }

    // empty the fd, translating and sending key events
    loop {
      match tk.getkey() {
        TermKeyResult::None_        => break,  // got nothing, done here
        TermKeyResult::Eof          =>
          panic!("stdin closed, you're on your own."),
        TermKeyResult::Error{errno} =>
          panic!("termkey::geykey failed with error code {}", errno),
        TermKeyResult::Key(key)     => translate_key(key),
        TermKeyResult::Again        =>
          // There's input available, but not enough to make a key event. Likely
          // escape has been pushed, which we want to force out and interpret as
          // a key on its own, otherwise oops.
          match tk.getkey_force() {
            TermKeyResult::Key(key)     => translate_key(key),
            TermKeyResult::Eof          =>
              panic!("stdin closed, you're on your own."),
            TermKeyResult::Error{errno} =>
              panic!("termkey::geykey_force failed with error code {}", errno),
            _                           => unreachable!(),
          },
      }.map(|key| key_tx.send(key));
    }
  }

  died_tx.send(()).unwrap();
}

fn translate_key(key: TermKeyEvent) -> Option<keymap::Key> {
  match key {
    TermKeyEvent::FunctionEvent{num, mods}                =>
      Some(keymap::Key::Fn{num: num, mods: translate_mods(mods)}),
    TermKeyEvent::KeySymEvent{sym, mods}                  =>
      Some(keymap::Key::Sym{
        sym: translate_sym(sym), mods: translate_mods(mods)}),
    TermKeyEvent::UnicodeEvent{codepoint, mods, utf8:_}   =>
      Some(keymap::Key::Unicode{
        codepoint: codepoint, mods: translate_mods(mods)}),
    _                                                     =>
      None,
  }
}

fn translate_sym(sym: TermKeySym) -> keymap::KeySym {
  match sym {
    TermKeySym::TERMKEY_SYM_UNKNOWN   => keymap::KeySym::Unknown,
    TermKeySym::TERMKEY_SYM_NONE      => keymap::KeySym::None,
    TermKeySym::TERMKEY_SYM_BACKSPACE => keymap::KeySym::Backspace,
    TermKeySym::TERMKEY_SYM_TAB       => keymap::KeySym::Tab,
    TermKeySym::TERMKEY_SYM_ENTER     => keymap::KeySym::Enter,
    TermKeySym::TERMKEY_SYM_ESCAPE    => keymap::KeySym::Escape,
    TermKeySym::TERMKEY_SYM_SPACE     => keymap::KeySym::Space,
    TermKeySym::TERMKEY_SYM_DEL       => keymap::KeySym::Del,
    TermKeySym::TERMKEY_SYM_UP        => keymap::KeySym::Up,
    TermKeySym::TERMKEY_SYM_DOWN      => keymap::KeySym::Down,
    TermKeySym::TERMKEY_SYM_LEFT      => keymap::KeySym::Left,
    TermKeySym::TERMKEY_SYM_RIGHT     => keymap::KeySym::Right,
    TermKeySym::TERMKEY_SYM_BEGIN     => keymap::KeySym::Begin,
    TermKeySym::TERMKEY_SYM_FIND      => keymap::KeySym::Find,
    TermKeySym::TERMKEY_SYM_INSERT    => keymap::KeySym::Insert,
    TermKeySym::TERMKEY_SYM_DELETE    => keymap::KeySym::Delete,
    TermKeySym::TERMKEY_SYM_SELECT    => keymap::KeySym::Select,
    TermKeySym::TERMKEY_SYM_PAGEUP    => keymap::KeySym::Pageup,
    TermKeySym::TERMKEY_SYM_PAGEDOWN  => keymap::KeySym::Pagedown,
    TermKeySym::TERMKEY_SYM_HOME      => keymap::KeySym::Home,
    TermKeySym::TERMKEY_SYM_END       => keymap::KeySym::End,
    TermKeySym::TERMKEY_SYM_CANCEL    => keymap::KeySym::Cancel,
    TermKeySym::TERMKEY_SYM_CLEAR     => keymap::KeySym::Clear,
    TermKeySym::TERMKEY_SYM_CLOSE     => keymap::KeySym::Close,
    TermKeySym::TERMKEY_SYM_COMMAND   => keymap::KeySym::Command,
    TermKeySym::TERMKEY_SYM_COPY      => keymap::KeySym::Copy,
    TermKeySym::TERMKEY_SYM_EXIT      => keymap::KeySym::Exit,
    TermKeySym::TERMKEY_SYM_HELP      => keymap::KeySym::Help,
    TermKeySym::TERMKEY_SYM_MARK      => keymap::KeySym::Mark,
    TermKeySym::TERMKEY_SYM_MESSAGE   => keymap::KeySym::Message,
    TermKeySym::TERMKEY_SYM_MOVE      => keymap::KeySym::Move,
    TermKeySym::TERMKEY_SYM_OPEN      => keymap::KeySym::Open,
    TermKeySym::TERMKEY_SYM_OPTIONS   => keymap::KeySym::Options,
    TermKeySym::TERMKEY_SYM_PRINT     => keymap::KeySym::Print,
    TermKeySym::TERMKEY_SYM_REDO      => keymap::KeySym::Redo,
    TermKeySym::TERMKEY_SYM_REFERENCE => keymap::KeySym::Reference,
    TermKeySym::TERMKEY_SYM_REFRESH   => keymap::KeySym::Refresh,
    TermKeySym::TERMKEY_SYM_REPLACE   => keymap::KeySym::Replace,
    TermKeySym::TERMKEY_SYM_RESTART   => keymap::KeySym::Restart,
    TermKeySym::TERMKEY_SYM_RESUME    => keymap::KeySym::Resume,
    TermKeySym::TERMKEY_SYM_SAVE      => keymap::KeySym::Save,
    TermKeySym::TERMKEY_SYM_SUSPEND   => keymap::KeySym::Suspend,
    TermKeySym::TERMKEY_SYM_UNDO      => keymap::KeySym::Undo,
    TermKeySym::TERMKEY_SYM_KP0       => keymap::KeySym::KP0,
    TermKeySym::TERMKEY_SYM_KP1       => keymap::KeySym::KP1,
    TermKeySym::TERMKEY_SYM_KP2       => keymap::KeySym::KP2,
    TermKeySym::TERMKEY_SYM_KP3       => keymap::KeySym::KP3,
    TermKeySym::TERMKEY_SYM_KP4       => keymap::KeySym::KP4,
    TermKeySym::TERMKEY_SYM_KP5       => keymap::KeySym::KP5,
    TermKeySym::TERMKEY_SYM_KP6       => keymap::KeySym::KP6,
    TermKeySym::TERMKEY_SYM_KP7       => keymap::KeySym::KP7,
    TermKeySym::TERMKEY_SYM_KP8       => keymap::KeySym::KP8,
    TermKeySym::TERMKEY_SYM_KP9       => keymap::KeySym::KP9,
    TermKeySym::TERMKEY_SYM_KPENTER   => keymap::KeySym::KPEnter,
    TermKeySym::TERMKEY_SYM_KPPLUS    => keymap::KeySym::KPPlus,
    TermKeySym::TERMKEY_SYM_KPMINUS   => keymap::KeySym::KPMinus,
    TermKeySym::TERMKEY_SYM_KPMULT    => keymap::KeySym::KPMult,
    TermKeySym::TERMKEY_SYM_KPDIV     => keymap::KeySym::KPDiv,
    TermKeySym::TERMKEY_SYM_KPCOMMA   => keymap::KeySym::KPComma,
    TermKeySym::TERMKEY_SYM_KPPERIOD  => keymap::KeySym::KPPeriod,
    TermKeySym::TERMKEY_SYM_KPEQUALS  => keymap::KeySym::KPEquals,
    TermKeySym::TERMKEY_N_SYMS        => keymap::KeySym::NSyms,
  }
}

fn translate_mods(mods: termkey::c::X_TermKey_KeyMod) -> keymap::KeyMod {
  let mut ret = keymap::MOD_NONE;
  if mods.contains(termkey::c::TERMKEY_KEYMOD_SHIFT) {
    ret.insert(keymap::MOD_SHIFT);
  }
  if mods.contains(termkey::c::TERMKEY_KEYMOD_ALT) {
    ret.insert(keymap::MOD_ALT);
  }
  if mods.contains(termkey::c::TERMKEY_KEYMOD_CTRL) {
    ret.insert(keymap::MOD_CTRL);
  }
  return ret;
}

#[cfg(test)]
mod test {
  extern crate time;

  use super::libc;
  use std::sync::mpsc::{channel, Sender};
  use std::old_io::pipe::PipeStream;
  use std::old_io::timer;
  use std::os;
  use std::thread::Thread;
  use std::time::duration::Duration;

  use keymap;

  // Simulates stdin by writing bytes to a pipe, then listens for the key
  // outputs and matches with expectations.
  #[test]
  fn test_input() {
    // pairs of input bytes on "stdin" and corresponding expected key output
    let input_output_pairs = vec!(
      (vec!(0x61),
        keymap::Key::Unicode{codepoint: 'a', mods: keymap::MOD_NONE}),
      (vec!(0x1B, 0x61),
        keymap::Key::Unicode{codepoint: 'a', mods: keymap::MOD_ALT}),
      (vec!(0x1B),
        keymap::Key::Sym{sym: keymap::KeySym::Escape, mods: keymap::MOD_NONE}),
      (vec!(0x61),
        keymap::Key::Unicode{codepoint: 'a', mods: keymap::MOD_NONE}),
      (vec!(0x03),
        keymap::Key::Unicode{codepoint: 'c', mods: keymap::MOD_CTRL}),
      (vec!(0x1B, 0x5B, 0x41),
        keymap::Key::Sym{sym: keymap::KeySym::Up, mods: keymap::MOD_NONE}),
      (vec!(0x1B, 0x4F, 0x53),
        keymap::Key::Fn{num: 4, mods: keymap::MOD_NONE}),
      (vec!(0xE3, 0x81, 0x82),
        keymap::Key::Unicode{codepoint: 'あ', mods: keymap::MOD_NONE}),
    );

    let inputs: Vec<Vec<u8>> =
      input_output_pairs.iter().map(|&(ref input, _)| input.clone()).collect();
    let outputs: Vec<keymap::Key> =
      input_output_pairs.iter().map(|&(_, output)| output).collect();

    // set up communication channels
    let (key_tx, key_rx) = channel();
    let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };

    // start input listener
    let _term_input = super::start_on_fd(reader, key_tx);

    // make sure we quit in an orderly fashion even at failure
    let (close_writer_tx, close_writer_rx) = channel();
    struct PipeKiller { close_writer_tx: Sender<()>, reader: libc::c_int }
    impl Drop for PipeKiller {
      fn drop(&mut self) {
        unsafe { libc::close(self.reader); }
        self.close_writer_tx.send(()).unwrap();
      }
    }
    let _pipe_killer =
      PipeKiller { close_writer_tx: close_writer_tx, reader: reader };

    // simulate keyboard input
    Thread::spawn(move || {
      let mut pipe_out = PipeStream::open(writer);
      for input in inputs.iter() {
        pipe_out.write_all(input.as_slice()).unwrap();
        // give termkey a chance to parse escape as a standalone key
        timer::sleep(Duration::milliseconds(1));
      }
      // keep the pipe alive until we're finished with it
      close_writer_rx.recv().unwrap();
    });

    // receive key outputs and match with expectations
    let timeout_at = time::get_time() + Duration::milliseconds(100);
    for output in outputs.iter() {
      // just keep looping until the key arrives
      loop {
        match key_rx.try_recv() {
          Ok(key) => { assert_eq!(key, *output); break; }
          _       => (),
        }
        let time_now = time::get_time();
        if time_now > timeout_at { panic!("Timeout waiting for key event."); }
      }
    }
  }
}
<commit_msg>Thread::spawn made module-level free function<commit_after>/*
 * Copyright (c) 2014-2015 Mathias Hällman
 *
 * 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/.
 */

extern crate libc;
extern crate termkey;

use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
use std::thread;

use self::termkey::{TermKeyEvent, TermKeyResult};
use self::termkey::c::TermKeySym;

use keymap;

#[cfg(not(test))]
const STDIN_FILENO: libc::c_int = 0;

/*
 * TermInput is returned when starting listening for key events on a file
 * descriptor. It controls the life time of the terminal input loop. When the
 * TermInput is dropped, the terminal input loop will finish.
 */
pub struct TermInput {
  kill_tx: Sender<()>,
  died_rx: Receiver<()>,
}

impl Drop for TermInput {
  fn drop(&mut self) {
    self.kill_tx.send(()).unwrap();
    self.died_rx.recv().unwrap();
  }
}

// start listening for terminal input on stdin
#[cfg(not(test))]
pub fn start(key_tx: Sender<keymap::Key>) -> TermInput {
  start_on_fd(STDIN_FILENO, key_tx)
}

// start listening for terminal input on the specified file descriptor
pub fn start_on_fd(fd: libc::c_int, key_tx: Sender<keymap::Key>) -> TermInput {
  let (kill_tx, kill_rx) = channel();
  let (died_tx, died_rx) = channel();
  thread::spawn(move || { input_loop(kill_rx, died_tx, key_tx, fd); });
  TermInput { kill_tx: kill_tx, died_rx: died_rx }
}

/*
 * Helper module for detecting available bytes on the file descriptor being
 * listened to.
 */
mod libc_poll {
  use super::libc::{c_int, c_long, c_short};

  #[repr(C)]
  struct Pollfd {
    fd: c_int,
    events: c_short,
    revents: c_short
  }

  extern {
    fn poll(fds: *mut Pollfd, nfds: c_long, timeout: c_int) -> c_int;
  }

  #[derive(PartialEq)]
  pub enum PollResult {
    Ready,
    Timeout,
  }

  pub fn poll_fd(fd: c_int, timeout_ms: int) -> PollResult {
    const POLLIN: c_short = 1;
    let mut pollfd = Pollfd { fd: fd, events: POLLIN, revents: 0 };
    let num_fds = 1;
    let poll_result = unsafe {
      poll(&mut pollfd, num_fds, timeout_ms as c_int)
    };
    if poll_result < 0      { panic!("Unable to poll stdin."); }
    else if poll_result > 0 { PollResult::Ready }
    else                    { PollResult::Timeout }
  }
}

fn input_loop(kill_rx: Receiver<()>, died_tx: Sender<()>,
              key_tx: Sender<keymap::Key>, fd: libc::c_int) {
  let is_alive = |&:| kill_rx.try_recv() == Err(TryRecvError::Empty);
  let mut tk = termkey::TermKey::new(fd, termkey::c::TERMKEY_FLAG_CTRLC);

  while is_alive() {
    // check for available input
    let poll_timeout_ms = 10;
    if libc_poll::poll_fd(fd, poll_timeout_ms) == libc_poll::PollResult::Ready {
      // tell termkey that there's input available
      tk.advisereadable();
    }

    // empty the fd, translating and sending key events
    loop {
      match tk.getkey() {
        TermKeyResult::None_        => break,  // got nothing, done here
        TermKeyResult::Eof          =>
          panic!("stdin closed, you're on your own."),
        TermKeyResult::Error{errno} =>
          panic!("termkey::geykey failed with error code {}", errno),
        TermKeyResult::Key(key)     => translate_key(key),
        TermKeyResult::Again        =>
          // There's input available, but not enough to make a key event. Likely
          // escape has been pushed, which we want to force out and interpret as
          // a key on its own, otherwise oops.
          match tk.getkey_force() {
            TermKeyResult::Key(key)     => translate_key(key),
            TermKeyResult::Eof          =>
              panic!("stdin closed, you're on your own."),
            TermKeyResult::Error{errno} =>
              panic!("termkey::geykey_force failed with error code {}", errno),
            _                           => unreachable!(),
          },
      }.map(|key| key_tx.send(key));
    }
  }

  died_tx.send(()).unwrap();
}

fn translate_key(key: TermKeyEvent) -> Option<keymap::Key> {
  match key {
    TermKeyEvent::FunctionEvent{num, mods}                =>
      Some(keymap::Key::Fn{num: num, mods: translate_mods(mods)}),
    TermKeyEvent::KeySymEvent{sym, mods}                  =>
      Some(keymap::Key::Sym{
        sym: translate_sym(sym), mods: translate_mods(mods)}),
    TermKeyEvent::UnicodeEvent{codepoint, mods, utf8:_}   =>
      Some(keymap::Key::Unicode{
        codepoint: codepoint, mods: translate_mods(mods)}),
    _                                                     =>
      None,
  }
}

fn translate_sym(sym: TermKeySym) -> keymap::KeySym {
  match sym {
    TermKeySym::TERMKEY_SYM_UNKNOWN   => keymap::KeySym::Unknown,
    TermKeySym::TERMKEY_SYM_NONE      => keymap::KeySym::None,
    TermKeySym::TERMKEY_SYM_BACKSPACE => keymap::KeySym::Backspace,
    TermKeySym::TERMKEY_SYM_TAB       => keymap::KeySym::Tab,
    TermKeySym::TERMKEY_SYM_ENTER     => keymap::KeySym::Enter,
    TermKeySym::TERMKEY_SYM_ESCAPE    => keymap::KeySym::Escape,
    TermKeySym::TERMKEY_SYM_SPACE     => keymap::KeySym::Space,
    TermKeySym::TERMKEY_SYM_DEL       => keymap::KeySym::Del,
    TermKeySym::TERMKEY_SYM_UP        => keymap::KeySym::Up,
    TermKeySym::TERMKEY_SYM_DOWN      => keymap::KeySym::Down,
    TermKeySym::TERMKEY_SYM_LEFT      => keymap::KeySym::Left,
    TermKeySym::TERMKEY_SYM_RIGHT     => keymap::KeySym::Right,
    TermKeySym::TERMKEY_SYM_BEGIN     => keymap::KeySym::Begin,
    TermKeySym::TERMKEY_SYM_FIND      => keymap::KeySym::Find,
    TermKeySym::TERMKEY_SYM_INSERT    => keymap::KeySym::Insert,
    TermKeySym::TERMKEY_SYM_DELETE    => keymap::KeySym::Delete,
    TermKeySym::TERMKEY_SYM_SELECT    => keymap::KeySym::Select,
    TermKeySym::TERMKEY_SYM_PAGEUP    => keymap::KeySym::Pageup,
    TermKeySym::TERMKEY_SYM_PAGEDOWN  => keymap::KeySym::Pagedown,
    TermKeySym::TERMKEY_SYM_HOME      => keymap::KeySym::Home,
    TermKeySym::TERMKEY_SYM_END       => keymap::KeySym::End,
    TermKeySym::TERMKEY_SYM_CANCEL    => keymap::KeySym::Cancel,
    TermKeySym::TERMKEY_SYM_CLEAR     => keymap::KeySym::Clear,
    TermKeySym::TERMKEY_SYM_CLOSE     => keymap::KeySym::Close,
    TermKeySym::TERMKEY_SYM_COMMAND   => keymap::KeySym::Command,
    TermKeySym::TERMKEY_SYM_COPY      => keymap::KeySym::Copy,
    TermKeySym::TERMKEY_SYM_EXIT      => keymap::KeySym::Exit,
    TermKeySym::TERMKEY_SYM_HELP      => keymap::KeySym::Help,
    TermKeySym::TERMKEY_SYM_MARK      => keymap::KeySym::Mark,
    TermKeySym::TERMKEY_SYM_MESSAGE   => keymap::KeySym::Message,
    TermKeySym::TERMKEY_SYM_MOVE      => keymap::KeySym::Move,
    TermKeySym::TERMKEY_SYM_OPEN      => keymap::KeySym::Open,
    TermKeySym::TERMKEY_SYM_OPTIONS   => keymap::KeySym::Options,
    TermKeySym::TERMKEY_SYM_PRINT     => keymap::KeySym::Print,
    TermKeySym::TERMKEY_SYM_REDO      => keymap::KeySym::Redo,
    TermKeySym::TERMKEY_SYM_REFERENCE => keymap::KeySym::Reference,
    TermKeySym::TERMKEY_SYM_REFRESH   => keymap::KeySym::Refresh,
    TermKeySym::TERMKEY_SYM_REPLACE   => keymap::KeySym::Replace,
    TermKeySym::TERMKEY_SYM_RESTART   => keymap::KeySym::Restart,
    TermKeySym::TERMKEY_SYM_RESUME    => keymap::KeySym::Resume,
    TermKeySym::TERMKEY_SYM_SAVE      => keymap::KeySym::Save,
    TermKeySym::TERMKEY_SYM_SUSPEND   => keymap::KeySym::Suspend,
    TermKeySym::TERMKEY_SYM_UNDO      => keymap::KeySym::Undo,
    TermKeySym::TERMKEY_SYM_KP0       => keymap::KeySym::KP0,
    TermKeySym::TERMKEY_SYM_KP1       => keymap::KeySym::KP1,
    TermKeySym::TERMKEY_SYM_KP2       => keymap::KeySym::KP2,
    TermKeySym::TERMKEY_SYM_KP3       => keymap::KeySym::KP3,
    TermKeySym::TERMKEY_SYM_KP4       => keymap::KeySym::KP4,
    TermKeySym::TERMKEY_SYM_KP5       => keymap::KeySym::KP5,
    TermKeySym::TERMKEY_SYM_KP6       => keymap::KeySym::KP6,
    TermKeySym::TERMKEY_SYM_KP7       => keymap::KeySym::KP7,
    TermKeySym::TERMKEY_SYM_KP8       => keymap::KeySym::KP8,
    TermKeySym::TERMKEY_SYM_KP9       => keymap::KeySym::KP9,
    TermKeySym::TERMKEY_SYM_KPENTER   => keymap::KeySym::KPEnter,
    TermKeySym::TERMKEY_SYM_KPPLUS    => keymap::KeySym::KPPlus,
    TermKeySym::TERMKEY_SYM_KPMINUS   => keymap::KeySym::KPMinus,
    TermKeySym::TERMKEY_SYM_KPMULT    => keymap::KeySym::KPMult,
    TermKeySym::TERMKEY_SYM_KPDIV     => keymap::KeySym::KPDiv,
    TermKeySym::TERMKEY_SYM_KPCOMMA   => keymap::KeySym::KPComma,
    TermKeySym::TERMKEY_SYM_KPPERIOD  => keymap::KeySym::KPPeriod,
    TermKeySym::TERMKEY_SYM_KPEQUALS  => keymap::KeySym::KPEquals,
    TermKeySym::TERMKEY_N_SYMS        => keymap::KeySym::NSyms,
  }
}

fn translate_mods(mods: termkey::c::X_TermKey_KeyMod) -> keymap::KeyMod {
  let mut ret = keymap::MOD_NONE;
  if mods.contains(termkey::c::TERMKEY_KEYMOD_SHIFT) {
    ret.insert(keymap::MOD_SHIFT);
  }
  if mods.contains(termkey::c::TERMKEY_KEYMOD_ALT) {
    ret.insert(keymap::MOD_ALT);
  }
  if mods.contains(termkey::c::TERMKEY_KEYMOD_CTRL) {
    ret.insert(keymap::MOD_CTRL);
  }
  return ret;
}

#[cfg(test)]
mod test {
  extern crate time;

  use super::libc;
  use std::sync::mpsc::{channel, Sender};
  use std::old_io::pipe::PipeStream;
  use std::old_io::timer;
  use std::os;
  use std::thread;
  use std::time::duration::Duration;

  use keymap;

  // Simulates stdin by writing bytes to a pipe, then listens for the key
  // outputs and matches with expectations.
  #[test]
  fn test_input() {
    // pairs of input bytes on "stdin" and corresponding expected key output
    let input_output_pairs = vec!(
      (vec!(0x61),
        keymap::Key::Unicode{codepoint: 'a', mods: keymap::MOD_NONE}),
      (vec!(0x1B, 0x61),
        keymap::Key::Unicode{codepoint: 'a', mods: keymap::MOD_ALT}),
      (vec!(0x1B),
        keymap::Key::Sym{sym: keymap::KeySym::Escape, mods: keymap::MOD_NONE}),
      (vec!(0x61),
        keymap::Key::Unicode{codepoint: 'a', mods: keymap::MOD_NONE}),
      (vec!(0x03),
        keymap::Key::Unicode{codepoint: 'c', mods: keymap::MOD_CTRL}),
      (vec!(0x1B, 0x5B, 0x41),
        keymap::Key::Sym{sym: keymap::KeySym::Up, mods: keymap::MOD_NONE}),
      (vec!(0x1B, 0x4F, 0x53),
        keymap::Key::Fn{num: 4, mods: keymap::MOD_NONE}),
      (vec!(0xE3, 0x81, 0x82),
        keymap::Key::Unicode{codepoint: 'あ', mods: keymap::MOD_NONE}),
    );

    let inputs: Vec<Vec<u8>> =
      input_output_pairs.iter().map(|&(ref input, _)| input.clone()).collect();
    let outputs: Vec<keymap::Key> =
      input_output_pairs.iter().map(|&(_, output)| output).collect();

    // set up communication channels
    let (key_tx, key_rx) = channel();
    let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };

    // start input listener
    let _term_input = super::start_on_fd(reader, key_tx);

    // make sure we quit in an orderly fashion even at failure
    let (close_writer_tx, close_writer_rx) = channel();
    struct PipeKiller { close_writer_tx: Sender<()>, reader: libc::c_int }
    impl Drop for PipeKiller {
      fn drop(&mut self) {
        unsafe { libc::close(self.reader); }
        self.close_writer_tx.send(()).unwrap();
      }
    }
    let _pipe_killer =
      PipeKiller { close_writer_tx: close_writer_tx, reader: reader };

    // simulate keyboard input
    thread::spawn(move || {
      let mut pipe_out = PipeStream::open(writer);
      for input in inputs.iter() {
        pipe_out.write_all(input.as_slice()).unwrap();
        // give termkey a chance to parse escape as a standalone key
        timer::sleep(Duration::milliseconds(1));
      }
      // keep the pipe alive until we're finished with it
      close_writer_rx.recv().unwrap();
    });

    // receive key outputs and match with expectations
    let timeout_at = time::get_time() + Duration::milliseconds(100);
    for output in outputs.iter() {
      // just keep looping until the key arrives
      loop {
        match key_rx.try_recv() {
          Ok(key) => { assert_eq!(key, *output); break; }
          _       => (),
        }
        let time_now = time::get_time();
        if time_now > timeout_at { panic!("Timeout waiting for key event."); }
      }
    }
  }
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::io::Read;
use std::path::PathBuf;

use email::MimeMessage;

use libimagentryref::hasher::Hasher;
use libimagentryref::hasher::DefaultHasher;
use libimagentryref::error::RefErrorKind as REK;
use libimagentryref::error::ResultExt;
use libimagentryref::error::Result as RResult;

pub struct MailHasher {
    defaulthasher: DefaultHasher,
}

impl MailHasher {

    pub fn new() -> MailHasher {
        MailHasher { defaulthasher: DefaultHasher::new() }
    }

}

impl Hasher for MailHasher {

    fn hash_name(&self) -> &'static str {
        "default_mail_hasher"
    }

    fn create_hash<R: Read>(&mut self, pb: &PathBuf, c: &mut R) -> RResult<String> {
        use filters::filter::Filter;
        use email::Header;

        let mut s = String::new();
        try!(c.read_to_string(&mut s).chain_err(|| REK::UTF8Error).chain_err(|| REK::IOError));

        MimeMessage::parse(&s)
            .chain_err(|| REK::RefHashingError)
            .and_then(|mail| {
                let has_key = |hdr: &Header, exp: &str| hdr.name == exp;

                let subject_filter = |hdr: &Header| has_key(hdr, "Subject");
                let from_filter    = |hdr: &Header| has_key(hdr, "From");
                let to_filter      = |hdr: &Header| has_key(hdr, "To");

                let filter = subject_filter.or(from_filter).or(to_filter);

                let mut v : Vec<String> = vec![];
                for hdr in mail.headers.iter().filter(|item| filter.filter(item)) {
                    let s = try!(hdr
                        .get_value()
                        .chain_err(|| REK::RefHashingError));

                    v.push(s);
                }
                let s : String = v.join("");

                self.defaulthasher.create_hash(pb, &mut s.as_bytes())
            })
    }

}
<commit_msg>Adjust for new error linking setup in libimagentryref<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::io::Read;
use std::path::PathBuf;

use email::MimeMessage;

use libimagentryref::hasher::Hasher;
use libimagentryref::hasher::DefaultHasher;
use libimagentryref::error::RefErrorKind as REK;
use libimagentryref::error::ResultExt;
use libimagentryref::error::Result as RResult;

pub struct MailHasher {
    defaulthasher: DefaultHasher,
}

impl MailHasher {

    pub fn new() -> MailHasher {
        MailHasher { defaulthasher: DefaultHasher::new() }
    }

}

impl Hasher for MailHasher {

    fn hash_name(&self) -> &'static str {
        "default_mail_hasher"
    }

    fn create_hash<R: Read>(&mut self, pb: &PathBuf, c: &mut R) -> RResult<String> {
        use filters::filter::Filter;
        use email::Header;

        let mut s = String::new();
        try!(c.read_to_string(&mut s));

        MimeMessage::parse(&s)
            .chain_err(|| REK::RefHashingError)
            .and_then(|mail| {
                let has_key = |hdr: &Header, exp: &str| hdr.name == exp;

                let subject_filter = |hdr: &Header| has_key(hdr, "Subject");
                let from_filter    = |hdr: &Header| has_key(hdr, "From");
                let to_filter      = |hdr: &Header| has_key(hdr, "To");

                let filter = subject_filter.or(from_filter).or(to_filter);

                let mut v : Vec<String> = vec![];
                for hdr in mail.headers.iter().filter(|item| filter.filter(item)) {
                    let s = try!(hdr
                        .get_value()
                        .chain_err(|| REK::RefHashingError));

                    v.push(s);
                }
                let s : String = v.join("");

                self.defaulthasher.create_hash(pb, &mut s.as_bytes())
            })
    }

}
<|endoftext|>