<commit_before>#![deny(missing_docs)]

//! A GLFW window back-end for the Piston game engine.

extern crate glfw;
extern crate gl;
extern crate window;
extern crate shader_version;
extern crate input;
#[macro_use]
extern crate quack;

use std::sync::mpsc::Receiver;
use quack::Associative;

// External crates.
use std::collections::VecDeque;
use glfw::Context;
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
    Motion,
};
use window::{
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    CaptureCursor, DrawSize, Title,
    ExitOnEsc
};
use shader_version::opengl::OpenGL;

/// Contains stuff for game window.
pub struct GlfwWindow {
    /// The window.
    pub window: glfw::Window,
    /// Receives events from window.
    events: Receiver<(f64, glfw::WindowEvent)>,
    /// GLFW context.
    pub glfw: glfw::Glfw,
    event_queue: VecDeque<input::Input>,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
}

impl GlfwWindow {
    /// Create a new game window from an existing GLFW window.
    pub fn from_pieces(mut win: glfw::Window, glfw: glfw::Glfw,
                       events: Receiver<(f64, glfw::WindowEvent)>,
                       exit_on_esc: bool) -> GlfwWindow {
        win.set_all_polling(true);
        win.make_current();
        let title = "<unknown window title, created from_pieces>";
        GlfwWindow {
            window: win,
            events: events,
            glfw: glfw,
            exit_on_esc: exit_on_esc,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: title.to_string(),
        }
    }

    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlfwWindow {
        use glfw::Context;

        // Initialize GLFW.
        let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

        let (major, minor) = opengl.get_major_minor();

        // Make sure we have the right GL version.
        glfw.window_hint(glfw::WindowHint::ContextVersion(major as u32, minor as u32));
        if opengl >= OpenGL::_3_0 {
            glfw.window_hint(glfw::WindowHint::OpenglForwardCompat(true));
        }
        if opengl >= OpenGL::_3_2 {
            glfw.window_hint(glfw::WindowHint::OpenglProfile(glfw::OpenGlProfileHint::Core));
        }
        glfw.window_hint(glfw::WindowHint::Samples(settings.samples as u32));

        // Create GLFW window.
        let (mut window, events) = glfw.create_window(
            settings.size[0],
            settings.size[1],
            &settings.title, glfw::WindowMode::Windowed
        ).expect("Failed to create GLFW window.");
        window.set_all_polling(true);
        window.make_current();

        // Load the OpenGL function pointers
        gl::load_with(|s| window.get_proc_address(s));

        GlfwWindow {
            window: window,
            events: events,
            glfw: glfw,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: settings.title,
            exit_on_esc: settings.exit_on_esc,
        }
    }

    fn flush_messages(&mut self) {
        if self.event_queue.len() != 0 {
            return;
        }

        self.glfw.poll_events();
        for (_, event) in glfw::flush_messages(&self.events) {
            match event {
                glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _)
                if self.exit_on_esc => {
                    self.window.set_should_close(true);
                }
                glfw::WindowEvent::Char(ch) => {
                    self.event_queue.push_back(Input::Text(ch.to_string()));
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::CursorPos(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseCursor(x, y)));
                    match self.last_mouse_pos {
                        Some((lx, ly)) => {
                            self.event_queue.push_back(
                                Input::Move(Motion::MouseRelative(x - lx, y - ly))
                            )
                        }
                        None => {}
                    };
                    self.last_mouse_pos = Some((x, y));
                }
                glfw::WindowEvent::Scroll(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseScroll(x, y)));
                }
                glfw::WindowEvent::Size(w, h) => {
                    self.event_queue.push_back(Input::Resize(w as u32, h as u32));
                }
                glfw::WindowEvent::Focus(focus) => {
                    self.event_queue.push_back(Input::Focus(focus));
                }
                _ => {}
            }
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        self.flush_messages();

        if self.event_queue.len() != 0 {
            self.event_queue.pop_front()
        } else {
            None
        }
    }

    fn capture_cursor(&mut self, enabled: bool) {
        if enabled {
            self.window.set_cursor_mode(glfw::CursorMode::Disabled)
        } else {
            self.window.set_cursor_mode(glfw::CursorMode::Normal);
            self.last_mouse_pos = None;
        }
    }
}

quack! {
obj: GlfwWindow[]
get:
    fn () -> Size [] {
        let (w, h) = obj.window.get_size();
        Size([w as u32, h as u32])
    }
    fn () -> ShouldClose [] {
        ShouldClose(obj.window.should_close())
    }
    fn () -> DrawSize [] {
        let (w, h) = obj.window.get_framebuffer_size();
        DrawSize([w as u32, h as u32])
    }
    fn () -> Title [] { Title(obj.title.clone()) }
    fn () -> ExitOnEsc [] { ExitOnEsc(obj.exit_on_esc) }
set:
    fn (val: CaptureCursor) [] { obj.capture_cursor(val.0) }
    fn (val: ShouldClose) [] { obj.window.set_should_close(val.0) }
    fn (val: Title) [] { obj.window.set_title(&val.0) }
    fn (val: ExitOnEsc) [] { obj.exit_on_esc = val.0 }
action:
    fn (__: PollEvent) -> Option<Input> [] { obj.poll_event() }
    fn (__: SwapBuffers) -> () [] { obj.window.swap_buffers() }
}

impl Associative for (PollEvent, GlfwWindow) {
    type Type = Input;
}

fn glfw_map_key(keycode: glfw::Key) -> keyboard::Key {
    use input::keyboard::Key;

    match keycode {
        glfw::Key::Num0 => Key::D0,
        glfw::Key::Num1 => Key::D1,
        glfw::Key::Num2 => Key::D2,
        glfw::Key::Num3 => Key::D3,
        glfw::Key::Num4 => Key::D4,
        glfw::Key::Num5 => Key::D5,
        glfw::Key::Num6 => Key::D6,
        glfw::Key::Num7 => Key::D7,
        glfw::Key::Num8 => Key::D8,
        glfw::Key::Num9 => Key::D9,
        glfw::Key::A => Key::A,
        glfw::Key::B => Key::B,
        glfw::Key::C => Key::C,
        glfw::Key::D => Key::D,
        glfw::Key::E => Key::E,
        glfw::Key::F => Key::F,
        glfw::Key::G => Key::G,
        glfw::Key::H => Key::H,
        glfw::Key::I => Key::I,
        glfw::Key::J => Key::J,
        glfw::Key::K => Key::K,
        glfw::Key::L => Key::L,
        glfw::Key::M => Key::M,
        glfw::Key::N => Key::N,
        glfw::Key::O => Key::O,
        glfw::Key::P => Key::P,
        glfw::Key::Q => Key::Q,
        glfw::Key::R => Key::R,
        glfw::Key::S => Key::S,
        glfw::Key::T => Key::T,
        glfw::Key::U => Key::U,
        glfw::Key::V => Key::V,
        glfw::Key::W => Key::W,
        glfw::Key::X => Key::X,
        glfw::Key::Y => Key::Y,
        glfw::Key::Z => Key::Z,
        glfw::Key::Apostrophe => Key::Unknown,
        glfw::Key::Backslash => Key::Backslash,
        glfw::Key::Backspace => Key::Backspace,
        glfw::Key::CapsLock => Key::CapsLock,
        glfw::Key::Delete => Key::Delete,
        glfw::Key::Comma => Key::Comma,
        glfw::Key::Down => Key::Down,
        glfw::Key::End => Key::End,
        glfw::Key::Enter => Key::Return,
        glfw::Key::Equal => Key::Equals,
        glfw::Key::Escape => Key::Escape,
        glfw::Key::F1 => Key::F1,
        glfw::Key::F2 => Key::F2,
        glfw::Key::F3 => Key::F3,
        glfw::Key::F4 => Key::F4,
        glfw::Key::F5 => Key::F5,
        glfw::Key::F6 => Key::F6,
        glfw::Key::F7 => Key::F7,
        glfw::Key::F8 => Key::F8,
        glfw::Key::F9 => Key::F9,
        glfw::Key::F10 => Key::F10,
        glfw::Key::F11 => Key::F11,
        glfw::Key::F12 => Key::F12,
        glfw::Key::F13 => Key::F13,
        glfw::Key::F14 => Key::F14,
        glfw::Key::F15 => Key::F15,
        glfw::Key::F16 => Key::F16,
        glfw::Key::F17 => Key::F17,
        glfw::Key::F18 => Key::F18,
        glfw::Key::F19 => Key::F19,
        glfw::Key::F20 => Key::F20,
        glfw::Key::F21 => Key::F21,
        glfw::Key::F22 => Key::F22,
        glfw::Key::F23 => Key::F23,
        glfw::Key::F24 => Key::F24,
        // Possibly next code.
        glfw::Key::F25 => Key::Unknown,
        glfw::Key::Kp0 => Key::NumPad0,
        glfw::Key::Kp1 => Key::NumPad1,
        glfw::Key::Kp2 => Key::NumPad2,
        glfw::Key::Kp3 => Key::NumPad3,
        glfw::Key::Kp4 => Key::NumPad4,
        glfw::Key::Kp5 => Key::NumPad5,
        glfw::Key::Kp6 => Key::NumPad6,
        glfw::Key::Kp7 => Key::NumPad7,
        glfw::Key::Kp8 => Key::NumPad8,
        glfw::Key::Kp9 => Key::NumPad9,
        glfw::Key::KpDecimal => Key::NumPadDecimal,
        glfw::Key::KpDivide => Key::NumPadDivide,
        glfw::Key::KpMultiply => Key::NumPadMultiply,
        glfw::Key::KpSubtract => Key::NumPadMinus,
        glfw::Key::KpAdd => Key::NumPadPlus,
        glfw::Key::KpEnter => Key::NumPadEnter,
        glfw::Key::KpEqual => Key::NumPadEquals,
        glfw::Key::LeftShift => Key::LShift,
        glfw::Key::LeftControl => Key::LCtrl,
        glfw::Key::LeftAlt => Key::LAlt,
        glfw::Key::LeftSuper => Key::LGui,
        glfw::Key::RightShift => Key::RShift,
        glfw::Key::RightControl => Key::RCtrl,
        glfw::Key::RightAlt => Key::RAlt,
        glfw::Key::RightSuper => Key::RGui,
        // Map to backslash?
        glfw::Key::GraveAccent => Key::Unknown,
        glfw::Key::Home => Key::Home,
        glfw::Key::Insert => Key::Insert,
        glfw::Key::Left => Key::Left,
        glfw::Key::LeftBracket => Key::LeftBracket,
        glfw::Key::Menu => Key::Menu,
        glfw::Key::Minus => Key::Minus,
        glfw::Key::NumLock => Key::NumLockClear,
        glfw::Key::PageDown => Key::PageDown,
        glfw::Key::PageUp => Key::PageUp,
        glfw::Key::Pause => Key::Pause,
        glfw::Key::Period => Key::Period,
        glfw::Key::PrintScreen => Key::PrintScreen,
        glfw::Key::Right => Key::Right,
        glfw::Key::RightBracket => Key::RightBracket,
        glfw::Key::ScrollLock => Key::ScrollLock,
        glfw::Key::Semicolon => Key::Semicolon,
        glfw::Key::Slash => Key::Slash,
        glfw::Key::Space => Key::Space,
        glfw::Key::Tab => Key::Tab,
        glfw::Key::Up => Key::Up,
        glfw::Key::World1 => Key::Unknown,
        glfw::Key::World2 => Key::Unknown,
        // _ => keyboard::Unknown,
    }
}

