<commit_before>#![cfg(target_os = "windows")]

use std::mem;
use std::ptr;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::sync::{
    Arc,
    Mutex
};
use std::sync::mpsc::Receiver;
use libc;
use {CreationError, Event, MouseCursor};
use CursorState;

use WindowAttributes;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes;
#[derive(Clone, Default)]
pub struct PlatformSpecificHeadlessBuilderAttributes;

pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};

use winapi;
use user32;
use kernel32;

mod callback;
mod event;
mod init;
mod monitor;

lazy_static! {
    static ref WAKEUP_MSG_ID: u32 = unsafe { user32::RegisterWindowMessageA("Glutin::EventID".as_ptr() as *const i8) };
}

/// Cursor
pub type Cursor = *const winapi::wchar_t;

/// Contains information about states and the window for the callback.
#[derive(Clone)]
pub struct WindowState {
    pub cursor: Cursor,
    pub cursor_state: CursorState,
    pub attributes: WindowAttributes
}

/// The Win32 implementation of the main `Window` object.
pub struct Window {
    /// Main handle for the window.
    window: WindowWrapper,

    /// Receiver for the events dispatched by the window callback.
    events_receiver: Receiver<Event>,

    /// The current window state.
    window_state: Arc<Mutex<WindowState>>,
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

/// A simple wrapper that destroys the window when it is destroyed.
// FIXME: remove `pub` (https://github.com/rust-lang/rust/issues/23585)
#[doc(hidden)]
pub struct WindowWrapper(pub winapi::HWND, pub winapi::HDC);

impl Drop for WindowWrapper {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            user32::DestroyWindow(self.0);
        }
    }
}

#[derive(Clone)]
pub struct WindowProxy {
    hwnd: winapi::HWND,
}

unsafe impl Send for WindowProxy {}
unsafe impl Sync for WindowProxy {}

impl WindowProxy {
    #[inline]
    pub fn wakeup_event_loop(&self) {
        unsafe {
            user32::PostMessageA(self.hwnd, *WAKEUP_MSG_ID, 0, 0);
        }
    }
}

impl Window {
    /// See the docs in the crate root file.
    pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes)
               -> Result<Window, CreationError>
    {
        init::new_window(window)
    }

    /// See the docs in the crate root file.
    ///
    /// Calls SetWindowText on the HWND.
    pub fn set_title(&self, text: &str) {
        let text = OsStr::new(text).encode_wide().chain(Some(0).into_iter())
                                   .collect::<Vec<_>>();

        unsafe {
            user32::SetWindowTextW(self.window.0, text.as_ptr() as winapi::LPCWSTR);
        }
    }

    #[inline]
    pub fn show(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_SHOW);
        }
    }

    #[inline]
    pub fn hide(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_HIDE);
        }
    }

    /// See the docs in the crate root file.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        use std::mem;

        let mut placement: winapi::WINDOWPLACEMENT = unsafe { mem::zeroed() };
        placement.length = mem::size_of::<winapi::WINDOWPLACEMENT>() as winapi::UINT;

        if unsafe { user32::GetWindowPlacement(self.window.0, &mut placement) } == 0 {
            return None
        }

        let ref rect = placement.rcNormalPosition;
        Some((rect.left as i32, rect.top as i32))
    }

    /// See the docs in the crate root file.
    pub fn set_position(&self, x: i32, y: i32) {
        use libc;

        unsafe {
            user32::SetWindowPos(self.window.0, ptr::null_mut(), x as libc::c_int, y as libc::c_int,
                0, 0, winapi::SWP_NOZORDER | winapi::SWP_NOSIZE);
            user32::UpdateWindow(self.window.0);
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetClientRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetWindowRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    pub fn set_inner_size(&self, x: u32, y: u32) {
        use libc;

        unsafe {
            // Calculate the outer size based upon the specified inner size
            let mut rect = winapi::RECT { top: 0, left: 0, bottom: y as winapi::LONG, right: x as winapi::LONG };
            let dw_style = user32::GetWindowLongA(self.window.0, winapi::GWL_STYLE) as winapi::DWORD;
            let b_menu = !user32::GetMenu(self.window.0).is_null() as winapi::BOOL;
            let dw_style_ex = user32::GetWindowLongA(self.window.0, winapi::GWL_EXSTYLE) as winapi::DWORD;
            user32::AdjustWindowRectEx(&mut rect, dw_style, b_menu, dw_style_ex);
            let outer_x = (rect.right - rect.left).abs() as libc::c_int;
            let outer_y = (rect.top - rect.bottom).abs() as libc::c_int;

            user32::SetWindowPos(self.window.0, ptr::null_mut(), 0, 0, outer_x, outer_y,
                winapi::SWP_NOZORDER | winapi::SWP_NOREPOSITION | winapi::SWP_NOMOVE);
            user32::UpdateWindow(self.window.0);
        }
    }

    #[inline]
    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy { hwnd: self.window.0 }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self,
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self,
        }
    }

    #[inline]
    pub fn platform_display(&self) -> *mut libc::c_void {
        // What should this return on win32?
        // It could be GetDC(NULL), but that requires a ReleaseDC()
        // to avoid leaking the DC.
        ptr::null_mut()
    }

    #[inline]
    pub fn platform_window(&self) -> *mut libc::c_void {
        self.window.0 as *mut libc::c_void
    }

    #[inline]
    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    #[inline]
    pub fn set_cursor(&self, _cursor: MouseCursor) {
        let cursor_id = match _cursor {
            MouseCursor::Arrow | MouseCursor::Default => winapi::IDC_ARROW,
            MouseCursor::Hand => winapi::IDC_HAND,
            MouseCursor::Crosshair => winapi::IDC_CROSS,
            MouseCursor::Text | MouseCursor::VerticalText => winapi::IDC_IBEAM,
            MouseCursor::NotAllowed | MouseCursor::NoDrop => winapi::IDC_NO,
            MouseCursor::EResize => winapi::IDC_SIZEWE,
            MouseCursor::NResize => winapi::IDC_SIZENS,
            MouseCursor::WResize => winapi::IDC_SIZEWE,
            MouseCursor::SResize => winapi::IDC_SIZENS,
            MouseCursor::EwResize | MouseCursor::ColResize => winapi::IDC_SIZEWE,
            MouseCursor::NsResize | MouseCursor::RowResize => winapi::IDC_SIZENS,
            MouseCursor::Wait | MouseCursor::Progress => winapi::IDC_WAIT,
            MouseCursor::Help => winapi::IDC_HELP,
            _ => winapi::IDC_ARROW, // use arrow for the missing cases.
        };

        let mut cur = self.window_state.lock().unwrap();
        cur.cursor = cursor_id;
    }

    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
        let mut current_state = self.window_state.lock().unwrap();

        let foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) };
        let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) };

        let res = match (state, current_state.cursor_state) {
            (CursorState::Normal, CursorState::Normal) => Ok(()),
            (CursorState::Hide, CursorState::Hide) => Ok(()),
            (CursorState::Grab, CursorState::Grab) => Ok(()),

            (CursorState::Hide, CursorState::Normal) => {
                current_state.cursor_state = CursorState::Hide;
                Ok(())
            },

            (CursorState::Normal, CursorState::Hide) => {
                current_state.cursor_state = CursorState::Normal;
                Ok(())
            },

            (CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => {
                unsafe {
                    let mut rect = mem::uninitialized();
                    if user32::GetClientRect(self.window.0, &mut rect) == 0 {
                        return Err(format!("GetWindowRect failed"));
                    }
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.left));
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.right));
                    if user32::ClipCursor(&rect) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Grab;
                    Ok(())
                }
            },

            (CursorState::Normal, CursorState::Grab) => {
                unsafe {
                    if user32::ClipCursor(ptr::null()) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Normal;
                    Ok(())
                }
            },

            _ => unimplemented!(),
        };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 0) };

        res
    }

    #[inline]
    pub fn hidpi_factor(&self) -> f32 {
        1.0
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        let mut point = winapi::POINT {
            x: x,
            y: y,
        };

        unsafe {
            if user32::ClientToScreen(self.window.0, &mut point) == 0 {
                return Err(());
            }

            if user32::SetCursorPos(point.x, point.y) == 0 {
                return Err(());
            }
        }

        Ok(())
    }
}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.try_recv().ok()
    }
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.recv().ok()
    }
}

impl Drop for Window {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            // we don't call MakeCurrent(0, 0) because we are not sure that the context
            // is still the current one
            user32::PostMessageW(self.window.0, winapi::WM_DESTROY, 0, 0);
        }
    }
}
<commit_msg>Remove dependency on libc when possible<commit_after>#![cfg(target_os = "windows")]

use std::mem;
use std::ptr;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::os::raw::c_int;
use std::sync::{
    Arc,
    Mutex
};
use std::sync::mpsc::Receiver;
use {CreationError, Event, MouseCursor};
use CursorState;

use WindowAttributes;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes;
#[derive(Clone, Default)]
pub struct PlatformSpecificHeadlessBuilderAttributes;

pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};

use winapi;
use user32;
use kernel32;

mod callback;
mod event;
mod init;
mod monitor;

lazy_static! {
    static ref WAKEUP_MSG_ID: u32 = unsafe { user32::RegisterWindowMessageA("Glutin::EventID".as_ptr() as *const i8) };
}

/// Cursor
pub type Cursor = *const winapi::wchar_t;

/// Contains information about states and the window for the callback.
#[derive(Clone)]
pub struct WindowState {
    pub cursor: Cursor,
    pub cursor_state: CursorState,
    pub attributes: WindowAttributes
}

/// The Win32 implementation of the main `Window` object.
pub struct Window {
    /// Main handle for the window.
    window: WindowWrapper,

    /// Receiver for the events dispatched by the window callback.
    events_receiver: Receiver<Event>,

    /// The current window state.
    window_state: Arc<Mutex<WindowState>>,
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

/// A simple wrapper that destroys the window when it is destroyed.
// FIXME: remove `pub` (https://github.com/rust-lang/rust/issues/23585)
#[doc(hidden)]
pub struct WindowWrapper(pub winapi::HWND, pub winapi::HDC);

impl Drop for WindowWrapper {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            user32::DestroyWindow(self.0);
        }
    }
}

#[derive(Clone)]
pub struct WindowProxy {
    hwnd: winapi::HWND,
}

unsafe impl Send for WindowProxy {}
unsafe impl Sync for WindowProxy {}

impl WindowProxy {
    #[inline]
    pub fn wakeup_event_loop(&self) {
        unsafe {
            user32::PostMessageA(self.hwnd, *WAKEUP_MSG_ID, 0, 0);
        }
    }
}

impl Window {
    /// See the docs in the crate root file.
    pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes)
               -> Result<Window, CreationError>
    {
        init::new_window(window)
    }

    /// See the docs in the crate root file.
    ///
    /// Calls SetWindowText on the HWND.
    pub fn set_title(&self, text: &str) {
        let text = OsStr::new(text).encode_wide().chain(Some(0).into_iter())
                                   .collect::<Vec<_>>();

        unsafe {
            user32::SetWindowTextW(self.window.0, text.as_ptr() as winapi::LPCWSTR);
        }
    }

    #[inline]
    pub fn show(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_SHOW);
        }
    }

    #[inline]
    pub fn hide(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_HIDE);
        }
    }

    /// See the docs in the crate root file.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        use std::mem;

        let mut placement: winapi::WINDOWPLACEMENT = unsafe { mem::zeroed() };
        placement.length = mem::size_of::<winapi::WINDOWPLACEMENT>() as winapi::UINT;

        if unsafe { user32::GetWindowPlacement(self.window.0, &mut placement) } == 0 {
            return None
        }

        let ref rect = placement.rcNormalPosition;
        Some((rect.left as i32, rect.top as i32))
    }

    /// See the docs in the crate root file.
    pub fn set_position(&self, x: i32, y: i32) {
        unsafe {
            user32::SetWindowPos(self.window.0, ptr::null_mut(), x as c_int, y as c_int,
                                 0, 0, winapi::SWP_NOZORDER | winapi::SWP_NOSIZE);
            user32::UpdateWindow(self.window.0);
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetClientRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetWindowRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    pub fn set_inner_size(&self, x: u32, y: u32) {
        unsafe {
            // Calculate the outer size based upon the specified inner size
            let mut rect = winapi::RECT { top: 0, left: 0, bottom: y as winapi::LONG, right: x as winapi::LONG };
            let dw_style = user32::GetWindowLongA(self.window.0, winapi::GWL_STYLE) as winapi::DWORD;
            let b_menu = !user32::GetMenu(self.window.0).is_null() as winapi::BOOL;
            let dw_style_ex = user32::GetWindowLongA(self.window.0, winapi::GWL_EXSTYLE) as winapi::DWORD;
            user32::AdjustWindowRectEx(&mut rect, dw_style, b_menu, dw_style_ex);
            let outer_x = (rect.right - rect.left).abs() as c_int;
            let outer_y = (rect.top - rect.bottom).abs() as c_int;

            user32::SetWindowPos(self.window.0, ptr::null_mut(), 0, 0, outer_x, outer_y,
                winapi::SWP_NOZORDER | winapi::SWP_NOREPOSITION | winapi::SWP_NOMOVE);
            user32::UpdateWindow(self.window.0);
        }
    }

    #[inline]
    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy { hwnd: self.window.0 }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self,
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self,
        }
    }

    #[inline]
    pub fn platform_display(&self) -> *mut ::libc::c_void {
        // What should this return on win32?
        // It could be GetDC(NULL), but that requires a ReleaseDC()
        // to avoid leaking the DC.
        ptr::null_mut()
    }

    #[inline]
    pub fn platform_window(&self) -> *mut ::libc::c_void {
        self.window.0 as *mut ::libc::c_void
    }

    #[inline]
    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    #[inline]
    pub fn set_cursor(&self, _cursor: MouseCursor) {
        let cursor_id = match _cursor {
            MouseCursor::Arrow | MouseCursor::Default => winapi::IDC_ARROW,
            MouseCursor::Hand => winapi::IDC_HAND,
            MouseCursor::Crosshair => winapi::IDC_CROSS,
            MouseCursor::Text | MouseCursor::VerticalText => winapi::IDC_IBEAM,
            MouseCursor::NotAllowed | MouseCursor::NoDrop => winapi::IDC_NO,
            MouseCursor::EResize => winapi::IDC_SIZEWE,
            MouseCursor::NResize => winapi::IDC_SIZENS,
            MouseCursor::WResize => winapi::IDC_SIZEWE,
            MouseCursor::SResize => winapi::IDC_SIZENS,
            MouseCursor::EwResize | MouseCursor::ColResize => winapi::IDC_SIZEWE,
            MouseCursor::NsResize | MouseCursor::RowResize => winapi::IDC_SIZENS,
            MouseCursor::Wait | MouseCursor::Progress => winapi::IDC_WAIT,
            MouseCursor::Help => winapi::IDC_HELP,
            _ => winapi::IDC_ARROW, // use arrow for the missing cases.
        };

        let mut cur = self.window_state.lock().unwrap();
        cur.cursor = cursor_id;
    }

    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
        let mut current_state = self.window_state.lock().unwrap();

        let foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) };
        let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) };

        let res = match (state, current_state.cursor_state) {
            (CursorState::Normal, CursorState::Normal) => Ok(()),
            (CursorState::Hide, CursorState::Hide) => Ok(()),
            (CursorState::Grab, CursorState::Grab) => Ok(()),

            (CursorState::Hide, CursorState::Normal) => {
                current_state.cursor_state = CursorState::Hide;
                Ok(())
            },

            (CursorState::Normal, CursorState::Hide) => {
                current_state.cursor_state = CursorState::Normal;
                Ok(())
            },

            (CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => {
                unsafe {
                    let mut rect = mem::uninitialized();
                    if user32::GetClientRect(self.window.0, &mut rect) == 0 {
                        return Err(format!("GetWindowRect failed"));
                    }
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.left));
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.right));
                    if user32::ClipCursor(&rect) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Grab;
                    Ok(())
                }
            },

            (CursorState::Normal, CursorState::Grab) => {
                unsafe {
                    if user32::ClipCursor(ptr::null()) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Normal;
                    Ok(())
                }
            },

            _ => unimplemented!(),
        };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 0) };

        res
    }

    #[inline]
    pub fn hidpi_factor(&self) -> f32 {
        1.0
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        let mut point = winapi::POINT {
            x: x,
            y: y,
        };

        unsafe {
            if user32::ClientToScreen(self.window.0, &mut point) == 0 {
                return Err(());
            }

            if user32::SetCursorPos(point.x, point.y) == 0 {
                return Err(());
            }
        }

        Ok(())
    }
}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.try_recv().ok()
    }
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.recv().ok()
    }
}

impl Drop for Window {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            // we don't call MakeCurrent(0, 0) because we are not sure that the context
            // is still the current one
            user32::PostMessageW(self.window.0, winapi::WM_DESTROY, 0, 0);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![allow(dead_code)]

use {Result, Error, Promise};
use private::{Event, with_current_event_loop, PromiseNode};

/// A PromiseNode that transforms the result of another PromiseNode through an application-provided
/// function (implements `then()`).
pub struct Transform<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    dependency: Box<PromiseNode<DepT>>,
    func: Func,
    error_handler: ErrorFunc,
}

impl <T, DepT, Func, ErrorFunc> Transform<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    pub fn new(dependency: Box<PromiseNode<DepT>>, func: Func, error_handler: ErrorFunc)
           -> Transform<T, DepT, Func, ErrorFunc> {
        Transform { dependency : dependency,
                    func: func, error_handler: error_handler }
    }
}

impl <T, DepT, Func, ErrorFunc> PromiseNode<T> for Transform<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        self.dependency.on_ready(event);
    }
    fn get(self: Box<Self>) -> Result<T> {
        let tmp = *self;
        let Transform {dependency, func, error_handler} = tmp;
        match dependency.get() {
            Ok(value) => {
                func(value)
            }
            Err(e) => {
                error_handler(e)
            }
        }
    }
}

/// A promise that has already been resolved to an immediate value or error.
pub struct Immediate<T> {
    result: Result<T>,
}

impl <T> Immediate<T> {
    pub fn new(result: Result<T>) -> Immediate<T> {
        Immediate { result: result }
    }
}

impl <T> PromiseNode<T> for Immediate<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        with_current_event_loop(|event_loop| {
            event_loop.arm_breadth_first(event);
        });
    }
    fn get(self: Box<Self>) -> Result<T> {
        self.result
    }
}

enum ChainState<T> {
    Step1(Box<PromiseNode<Promise<T>>>),
    Step2(Box<PromiseNode<T>>)
}

/// Promise node that reduces Promise<Promise<T>> to Promise<T>.
pub struct Chain<T> {
    state: ChainState<T>,
}

impl <T> Chain <T> {
    pub fn new(inner: Box<PromiseNode<Promise<T>>>) -> Chain<T> {
        Chain { state: ChainState::Step1(inner) }
    }
}
<commit_msg>impl PromiseNode for Chain<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![allow(dead_code)]

use {Result, Error, Promise};
use private::{Event, with_current_event_loop, OnReadyEvent, PromiseNode};

/// A PromiseNode that transforms the result of another PromiseNode through an application-provided
/// function (implements `then()`).
pub struct Transform<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    dependency: Box<PromiseNode<DepT>>,
    func: Func,
    error_handler: ErrorFunc,
}

impl <T, DepT, Func, ErrorFunc> Transform<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    pub fn new(dependency: Box<PromiseNode<DepT>>, func: Func, error_handler: ErrorFunc)
           -> Transform<T, DepT, Func, ErrorFunc> {
        Transform { dependency : dependency,
                    func: func, error_handler: error_handler }
    }
}

impl <T, DepT, Func, ErrorFunc> PromiseNode<T> for Transform<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        self.dependency.on_ready(event);
    }
    fn get(self: Box<Self>) -> Result<T> {
        let tmp = *self;
        let Transform {dependency, func, error_handler} = tmp;
        match dependency.get() {
            Ok(value) => {
                func(value)
            }
            Err(e) => {
                error_handler(e)
            }
        }
    }
}

/// A promise that has already been resolved to an immediate value or error.
pub struct Immediate<T> {
    result: Result<T>,
}

impl <T> Immediate<T> {
    pub fn new(result: Result<T>) -> Immediate<T> {
        Immediate { result: result }
    }
}

impl <T> PromiseNode<T> for Immediate<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        with_current_event_loop(|event_loop| {
            event_loop.arm_breadth_first(event);
        });
    }
    fn get(self: Box<Self>) -> Result<T> {
        self.result
    }
}

enum ChainState<T> {
    Step1(Box<PromiseNode<Promise<T>>>),
    Step2(Box<PromiseNode<T>>)
}

/// Promise node that reduces Promise<Promise<T>> to Promise<T>.
pub struct Chain<T> {
    state: ChainState<T>,
    on_ready_event: OnReadyEvent,
}

impl <T> Chain<T> {
    pub fn new(inner: Box<PromiseNode<Promise<T>>>) -> Chain<T> {

        // TODO:
        //inner.on_ready(..)

        Chain { state: ChainState::Step1(inner),
                on_ready_event: OnReadyEvent::Empty }
    }
}