fn glfw_map_mouse(mouse_button: glfw::MouseButton) -> MouseButton {
    match mouse_button {
        glfw::MouseButton::Button1 => MouseButton::Left,
        glfw::MouseButton::Button2 => MouseButton::Right,
        glfw::MouseButton::Button3 => MouseButton::Middle,
        glfw::MouseButton::Button4 => MouseButton::X1,
        glfw::MouseButton::Button5 => MouseButton::X2,
        glfw::MouseButton::Button6 => MouseButton::Button6,
        glfw::MouseButton::Button7 => MouseButton::Button7,
        glfw::MouseButton::Button8 => MouseButton::Button8,
    }
}
<commit_msg>Impl OpenGLWindow, reexport OpenGL.<commit_after>#![deny(missing_docs)]

//! A GLFW window back-end for the Piston game engine.

extern crate glfw;
extern crate gl;
extern crate window;
extern crate shader_version;
extern crate input;
#[macro_use]
extern crate quack;

// External crates.
use std::sync::mpsc::Receiver;
use std::collections::VecDeque;
use quack::Associative;
use glfw::Context;
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
    Motion,
};
use window::{
    OpenGLWindow,
    ProcAddress,
    WindowSettings,
    ShouldClose,
    Size,
    PollEvent,
    SwapBuffers,
    CaptureCursor,
    DrawSize,
    Title,
    ExitOnEsc
};

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlfwWindow {
    /// The window.
    pub window: glfw::Window,
    /// Receives events from window.
    events: Receiver<(f64, glfw::WindowEvent)>,
    /// GLFW context.
    pub glfw: glfw::Glfw,
    event_queue: VecDeque<input::Input>,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
}

impl GlfwWindow {
    /// Create a new game window from an existing GLFW window.
    pub fn from_pieces(mut win: glfw::Window, glfw: glfw::Glfw,
                       events: Receiver<(f64, glfw::WindowEvent)>,
                       exit_on_esc: bool) -> GlfwWindow {
        win.set_all_polling(true);
        win.make_current();
        let title = "<unknown window title, created from_pieces>";
        GlfwWindow {
            window: win,
            events: events,
            glfw: glfw,
            exit_on_esc: exit_on_esc,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: title.to_string(),
        }
    }

    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlfwWindow {
        use glfw::Context;

        // Initialize GLFW.
        let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

        let (major, minor) = opengl.get_major_minor();

        // Make sure we have the right GL version.
        glfw.window_hint(glfw::WindowHint::ContextVersion(major as u32, minor as u32));
        if opengl >= OpenGL::_3_0 {
            glfw.window_hint(glfw::WindowHint::OpenglForwardCompat(true));
        }
        if opengl >= OpenGL::_3_2 {
            glfw.window_hint(glfw::WindowHint::OpenglProfile(glfw::OpenGlProfileHint::Core));
        }
        glfw.window_hint(glfw::WindowHint::Samples(settings.samples as u32));

        // Create GLFW window.
        let (mut window, events) = glfw.create_window(
            settings.size[0],
            settings.size[1],
            &settings.title, glfw::WindowMode::Windowed
        ).expect("Failed to create GLFW window.");
        window.set_all_polling(true);
        window.make_current();

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s));

        GlfwWindow {
            window: window,
            events: events,
            glfw: glfw,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: settings.title,
            exit_on_esc: settings.exit_on_esc,
        }
    }

    fn flush_messages(&mut self) {
        if self.event_queue.len() != 0 {
            return;
        }

        self.glfw.poll_events();
        for (_, event) in glfw::flush_messages(&self.events) {
            match event {
                glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _)
                if self.exit_on_esc => {
                    self.window.set_should_close(true);
                }
                glfw::WindowEvent::Char(ch) => {
                    self.event_queue.push_back(Input::Text(ch.to_string()));
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::CursorPos(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseCursor(x, y)));
                    match self.last_mouse_pos {
                        Some((lx, ly)) => {
                            self.event_queue.push_back(
                                Input::Move(Motion::MouseRelative(x - lx, y - ly))
                            )
                        }
                        None => {}
                    };
                    self.last_mouse_pos = Some((x, y));
                }
                glfw::WindowEvent::Scroll(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseScroll(x, y)));
                }
                glfw::WindowEvent::Size(w, h) => {
                    self.event_queue.push_back(Input::Resize(w as u32, h as u32));
                }
                glfw::WindowEvent::Focus(focus) => {
                    self.event_queue.push_back(Input::Focus(focus));
                }
                _ => {}
            }
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        self.flush_messages();

        if self.event_queue.len() != 0 {
            self.event_queue.pop_front()
        } else {
            None
        }
    }

    fn capture_cursor(&mut self, enabled: bool) {
        if enabled {
            self.window.set_cursor_mode(glfw::CursorMode::Disabled)
        } else {
            self.window.set_cursor_mode(glfw::CursorMode::Normal);
            self.last_mouse_pos = None;
        }
    }
}

quack! {
obj: GlfwWindow[]
get:
    fn () -> Size [] {
        let (w, h) = obj.window.get_size();
        Size([w as u32, h as u32])
    }
    fn () -> ShouldClose [] {
        ShouldClose(obj.window.should_close())
    }
    fn () -> DrawSize [] {
        let (w, h) = obj.window.get_framebuffer_size();
        DrawSize([w as u32, h as u32])
    }
    fn () -> Title [] { Title(obj.title.clone()) }
    fn () -> ExitOnEsc [] { ExitOnEsc(obj.exit_on_esc) }
set:
    fn (val: CaptureCursor) [] { obj.capture_cursor(val.0) }
    fn (val: ShouldClose) [] { obj.window.set_should_close(val.0) }
    fn (val: Title) [] { obj.window.set_title(&val.0) }
    fn (val: ExitOnEsc) [] { obj.exit_on_esc = val.0 }
action:
    fn (__: PollEvent) -> Option<Input> [] { obj.poll_event() }
    fn (__: SwapBuffers) -> () [] { obj.window.swap_buffers() }
}

impl Associative for (PollEvent, GlfwWindow) {
    type Type = Input;
}

impl OpenGLWindow for GlfwWindow {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.window.get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.window.is_current()
    }

    fn make_current(&mut self) {
        self.window.make_current()
    }
}

fn glfw_map_key(keycode: glfw::Key) -> keyboard::Key {
    use input::keyboard::Key;

    match keycode {
        glfw::Key::Num0 => Key::D0,
        glfw::Key::Num1 => Key::D1,
        glfw::Key::Num2 => Key::D2,
        glfw::Key::Num3 => Key::D3,
        glfw::Key::Num4 => Key::D4,
        glfw::Key::Num5 => Key::D5,
        glfw::Key::Num6 => Key::D6,
        glfw::Key::Num7 => Key::D7,
        glfw::Key::Num8 => Key::D8,
        glfw::Key::Num9 => Key::D9,
        glfw::Key::A => Key::A,
        glfw::Key::B => Key::B,
        glfw::Key::C => Key::C,
        glfw::Key::D => Key::D,
        glfw::Key::E => Key::E,
        glfw::Key::F => Key::F,
        glfw::Key::G => Key::G,
        glfw::Key::H => Key::H,
        glfw::Key::I => Key::I,
        glfw::Key::J => Key::J,
        glfw::Key::K => Key::K,
        glfw::Key::L => Key::L,
        glfw::Key::M => Key::M,
        glfw::Key::N => Key::N,
        glfw::Key::O => Key::O,
        glfw::Key::P => Key::P,
        glfw::Key::Q => Key::Q,
        glfw::Key::R => Key::R,
        glfw::Key::S => Key::S,
        glfw::Key::T => Key::T,
        glfw::Key::U => Key::U,
        glfw::Key::V => Key::V,
        glfw::Key::W => Key::W,
        glfw::Key::X => Key::X,
        glfw::Key::Y => Key::Y,
        glfw::Key::Z => Key::Z,
        glfw::Key::Apostrophe => Key::Unknown,
        glfw::Key::Backslash => Key::Backslash,
        glfw::Key::Backspace => Key::Backspace,
        glfw::Key::CapsLock => Key::CapsLock,
        glfw::Key::Delete => Key::Delete,
        glfw::Key::Comma => Key::Comma,
        glfw::Key::Down => Key::Down,
        glfw::Key::End => Key::End,
        glfw::Key::Enter => Key::Return,
        glfw::Key::Equal => Key::Equals,
        glfw::Key::Escape => Key::Escape,
        glfw::Key::F1 => Key::F1,
        glfw::Key::F2 => Key::F2,
        glfw::Key::F3 => Key::F3,
        glfw::Key::F4 => Key::F4,
        glfw::Key::F5 => Key::F5,
        glfw::Key::F6 => Key::F6,
        glfw::Key::F7 => Key::F7,
        glfw::Key::F8 => Key::F8,
        glfw::Key::F9 => Key::F9,
        glfw::Key::F10 => Key::F10,
        glfw::Key::F11 => Key::F11,
        glfw::Key::F12 => Key::F12,
        glfw::Key::F13 => Key::F13,
        glfw::Key::F14 => Key::F14,
        glfw::Key::F15 => Key::F15,
        glfw::Key::F16 => Key::F16,
        glfw::Key::F17 => Key::F17,
        glfw::Key::F18 => Key::F18,
        glfw::Key::F19 => Key::F19,
        glfw::Key::F20 => Key::F20,
        glfw::Key::F21 => Key::F21,
        glfw::Key::F22 => Key::F22,
        glfw::Key::F23 => Key::F23,
        glfw::Key::F24 => Key::F24,
        // Possibly next code.
        glfw::Key::F25 => Key::Unknown,
        glfw::Key::Kp0 => Key::NumPad0,
        glfw::Key::Kp1 => Key::NumPad1,
        glfw::Key::Kp2 => Key::NumPad2,
        glfw::Key::Kp3 => Key::NumPad3,
        glfw::Key::Kp4 => Key::NumPad4,
        glfw::Key::Kp5 => Key::NumPad5,
        glfw::Key::Kp6 => Key::NumPad6,
        glfw::Key::Kp7 => Key::NumPad7,
        glfw::Key::Kp8 => Key::NumPad8,
        glfw::Key::Kp9 => Key::NumPad9,
        glfw::Key::KpDecimal => Key::NumPadDecimal,
        glfw::Key::KpDivide => Key::NumPadDivide,
        glfw::Key::KpMultiply => Key::NumPadMultiply,
        glfw::Key::KpSubtract => Key::NumPadMinus,
        glfw::Key::KpAdd => Key::NumPadPlus,
        glfw::Key::KpEnter => Key::NumPadEnter,
        glfw::Key::KpEqual => Key::NumPadEquals,
        glfw::Key::LeftShift => Key::LShift,
        glfw::Key::LeftControl => Key::LCtrl,
        glfw::Key::LeftAlt => Key::LAlt,
        glfw::Key::LeftSuper => Key::LGui,
        glfw::Key::RightShift => Key::RShift,
        glfw::Key::RightControl => Key::RCtrl,
        glfw::Key::RightAlt => Key::RAlt,
        glfw::Key::RightSuper => Key::RGui,
        // Map to backslash?
        glfw::Key::GraveAccent => Key::Unknown,
        glfw::Key::Home => Key::Home,
        glfw::Key::Insert => Key::Insert,
        glfw::Key::Left => Key::Left,
        glfw::Key::LeftBracket => Key::LeftBracket,
        glfw::Key::Menu => Key::Menu,
        glfw::Key::Minus => Key::Minus,
        glfw::Key::NumLock => Key::NumLockClear,
        glfw::Key::PageDown => Key::PageDown,
        glfw::Key::PageUp => Key::PageUp,
        glfw::Key::Pause => Key::Pause,
        glfw::Key::Period => Key::Period,
        glfw::Key::PrintScreen => Key::PrintScreen,
        glfw::Key::Right => Key::Right,
        glfw::Key::RightBracket => Key::RightBracket,
        glfw::Key::ScrollLock => Key::ScrollLock,
        glfw::Key::Semicolon => Key::Semicolon,
        glfw::Key::Slash => Key::Slash,
        glfw::Key::Space => Key::Space,
        glfw::Key::Tab => Key::Tab,
        glfw::Key::Up => Key::Up,
        glfw::Key::World1 => Key::Unknown,
        glfw::Key::World2 => Key::Unknown,
        // _ => keyboard::Unknown,
    }
}