impl <T> PromiseNode<T> for Chain<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        match self {
            &mut Chain { state: ChainState::Step2(ref mut inner), .. } => {
                inner.on_ready(event);
            }
            &mut Chain {on_ready_event : OnReadyEvent::AlreadyReady, .. } |
            &mut Chain {on_ready_event : OnReadyEvent::Full(_), .. } => {
                panic!("on_ready() can only be called once.");
            }
            &mut Chain {ref mut on_ready_event, .. } => {
                *on_ready_event = OnReadyEvent::Full(event);
            }
        }
    }
    fn get(self: Box<Self>) -> Result<T> {
        match self.state {
            ChainState::Step2(inner) => {
                inner.get()
            }
            _ => {
                panic!()
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::*;

use std::borrow::Borrow;
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use std::collections::{btree_map, hash_map};
use std::hash::Hash;
use std::mem::replace;

impl<T> Collection for [T] {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Ord> Collection for BinaryHeap<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Ord> Remove for BinaryHeap<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<K: Ord, V> Collection for BTreeMap<K, V> {
    type Item = (K, V);
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<K: Ord, V> Insert for BTreeMap<K, V> {
    fn append(&mut self, other: &mut Self) { self.extend(replace(other, Self::new())); }
}

impl<K: Ord, V> Remove for BTreeMap<K, V> {
    fn clear(&mut self) { self.clear(); }
}

impl<K: Ord, V> map::Map for BTreeMap<K, V> {
    type Key = K;
    type Value = V;
}

impl<K: Ord + Borrow<Q>, V, Q: ?Sized + Ord> map::Get<Q> for BTreeMap<K, V> {
    fn contains_key(&self, key: &Q) -> bool { self.contains_key(key) }
    fn get(&self, key: &Q) -> Option<&V> { self.get(key) }
    fn get_mut(&mut self, key: &Q) -> Option<&mut V> { self.get_mut(key) }
}

impl<K: Ord + Borrow<Q>, V, Q: ?Sized + Ord> map::Remove<Q> for BTreeMap<K, V> {
    fn remove(&mut self, key: &Q) -> Option<V> { self.remove(key) }
}

impl<K: Ord, V> map::Insert for BTreeMap<K, V> {
    fn insert(&mut self, key: K, value: V) -> Option<V> { self.insert(key, value) }
}

impl<'a, K: 'a + Ord, V: 'a> map::EntryMap<'a> for BTreeMap<K, V> {
    type OccupiedEntry = btree_map::OccupiedEntry<'a, K, V>;
    type VacantEntry = btree_map::VacantEntry<'a, K, V>;

    fn entry(&'a mut self, key: K) -> map::Entry<Self> {
        match self.entry(key) {
            btree_map::Entry::Occupied(e) => map::Entry::Occupied(e),
            btree_map::Entry::Vacant(e) => map::Entry::Vacant(e),
        }
    }
}

impl<'a, K: 'a + Ord, V: 'a> map::OccupiedEntry<'a> for btree_map::OccupiedEntry<'a, K, V> {
    type Map = BTreeMap<K, V>;
    fn get(&self) -> &V { self.get() }
    fn get_mut(&mut self) -> &mut V { self.get_mut() }
    fn into_mut(self) -> &'a mut V { self.into_mut() }
    fn insert(&mut self, value: V) -> V { self.insert(value) }
    fn remove(self) -> V { self.remove() }
}

impl<'a, K: 'a + Ord, V: 'a> map::VacantEntry<'a> for btree_map::VacantEntry<'a, K, V> {
    type Map = BTreeMap<K, V>;
    fn insert(self, value: V) -> &'a mut V { self.insert(value) }
}

impl<T: Ord> Collection for BTreeSet<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Ord> Insert for BTreeSet<T> {
    fn append(&mut self, other: &mut Self) { self.extend(replace(other, Self::new())); }
}

impl<T: Ord> Remove for BTreeSet<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T: Ord> set::Set for BTreeSet<T> {
    fn is_disjoint(&self, other: &Self) -> bool {
        self.is_disjoint(other)
    }

    fn is_subset(&self, other: &Self) -> bool {
        self.is_subset(other)
    }

    fn is_superset(&self, other: &Self) -> bool {
        self.is_superset(other)
    }
}

impl<T: Ord + Borrow<Q>, Q: ?Sized + Ord> set::Get<Q> for BTreeSet<T> {
    fn contains(&self, item: &Q) -> bool { self.contains(item) }
    fn get(&self, item: &Q) -> Option<&T> { self.get(item) }
}

impl<T: Ord + Borrow<Q>, Q: ?Sized + Ord> set::Remove<Q> for BTreeSet<T> {
    fn remove(&mut self, item: &Q) -> bool { self.remove(item) }
    fn take(&mut self, item: &Q) -> Option<T> { self.take(item) }
}

impl<T: Ord> set::Insert for BTreeSet<T> {
    fn insert(&mut self, item: T) -> bool { self.insert(item) }
    fn replace(&mut self, item: T) -> Option<T> { self.replace(item) }
}

impl<K: Eq + Hash, V> Collection for HashMap<K, V> {
    type Item = (K, V);
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<K: Eq + Hash, V> Insert for HashMap<K, V> {
    fn append(&mut self, other: &mut Self) { self.extend(other.drain()); }
}

impl<K: Eq + Hash, V> Remove for HashMap<K, V> {
    fn clear(&mut self) { self.clear(); }
}

impl<K: Eq + Hash, V> map::Map for HashMap<K, V> {
    type Key = K;
    type Value = V;
}

impl<K: Eq + Hash + Borrow<Q>, V, Q: ?Sized + Eq + Hash> map::Get<Q> for HashMap<K, V> {
    fn contains_key(&self, key: &Q) -> bool { self.contains_key(key) }
    fn get(&self, key: &Q) -> Option<&V> { self.get(key) }
    fn get_mut(&mut self, key: &Q) -> Option<&mut V> { self.get_mut(key) }
}

impl<K: Eq + Hash + Borrow<Q>, V, Q: ?Sized + Eq + Hash> map::Remove<Q> for HashMap<K, V> {
    fn remove(&mut self, key: &Q) -> Option<V> { self.remove(key) }
}

impl<K: Eq + Hash, V> map::Insert for HashMap<K, V> {
    fn insert(&mut self, key: K, value: V) -> Option<V> { self.insert(key, value) }
}

impl<'a, K: 'a + Eq + Hash, V: 'a> map::EntryMap<'a> for HashMap<K, V> {
    type OccupiedEntry = hash_map::OccupiedEntry<'a, K, V>;
    type VacantEntry = hash_map::VacantEntry<'a, K, V>;

    fn entry(&'a mut self, key: K) -> map::Entry<Self> {
        match self.entry(key) {
            hash_map::Entry::Occupied(e) => map::Entry::Occupied(e),
            hash_map::Entry::Vacant(e) => map::Entry::Vacant(e),
        }
    }
}

impl<'a, K: 'a + Eq + Hash, V: 'a> map::OccupiedEntry<'a> for hash_map::OccupiedEntry<'a, K, V> {
    type Map = HashMap<K, V>;
    fn get(&self) -> &V { self.get() }
    fn get_mut(&mut self) -> &mut V { self.get_mut() }
    fn into_mut(self) -> &'a mut V { self.into_mut() }
    fn insert(&mut self, value: V) -> V { self.insert(value) }
    fn remove(self) -> V { self.remove() }
}

impl<'a, K: 'a + Eq + Hash, V: 'a> map::VacantEntry<'a> for hash_map::VacantEntry<'a, K, V> {
    type Map = HashMap<K, V>;
    fn insert(self, value: V) -> &'a mut V { self.insert(value) }
}

impl<T: Eq + Hash> Collection for HashSet<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Eq + Hash> Insert for HashSet<T> {
    fn append(&mut self, other: &mut Self) { self.extend(other.drain()); }
}

impl<T: Eq + Hash> Remove for HashSet<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T: Eq + Hash> set::Set for HashSet<T> {
    fn is_disjoint(&self, other: &Self) -> bool {
        self.is_disjoint(other)
    }

    fn is_subset(&self, other: &Self) -> bool {
        self.is_subset(other)
    }

    fn is_superset(&self, other: &Self) -> bool {
        self.is_superset(other)
    }
}

impl<T: Eq + Hash + Borrow<Q>, Q: ?Sized + Eq + Hash> set::Get<Q> for HashSet<T> {
    fn contains(&self, item: &Q) -> bool { self.contains(item) }
    fn get(&self, item: &Q) -> Option<&T> { self.get(item) }
}

impl<T: Eq + Hash + Borrow<Q>, Q: ?Sized + Eq + Hash> set::Remove<Q> for HashSet<T> {
    fn remove(&mut self, item: &Q) -> bool { self.remove(item) }
    fn take(&mut self, item: &Q) -> Option<T> { self.take(item) }
}

impl<T: Eq + Hash> set::Insert for HashSet<T> {
    fn insert(&mut self, item: T) -> bool { self.insert(item) }
    fn replace(&mut self, item: T) -> Option<T> { self.replace(item) }
}

impl<T> Collection for LinkedList<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T> Remove for LinkedList<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T> Collection for Vec<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T> Remove for Vec<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T> Collection for VecDeque<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T> Remove for VecDeque<T> {
    fn clear(&mut self) { self.clear(); }
}

#[test]
fn test() {
    let chars = ['a', 'a', 'b', 'c', 'a', 'b'];

    let counts: BTreeMap<_, _> = map::count(chars.iter().cloned());
    assert_eq!(counts[&'a'], 3);
    assert_eq!(counts[&'b'], 2);
    assert_eq!(counts[&'c'], 1);

    let counts: HashMap<_, _> = map::count(chars.iter().cloned());
    assert_eq!(counts[&'a'], 3);
    assert_eq!(counts[&'b'], 2);
    assert_eq!(counts[&'c'], 1);
}
<commit_msg>Implement `Insert`<commit_after>use super::*;

use std::borrow::Borrow;
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use std::collections::{btree_map, hash_map};
use std::hash::Hash;
use std::mem::replace;

impl<T> Collection for [T] {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Ord> Collection for BinaryHeap<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Ord> Insert for BinaryHeap<T> {
    fn append(&mut self, other: &mut Self) { self.extend(other.drain()); }
}

impl<T: Ord> Remove for BinaryHeap<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<K: Ord, V> Collection for BTreeMap<K, V> {
    type Item = (K, V);
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<K: Ord, V> Insert for BTreeMap<K, V> {
    fn append(&mut self, other: &mut Self) { self.extend(replace(other, Self::new())); }
}

impl<K: Ord, V> Remove for BTreeMap<K, V> {
    fn clear(&mut self) { self.clear(); }
}

impl<K: Ord, V> map::Map for BTreeMap<K, V> {
    type Key = K;
    type Value = V;
}

impl<K: Ord + Borrow<Q>, V, Q: ?Sized + Ord> map::Get<Q> for BTreeMap<K, V> {
    fn contains_key(&self, key: &Q) -> bool { self.contains_key(key) }
    fn get(&self, key: &Q) -> Option<&V> { self.get(key) }
    fn get_mut(&mut self, key: &Q) -> Option<&mut V> { self.get_mut(key) }
}

impl<K: Ord + Borrow<Q>, V, Q: ?Sized + Ord> map::Remove<Q> for BTreeMap<K, V> {
    fn remove(&mut self, key: &Q) -> Option<V> { self.remove(key) }
}

impl<K: Ord, V> map::Insert for BTreeMap<K, V> {
    fn insert(&mut self, key: K, value: V) -> Option<V> { self.insert(key, value) }
}

impl<'a, K: 'a + Ord, V: 'a> map::EntryMap<'a> for BTreeMap<K, V> {
    type OccupiedEntry = btree_map::OccupiedEntry<'a, K, V>;
    type VacantEntry = btree_map::VacantEntry<'a, K, V>;

    fn entry(&'a mut self, key: K) -> map::Entry<Self> {
        match self.entry(key) {
            btree_map::Entry::Occupied(e) => map::Entry::Occupied(e),
            btree_map::Entry::Vacant(e) => map::Entry::Vacant(e),
        }
    }
}

impl<'a, K: 'a + Ord, V: 'a> map::OccupiedEntry<'a> for btree_map::OccupiedEntry<'a, K, V> {
    type Map = BTreeMap<K, V>;
    fn get(&self) -> &V { self.get() }
    fn get_mut(&mut self) -> &mut V { self.get_mut() }
    fn into_mut(self) -> &'a mut V { self.into_mut() }
    fn insert(&mut self, value: V) -> V { self.insert(value) }
    fn remove(self) -> V { self.remove() }
}

impl<'a, K: 'a + Ord, V: 'a> map::VacantEntry<'a> for btree_map::VacantEntry<'a, K, V> {
    type Map = BTreeMap<K, V>;
    fn insert(self, value: V) -> &'a mut V { self.insert(value) }
}

impl<T: Ord> Collection for BTreeSet<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Ord> Insert for BTreeSet<T> {
    fn append(&mut self, other: &mut Self) { self.extend(replace(other, Self::new())); }
}

impl<T: Ord> Remove for BTreeSet<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T: Ord> set::Set for BTreeSet<T> {
    fn is_disjoint(&self, other: &Self) -> bool {
        self.is_disjoint(other)
    }

    fn is_subset(&self, other: &Self) -> bool {
        self.is_subset(other)
    }

    fn is_superset(&self, other: &Self) -> bool {
        self.is_superset(other)
    }
}

impl<T: Ord + Borrow<Q>, Q: ?Sized + Ord> set::Get<Q> for BTreeSet<T> {
    fn contains(&self, item: &Q) -> bool { self.contains(item) }
    fn get(&self, item: &Q) -> Option<&T> { self.get(item) }
}

impl<T: Ord + Borrow<Q>, Q: ?Sized + Ord> set::Remove<Q> for BTreeSet<T> {
    fn remove(&mut self, item: &Q) -> bool { self.remove(item) }
    fn take(&mut self, item: &Q) -> Option<T> { self.take(item) }
}

impl<T: Ord> set::Insert for BTreeSet<T> {
    fn insert(&mut self, item: T) -> bool { self.insert(item) }
    fn replace(&mut self, item: T) -> Option<T> { self.replace(item) }
}

impl<K: Eq + Hash, V> Collection for HashMap<K, V> {
    type Item = (K, V);
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<K: Eq + Hash, V> Insert for HashMap<K, V> {
    fn append(&mut self, other: &mut Self) { self.extend(other.drain()); }
}

impl<K: Eq + Hash, V> Remove for HashMap<K, V> {
    fn clear(&mut self) { self.clear(); }
}

impl<K: Eq + Hash, V> map::Map for HashMap<K, V> {
    type Key = K;
    type Value = V;
}

impl<K: Eq + Hash + Borrow<Q>, V, Q: ?Sized + Eq + Hash> map::Get<Q> for HashMap<K, V> {
    fn contains_key(&self, key: &Q) -> bool { self.contains_key(key) }
    fn get(&self, key: &Q) -> Option<&V> { self.get(key) }
    fn get_mut(&mut self, key: &Q) -> Option<&mut V> { self.get_mut(key) }
}

impl<K: Eq + Hash + Borrow<Q>, V, Q: ?Sized + Eq + Hash> map::Remove<Q> for HashMap<K, V> {
    fn remove(&mut self, key: &Q) -> Option<V> { self.remove(key) }
}

impl<K: Eq + Hash, V> map::Insert for HashMap<K, V> {
    fn insert(&mut self, key: K, value: V) -> Option<V> { self.insert(key, value) }
}

impl<'a, K: 'a + Eq + Hash, V: 'a> map::EntryMap<'a> for HashMap<K, V> {
    type OccupiedEntry = hash_map::OccupiedEntry<'a, K, V>;
    type VacantEntry = hash_map::VacantEntry<'a, K, V>;

    fn entry(&'a mut self, key: K) -> map::Entry<Self> {
        match self.entry(key) {
            hash_map::Entry::Occupied(e) => map::Entry::Occupied(e),
            hash_map::Entry::Vacant(e) => map::Entry::Vacant(e),
        }
    }
}

impl<'a, K: 'a + Eq + Hash, V: 'a> map::OccupiedEntry<'a> for hash_map::OccupiedEntry<'a, K, V> {
    type Map = HashMap<K, V>;
    fn get(&self) -> &V { self.get() }
    fn get_mut(&mut self) -> &mut V { self.get_mut() }
    fn into_mut(self) -> &'a mut V { self.into_mut() }
    fn insert(&mut self, value: V) -> V { self.insert(value) }
    fn remove(self) -> V { self.remove() }
}

impl<'a, K: 'a + Eq + Hash, V: 'a> map::VacantEntry<'a> for hash_map::VacantEntry<'a, K, V> {
    type Map = HashMap<K, V>;
    fn insert(self, value: V) -> &'a mut V { self.insert(value) }
}

impl<T: Eq + Hash> Collection for HashSet<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T: Eq + Hash> Insert for HashSet<T> {
    fn append(&mut self, other: &mut Self) { self.extend(other.drain()); }
}

impl<T: Eq + Hash> Remove for HashSet<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T: Eq + Hash> set::Set for HashSet<T> {
    fn is_disjoint(&self, other: &Self) -> bool {
        self.is_disjoint(other)
    }

    fn is_subset(&self, other: &Self) -> bool {
        self.is_subset(other)
    }

    fn is_superset(&self, other: &Self) -> bool {
        self.is_superset(other)
    }
}

impl<T: Eq + Hash + Borrow<Q>, Q: ?Sized + Eq + Hash> set::Get<Q> for HashSet<T> {
    fn contains(&self, item: &Q) -> bool { self.contains(item) }
    fn get(&self, item: &Q) -> Option<&T> { self.get(item) }
}

impl<T: Eq + Hash + Borrow<Q>, Q: ?Sized + Eq + Hash> set::Remove<Q> for HashSet<T> {
    fn remove(&mut self, item: &Q) -> bool { self.remove(item) }
    fn take(&mut self, item: &Q) -> Option<T> { self.take(item) }
}

impl<T: Eq + Hash> set::Insert for HashSet<T> {
    fn insert(&mut self, item: T) -> bool { self.insert(item) }
    fn replace(&mut self, item: T) -> Option<T> { self.replace(item) }
}

impl<T> Collection for LinkedList<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T> Insert for LinkedList<T> {
    fn append(&mut self, other: &mut Self) {
        self.append(other);
    }
}

impl<T> Remove for LinkedList<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T> Collection for Vec<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T> Insert for Vec<T> {
    fn append(&mut self, other: &mut Self) { self.append(other); }
}

impl<T> Remove for Vec<T> {
    fn clear(&mut self) { self.clear(); }
}

impl<T> Collection for VecDeque<T> {
    type Item = T;
    fn is_empty(&self) -> bool { self.is_empty() }
    fn len(&self) -> usize { self.len() }
}

impl<T> Insert for VecDeque<T> {
    fn append(&mut self, other: &mut Self) { self.append(other); }
}

impl<T> Remove for VecDeque<T> {
    fn clear(&mut self) { self.clear(); }
}

#[test]
fn test() {
    let chars = ['a', 'a', 'b', 'c', 'a', 'b'];

    let counts: BTreeMap<_, _> = map::count(chars.iter().cloned());
    assert_eq!(counts[&'a'], 3);
    assert_eq!(counts[&'b'], 2);
    assert_eq!(counts[&'c'], 1);

    let counts: HashMap<_, _> = map::count(chars.iter().cloned());
    assert_eq!(counts[&'a'], 3);
    assert_eq!(counts[&'b'], 2);
    assert_eq!(counts[&'c'], 1);
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader, Error};
use std::path::Path;

#[derive(Debug, Copy, Clone)]
pub struct Bytes(u64);

impl Bytes {
    pub fn kibi(n: f32) -> Self { Bytes(1024*n as u64) }
    pub fn gibi(n: f32) -> Self { Bytes((1024.0f32.powi(3)*n) as u64) }

    pub fn in_gib(&self) -> f32 { (self.0 as f32)/1024.0f32.powi(3) }
}

impl From<Bytes> for usize {
    fn from(bytes: Bytes) -> Self {
        bytes.0 as usize
    }
}

pub fn meminfo(field: &str) -> Result<Bytes, Error> {
    let path = Path::new("/proc/meminfo");
    let proc_meminfo = match File::open(path) {
        Ok(f) => f,
        Err(e) => {
            println!("Error: {:?}", e);
            return Err(e);
        }
    };
    let reader = BufReader::new(proc_meminfo);
    for line in reader.lines() {
        let entry = line.expect("couldn't get line?!");
        let label = &format!("{}:", field);
        if entry.starts_with(label) {
            // like "MemFree:  3274928 kB"
            let mut figure = entry.trim_left_matches(label);
            figure = figure.trim_left();
            figure = &figure[0..figure.len() - 3]; // chop off " kB"
            let value: u64 = figure.parse()
                                   .expect("couldn't parse memory inventory \
                                            entry?!");
            return Ok(Bytes::kibi(value as f32));
        }
    }
    moral_panic!("couldn't find amount of free memory");
}

pub fn memory_free() -> Option<Bytes> {
    match meminfo("MemFree") {
        Ok(bytes) => Some(bytes),
        Err(_) => None
    }
}

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

    #[test]
    fn concerning_conversion_from_bytes() {
        assert_eq!(3, usize::from(Bytes(3)))
    }

}
<commit_msg>Update deprecated string trimming<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader, Error};
use std::path::Path;

#[derive(Debug, Copy, Clone)]
pub struct Bytes(u64);

impl Bytes {
    pub fn kibi(n: f32) -> Self { Bytes(1024*n as u64) }
    pub fn gibi(n: f32) -> Self { Bytes((1024.0f32.powi(3)*n) as u64) }

    pub fn in_gib(&self) -> f32 { (self.0 as f32)/1024.0f32.powi(3) }
}

impl From<Bytes> for usize {
    fn from(bytes: Bytes) -> Self {
        bytes.0 as usize
    }
}

pub fn meminfo(field: &str) -> Result<Bytes, Error> {
    let path = Path::new("/proc/meminfo");
    let proc_meminfo = match File::open(path) {
        Ok(f) => f,
        Err(e) => {
            println!("Error: {:?}", e);
            return Err(e);
        }
    };
    let reader = BufReader::new(proc_meminfo);
    for line in reader.lines() {
        let entry = line.expect("couldn't get line?!");
        let label = &format!("{}:", field);
        if entry.starts_with(label) {
            // like "MemFree:  3274928 kB"
            let mut figure = entry.trim_start_matches(label);
            figure = figure.trim_start();
            figure = &figure[0..figure.len() - 3]; // chop off " kB"
            let value: u64 = figure.parse()
                                   .expect("couldn't parse memory inventory \
                                            entry?!");
            return Ok(Bytes::kibi(value as f32));
        }
    }
    moral_panic!("couldn't find amount of free memory");
}