fn glfw_map_mouse(mouse_button: glfw::MouseButton) -> MouseButton {
    match mouse_button {
        glfw::MouseButton::Button1 => MouseButton::Left,
        glfw::MouseButton::Button2 => MouseButton::Right,
        glfw::MouseButton::Button3 => MouseButton::Middle,
        glfw::MouseButton::Button4 => MouseButton::X1,
        glfw::MouseButton::Button5 => MouseButton::X2,
        glfw::MouseButton::Button6 => MouseButton::Button6,
        glfw::MouseButton::Button7 => MouseButton::Button7,
        glfw::MouseButton::Button8 => MouseButton::Button8,
    }
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::str::FromStr;

pub fn puzzle(input: &str) -> i32 {
    for line in input.lines() {
        let line = line.trim();
    }
    0
}

#[derive(Debug, PartialEq)]
pub enum Instruction {
    Copy(FromLocation, Register),
    Increment(Register),
}

impl FromStr for Instruction {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut parts = s.split_whitespace();
        match parts.next() {
            Some("cpy") => Ok(
                Instruction::Copy(
                    parts.next().ok_or("no from location")?.parse()?,
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("inc") => Ok(
                Instruction::Increment(
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            _ => unimplemented!(),
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum FromLocation {
    Integer(i32),
    Register(Register),
}

impl FromStr for FromLocation {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.parse().map(FromLocation::Integer)
                 .or_else(|_| s.parse().map(FromLocation::Register))
    }
}

#[derive(Debug, PartialEq)]
pub enum Register {
    A,
    B,
    C,
    D,
}

impl FromStr for Register {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use Register::*;
        match s {
            "a" => Ok(A),
            "b" => Ok(B),
            "c" => Ok(C),
            "d" => Ok(D),
            other => Err(format!("Unknown register {}", other).into()),
        }
    }
}

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

    #[test]
    fn parse_cpy() {
        let instr: Instruction = "cpy 41 a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Copy(FromLocation::Integer(41), Register::A)
        );
    }

    #[test]
    fn parse_cpy_register() {
        let instr: Instruction = "cpy a c".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Copy(
                FromLocation::Register(Register::A),
                Register::C,
            )
        );
    }

    #[test]
    fn parse_inc() {
        let instr: Instruction = "inc a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Increment(Register::A)
        );
    }

    #[test]
    fn sample() {
        let input = "cpy 41 a
            inc a
            inc a
            dec a
            jnz a 2
            dec a";
        assert_eq!(puzzle(input), 42);
    }
}
<commit_msg>Parse jnz<commit_after>use std::error::Error;
use std::str::FromStr;

pub fn puzzle(input: &str) -> i32 {
    for line in input.lines() {
        let line = line.trim();
    }
    0
}

#[derive(Debug, PartialEq)]
pub enum Instruction {
    Copy(FromLocation, Register),
    Increment(Register),
    Decrement(Register),
    JumpNonZero(Register, i32),
}

impl FromStr for Instruction {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut parts = s.split_whitespace();
        match parts.next() {
            Some("cpy") => Ok(
                Instruction::Copy(
                    parts.next().ok_or("no from location")?.parse()?,
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("inc") => Ok(
                Instruction::Increment(
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("dec") => Ok(
                Instruction::Decrement(
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("jnz") => Ok(
                Instruction::JumpNonZero(
                    parts.next().ok_or("no register")?.parse()?,
                    parts.next().ok_or("no offset")?.parse()?
                )
            ),
            Some(other) => Err(format!("Unknown instruction: {}", other).into()),
            None => Err("Instruction missing".into()),
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum FromLocation {
    Integer(i32),
    Register(Register),
}

impl FromStr for FromLocation {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.parse().map(FromLocation::Integer)
                 .or_else(|_| s.parse().map(FromLocation::Register))
    }
}

#[derive(Debug, PartialEq)]
pub enum Register {
    A,
    B,
    C,
    D,
}

impl FromStr for Register {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use Register::*;
        match s {
            "a" => Ok(A),
            "b" => Ok(B),
            "c" => Ok(C),
            "d" => Ok(D),
            other => Err(format!("Unknown register {}", other).into()),
        }
    }
}

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

    #[test]
    fn parse_cpy() {
        let instr: Instruction = "cpy 41 a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Copy(FromLocation::Integer(41), Register::A)
        );
    }

    #[test]
    fn parse_cpy_register() {
        let instr: Instruction = "cpy a c".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Copy(
                FromLocation::Register(Register::A),
                Register::C,
            )
        );
    }

    #[test]
    fn parse_inc() {
        let instr: Instruction = "inc a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Increment(Register::A)
        );
    }

    #[test]
    fn parse_dec() {
        let instr: Instruction = "dec a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Decrement(Register::A)
        );
    }

    #[test]
    fn parse_jnz() {
        let instr: Instruction = "jnz a 2".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::JumpNonZero(Register::A, 2)
        );
    }

    #[test]
    fn sample() {
        let input = "cpy 41 a
            inc a
            inc a
            dec a
            jnz a 2
            dec a";
        assert_eq!(puzzle(input), 42);
    }
}
<|endoftext|>


<commit_before>
pub fn puzzle(input: &str) -> u32 {
    let initial_world_state = WorldState {
        steps: 0,
        building: BuildingState {
            elevator_floor: 0,
            floors: [
                vec![
                    Component::Microchip(Element::Hydrogen),
                    Component::Microchip(Element::Lithium),
                ],
                vec![
                    Component::Generator(Element::Hydrogen),
                ],
                vec![
                    Component::Generator(Element::Lithium),
                ],
                vec![],
            ],
        }
    };
    let mut queue = vec![initial_world_state];
    while !queue.is_empty() {
        let world = queue.remove(0);
        if world.in_end_state() {
            return world.steps;
        }

        let mut valid_next_moves = world.next_moves();
        queue.append(&mut valid_next_moves);
    }

    panic!("Exhausted all possible moves without finding end condition!");
}

pub struct WorldState {
    steps: u32,
    building: BuildingState,
}

impl WorldState {
    pub fn in_end_state(&self) -> bool {
        self.building.in_end_state()
    }

    pub fn next_moves(&self) -> Vec<WorldState> {
        self.building.next_moves().into_iter().map(|b| {
            WorldState {
                steps: self.steps + 1,
                building: b,
            }
        }).collect()
    }
}

#[derive(PartialEq, Copy, Clone)]
pub enum Component {
    Microchip(Element),
    Generator(Element),
}

impl Component {
    fn is_fried(&self, others: &Vec<Component>) -> bool {
        match *self {
            Component::Generator(my_element) => {
                // There's microchip(s) that are not my element
                // and no generator that is that microchip's element
                (*others).iter().any(|&c|
                    match c {
                        Component::Microchip(e) if e != my_element && !(*others).contains(&Component::Generator(e)) => true,
                        _ => false,
                    }
                )
            },
            Component::Microchip(my_element) => {
                // There's some generator that is not my element
                (*others).iter().find(|&c| {
                    match *c {
                        Component::Generator(e) if e != my_element => true,
                        _ => false,
                    }
                }).is_some() &&
                // There is no generator that is my element
                (*others).iter().find(|&c| {
                    match *c {
                        Component::Generator(e) if e == my_element => true,
                        _ => false,
                    }
                }).is_none()
            }
        }
    }
}

#[derive(PartialEq, Copy, Clone)]
pub enum Element {
    Hydrogen,
    Lithium,
}

pub struct BuildingState {
    elevator_floor: usize,
    floors: [Vec<Component>; 4],
}

impl BuildingState {
    pub fn in_end_state(&self) -> bool {
        self.floors[0].is_empty() &&
            self.floors[1].is_empty() &&
            self.floors[2].is_empty()
    }

    pub fn next_moves(&self) -> Vec<BuildingState> {
        // TODO: actually determine valid next moves
        vec![]
    }

    pub fn has_fried_chips(&self) -> bool {
        for floor in self.floors.iter() {
            for component in floor {
                // This is doing an extra comparison to itself :shrug:
                if component.is_fried(&floor) {
                    return true
                }
            }
        }
        false
    }
}

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

    #[test]
    fn not_in_end_state() {
        let world_state = WorldState {
            steps: 0,
            building: BuildingState {
                elevator_floor: 0,
                floors: [
                    vec![
                        Component::Microchip(Element::Hydrogen),
                        Component::Microchip(Element::Lithium),
                    ],
                    vec![
                        Component::Generator(Element::Hydrogen),
                    ],
                    vec![
                        Component::Generator(Element::Lithium),
                    ],
                    vec![],
                ],
            }
        };
        assert!( ! world_state.in_end_state() );
    }

    #[test]
    fn in_end_state() {
        let world_state = WorldState {
            steps: 0,
            building: BuildingState {
                elevator_floor: 0,
                floors: [
                    vec![],
                    vec![],
                    vec![],
                    vec![
                        Component::Generator(Element::Hydrogen),
                        Component::Microchip(Element::Hydrogen),
                        Component::Microchip(Element::Lithium),
                        Component::Generator(Element::Lithium),
                    ],
                ],
            }
        };

        assert!(world_state.in_end_state());
    }

    #[test]
    fn two_microchips_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Lithium)]
            )
        )
    }

    #[test]
    fn microchip_alone_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![]
            )
        )
    }

    #[test]
    fn microchip_with_itself_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn two_generators_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Lithium)]
            )
        )
    }

    #[test]
    fn microchip_and_matching_generator_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn microchip_attached_to_matching_generator_not_fried_by_other_generator() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![
                    Component::Generator(Element::Lithium),
                    Component::Generator(Element::Hydrogen),
                ]
            )
        )
    }

    #[test]
    fn microchip_without_its_generator_with_another_generator_fried() {
        assert!(
            Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Lithium)]
            )
        )
    }

    #[test]
    fn generator_with_a_microchip_without_its_generator_fried() {
        assert!(
            Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Lithium)]
            )
        )
    }

    #[test]
    fn generator_with_a_generator_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Lithium)]
            )
        )
    }

    #[test]
    fn generator_with_its_microchip_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn generator_with_itself_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn generator_with_a_microchip_with_its_generator_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![
                    Component::Generator(Element::Lithium),
                    Component::Microchip(Element::Lithium),
                ]
            )
        )
    }

}
<commit_msg>Add a method to generate valid next floors for the elevator<commit_after>
pub fn puzzle(input: &str) -> u32 {
    let initial_world_state = WorldState {
        steps: 0,
        building: BuildingState {
            elevator_floor: 0,
            floors: [
                vec![
                    Component::Microchip(Element::Hydrogen),
                    Component::Microchip(Element::Lithium),
                ],
                vec![
                    Component::Generator(Element::Hydrogen),
                ],
                vec![
                    Component::Generator(Element::Lithium),
                ],
                vec![],
            ],
        }
    };
    let mut queue = vec![initial_world_state];
    while !queue.is_empty() {
        let world = queue.remove(0);
        if world.in_end_state() {
            return world.steps;
        }

        let mut valid_next_moves = world.next_moves();
        queue.append(&mut valid_next_moves);
    }

    panic!("Exhausted all possible moves without finding end condition!");
}

pub struct WorldState {
    steps: u32,
    building: BuildingState,
}

impl WorldState {
    pub fn in_end_state(&self) -> bool {
        self.building.in_end_state()
    }

    pub fn next_moves(&self) -> Vec<WorldState> {
        self.building.next_moves().into_iter().map(|b| {
            WorldState {
                steps: self.steps + 1,
                building: b,
            }
        }).collect()
    }
}

#[derive(PartialEq, Copy, Clone)]
pub enum Component {
    Microchip(Element),
    Generator(Element),
}

impl Component {
    fn is_fried(&self, others: &Vec<Component>) -> bool {
        match *self {
            Component::Generator(my_element) => {
                // There's microchip(s) that are not my element
                // and no generator that is that microchip's element
                (*others).iter().any(|&c|
                    match c {
                        Component::Microchip(e) if e != my_element && !(*others).contains(&Component::Generator(e)) => true,
                        _ => false,
                    }
                )
            },
            Component::Microchip(my_element) => {
                // There's some generator that is not my element
                (*others).iter().find(|&c| {
                    match *c {
                        Component::Generator(e) if e != my_element => true,
                        _ => false,
                    }
                }).is_some() &&
                // There is no generator that is my element
                (*others).iter().find(|&c| {
                    match *c {
                        Component::Generator(e) if e == my_element => true,
                        _ => false,
                    }
                }).is_none()
            }
        }
    }
}

#[derive(PartialEq, Copy, Clone)]
pub enum Element {
    Hydrogen,
    Lithium,
}

pub struct BuildingState {
    elevator_floor: usize,
    floors: [Vec<Component>; 4],
}

impl BuildingState {
    pub fn in_end_state(&self) -> bool {
        self.floors[0].is_empty() &&
            self.floors[1].is_empty() &&
            self.floors[2].is_empty()
    }

    pub fn next_floors(&self) -> Vec<usize> {
        match self.elevator_floor {
            0 => vec![1],
            1 => vec![0, 2],
            2 => vec![1, 3],
            3 => vec![2],
            other => panic!("How did you get on floor {}, elevator?", other),
        }
    }

    pub fn next_moves(&self) -> Vec<BuildingState> {
        // TODO: actually determine valid next moves
        vec![]
    }

    pub fn has_fried_chips(&self) -> bool {
        for floor in self.floors.iter() {
            for component in floor {
                // This is doing an extra comparison to itself :shrug:
                if component.is_fried(&floor) {
                    return true
                }
            }
        }
        false
    }
}

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

    #[test]
    fn not_in_end_state() {
        let world_state = WorldState {
            steps: 0,
            building: BuildingState {
                elevator_floor: 0,
                floors: [
                    vec![
                        Component::Microchip(Element::Hydrogen),
                        Component::Microchip(Element::Lithium),
                    ],
                    vec![
                        Component::Generator(Element::Hydrogen),
                    ],
                    vec![
                        Component::Generator(Element::Lithium),
                    ],
                    vec![],
                ],
            }
        };
        assert!( ! world_state.in_end_state() );
    }

    #[test]
    fn in_end_state() {
        let world_state = WorldState {
            steps: 0,
            building: BuildingState {
                elevator_floor: 0,
                floors: [
                    vec![],
                    vec![],
                    vec![],
                    vec![
                        Component::Generator(Element::Hydrogen),
                        Component::Microchip(Element::Hydrogen),
                        Component::Microchip(Element::Lithium),
                        Component::Generator(Element::Lithium),
                    ],
                ],
            }
        };

        assert!(world_state.in_end_state());
    }

    #[test]
    fn two_microchips_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Lithium)]
            )
        )
    }

    #[test]
    fn microchip_alone_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![]
            )
        )
    }

    #[test]
    fn microchip_with_itself_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn two_generators_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Lithium)]
            )
        )
    }

    #[test]
    fn microchip_and_matching_generator_not_fried() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn microchip_attached_to_matching_generator_not_fried_by_other_generator() {
        assert!(
            ! Component::Microchip(Element::Hydrogen).is_fried(
                &vec![
                    Component::Generator(Element::Lithium),
                    Component::Generator(Element::Hydrogen),
                ]
            )
        )
    }

    #[test]
    fn microchip_without_its_generator_with_another_generator_fried() {
        assert!(
            Component::Microchip(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Lithium)]
            )
        )
    }

    #[test]
    fn generator_with_a_microchip_without_its_generator_fried() {
        assert!(
            Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Lithium)]
            )
        )
    }

    #[test]
    fn generator_with_a_generator_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Lithium)]
            )
        )
    }

    #[test]
    fn generator_with_its_microchip_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Microchip(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn generator_with_itself_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![Component::Generator(Element::Hydrogen)]
            )
        )
    }

    #[test]
    fn generator_with_a_microchip_with_its_generator_not_fried() {
        assert!(
            ! Component::Generator(Element::Hydrogen).is_fried(
                &vec![
                    Component::Generator(Element::Lithium),
                    Component::Microchip(Element::Lithium),
                ]
            )
        )
    }

}
<|endoftext|>


<commit_before>//! A concurrent work-stealing deque.
//!
//! This data structure is most commonly used in schedulers. The typical setup involves a number of
//! threads where each thread has its own deque containing tasks. A thread may push tasks into its
//! deque as well as pop tasks from it. Once it runs out of tasks, it may steal some from other
//! threads to help complete tasks more quickly. Therefore, work-stealing deques supports three
//! essential operations: *push*, *pop*, and *steal*.
//!
//! # Types of deques
//!
//! There are two types of deques, differing only in which order tasks get pushed and popped. The
//! two task ordering strategies are:
//!
//! * First-in first-out (FIFO)
//! * Last-in first-out (LIFO)
//!
//! A deque is a buffer with two ends, front and back. In a FIFO deque, tasks are pushed into the
//! back, popped from the front, and stolen from the front. However, in a LIFO deque, tasks are
//! popped from the back instead - that is the only difference.
//!
//! # Workers and stealers
//!
//! There are two functions that construct a deque: [`fifo`] and [`lifo`]. These functions return a
//! [`Worker`] and a [`Stealer`]. The thread which owns the deque is usually called *worker*, while
//! all other threads are *stealers*.
//!
//! [`Worker`] is able to push and pop tasks. It cannot be shared among multiple threads - only
//! one thread owns it.
//!
//! [`Stealer`] can only steal tasks. It can be shared among multiple threads by reference or by
//! cloning. Cloning a [`Stealer`] simply creates another one associated with the same deque.
//!
//! # Examples
//!
//! ```
//! use crossbeam_deque as deque;
//! use std::thread;
//!
//! // Create a LIFO deque.
//! let (w, s) = deque::lifo();
//!
//! // Push several elements into the back.
//! w.push(1);
//! w.push(2);
//! w.push(3);
//!
//! // This is a LIFO deque, which means an element is popped from the back.
//! // If it was a FIFO deque, `w.pop()` would return `Some(1)`.
//! assert_eq!(w.pop(), Some(3));
//!
//! // Create a stealer thread.
//! thread::spawn(move || {
//!     assert_eq!(s.steal(), Some(1));
//!     assert_eq!(s.steal(), Some(2));
//! }).join().unwrap();
//! ```
//!
//! [`Worker`]: struct.Worker.html
//! [`Stealer`]: struct.Stealer.html
//! [`fifo`]: fn.fifo.html
//! [`lifo`]: fn.lifo.html

extern crate crossbeam_epoch as epoch;
extern crate crossbeam_utils as utils;

use std::fmt;

mod fifo;
mod lifo;

/// Creates a work-stealing deque with the first-in first-out strategy.
///
/// Elements are pushed into the back, popped from the front, and stolen from the front. In other
/// words, the worker side behaves as a FIFO queue.
///
/// # Examples
///
/// ```
/// use crossbeam_deque as deque;
///
/// let (w, s) = deque::fifo::<i32>();
/// w.push(1);
/// w.push(2);
/// w.push(3);
///
/// assert_eq!(s.steal(), Some(1));
/// assert_eq!(w.pop(), Some(2));
/// assert_eq!(w.pop(), Some(3));
/// ```
pub fn fifo<T>() -> (Worker<T>, Stealer<T>) {
    let (w, s) = fifo::new();
    let w = Worker { flavor: WorkerFlavor::Fifo(w) };
    let s = Stealer { flavor: StealerFlavor::Fifo(s) };
    (w, s)
}

/// Creates a work-stealing deque with the last-in first-out strategy.
///
/// Elements are pushed into the back, popped from the back, and stolen from the front. In other
/// words, the worker side behaves as a LIFO stack.
///
/// # Examples
///
/// ```
/// use crossbeam_deque as deque;
///
/// let (w, s) = deque::lifo::<i32>();
/// w.push(1);
/// w.push(2);
/// w.push(3);
///
/// assert_eq!(s.steal(), Some(1));
/// assert_eq!(w.pop(), Some(3));
/// assert_eq!(w.pop(), Some(2));
/// ```
pub fn lifo<T>() -> (Worker<T>, Stealer<T>) {
    let (w, s) = lifo::new();
    let w = Worker { flavor: WorkerFlavor::Lifo(w) };
    let s = Stealer { flavor: StealerFlavor::Lifo(s) };
    (w, s)
}

enum WorkerFlavor<T> {
    Fifo(fifo::Worker<T>),
    Lifo(lifo::Worker<T>),
}

/// The worker side of a deque.
///
/// Workers push elements into the back and pop elements depending on the strategy:
///
/// * In FIFO deques, elements are popped from the front.
/// * In LIFO deques, elements are popped from the back.
///
/// A deque has only one worker. Workers are not intended to be shared among multiple threads.
pub struct Worker<T> {
    flavor: WorkerFlavor<T>,
}

unsafe impl<T: Send> Send for Worker<T> {}

impl<T> Worker<T> {
    /// Returns `true` if the deque is empty.
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, _) = deque::lifo();
    /// assert!(w.is_empty());
    /// w.push(1);
    /// assert!(!w.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        match &self.flavor {
            WorkerFlavor::Fifo(flavor) => flavor.is_empty(),
            WorkerFlavor::Lifo(flavor) => flavor.is_empty(),
        }
    }

    /// Pushes an element into the back of the deque.
    ///
    /// # Examples
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, _) = deque::lifo();
    /// w.push(1);
    /// w.push(2);
    /// ```
    pub fn push(&self, value: T) {
        match &self.flavor {
            WorkerFlavor::Fifo(flavor) => flavor.push(value),
            WorkerFlavor::Lifo(flavor) => flavor.push(value),
        }
    }

    /// Pops an element from the deque.
    ///
    /// Which end of the deque is used depends on the strategy:
    ///
    /// * If this is a FIFO deque, an element is popped from the front.
    /// * If this is a LIFO deque, an element is popped from the back.
    ///
    /// # Examples
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, _) = deque::fifo();
    /// w.push(1);
    /// w.push(2);
    ///
    /// assert_eq!(w.pop(), Some(1));
    /// assert_eq!(w.pop(), Some(2));
    /// assert_eq!(w.pop(), None);
    /// ```
    pub fn pop(&self) -> Option<T> {
        match &self.flavor {
            WorkerFlavor::Fifo(flavor) => flavor.pop(),
            WorkerFlavor::Lifo(flavor) => flavor.pop(),
        }
    }
}

impl<T> fmt::Debug for Worker<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Worker {{ ... }}")
    }
}

enum StealerFlavor<T> {
    Fifo(fifo::Stealer<T>),
    Lifo(lifo::Stealer<T>),
}

/// The stealer side of a deque.
///
/// Stealers can only steal elements from the front of the deque.
///
/// Stealers are cloneable so that they can be easily shared among multiple threads.
pub struct Stealer<T> {
    flavor: StealerFlavor<T>,
}