pub fn memory_free() -> Option<Bytes> {
    match meminfo("MemFree") {
        Ok(bytes) => Some(bytes),
        Err(_) => None
    }
}

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

    #[test]
    fn concerning_conversion_from_bytes() {
        assert_eq!(3, usize::from(Bytes(3)))
    }

}
<|endoftext|>


<commit_before>use emulator::{State, execute_expr};
use expr::{Expr, ExprType, ExprBuilder};
use op::{OpArith, OpLogic, OpUnary, OpBool, OpCast};

use num::bigint::{BigUint, ToBigUint};
use num::traits::{One, Zero};//, ToPrimitive};
use std::collections::HashMap;
use std::iter::Iterator;

use permutohedron::LexicalPermutation;
use itertools::Itertools;

/// Trait required for becoming a Template
trait Template2  {
    fn exec(&[&Expr], u32) -> Vec<Expr>;
    fn args() -> u32;
}

trait Template: Template2 {
    fn n_args(&self) -> u32 { Self::args() }
}

impl<T> Template for T where T: Template2 {}
//impl<T> Debug for T where T: Template2 {}

struct ParityTemplate;

impl ParityTemplate {
    /// Mod(Add(Bit(0), Add(Bit(1), Add(Bit....))), 2)
    fn parity_flag(e: &Expr, width: u32) -> Expr {
        let mut expr_builder = ExprBuilder::new();
        for i in 0..width {
            let bit = Expr::Bit(i, Box::new(e.clone()));
            let add = Expr::ArithOp(OpArith::Add,
                                    Box::new(bit),
                                    Box::new(Expr::Int(BigUint::zero())),
                                    ExprType::Int(width));
            expr_builder.insert_last_right_or_replace(&add);
        }
        expr_builder.preinsert_with_second(
            &Expr::ArithOp(
                OpArith::Mod,
                Box::new(Expr::NoOp),
                Box::new(Expr::Int(2.to_biguint().unwrap())),
                ExprType::Int(width))
                );
        expr_builder.finalize()
    }
    fn reverse_parity_flag(e: &Expr, width: u32) -> Expr {
        let e = Self::parity_flag(e, width);
        Expr::ArithOp(OpArith::Sub,
                      Box::new(Expr::Int(BigUint::one())),
                      Box::new(e),
                      ExprType::Int(1))
    }
}

impl Template2 for ParityTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        [1, 4, 8, 16, 32, 64, 128, 256]
            .iter()
            .flat_map(|w| vec![Self::parity_flag(e[0], *w),
                               Self::reverse_parity_flag(e[0], *w)])
            .collect()
    }

    fn args() -> u32 { 1 }
}

struct CarryTemplate;

impl CarryTemplate {
    fn carry_flag(e1: &Expr, e2: &Expr) -> Vec<Expr> {
        Vec::new()
    }
}

impl Template2 for CarryTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        Self::carry_flag(e[0], e[1])
    }

    fn args() -> u32 { 2 }
}

struct SignTemplate;

impl SignTemplate {
    fn sign_flag(e: &Expr, width: u32) -> Expr {
        let width = {
            match e.get_width() {
                Some(w) => w,
                None => width
            }
        };
        let mask = BigUint::one() << ((width as usize) - 1);
        Expr::Bit(
            width - 1,
            Box::new(e.clone()))
    }
}

impl Template2 for SignTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        vec![Self::sign_flag(e[0], width)]
    }

    fn args() -> u32 { 1 }
}

struct ZeroTemplate;

impl ZeroTemplate {
    fn zero_flag(e: &Expr, width: u32) -> Expr {
        let mask = BigUint::one() << ((width as usize) - 1);
        Expr::BoolOp(
            OpBool::EQ,
            Box::new(e.clone()),
            Box::new(Expr::Int(BigUint::zero())),
        )
    }
}

impl Template2 for ZeroTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        vec![Self::zero_flag(e[0], width)]
    }

    fn args() -> u32 { 1 }
}

    /* Carry flag
    ITE(EQ(MSB(p1), MSB(r1)), 0, 1)
    ITE(EQ(MSB(p1),
    if res < p1 || res < p2
     */
    fn exprs_to_replace(width: u32) -> Vec<Expr> {
        // Carry
        // Overflow
        // Parity
        vec![]
    }

pub struct TemplateSearch<'a> {
    args: &'a[&'a Expr],
    io_sets: &'a [(BigUint,HashMap<Expr, BigUint>)],
    expr_width: u32
}

impl<'a> TemplateSearch<'a> {
    pub fn new(args: &'a [&'a Expr],
               io_sets: &'a [(BigUint,HashMap<Expr, BigUint>)],
               expr_width: u32)
               -> TemplateSearch<'a> {
        TemplateSearch {
            args: args,
            io_sets: io_sets,
            expr_width: expr_width
        }
    }

    /// Execute with an I/O set and return true if it matches the
    /// result
    fn execute_once(&self,
                    e: &Expr,
                    io_set: &HashMap<Expr, BigUint>)
                    -> Result<BigUint,()>
    {
        let state = State::borrow(io_set);
        Ok(
            try!(execute_expr(&state, e)).value().clone())
    }

    /// Execute all the I/O sets for an expression and return true if
    /// the expected outputs match with the obtained ones
    fn execute_expected(&self, e: &Expr) -> bool {
        for &(ref expected, ref io_set) in self.io_sets {
            if let Ok(res) = self.execute_once(e, io_set) {
                if &res == expected {
                    continue;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }

    /// Try Template
    fn try_template<T>(&self) -> Vec<Expr>
        where T: Template2
    {
        // Generate all the possible orders of combinations of the arguments
        let mut all = Vec::new();
        for combination in self.args.iter()
            .cloned().combinations_n(T::args() as usize)
        {
            let mut comb = combination.to_vec();
            all.push(comb.clone());
            while (comb).next_permutation() {
                all.push(comb.clone());
            }
        }

        // Now generate the exprs and save only the ones that pass the
        // execution tests
        let mut res = Vec::new();
        for exprs in &all {
            T::exec(exprs, self.expr_width)
                .iter()
                .filter(|&e| self.execute_expected(e))
                .inspect(|&e| res.push(e.clone()))
                .count();
        }
        res
    }

    /// Try finding exprs for the template
    pub fn work(&self) -> Vec<Expr> {
        let mut res = Vec::new();
        macro_rules! exec_for{
            ($res:expr, $($T:ident),*) => (
                $(
                    println!("template: {}", stringify!($T));
                    $res.append(&mut self.try_template::<$T>());
                )*
            )
        }
        exec_for!(res,
                  ParityTemplate, CarryTemplate, SignTemplate, ZeroTemplate);
        res
    }
}
<commit_msg>removing duplicates in TemplateSearch<commit_after>use emulator::{State, execute_expr};
use expr::{Expr, ExprType, ExprBuilder};
use op::{OpArith, OpLogic, OpUnary, OpBool, OpCast};

use num::bigint::{BigUint, ToBigUint};
use num::traits::{One, Zero};//, ToPrimitive};
use std::collections::HashMap;
use std::iter::Iterator;

use permutohedron::LexicalPermutation;
use itertools::Itertools;

/// Trait required for becoming a Template
trait Template2  {
    fn exec(&[&Expr], u32) -> Vec<Expr>;
    fn args() -> u32;
}

trait Template: Template2 {
    fn n_args(&self) -> u32 { Self::args() }
}

impl<T> Template for T where T: Template2 {}
//impl<T> Debug for T where T: Template2 {}

struct ParityTemplate;

impl ParityTemplate {
    /// Mod(Add(Bit(0), Add(Bit(1), Add(Bit....))), 2)
    fn parity_flag(e: &Expr, width: u32) -> Expr {
        let mut expr_builder = ExprBuilder::new();
        for i in 0..width {
            let bit = Expr::Bit(i, Box::new(e.clone()));
            let add = Expr::ArithOp(OpArith::Add,
                                    Box::new(bit),
                                    Box::new(Expr::Int(BigUint::zero())),
                                    ExprType::Int(width));
            expr_builder.insert_last_right_or_replace(&add);
        }
        expr_builder.preinsert_with_second(
            &Expr::ArithOp(
                OpArith::Mod,
                Box::new(Expr::NoOp),
                Box::new(Expr::Int(2.to_biguint().unwrap())),
                ExprType::Int(width))
                );
        expr_builder.finalize()
    }
    fn reverse_parity_flag(e: &Expr, width: u32) -> Expr {
        let e = Self::parity_flag(e, width);
        Expr::ArithOp(OpArith::Sub,
                      Box::new(Expr::Int(BigUint::one())),
                      Box::new(e),
                      ExprType::Int(1))
    }
}

impl Template2 for ParityTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        [1, 4, 8, 16, 32, 64, 128, 256]
            .iter()
            .flat_map(|w| vec![Self::parity_flag(e[0], *w),
                               Self::reverse_parity_flag(e[0], *w)])
            .collect()
    }

    fn args() -> u32 { 1 }
}

struct CarryTemplate;

impl CarryTemplate {
    fn carry_flag(e1: &Expr, e2: &Expr) -> Vec<Expr> {
        Vec::new()
    }
}