unsafe impl<T: Send> Send for Stealer<T> {}
unsafe impl<T: Send> Sync for Stealer<T> {}

impl<T> Stealer<T> {
    /// Returns `true` if the deque is empty.
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, s) = deque::lifo();
    /// assert!(s.is_empty());
    /// w.push(1);
    /// assert!(!s.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        match &self.flavor {
            StealerFlavor::Fifo(flavor) => flavor.is_empty(),
            StealerFlavor::Lifo(flavor) => flavor.is_empty(),
        }
    }

    /// Steals an element from the front of the deque.
    ///
    /// # Examples
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, s) = deque::lifo();
    /// w.push(1);
    /// w.push(2);
    ///
    /// assert_eq!(s.steal(), Some(1));
    /// assert_eq!(s.steal(), Some(2));
    /// assert_eq!(s.steal(), None);
    /// ```
    pub fn steal(&self) -> Option<T> {
        match &self.flavor {
            StealerFlavor::Fifo(flavor) => flavor.steal(),
            StealerFlavor::Lifo(flavor) => flavor.steal(),
        }
    }
}

impl<T> Clone for Stealer<T> {
    fn clone(&self) -> Stealer<T> {
        match &self.flavor {
            StealerFlavor::Fifo(flavor) => Stealer {
                flavor: StealerFlavor::Fifo(flavor.clone()),
            },
            StealerFlavor::Lifo(flavor) => Stealer {
                flavor: StealerFlavor::Lifo(flavor.clone()),
            },
        }
    }
}

impl<T> fmt::Debug for Stealer<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Stealer {{ ... }}")
    }
}
<commit_msg>Compatibility with Rust 1.25<commit_after>//! A concurrent work-stealing deque.
//!
//! This data structure is most commonly used in schedulers. The typical setup involves a number of
//! threads where each thread has its own deque containing tasks. A thread may push tasks into its
//! deque as well as pop tasks from it. Once it runs out of tasks, it may steal some from other
//! threads to help complete tasks more quickly. Therefore, work-stealing deques supports three
//! essential operations: *push*, *pop*, and *steal*.
//!
//! # Types of deques
//!
//! There are two types of deques, differing only in which order tasks get pushed and popped. The
//! two task ordering strategies are:
//!
//! * First-in first-out (FIFO)
//! * Last-in first-out (LIFO)
//!
//! A deque is a buffer with two ends, front and back. In a FIFO deque, tasks are pushed into the
//! back, popped from the front, and stolen from the front. However, in a LIFO deque, tasks are
//! popped from the back instead - that is the only difference.
//!
//! # Workers and stealers
//!
//! There are two functions that construct a deque: [`fifo`] and [`lifo`]. These functions return a
//! [`Worker`] and a [`Stealer`]. The thread which owns the deque is usually called *worker*, while
//! all other threads are *stealers*.
//!
//! [`Worker`] is able to push and pop tasks. It cannot be shared among multiple threads - only
//! one thread owns it.
//!
//! [`Stealer`] can only steal tasks. It can be shared among multiple threads by reference or by
//! cloning. Cloning a [`Stealer`] simply creates another one associated with the same deque.
//!
//! # Examples
//!
//! ```
//! use crossbeam_deque as deque;
//! use std::thread;
//!
//! // Create a LIFO deque.
//! let (w, s) = deque::lifo();
//!
//! // Push several elements into the back.
//! w.push(1);
//! w.push(2);
//! w.push(3);
//!
//! // This is a LIFO deque, which means an element is popped from the back.
//! // If it was a FIFO deque, `w.pop()` would return `Some(1)`.
//! assert_eq!(w.pop(), Some(3));
//!
//! // Create a stealer thread.
//! thread::spawn(move || {
//!     assert_eq!(s.steal(), Some(1));
//!     assert_eq!(s.steal(), Some(2));
//! }).join().unwrap();
//! ```
//!
//! [`Worker`]: struct.Worker.html
//! [`Stealer`]: struct.Stealer.html
//! [`fifo`]: fn.fifo.html
//! [`lifo`]: fn.lifo.html

extern crate crossbeam_epoch as epoch;
extern crate crossbeam_utils as utils;

use std::fmt;

mod fifo;
mod lifo;

/// Creates a work-stealing deque with the first-in first-out strategy.
///
/// Elements are pushed into the back, popped from the front, and stolen from the front. In other
/// words, the worker side behaves as a FIFO queue.
///
/// # Examples
///
/// ```
/// use crossbeam_deque as deque;
///
/// let (w, s) = deque::fifo::<i32>();
/// w.push(1);
/// w.push(2);
/// w.push(3);
///
/// assert_eq!(s.steal(), Some(1));
/// assert_eq!(w.pop(), Some(2));
/// assert_eq!(w.pop(), Some(3));
/// ```
pub fn fifo<T>() -> (Worker<T>, Stealer<T>) {
    let (w, s) = fifo::new();
    let w = Worker { flavor: WorkerFlavor::Fifo(w) };
    let s = Stealer { flavor: StealerFlavor::Fifo(s) };
    (w, s)
}

/// Creates a work-stealing deque with the last-in first-out strategy.
///
/// Elements are pushed into the back, popped from the back, and stolen from the front. In other
/// words, the worker side behaves as a LIFO stack.
///
/// # Examples
///
/// ```
/// use crossbeam_deque as deque;
///
/// let (w, s) = deque::lifo::<i32>();
/// w.push(1);
/// w.push(2);
/// w.push(3);
///
/// assert_eq!(s.steal(), Some(1));
/// assert_eq!(w.pop(), Some(3));
/// assert_eq!(w.pop(), Some(2));
/// ```
pub fn lifo<T>() -> (Worker<T>, Stealer<T>) {
    let (w, s) = lifo::new();
    let w = Worker { flavor: WorkerFlavor::Lifo(w) };
    let s = Stealer { flavor: StealerFlavor::Lifo(s) };
    (w, s)
}

enum WorkerFlavor<T> {
    Fifo(fifo::Worker<T>),
    Lifo(lifo::Worker<T>),
}

/// The worker side of a deque.
///
/// Workers push elements into the back and pop elements depending on the strategy:
///
/// * In FIFO deques, elements are popped from the front.
/// * In LIFO deques, elements are popped from the back.
///
/// A deque has only one worker. Workers are not intended to be shared among multiple threads.
pub struct Worker<T> {
    flavor: WorkerFlavor<T>,
}

unsafe impl<T: Send> Send for Worker<T> {}

impl<T> Worker<T> {
    /// Returns `true` if the deque is empty.
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, _) = deque::lifo();
    /// assert!(w.is_empty());
    /// w.push(1);
    /// assert!(!w.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        match self.flavor {
            WorkerFlavor::Fifo(ref flavor) => flavor.is_empty(),
            WorkerFlavor::Lifo(ref flavor) => flavor.is_empty(),
        }
    }

    /// Pushes an element into the back of the deque.
    ///
    /// # Examples
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, _) = deque::lifo();
    /// w.push(1);
    /// w.push(2);
    /// ```
    pub fn push(&self, value: T) {
        match self.flavor {
            WorkerFlavor::Fifo(ref flavor) => flavor.push(value),
            WorkerFlavor::Lifo(ref flavor) => flavor.push(value),
        }
    }

    /// Pops an element from the deque.
    ///
    /// Which end of the deque is used depends on the strategy:
    ///
    /// * If this is a FIFO deque, an element is popped from the front.
    /// * If this is a LIFO deque, an element is popped from the back.
    ///
    /// # Examples
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, _) = deque::fifo();
    /// w.push(1);
    /// w.push(2);
    ///
    /// assert_eq!(w.pop(), Some(1));
    /// assert_eq!(w.pop(), Some(2));
    /// assert_eq!(w.pop(), None);
    /// ```
    pub fn pop(&self) -> Option<T> {
        match self.flavor {
            WorkerFlavor::Fifo(ref flavor) => flavor.pop(),
            WorkerFlavor::Lifo(ref flavor) => flavor.pop(),
        }
    }
}

impl<T> fmt::Debug for Worker<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Worker {{ ... }}")
    }
}

enum StealerFlavor<T> {
    Fifo(fifo::Stealer<T>),
    Lifo(lifo::Stealer<T>),
}

/// The stealer side of a deque.
///
/// Stealers can only steal elements from the front of the deque.
///
/// Stealers are cloneable so that they can be easily shared among multiple threads.
pub struct Stealer<T> {
    flavor: StealerFlavor<T>,
}

unsafe impl<T: Send> Send for Stealer<T> {}
unsafe impl<T: Send> Sync for Stealer<T> {}

impl<T> Stealer<T> {
    /// Returns `true` if the deque is empty.
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, s) = deque::lifo();
    /// assert!(s.is_empty());
    /// w.push(1);
    /// assert!(!s.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        match self.flavor {
            StealerFlavor::Fifo(ref flavor) => flavor.is_empty(),
            StealerFlavor::Lifo(ref flavor) => flavor.is_empty(),
        }
    }

    /// Steals an element from the front of the deque.
    ///
    /// # Examples
    ///
    /// ```
    /// use crossbeam_deque as deque;
    ///
    /// let (w, s) = deque::lifo();
    /// w.push(1);
    /// w.push(2);
    ///
    /// assert_eq!(s.steal(), Some(1));
    /// assert_eq!(s.steal(), Some(2));
    /// assert_eq!(s.steal(), None);
    /// ```
    pub fn steal(&self) -> Option<T> {
        match self.flavor {
            StealerFlavor::Fifo(ref flavor) => flavor.steal(),
            StealerFlavor::Lifo(ref flavor) => flavor.steal(),
        }
    }
}