impl Template2 for CarryTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        Self::carry_flag(e[0], e[1])
    }

    fn args() -> u32 { 2 }
}

struct SignTemplate;

impl SignTemplate {
    fn sign_flag(e: &Expr, width: u32) -> Expr {
        let width = {
            match e.get_width() {
                Some(w) => w,
                None => width
            }
        };
        let mask = BigUint::one() << ((width as usize) - 1);
        Expr::Bit(
            width - 1,
            Box::new(e.clone()))
    }
}

impl Template2 for SignTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        vec![Self::sign_flag(e[0], width)]
    }

    fn args() -> u32 { 1 }
}

struct ZeroTemplate;

impl ZeroTemplate {
    fn zero_flag(e: &Expr, width: u32) -> Expr {
        let mask = BigUint::one() << ((width as usize) - 1);
        Expr::BoolOp(
            OpBool::EQ,
            Box::new(e.clone()),
            Box::new(Expr::Int(BigUint::zero())),
        )
    }
}

impl Template2 for ZeroTemplate {
    fn exec(e: &[&Expr], width: u32) -> Vec<Expr> {
        vec![Self::zero_flag(e[0], width)]
    }

    fn args() -> u32 { 1 }
}

    /* Carry flag
    ITE(EQ(MSB(p1), MSB(r1)), 0, 1)
    ITE(EQ(MSB(p1),
    if res < p1 || res < p2
     */
    fn exprs_to_replace(width: u32) -> Vec<Expr> {
        // Carry
        // Overflow
        // Parity
        vec![]
    }

pub struct TemplateSearch<'a> {
    args: &'a[&'a Expr],
    io_sets: &'a [(BigUint,HashMap<Expr, BigUint>)],
    expr_width: u32
}

impl<'a> TemplateSearch<'a> {
    pub fn new(args: &'a [&'a Expr],
               io_sets: &'a [(BigUint,HashMap<Expr, BigUint>)],
               expr_width: u32)
               -> TemplateSearch<'a> {
        TemplateSearch {
            args: args,
            io_sets: io_sets,
            expr_width: expr_width
        }
    }

    /// Execute with an I/O set and return true if it matches the
    /// result
    fn execute_once(&self,
                    e: &Expr,
                    io_set: &HashMap<Expr, BigUint>)
                    -> Result<BigUint,()>
    {
        let state = State::borrow(io_set);
        Ok(
            try!(execute_expr(&state, e)).value().clone())
    }

    /// Execute all the I/O sets for an expression and return true if
    /// the expected outputs match with the obtained ones
    fn execute_expected(&self, e: &Expr) -> bool {
        for &(ref expected, ref io_set) in self.io_sets {
            if let Ok(res) = self.execute_once(e, io_set) {
                if &res == expected {
                    continue;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }

    /// Try Template
    fn try_template<T>(&self) -> Vec<Expr>
        where T: Template2
    {
        // Generate all the possible orders of combinations of the arguments
        let mut all = Vec::new();
        for combination in self.args.iter()
            .cloned().combinations_n(T::args() as usize)
        {
            let mut comb = combination.to_vec();
            all.push(comb.clone());
            while (comb).next_permutation() {
                if !all.contains(&comb) {
                    all.push(comb.clone());
                }
            }
        }

        // Now generate the exprs and save only the ones that pass the
        // execution tests
        let mut res = Vec::new();
        for exprs in &all {
            T::exec(exprs, self.expr_width)
                .iter()
                .filter(|&e| self.execute_expected(e))
                .inspect(|&e| res.push(e.clone()))
                .count();
        }
        res
    }

    /// Try finding exprs for the template
    pub fn work(&self) -> Vec<Expr> {
        let mut res = Vec::new();
        macro_rules! exec_for{
            ($res:expr, $($T:ident),*) => (
                $(
                    //println!("template: {}", stringify!($T));
                    $res.append(&mut self.try_template::<$T>());
                )*
            )
        }
        exec_for!(res,
                  ParityTemplate, CarryTemplate, SignTemplate, ZeroTemplate);
        res
    }
}
<|endoftext|>


<commit_before>use piston_window::{Context, G2d};
use piston_window::types::Color;
use rand::{Rng, thread_rng};

use colors::*;
use game::{Renderer, render_square_in_grid};
use settings::WIDTH_IN_BLOCKS;

pub fn create_random_piece() -> Piece {
    let all_tetrominos = [&I, &J, &L, &O, &S, &T, &Z];
    let ptype = thread_rng().choose(&all_tetrominos).unwrap();
    Piece::create(*ptype)
}

pub static I: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}, Block{x:3, y:1}],
        [Block{x:2, y:0}, Block{x:2, y:1}, Block{x:2, y:2}, Block{x:2, y:3}],
        [Block{x:0, y:2}, Block{x:1, y:2}, Block{x:2, y:2}, Block{x:3, y:2}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}, Block{x:1, y:3}]
    ],
    color: CYAN
};

pub static J: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:0}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:2, y:0}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}],
        [Block{x:2, y:2}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:0, y:2}, Block{x:1, y:2}, Block{x:1, y:1}, Block{x:1, y:0}]
    ],
    color: BLUE
};

pub static L: Tetromino = Tetromino {
    configurations: [
        [Block{x:2, y:0}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:2, y:2}, Block{x:1, y:2}, Block{x:1, y:1}, Block{x:1, y:0}],
        [Block{x:0, y:2}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:0, y:0}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}]
    ],
    color: ORANGE
};

pub static O: Tetromino = Tetromino {
    configurations: [
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}]
    ],
    color: YELLOW
};

pub static S: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:1}, Block{x:1, y:1}, Block{x:1, y:0}, Block{x:2, y:0}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:1}, Block{x:2, y:2}],
        [Block{x:2, y:1}, Block{x:1, y:1}, Block{x:1, y:2}, Block{x:0, y:2}],
        [Block{x:1, y:2}, Block{x:1, y:1}, Block{x:0, y:1}, Block{x:0, y:0}]
    ],
    color: LIME
};

pub static T: Tetromino = Tetromino {
    configurations: [
        [Block{x:1, y:0}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:2, y:1}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}],
        [Block{x:1, y:2}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:0, y:1}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}]
    ],
    color: PURPLE
};

pub static Z: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:0}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:2, y:0}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:1, y:2}],
        [Block{x:2, y:2}, Block{x:1, y:2}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:0, y:2}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:1, y:0}]
    ],
    color: RED
};

pub type Configuration = [Block; 4];
type Rotation = usize;

pub struct Piece {
    // TODO: Replace with position
    // TODO: Make this private again
    pub x: i32,
    pub y: i32,
    ptype: &'static Tetromino,
    rotation: Rotation
}
impl Piece {
    pub fn create(ptype: &'static Tetromino) -> Piece {
        let x = (WIDTH_IN_BLOCKS as i32 / 2) - 2;
        Piece::new(x, 0, ptype, 0)
    }

    fn new(x: i32, y: i32, ptype: &'static Tetromino, rotation: Rotation) -> Piece {
        Piece {
            x: x,
            y: y,
            ptype: ptype,
            rotation: rotation
        }
    }

    pub fn get_blocks(&self) -> &Configuration {
        self.ptype.get_configuration(self.rotation)
    }

    pub fn rotated(&self) -> Self {
        let rotation = (self.rotation + 1) % self.ptype.configurations.len();
        Self::new(self.x, self.y, self.ptype, rotation)
    }

    pub fn moved(&self, direction: Direction) -> Self {
        match direction {
            Direction::Left => Self::new(self.x - 1, self.y, self.ptype, self.rotation),
            Direction::Right => Self::new(self.x + 1, self.y, self.ptype, self.rotation)
        }
    }

    pub fn wall_kick(&self) -> Self {
        let mut translation = 0;
        let min_block = self.get_blocks().iter().min_by_key(|block| self.x + block.x).unwrap();
        let max_block = self.get_blocks().iter().max_by_key(|block| self.x + block.x).unwrap();
        if self.x + min_block.x < 0 {
            translation = self.x + min_block.x;
        } else if self.x + max_block.x >= WIDTH_IN_BLOCKS as i32 {
            translation = (self.x + max_block.x) - (WIDTH_IN_BLOCKS - 1) as i32;
        }
        Self::new(self.x - translation, self.y, self.ptype, self.rotation)
    }

    fn get_color(&self) -> Color {
        self.ptype.color
    }
}
impl Renderer for Piece {
    fn render(&self, context: Context, graphics: &mut G2d) {
        for block in self.get_blocks() {
            let x = self.x + block.x;
            let y = self.y + block.y;
            render_square_in_grid(x, y, self.get_color(), context, graphics);
        }
    }
}

pub enum Direction {
    Left,
    Right
}

#[derive(Debug)]
pub struct Tetromino {
    configurations: [Configuration; 4],
    color: Color
}
impl Tetromino {
    fn get_configuration(&self, rotation: Rotation) -> &Configuration {
        &self.configurations[rotation]
    }
}

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

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

    #[test]
    fn test_piece_rotated() {
        let mut p = Piece::create(&I);
        assert_eq!(p.rotation, 0);
        p = p.rotated();
        assert_eq!(p.rotation, 1);
        p = p.rotated();
        assert_eq!(p.rotation, 2);
        p = p.rotated();
        assert_eq!(p.rotation, 3);
        p = p.rotated();
        assert_eq!(p.rotation, 0);
    }

    #[test]
    fn test_piece_moved_left() {
        let mut p = Piece::create(&Z);
        let result = p.moved(Direction::Left);
        assert_eq!(result.x, p.x - 1);
    }

    #[test]
    fn test_piece_moved_right() {
        let mut p = Piece::create(&Z);
        let result = p.moved(Direction::Right);
        assert_eq!(result.x, p.x + 1);
    }
}
<commit_msg>remove duplication of the new call<commit_after>use piston_window::{Context, G2d};
use piston_window::types::Color;
use rand::{Rng, thread_rng};

use colors::*;
use game::{Renderer, render_square_in_grid};
use settings::WIDTH_IN_BLOCKS;

pub fn create_random_piece() -> Piece {
    let all_tetrominos = [&I, &J, &L, &O, &S, &T, &Z];
    let ptype = thread_rng().choose(&all_tetrominos).unwrap();
    Piece::create(*ptype)
}

pub static I: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}, Block{x:3, y:1}],
        [Block{x:2, y:0}, Block{x:2, y:1}, Block{x:2, y:2}, Block{x:2, y:3}],
        [Block{x:0, y:2}, Block{x:1, y:2}, Block{x:2, y:2}, Block{x:3, y:2}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}, Block{x:1, y:3}]
    ],
    color: CYAN
};

pub static J: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:0}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:2, y:0}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}],
        [Block{x:2, y:2}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:0, y:2}, Block{x:1, y:2}, Block{x:1, y:1}, Block{x:1, y:0}]
    ],
    color: BLUE
};