impl<T> Clone for Stealer<T> {
    fn clone(&self) -> Stealer<T> {
        match self.flavor {
            StealerFlavor::Fifo(ref flavor) => Stealer {
                flavor: StealerFlavor::Fifo(flavor.clone()),
            },
            StealerFlavor::Lifo(ref flavor) => Stealer {
                flavor: StealerFlavor::Lifo(flavor.clone()),
            },
        }
    }
}

impl<T> fmt::Debug for Stealer<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Stealer {{ ... }}")
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::vec;

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
	cont: Vec<(Kv1, Kv2)>,
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	/// Create a new empty instance of `BidirMap`
	pub fn new() -> Self {
		BidirMap{
			cont: Vec::new(),
		}
	}

	/// Clears the map, removing all entries.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.clear();
	/// assert!(a.is_empty());
	/// ```
	pub fn clear(&mut self) {
		self.cont.clear()
	}

	/// Inserts a K/V-K/V pair into the map.
	///
	/// If the map did not have this K/V-K/V pair present, `None` is returned.
	///
	/// If the map did have this K/V-K/V pair present, it's updated and the old K/V-K/V pair is returned.
	pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
		let retval =
			if self.contains_first_key(&kv1) {
				self.remove_by_first(&kv1)
			} else if self.contains_second_key(&kv2) {
				self.remove_by_second(&kv2)
			} else {
				None
			};

		self.cont.push((kv1, kv2));

		retval
	}

	/// Gets an iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// map.insert(2, "b");
	/// map.insert(3, "c");
	///
	/// for kv in map.iter() {
	/// 	println!("{}: {}", kv.0, kv.1);
	/// }
	///
	/// let first = map.iter().next().unwrap();
	/// assert_eq!(*first, (1, "a"));
	/// ```
	pub fn iter<'a>(&'a self) -> slice::Iter<'a, (Kv1, Kv2)> {
		self.cont.iter()
	}

	/// Gets a mutable iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert("a", 1);
	/// map.insert("b", 2);
	/// map.insert("c", 3);
	///
	/// // add 10 to the value if the key isn't "a"
	/// for kv in map.iter_mut() {
	/// 	if &kv.0 != &"a" {
	/// 		kv.1 += 10;
	/// 	}
	/// }
	/// ```
	pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, (Kv1, Kv2)> {
		self.cont.iter_mut()
	}

	//TODO: maybe implement keys() and values() as first_row() and second_row()?

	/// Returns the number of elements in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert_eq!(a.len(), 0);
	/// a.insert(1, "a");
	/// assert_eq!(a.len(), 1);
	/// ```
	pub fn len(&self) -> usize {
		self.cont.len()
	}

	/// Returns true if the map contains no elements.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert!(a.is_empty());
	/// a.insert(1, "a");
	/// assert!(!a.is_empty());
	/// ```
	pub fn is_empty(&self) -> bool {
		self.cont.is_empty()
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_first(&1), Some(&"a"));
	/// assert_eq!(map.get_by_first(&2), None);
	/// ```
	pub fn get_by_first<Q>(&self, key: &Q) -> Option<&Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_second(&"a"), Some(&1));
	/// assert_eq!(map.get_by_second(&"b"), None);
	/// ```
	pub fn get_by_second<Q>(&self, key: &Q) -> Option<&Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
	}

	/// Check if the map contains the first K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_first_key(&1), true);
	/// assert_eq!(map.contains_first_key(&2), false);
	/// ```
	pub fn contains_first_key<Q>(&self, key: &Q) -> bool
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.0)
	}

	/// Check if the map contains the second K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_second_key(&"a"), true);
	/// assert_eq!(map.contains_second_key(&"b"), false);
	/// ```
	pub fn contains_second_key<Q>(&self, key: &Q) -> bool
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.1)
	}

	//TODO: implement get_mut
	/*pub fn get_mut_by_first<Q>(&mut self, key: &Q) -> Option<&mut Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter_mut().find(|&mut kvs| key == kvs.0).map(|&mut kvs| &mut kvs.1)
	}
	pub fn get_mut_by_second<Q>(&mut self, key: &Q) -> Option<&mut Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter_mut().find(|&mut kvs| key == kvs.1).map(|&mut kvs| &mut kvs.0)
	}*/

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_first(&1), Some((1, "a")));
	/// assert_eq!(map.remove_by_first(&1), None);
	/// ```
	pub fn remove_by_first<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_second(&"a"), Some((1, "a")));
	/// assert_eq!(map.remove_by_second(&"b"), None);
	/// ```
	pub fn remove_by_second<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
	type Item = (Kv1, Kv2);
	type IntoIter = vec::IntoIter<Self::Item>;

	fn into_iter(self) -> Self::IntoIter {
		return self.cont.into_iter()
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
		BidirMap{
			cont: Vec::from_iter(iter),
		}
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
		self.cont.extend(iter)
	}
}
<commit_msg>Implement get_mut*<commit_after>use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::vec;

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
	cont: Vec<(Kv1, Kv2)>,
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	/// Create a new empty instance of `BidirMap`
	pub fn new() -> Self {
		BidirMap{
			cont: Vec::new(),
		}
	}

	/// Clears the map, removing all entries.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.clear();
	/// assert!(a.is_empty());
	/// ```
	pub fn clear(&mut self) {
		self.cont.clear()
	}

	/// Inserts a K/V-K/V pair into the map.
	///
	/// If the map did not have this K/V-K/V pair present, `None` is returned.
	///
	/// If the map did have this K/V-K/V pair present, it's updated and the old K/V-K/V pair is returned.
	pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
		let retval =
			if self.contains_first_key(&kv1) {
				self.remove_by_first(&kv1)
			} else if self.contains_second_key(&kv2) {
				self.remove_by_second(&kv2)
			} else {
				None
			};

		self.cont.push((kv1, kv2));

		retval
	}

	/// Gets an iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// map.insert(2, "b");
	/// map.insert(3, "c");
	///
	/// for kv in map.iter() {
	/// 	println!("{}: {}", kv.0, kv.1);
	/// }
	///
	/// let first = map.iter().next().unwrap();
	/// assert_eq!(*first, (1, "a"));
	/// ```
	pub fn iter<'a>(&'a self) -> slice::Iter<'a, (Kv1, Kv2)> {
		self.cont.iter()
	}

	/// Gets a mutable iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert("a", 1);
	/// map.insert("b", 2);
	/// map.insert("c", 3);
	///
	/// // add 10 to the value if the key isn't "a"
	/// for kv in map.iter_mut() {
	/// 	if &kv.0 != &"a" {
	/// 		kv.1 += 10;
	/// 	}
	/// }
	/// ```
	pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, (Kv1, Kv2)> {
		self.cont.iter_mut()
	}

	//TODO: maybe implement keys() and values() as first_row() and second_row()?

	/// Returns the number of elements in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert_eq!(a.len(), 0);
	/// a.insert(1, "a");
	/// assert_eq!(a.len(), 1);
	/// ```
	pub fn len(&self) -> usize {
		self.cont.len()
	}

	/// Returns true if the map contains no elements.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert!(a.is_empty());
	/// a.insert(1, "a");
	/// assert!(!a.is_empty());
	/// ```
	pub fn is_empty(&self) -> bool {
		self.cont.is_empty()
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_first(&1), Some(&"a"));
	/// assert_eq!(map.get_by_first(&2), None);
	/// ```
	pub fn get_by_first<Q>(&self, key: &Q) -> Option<&Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_second(&"a"), Some(&1));
	/// assert_eq!(map.get_by_second(&"b"), None);
	/// ```
	pub fn get_by_second<Q>(&self, key: &Q) -> Option<&Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
	}

	/// Check if the map contains the first K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_first_key(&1), true);
	/// assert_eq!(map.contains_first_key(&2), false);
	/// ```
	pub fn contains_first_key<Q>(&self, key: &Q) -> bool
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.0)
	}

	/// Check if the map contains the second K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_second_key(&"a"), true);
	/// assert_eq!(map.contains_second_key(&"b"), false);
	/// ```
	pub fn contains_second_key<Q>(&self, key: &Q) -> bool
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.1)
	}

	/// Returns a mutable reference to the second K/V corresponding to the first K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// if let Some(x) = map.get_mut_by_first(&1) {
	///     *x = "b";
	/// }
	/// assert_eq!(map.get_by_first(&1), Some(&"b"));
	/// ```
	pub fn get_mut_by_first<Q>(&mut self, key: &Q) -> Option<&mut Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|ref kvs| *key == kvs.0).and_then(|ref kvs| {
			Some(unsafe { &mut *(((&kvs.1) as *const Kv2) as *mut Kv2) })  // This *should* be safe, we're casting &Kv2 to &mut Kv2 from a mutable context
			                                                               // Using mutables all the way wouldn't work for the life of me.
		})
	}

	/// Returns a mutable reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// if let Some(x) = map.get_mut_by_second(&"a") {
	///     *x = 2;
	/// }
	/// assert_eq!(map.get_by_second(&"a"), Some(&2));
	/// ```
	pub fn get_mut_by_second<Q>(&mut self, key: &Q) -> Option<&mut Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|ref kvs| *key == kvs.1).and_then(|ref kvs| {
			Some(unsafe { &mut *(((&kvs.0) as *const Kv1) as *mut Kv1) })  // This *should* be safe, we're casting &Kv1 to &mut Kv1 from a mutable context
			                                                               // Using mutables all the way wouldn't work for the life of me.
		})
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_first(&1), Some((1, "a")));
	/// assert_eq!(map.remove_by_first(&1), None);
	/// ```
	pub fn remove_by_first<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_second(&"a"), Some((1, "a")));
	/// assert_eq!(map.remove_by_second(&"b"), None);
	/// ```
	pub fn remove_by_second<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
	type Item = (Kv1, Kv2);
	type IntoIter = vec::IntoIter<Self::Item>;

	fn into_iter(self) -> Self::IntoIter {
		return self.cont.into_iter()
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
		BidirMap{
			cont: Vec::from_iter(iter),
		}
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
		self.cont.extend(iter)
	}
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