pub static L: Tetromino = Tetromino {
    configurations: [
        [Block{x:2, y:0}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:2, y:2}, Block{x:1, y:2}, Block{x:1, y:1}, Block{x:1, y:0}],
        [Block{x:0, y:2}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:0, y:0}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}]
    ],
    color: ORANGE
};

pub static O: Tetromino = Tetromino {
    configurations: [
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:0}, Block{x:2, y:1}]
    ],
    color: YELLOW
};

pub static S: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:1}, Block{x:1, y:1}, Block{x:1, y:0}, Block{x:2, y:0}],
        [Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:1}, Block{x:2, y:2}],
        [Block{x:2, y:1}, Block{x:1, y:1}, Block{x:1, y:2}, Block{x:0, y:2}],
        [Block{x:1, y:2}, Block{x:1, y:1}, Block{x:0, y:1}, Block{x:0, y:0}]
    ],
    color: LIME
};

pub static T: Tetromino = Tetromino {
    configurations: [
        [Block{x:1, y:0}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:2, y:1}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}],
        [Block{x:1, y:2}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:0, y:1}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:1, y:2}]
    ],
    color: PURPLE
};

pub static Z: Tetromino = Tetromino {
    configurations: [
        [Block{x:0, y:0}, Block{x:1, y:0}, Block{x:1, y:1}, Block{x:2, y:1}],
        [Block{x:2, y:0}, Block{x:2, y:1}, Block{x:1, y:1}, Block{x:1, y:2}],
        [Block{x:2, y:2}, Block{x:1, y:2}, Block{x:1, y:1}, Block{x:0, y:1}],
        [Block{x:0, y:2}, Block{x:0, y:1}, Block{x:1, y:1}, Block{x:1, y:0}]
    ],
    color: RED
};

pub type Configuration = [Block; 4];
type Rotation = usize;

pub struct Piece {
    // TODO: Replace with position
    // TODO: Make this private again
    pub x: i32,
    pub y: i32,
    ptype: &'static Tetromino,
    rotation: Rotation
}
impl Piece {
    pub fn create(ptype: &'static Tetromino) -> Piece {
        let x = (WIDTH_IN_BLOCKS as i32 / 2) - 2;
        Piece::new(x, 0, ptype, 0)
    }

    fn new(x: i32, y: i32, ptype: &'static Tetromino, rotation: Rotation) -> Piece {
        Piece {
            x: x,
            y: y,
            ptype: ptype,
            rotation: rotation
        }
    }

    pub fn get_blocks(&self) -> &Configuration {
        self.ptype.get_configuration(self.rotation)
    }

    pub fn rotated(&self) -> Self {
        let rotation = (self.rotation + 1) % self.ptype.configurations.len();
        Self::new(self.x, self.y, self.ptype, rotation)
    }

    pub fn moved(&self, direction: Direction) -> Self {
        let translated_x = match direction {
            Direction::Left => self.x - 1,
            Direction::Right => self.x + 1
        };
        Self::new(translated_x, self.y, self.ptype, self.rotation)
    }

    pub fn wall_kick(&self) -> Self {
        let mut translation = 0;
        let min_block = self.get_blocks().iter().min_by_key(|block| self.x + block.x).unwrap();
        let max_block = self.get_blocks().iter().max_by_key(|block| self.x + block.x).unwrap();
        if self.x + min_block.x < 0 {
            translation = self.x + min_block.x;
        } else if self.x + max_block.x >= WIDTH_IN_BLOCKS as i32 {
            translation = (self.x + max_block.x) - (WIDTH_IN_BLOCKS - 1) as i32;
        }
        Self::new(self.x - translation, self.y, self.ptype, self.rotation)
    }

    fn get_color(&self) -> Color {
        self.ptype.color
    }
}
impl Renderer for Piece {
    fn render(&self, context: Context, graphics: &mut G2d) {
        for block in self.get_blocks() {
            let x = self.x + block.x;
            let y = self.y + block.y;
            render_square_in_grid(x, y, self.get_color(), context, graphics);
        }
    }
}

pub enum Direction {
    Left,
    Right
}

#[derive(Debug)]
pub struct Tetromino {
    configurations: [Configuration; 4],
    color: Color
}
impl Tetromino {
    fn get_configuration(&self, rotation: Rotation) -> &Configuration {
        &self.configurations[rotation]
    }
}

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

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

    #[test]
    fn test_piece_rotated() {
        let mut p = Piece::create(&I);
        assert_eq!(p.rotation, 0);
        p = p.rotated();
        assert_eq!(p.rotation, 1);
        p = p.rotated();
        assert_eq!(p.rotation, 2);
        p = p.rotated();
        assert_eq!(p.rotation, 3);
        p = p.rotated();
        assert_eq!(p.rotation, 0);
    }

    #[test]
    fn test_piece_moved_left() {
        let mut p = Piece::create(&Z);
        let result = p.moved(Direction::Left);
        assert_eq!(result.x, p.x - 1);
    }

    #[test]
    fn test_piece_moved_right() {
        let mut p = Piece::create(&Z);
        let result = p.moved(Direction::Right);
        assert_eq!(result.x, p.x + 1);
    }
}
<|endoftext|>


<commit_before>use super::Tokens;

pub trait ToTokens {
    fn to_tokens(&self, &mut Tokens);
}

impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
    fn to_tokens(&self, tokens: &mut Tokens) {
        (**self).to_tokens(tokens);
    }
}

impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        (**self).to_tokens(tokens);
    }
}

impl<T: ToTokens> ToTokens for Option<T> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        if let Some(ref t) = *self {
            t.to_tokens(tokens);
        }
    }
}

impl ToTokens for str {
    fn to_tokens(&self, tokens: &mut Tokens) {
        tokens.append(&escape_str(self));
    }
}

impl ToTokens for String {
    fn to_tokens(&self, tokens: &mut Tokens) {
        self.as_str().to_tokens(tokens);
    }
}

impl ToTokens for char {
    fn to_tokens(&self, tokens: &mut Tokens) {
        match *self {
            '\0' => tokens.append(r"'\0'"),
            '"' => tokens.append("'\"'"),
            _ => tokens.append(&format!("{:?}", self)),
        }
    }
}

/// Wrap a `&str` so it interpolates as a byte-string: `b"abc"`.
#[derive(Debug)]
pub struct ByteStr<'a>(pub &'a str);

impl<'a> ToTokens for ByteStr<'a> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        tokens.append(&format!("b{}", escape_str(self.0)));
    }
}

fn escape_str(s: &str) -> String {
    let mut escaped = "\"".to_string();
    for ch in s.chars() {
        match ch {
            '\0' => escaped.push_str(r"\0"),
            '\'' => escaped.push_str("'"),
            _ => escaped.extend(ch.escape_default().map(|c| c as char)),
        }
    }
    escaped.push('"');
    escaped
}

macro_rules! impl_to_tokens_display {
    ($ty:ty) => {
        impl ToTokens for $ty {
            fn to_tokens(&self, tokens: &mut Tokens) {
                tokens.append(&self.to_string());
            }
        }
    };
}

impl_to_tokens_display!(Tokens);
impl_to_tokens_display!(bool);

macro_rules! impl_to_tokens_integer {
    ($ty:ty) => {
        impl ToTokens for $ty {
            fn to_tokens(&self, tokens: &mut Tokens) {
                tokens.append(&format!(concat!("{}", stringify!($ty)), self));
            }
        }
    };
}

impl_to_tokens_integer!(i8);
impl_to_tokens_integer!(i16);
impl_to_tokens_integer!(i32);
impl_to_tokens_integer!(i64);
impl_to_tokens_integer!(isize);
impl_to_tokens_integer!(u8);
impl_to_tokens_integer!(u16);
impl_to_tokens_integer!(u32);
impl_to_tokens_integer!(u64);
impl_to_tokens_integer!(usize);

macro_rules! impl_to_tokens_floating {
    ($ty:ty) => {
        impl ToTokens for $ty {
            fn to_tokens(&self, tokens: &mut Tokens) {
                use std::num::FpCategory::*;
                match self.classify() {
                    Zero | Subnormal | Normal => {
                        tokens.append(&format!(concat!("{}", stringify!($ty)), self));
                    }
                    Nan => {
                        tokens.append("::");
                        tokens.append("std");
                        tokens.append("::");
                        tokens.append(stringify!($ty));
                        tokens.append("::");
                        tokens.append("NAN");
                    }
                    Infinite => {
                        tokens.append("::");
                        tokens.append("std");
                        tokens.append("::");
                        tokens.append(stringify!($ty));
                        tokens.append("::");
                        if self.is_sign_positive() {
                            tokens.append("INFINITY");
                        } else {
                            tokens.append("NEG_INFINITY");
                        }
                    }
                }
            }
        }
    };
}
impl_to_tokens_floating!(f32);
impl_to_tokens_floating!(f64);
<commit_msg>Document ToTokens<commit_after>use super::Tokens;

/// Types that can be interpolated inside a `quote!(...)` invocation.
pub trait ToTokens {
    /// Write `self` to the given `Tokens`.
    ///
    /// Example implementation for a struct representing Rust paths like
    /// `std::cmp::PartialEq`:
    ///
    /// ```ignore
    /// pub struct Path {
    ///     pub global: bool,
    ///     pub segments: Vec<PathSegment>,
    /// }
    ///
    /// impl ToTokens for Path {
    ///     fn to_tokens(&self, tokens: &mut Tokens) {
    ///         for (i, segment) in self.segments.iter().enumerate() {
    ///             if i > 0 || self.global {
    ///                 tokens.append("::");
    ///             }
    ///             segment.to_tokens(tokens);
    ///         }
    ///     }
    /// }
    /// ```
    fn to_tokens(&self, &mut Tokens);
}

impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
    fn to_tokens(&self, tokens: &mut Tokens) {
        (**self).to_tokens(tokens);
    }
}

impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        (**self).to_tokens(tokens);
    }
}

impl<T: ToTokens> ToTokens for Option<T> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        if let Some(ref t) = *self {
            t.to_tokens(tokens);
        }
    }
}

impl ToTokens for str {
    fn to_tokens(&self, tokens: &mut Tokens) {
        tokens.append(&escape_str(self));
    }
}

impl ToTokens for String {
    fn to_tokens(&self, tokens: &mut Tokens) {
        self.as_str().to_tokens(tokens);
    }
}

impl ToTokens for char {
    fn to_tokens(&self, tokens: &mut Tokens) {
        match *self {
            '\0' => tokens.append(r"'\0'"),
            '"' => tokens.append("'\"'"),
            _ => tokens.append(&format!("{:?}", self)),
        }
    }
}

/// Wrap a `&str` so it interpolates as a byte-string: `b"abc"`.
#[derive(Debug)]
pub struct ByteStr<'a>(pub &'a str);

impl<'a> ToTokens for ByteStr<'a> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        tokens.append(&format!("b{}", escape_str(self.0)));
    }
}

fn escape_str(s: &str) -> String {
    let mut escaped = "\"".to_string();
    for ch in s.chars() {
        match ch {
            '\0' => escaped.push_str(r"\0"),
            '\'' => escaped.push_str("'"),
            _ => escaped.extend(ch.escape_default().map(|c| c as char)),
        }
    }
    escaped.push('"');
    escaped
}

macro_rules! impl_to_tokens_display {
    ($ty:ty) => {
        impl ToTokens for $ty {
            fn to_tokens(&self, tokens: &mut Tokens) {
                tokens.append(&self.to_string());
            }
        }
    };
}

impl_to_tokens_display!(Tokens);
impl_to_tokens_display!(bool);

macro_rules! impl_to_tokens_integer {
    ($ty:ty) => {
        impl ToTokens for $ty {
            fn to_tokens(&self, tokens: &mut Tokens) {
                tokens.append(&format!(concat!("{}", stringify!($ty)), self));
            }
        }
    };
}

impl_to_tokens_integer!(i8);
impl_to_tokens_integer!(i16);
impl_to_tokens_integer!(i32);
impl_to_tokens_integer!(i64);
impl_to_tokens_integer!(isize);
impl_to_tokens_integer!(u8);
impl_to_tokens_integer!(u16);
impl_to_tokens_integer!(u32);
impl_to_tokens_integer!(u64);
impl_to_tokens_integer!(usize);

macro_rules! impl_to_tokens_floating {
    ($ty:ty) => {
        impl ToTokens for $ty {
            fn to_tokens(&self, tokens: &mut Tokens) {
                use std::num::FpCategory::*;
                match self.classify() {
                    Zero | Subnormal | Normal => {
                        tokens.append(&format!(concat!("{}", stringify!($ty)), self));
                    }
                    Nan => {
                        tokens.append("::");
                        tokens.append("std");
                        tokens.append("::");
                        tokens.append(stringify!($ty));
                        tokens.append("::");
                        tokens.append("NAN");
                    }
                    Infinite => {
                        tokens.append("::");
                        tokens.append("std");
                        tokens.append("::");
                        tokens.append(stringify!($ty));
                        tokens.append("::");
                        if self.is_sign_positive() {
                            tokens.append("INFINITY");
                        } else {
                            tokens.append("NEG_INFINITY");
                        }
                    }
                }
            }
        }
    };
}
impl_to_tokens_floating!(f32);
impl_to_tokens_floating!(f64);
<|endoftext|>


<commit_before>use operations::{Op, ToOp};

pub struct Tokenizer {
    words: Vec<String>,
    misses: u64,
    buf: String,
}

impl Tokenizer {
    pub fn new(words: Vec<String>) -> Tokenizer {
        Tokenizer { words: words, misses: 0, buf: "".to_string() }
    }

    pub fn tokenize(&mut self) -> Vec<Op> {
        let mut ops = vec!();
        for word in self.words.clone().iter() {
            self.buf.push_str(word.as_slice());
            println!("current buf: {}", self.buf);
            println!("misses: {}", self.misses);
            match self.buf.clone().to_op() {
                Op::Increment => self.push_op(&mut ops, Op::Increment),
                Op::Decrement => self.push_op(&mut ops, Op::Decrement),
                Op::Output    => self.push_op(&mut ops, Op::Output),
                Op::Right     => self.push_op(&mut ops, Op::Right),
                Op::Left      => self.push_op(&mut ops, Op::Left),
                Op::Jump      => self.push_op(&mut ops, Op::Jump),
                Op::JumpBack  => self.push_op(&mut ops, Op::JumpBack),
                Op::Unknown   => {
                    self.misses += 1;
                    if self.misses == 3 {
                        panic!("syntax error unknow token `{}`", self.buf);
                    }
                },
            }
        }
        ops
    }

    fn push_op(&mut self, ops: &mut Vec<Op>, op: Op) {
        ops.push(op);
        self.misses = 0;
        self.buf = "".to_string();
    }
}

<commit_msg>remove debug printing<commit_after>use operations::{Op, ToOp};

pub struct Tokenizer {
    words: Vec<String>,
    misses: u64,
    buf: String,
}

impl Tokenizer {
    pub fn new(words: Vec<String>) -> Tokenizer {
        Tokenizer { words: words, misses: 0, buf: "".to_string() }
    }

    pub fn tokenize(&mut self) -> Vec<Op> {
        let mut ops = vec!();
        for word in self.words.clone().iter() {
            self.buf.push_str(word.as_slice());
            match self.buf.clone().to_op() {
                Op::Increment => self.push_op(&mut ops, Op::Increment),
                Op::Decrement => self.push_op(&mut ops, Op::Decrement),
                Op::Output    => self.push_op(&mut ops, Op::Output),
                Op::Right     => self.push_op(&mut ops, Op::Right),
                Op::Left      => self.push_op(&mut ops, Op::Left),
                Op::Jump      => self.push_op(&mut ops, Op::Jump),
                Op::JumpBack  => self.push_op(&mut ops, Op::JumpBack),
                Op::Unknown   => {
                    self.misses += 1;
                    if self.misses == 3 {
                        panic!("syntax error unknow token `{}`", self.buf);
                    }
                },
            }
        }
        ops
    }

    fn push_op(&mut self, ops: &mut Vec<Op>, op: Op) {
        ops.push(op);
        self.misses = 0;
        self.buf = "".to_string();
    }
}

<|endoftext|>


<commit_before>use crate::utils::{is_entrypoint_fn, match_def_path, paths, qpath_res, span_lint};
use if_chain::if_chain;
use rustc::hir::{Expr, ExprKind, Item, ItemKind, Node};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** `exit()`  terminates the program and doesn't provide a
    /// stack trace.
    ///
    /// **Why is this bad?** Ideally a program is terminated by finishing
    /// the main function.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```ignore
    /// std::process::exit(0)
    /// ```
    pub EXIT,
    restriction,
    "`std::process::exit` is called, terminating the program"
}

declare_lint_pass!(Exit => [EXIT]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Exit {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if_chain! {
            if let ExprKind::Call(ref path_expr, ref _args) = e.kind;
            if let ExprKind::Path(ref path) = path_expr.kind;
            if let Some(def_id) = qpath_res(cx, path, path_expr.hir_id).opt_def_id();
            if match_def_path(cx, def_id, &paths::EXIT);
            then {
                let mut parent = cx.tcx.hir().get_parent_item(e.hir_id);
                if let Some(Node::Item(Item{ident, kind: ItemKind::Fn(..), ..})) = cx.tcx.hir().find(parent) {
                    // If the next item up is a function we check if it is an entry point
                    // and only then emit a linter warning
                    let def_id = cx.tcx.hir().local_def_id(parent);
                    if !is_entrypoint_fn(cx, def_id) {
                        span_lint(cx, EXIT, e.span, "usage of `process::exit`");
                    }
                }
            }
        }
    }
}
<commit_msg>remove unused warnings<commit_after>use crate::utils::{is_entrypoint_fn, match_def_path, paths, qpath_res, span_lint};
use if_chain::if_chain;
use rustc::hir::{Expr, ExprKind, Item, ItemKind, Node};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** `exit()`  terminates the program and doesn't provide a
    /// stack trace.
    ///
    /// **Why is this bad?** Ideally a program is terminated by finishing
    /// the main function.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```ignore
    /// std::process::exit(0)
    /// ```
    pub EXIT,
    restriction,
    "`std::process::exit` is called, terminating the program"
}

declare_lint_pass!(Exit => [EXIT]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Exit {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if_chain! {
            if let ExprKind::Call(ref path_expr, ref _args) = e.kind;
            if let ExprKind::Path(ref path) = path_expr.kind;
            if let Some(def_id) = qpath_res(cx, path, path_expr.hir_id).opt_def_id();
            if match_def_path(cx, def_id, &paths::EXIT);
            then {
                let parent = cx.tcx.hir().get_parent_item(e.hir_id);
                if let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.hir().find(parent) {
                    // If the next item up is a function we check if it is an entry point
                    // and only then emit a linter warning
                    let def_id = cx.tcx.hir().local_def_id(parent);
                    if !is_entrypoint_fn(cx, def_id) {
                        span_lint(cx, EXIT, e.span, "usage of `process::exit`");
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// OpenAOE: An open source reimplementation of Age of Empires (1997)
// Copyright (c) 2016 Kevin Fuller
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use error::*;

use io_tools::*;
use identifier::*;

use std::io::Read;

#[derive(Default, Debug)]
pub struct PlayerUnit {
    pub position_x: f32,
    pub position_y: f32,
    pub position_z: f32,
    pub spawn_id: SpawnId,
    pub unit_id: UnitId,
    pub state: u8,
    pub rotation: f32,
}

impl PlayerUnit {
    // TODO: Implement writing

    pub fn read_from_stream<S: Read>(stream: &mut S) -> Result<PlayerUnit> {
        let mut data: PlayerUnit = Default::default();
        data.position_x = try!(stream.read_f32());
        data.position_y = try!(stream.read_f32());
        data.position_z = try!(stream.read_f32());
        data.spawn_id = required_id!(try!(stream.read_i32()));
        data.unit_id = required_id!(try!(stream.read_i16()));
        data.state = try!(stream.read_u8());
        data.rotation = try!(stream.read_f32());
        Ok(data)
    }
}
<commit_msg>Successfully load scenarios without spawn IDs (fixes #23)<commit_after>// OpenAOE: An open source reimplementation of Age of Empires (1997)
// Copyright (c) 2016 Kevin Fuller
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use error::*;

use io_tools::*;
use identifier::*;

use std::io::Read;

#[derive(Default, Debug)]
pub struct PlayerUnit {
    pub position_x: f32,
    pub position_y: f32,
    pub position_z: f32,
    pub spawn_id: Option<SpawnId>,
    pub unit_id: UnitId,
    pub state: u8,
    pub rotation: f32,
}

impl PlayerUnit {
    // TODO: Implement writing

    pub fn read_from_stream<S: Read>(stream: &mut S) -> Result<PlayerUnit> {
        let mut data: PlayerUnit = Default::default();
        data.position_x = try!(stream.read_f32());
        data.position_y = try!(stream.read_f32());
        data.position_z = try!(stream.read_f32());
        data.spawn_id = optional_id!(try!(stream.read_i32()));
        data.unit_id = required_id!(try!(stream.read_i16()));
        data.state = try!(stream.read_u8());
        data.rotation = try!(stream.read_f32());
        Ok(data)
    }
}
<|endoftext|>