extern crate mio;
extern crate lifeguard;

use std::result::Result;

use mio::{Evented};
use mio::util::Slab;

use lifeguard::{Pool, Recycleable, Recycled};

pub struct BytesConsumed(usize);
pub struct BytesProduced(usize);

pub enum DecodingError {
  InvalidFrame(BytesConsumed),
  IncompleteFrame
}

pub enum EncodingError {
  InvalidFrame,
  InsufficientBufferSize
}

pub struct DecodedFrame<F> {
  frame: F,
  bytes_consumed: BytesConsumed
}

pub struct EncodedFrame<F> {
  frame: F,
  bytes_produced: BytesProduced
}

pub type DecodingResult<F> = Result<Option<DecodedFrame<F>>, DecodingError>;
pub type EncodingResult<F> = Result<Option<EncodedFrame<F>>, EncodingError>;

pub trait Codec<F> {
  fn encode(&mut self, &mut [u8]) -> EncodingResult<F>;
  fn decode(&mut self, &[u8]) -> DecodingResult<F>;
}

const BUFFER_SIZE : usize = 16 * 1_024;
const NUMBER_OF_POOLED_BUFFERS: usize = 16 * 1_024;

#[derive(Debug)]
struct Buffer {
  pub bytes: Vec<u8>
}

impl Buffer {
  pub fn new() -> Buffer {
    Buffer {
      bytes: Vec::with_capacity(BUFFER_SIZE)
    }
  }

  pub fn len(&self) -> usize {
    self.bytes.len()
  }

  pub fn restack(&mut self, num_consumed : usize) {
    let num_in_use = self.len();
    // If nothing was consumed, we're done
    if num_consumed == 0 {
      return;
    }
    // If everything was consumed, empty the buffer and return
    if num_consumed == num_in_use {
      self.bytes.reset();
      return;
    }
    // Otherwise, shift the remaining bytes as far left as possible
    // [ 0, 1, 2, 3, 4, 5 ]
    println!("num_in_use  : {}", num_in_use);
    println!("num_consumed: {}", num_consumed);
    for i in num_consumed..num_in_use {
      let (left, right) = self.bytes.split_at_mut(i);
      println!("i={}, left={:?}, right={:?}", i, left, right);
      left[i-num_consumed] = right[0];
    }
    self.bytes.truncate(num_in_use - num_consumed);
  }
}

impl Recycleable for Buffer {
  fn new() -> Buffer {
    Buffer::new()
  }

  fn reset(&mut self) {
    self.bytes.reset();
  }
}

pub struct ByteStream<E> where E: Evented {
  stream: E,
  buffer: Option<Buffer>
}

pub struct StreamManager<E> where E: Evented {
  streams: Slab<E>
}

#[test]
fn test_restack() {
  let mut buffer : Buffer = Buffer::new();
  buffer.bytes.extend(&[0u8, 1, 2, 3, 4, 5]);
  println!("Buffer: {:?}", buffer);
  assert_eq!(6, buffer.len());
  buffer.restack(3);
  assert_eq!(3, buffer.len());
  assert_eq!(buffer.bytes, &[3, 4, 5]);
}

#[test]
fn test_restack_nothing_consumed() {
  let mut buffer : Buffer = Buffer::new();
  buffer.bytes.extend(&[0u8, 1, 2, 3, 4, 5]);
  println!("Buffer: {:?}", buffer);
  assert_eq!(6, buffer.len());
  buffer.restack(0);
  assert_eq!(6, buffer.len());
  assert_eq!(buffer.bytes, &[0, 1, 2, 3, 4, 5]);
}

#[test]
fn test_restack_everything_consumed() {
  let mut buffer : Buffer = Buffer::new();
  buffer.bytes.extend(&[0u8, 1, 2, 3, 4, 5]);
  println!("Buffer: {:?}", buffer);
  assert_eq!(6, buffer.len());
  buffer.restack(6);
  assert_eq!(0, buffer.len());
  assert_eq!(buffer.bytes, &[]);
}
<commit_msg>Extend buffer, some additions to StreamManager.<commit_after>#![allow(dead_code)]

extern crate mio;
extern crate lifeguard;

use std::result::Result;

use mio::{Evented, EventLoop, Handler};
use mio::util::Slab;

use lifeguard::{Pool, Recycleable, Recycled};

pub struct BytesConsumed(usize);
pub struct BytesProduced(usize);

pub enum DecodingError {
  InvalidFrame(BytesConsumed),
  IncompleteFrame
}

pub enum EncodingError {
  InvalidFrame,
  InsufficientBufferSize
}

pub struct DecodedFrame<F> {
  frame: F,
  bytes_consumed: BytesConsumed
}

pub struct EncodedFrame<F> {
  frame: F,
  bytes_produced: BytesProduced
}

pub type DecodingResult<F> = Result<Option<DecodedFrame<F>>, DecodingError>;
pub type EncodingResult<F> = Result<Option<EncodedFrame<F>>, EncodingError>;

pub trait Codec<F> {
  fn encode(&mut self, &mut [u8]) -> EncodingResult<F>;
  fn decode(&mut self, &[u8]) -> DecodingResult<F>;
}

const BUFFER_SIZE : usize = 16 * 1_024;

#[derive(Debug)]
struct Buffer {
  bytes: Vec<u8>
}

impl Buffer {
  pub fn new() -> Buffer {
    Buffer {
      bytes: Vec::with_capacity(BUFFER_SIZE)
    }
  }

  pub fn bytes(&self) -> &[u8] {
    &self.bytes
  }

  pub fn len(&self) -> usize {
    self.bytes.len()
  }

  pub fn restack(&mut self, num_consumed : usize) {
    let num_in_use = self.len();
    // If nothing was consumed, we're done
    if num_consumed == 0 {
      return;
    }
    // If everything was consumed, empty the buffer and return
    if num_consumed == num_in_use {
      self.bytes.reset();
      return;
    }
    // Otherwise, shift the remaining bytes as far left as possible
    // [ 0, 1, 2, 3, 4, 5 ]
    println!("num_in_use  : {}", num_in_use);
    println!("num_consumed: {}", num_consumed);
    for i in num_consumed..num_in_use {
      let (left, right) = self.bytes.split_at_mut(i);
      println!("i={}, left={:?}, right={:?}", i, left, right);
      left[i-num_consumed] = right[0];
    }
    self.bytes.truncate(num_in_use - num_consumed);
  }

  pub fn extend(&mut self, bytes: &[u8]){
    self.bytes.extend(bytes)
  }
}

impl Recycleable for Buffer {
  fn new() -> Buffer {
    Buffer::new()
  }

  fn reset(&mut self) {
    self.bytes.reset();
  }
}

pub struct ByteStream<E> where E: Evented {
  stream: E,
  buffer: Option<Buffer>
}

pub struct IoHandler {
  dummy: usize
}

impl Handler for IoHandler {
  type Timeout = ();
  type Message = ();
}

const NUMBER_OF_POOLED_BUFFERS: usize = 16 * 1_024;

pub struct StreamManager<E> where E: Evented {
  streams: Slab<E>,
  event_loop: EventLoop<IoHandler>,
  buffer_pool: Pool<Buffer>
}

impl <E> StreamManager<E> where E: Evented {

}

#[test]
fn test_restack() {
  let mut buffer : Buffer = Buffer::new();
  buffer.extend(&[0u8, 1, 2, 3, 4, 5]);
  println!("Buffer: {:?}", buffer);
  assert_eq!(6, buffer.len());
  buffer.restack(3);
  assert_eq!(3, buffer.len());
  assert_eq!(buffer.bytes(), &[3, 4, 5]);
}

#[test]
fn test_restack_nothing_consumed() {
  let mut buffer : Buffer = Buffer::new();
  buffer.extend(&[0u8, 1, 2, 3, 4, 5]);
  println!("Buffer: {:?}", buffer);
  assert_eq!(6, buffer.len());
  buffer.restack(0);
  assert_eq!(6, buffer.len());
  assert_eq!(buffer.bytes(), &[0, 1, 2, 3, 4, 5]);
}

#[test]
fn test_restack_everything_consumed() {
  let mut buffer : Buffer = Buffer::new();
  buffer.extend(&[0u8, 1, 2, 3, 4, 5]);
  println!("Buffer: {:?}", buffer);
  assert_eq!(6, buffer.len());
  buffer.restack(6);
  assert_eq!(0, buffer.len());
  assert_eq!(buffer.bytes(), &[]);
}
<|endoftext|>