<commit_before>//! Utility functionality for integrating git hooks in the store
//!
//! Contains primitives to create a repository within the store path

use git2::{Repository, Index};

use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::runtime::Runtime as GRuntime;
use vcs::git::action::StoreAction;
use vcs::git::error::MapIntoHookError;

use libimagutil::debug_result::*;
use libimagstore::hook::error::HookError;

pub fn fetch_index(repo: &Repository, action: &StoreAction) -> Result<Index, HookError> {
    debug!("[GIT {} HOOK]: Getting Index", action.uppercase());
    repo.index()
        .map_dbg_err(|_| format!("[GIT {} HOOK]: Couldn't fetch Index", action.uppercase()))
        .map_dbg(|_| format!("[GIT {} HOOK]: Index object fetched", action.uppercase()))
        .map_err_into(GHEK::RepositoryIndexFetchingError)
        .map_into_hook_error()
}

<commit_msg>Remove unused imports: util module<commit_after>//! Utility functionality for integrating git hooks in the store
//!
//! Contains primitives to create a repository within the store path

use git2::{Repository, Index};

use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::action::StoreAction;
use vcs::git::error::MapIntoHookError;

use libimagutil::debug_result::*;
use libimagstore::hook::error::HookError;

pub fn fetch_index(repo: &Repository, action: &StoreAction) -> Result<Index, HookError> {
    debug!("[GIT {} HOOK]: Getting Index", action.uppercase());
    repo.index()
        .map_dbg_err(|_| format!("[GIT {} HOOK]: Couldn't fetch Index", action.uppercase()))
        .map_dbg(|_| format!("[GIT {} HOOK]: Index object fetched", action.uppercase()))
        .map_err_into(GHEK::RepositoryIndexFetchingError)
        .map_into_hook_error()
}

<|endoftext|>


<commit_before>extern crate metl;

use metl::extras::window::{Event, WindowBuilder};
use metl::ClearColor;

fn main() {
    let device = metl::Device::system_default_device().unwrap();
    let mut window = WindowBuilder::new(device)
                     .with_dimensions(800, 600)
                     .with_title("Metal Window".into())
                     .build()
                     .unwrap();
    window.view.set_clear_color(ClearColor::new(1.0, 0.0, 0.0, 1.0));

    'mainloop: loop {
        for event in window.poll_events() {
            match event {
                Event::Closed => {
                    break 'mainloop
                }
                _ => {}
            }
        }

        // drawing code here
        window.view.draw();
    }
}
<commit_msg>Improve example<commit_after>extern crate metl;

use metl::extras::window::{Event, WindowBuilder};
use metl::{ClearColor, PixelFormat};

fn main() {
    let device = metl::Device::system_default_device().unwrap();
    let mut window = WindowBuilder::new(device)
                     .with_dimensions(800, 600)
                     .with_title("Metal Window".into())
                     .build()
                     .unwrap();

    window.view.set_depth_stencil_pixel_format(PixelFormat::Rgba8Unorm);
    window.view.set_clear_color(ClearColor::new(1.0, 0.0, 0.0, 1.0));

    'mainloop: loop {
        for event in window.poll_events() {
            match event {
                Event::Closed => {
                    break 'mainloop
                }
                _ => {}
            }
        }

        window.view.draw();
    }
}
<|endoftext|>


<commit_before>use std::{os::unix::prelude::AsRawFd, sync::Arc};

use calloop::{generic::Generic, EventLoop, Interest, PostAction};
use slog::Logger;
use smithay::{
    desktop::{Space, WindowSurfaceType},
    utils::{Logical, Point},
    wayland::{
        compositor::CompositorState,
        output::OutputManagerState,
        seat::{Seat, SeatState},
        shell::xdg::XdgShellState,
        shm::ShmState,
    },
};
use wayland_server::{
    backend::{ClientData, ClientId, DisconnectReason},
    protocol::wl_surface::WlSurface,
    socket::ListeningSocket,
    Client, Display,
};

use crate::CalloopData;

pub struct Smallvil {
    pub pointer_location: Point<f64, Logical>,

    pub start_time: std::time::Instant,
    pub clients: Vec<Client>,

    pub space: Space,
    pub log: slog::Logger,
    // Smithay State
    pub compositor_state: CompositorState,
    pub xdg_shell_state: XdgShellState,
    pub shm_state: ShmState,
    pub output_manager_state: OutputManagerState,
    pub seat_state: SeatState<Smallvil>,
    pub seat: Seat<Self>,
}

impl Smallvil {
    pub fn new(event_loop: &mut EventLoop<CalloopData>, display: &mut Display<Self>, log: Logger) -> Self {
        let start_time = std::time::Instant::now();

        let compositor_state = CompositorState::new(display, None);
        let xdg_shell_state = XdgShellState::new(display, None).0;
        let shm_state = ShmState::new(display, vec![], None);
        let output_manager_state = OutputManagerState::new_with_xdg_output(display);
        let seat_state = SeatState::new();

        let mut seat: Seat<Self> = Seat::new(display, "winit", None);

        seat.add_keyboard(&mut display.handle(), Default::default(), 200, 200, |_, _| {})
            .unwrap();

        seat.add_pointer(&mut display.handle(), |_| {});

        Self::init_wayland_listener(event_loop);

        Self {
            pointer_location: Default::default(),

            start_time,
            clients: Vec::new(),

            space: Space::new(log.clone()),
            log,
            compositor_state,
            xdg_shell_state,
            shm_state,
            output_manager_state,
            seat_state,
            seat,
        }
    }

    fn init_wayland_listener(event_loop: &mut EventLoop<CalloopData>) {
        use calloop::Mode;

        let handle = event_loop.handle();
        let listener = ListeningSocket::bind("wayland-5").unwrap();

        event_loop
            .handle()
            .insert_source(
                Generic::from_fd(listener.as_raw_fd(), Interest::READ, Mode::Level),
                move |_, _, state| {
                    let display = &mut state.display;
                    let state = &mut state.state;

                    match listener.accept().unwrap() {
                        Some(stream) => {
                            handle
                                .insert_source(
                                    Generic::from_fd(stream.as_raw_fd(), Interest::READ, Mode::Level),
                                    |_, _, data| {
                                        data.display.dispatch_clients(&mut data.state).unwrap();
                                        Ok(PostAction::Continue)
                                    },
                                )
                                .unwrap();

                            let client = display.insert_client(stream, Arc::new(ClientState)).unwrap();
                            state.clients.push(client);
                        }
                        None => {}
                    }

                    display.dispatch_clients(state).unwrap();

                    Ok(PostAction::Continue)
                },
            )
            .expect("Failed to init the wayland event source.");
    }

    pub fn surface_under_pointer(&self) -> Option<(WlSurface, Point<i32, Logical>)> {
        let pos = self.pointer_location;

        if let Some(window) = self.space.window_under(pos) {
            let window_loc = self.space.window_location(window).unwrap();
            window
                .surface_under(pos - window_loc.to_f64(), WindowSurfaceType::all())
                .map(|(s, loc)| (s, loc + window_loc))
        } else {
            None
        }
    }
}

pub struct ClientState;
impl ClientData<Smallvil> for ClientState {
    fn initialized(&self, _client_id: ClientId) {}
    fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) {}
}
<commit_msg>smallvil: Fix surface_under to ignore decorations<commit_after>use std::{os::unix::prelude::AsRawFd, sync::Arc};

use calloop::{generic::Generic, EventLoop, Interest, PostAction};
use slog::Logger;
use smithay::{
    desktop::{Space, WindowSurfaceType},
    utils::{Logical, Point},
    wayland::{
        compositor::CompositorState,
        output::OutputManagerState,
        seat::{Seat, SeatState},
        shell::xdg::XdgShellState,
        shm::ShmState,
    },
};
use wayland_server::{
    backend::{ClientData, ClientId, DisconnectReason},
    protocol::wl_surface::WlSurface,
    socket::ListeningSocket,
    Client, Display,
};

use crate::CalloopData;

pub struct Smallvil {
    pub pointer_location: Point<f64, Logical>,

    pub start_time: std::time::Instant,
    pub clients: Vec<Client>,

    pub space: Space,
    pub log: slog::Logger,
    // Smithay State
    pub compositor_state: CompositorState,
    pub xdg_shell_state: XdgShellState,
    pub shm_state: ShmState,
    pub output_manager_state: OutputManagerState,
    pub seat_state: SeatState<Smallvil>,
    pub seat: Seat<Self>,
}

impl Smallvil {
    pub fn new(event_loop: &mut EventLoop<CalloopData>, display: &mut Display<Self>, log: Logger) -> Self {
        let start_time = std::time::Instant::now();

        let compositor_state = CompositorState::new(display, None);
        let xdg_shell_state = XdgShellState::new(display, None).0;
        let shm_state = ShmState::new(display, vec![], None);
        let output_manager_state = OutputManagerState::new_with_xdg_output(display);
        let seat_state = SeatState::new();

        let mut seat: Seat<Self> = Seat::new(display, "winit", None);

        seat.add_keyboard(&mut display.handle(), Default::default(), 200, 200, |_, _| {})
            .unwrap();

        seat.add_pointer(&mut display.handle(), |_| {});

        Self::init_wayland_listener(event_loop);

        Self {
            pointer_location: Default::default(),

            start_time,
            clients: Vec::new(),

            space: Space::new(log.clone()),
            log,
            compositor_state,
            xdg_shell_state,
            shm_state,
            output_manager_state,
            seat_state,
            seat,
        }
    }

    fn init_wayland_listener(event_loop: &mut EventLoop<CalloopData>) {
        use calloop::Mode;

        let handle = event_loop.handle();
        let listener = ListeningSocket::bind("wayland-5").unwrap();

        event_loop
            .handle()
            .insert_source(
                Generic::from_fd(listener.as_raw_fd(), Interest::READ, Mode::Level),
                move |_, _, state| {
                    let display = &mut state.display;
                    let state = &mut state.state;

                    match listener.accept().unwrap() {
                        Some(stream) => {
                            handle
                                .insert_source(
                                    Generic::from_fd(stream.as_raw_fd(), Interest::READ, Mode::Level),
                                    |_, _, data| {
                                        data.display.dispatch_clients(&mut data.state).unwrap();
                                        Ok(PostAction::Continue)
                                    },
                                )
                                .unwrap();

                            let client = display.insert_client(stream, Arc::new(ClientState)).unwrap();
                            state.clients.push(client);
                        }
                        None => {}
                    }

                    display.dispatch_clients(state).unwrap();

                    Ok(PostAction::Continue)
                },
            )
            .expect("Failed to init the wayland event source.");
    }

    pub fn surface_under_pointer(&self) -> Option<(WlSurface, Point<i32, Logical>)> {
        let pos = self.pointer_location;
        self.space
            .surface_under(pos, WindowSurfaceType::all())
            .map(|(_, surface, location)| (surface, location))
    }
}

pub struct ClientState;
impl ClientData<Smallvil> for ClientState {
    fn initialized(&self, _client_id: ClientId) {}
    fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) {}
}
<|endoftext|>


<commit_before>use std::fs;
use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::os::unix;
use std::path::Path;

// `% cat path` 的简单实现
fn cat(path: &Path) -> io::Result<String> {
    let mut f = try!(File::open(path));
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

// `% echo s > path` 的简单实现
fn echo(s: &str, path: &Path) -> io::Result<()> {
    let mut f = try!(File::create(path));

    f.write_all(s.as_bytes())
}

// `% touch path`（忽略已存在文件）的简单实现
fn touch(path: &Path) -> io::Result<()> {
    match OpenOptions::new().create(true).open(path) {
        Ok(_) => Ok(()),
        Err(e) => Err(e),
    }
}

fn main() {
    println!("`mkdir a`");
    // 创建一个目录，返回 `io::Result<()>`
    match fs::create_dir("a") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(_) => {},
    }

    println!("`echo hello > a/b.txt`");
    // 前面的匹配可以用 `unwrap_or_else` 方法简化
    echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`mkdir -p a/c/d`");
    // 递归创建一个目录，返回 `io::Result<()>`
    fs::create_dir_all("a/c/d").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`touch a/c/e.txt`");
    touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`ln -s ../b.txt a/c/b.txt`");
    // 创建一个符号链接，返回 `io::Resutl<()>`
    if cfg!(target_family = "unix") {
        unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
        });
    }

    println!("`cat a/c/b.txt`");
    match cat(&Path::new("a/c/b.txt")) {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(s) => println!("> {}", s),
    }

    println!("`ls a`");
    // 读取目录的内容，返回 `io::Result<Vec<Path>>`
    match fs::read_dir("a") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(paths) => for path in paths {
            println!("> {:?}", path.unwrap().path());
        },
    }

    println!("`rm a/c/e.txt`");
    // 删除一个文件，返回 `io::Result<()>`
    fs::remove_file("a/c/e.txt").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`rmdir a/c/d`");
    // 移除一个空目录，返回 `io::Result<()>`
    fs::remove_dir("a/c/d").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });
}
<commit_msg>Added missing write(true) option.<commit_after>use std::fs;
use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::os::unix;
use std::path::Path;

// `% cat path` 的简单实现
fn cat(path: &Path) -> io::Result<String> {
    let mut f = try!(File::open(path));
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

// `% echo s > path` 的简单实现
fn echo(s: &str, path: &Path) -> io::Result<()> {
    let mut f = try!(File::create(path));

    f.write_all(s.as_bytes())
}

// `% touch path`（忽略已存在文件）的简单实现
fn touch(path: &Path) -> io::Result<()> {
    match OpenOptions::new().create(true).write(true).open(path) {
        Ok(_) => Ok(()),
        Err(e) => Err(e),
    }
}

fn main() {
    println!("`mkdir a`");
    // 创建一个目录，返回 `io::Result<()>`
    match fs::create_dir("a") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(_) => {},
    }

    println!("`echo hello > a/b.txt`");
    // 前面的匹配可以用 `unwrap_or_else` 方法简化
    echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`mkdir -p a/c/d`");
    // 递归创建一个目录，返回 `io::Result<()>`
    fs::create_dir_all("a/c/d").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`touch a/c/e.txt`");
    touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`ln -s ../b.txt a/c/b.txt`");
    // 创建一个符号链接，返回 `io::Resutl<()>`
    if cfg!(target_family = "unix") {
        unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
        });
    }

    println!("`cat a/c/b.txt`");
    match cat(&Path::new("a/c/b.txt")) {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(s) => println!("> {}", s),
    }

    println!("`ls a`");
    // 读取目录的内容，返回 `io::Result<Vec<Path>>`
    match fs::read_dir("a") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(paths) => for path in paths {
            println!("> {:?}", path.unwrap().path());
        },
    }

    println!("`rm a/c/e.txt`");
    // 删除一个文件，返回 `io::Result<()>`
    fs::remove_file("a/c/e.txt").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });

    println!("`rmdir a/c/d`");
    // 移除一个空目录，返回 `io::Result<()>`
    fs::remove_dir("a/c/d").unwrap_or_else(|why| {
        println!("! {:?}", why.kind());
    });
}
<|endoftext|>


<commit_before>extern crate glutin;

pub struct CameraState {
    aspect_ratio: f32,
    position: (f32, f32, f32),
    direction: (f32, f32, f32),

    moving_up: bool,
    moving_left: bool,
    moving_down: bool,
    moving_right: bool,
    moving_forward: bool,
    moving_backward: bool,
}

impl CameraState {
    pub fn new() -> CameraState {
        CameraState {
            aspect_ratio: 1024.0 / 768.0,
            position: (0.1, 0.1, 1.0),
            direction: (0.0, 0.0, -1.0),
            moving_up: false,
            moving_left: false,
            moving_down: false,
            moving_right: false,
            moving_forward: false,
            moving_backward: false,
        }
    }

    pub fn get_perspective(&self) -> [[f32; 4]; 4] {
        let fov: f32 = 3.141592 / 2.0;
        let zfar = 25.0;
        let znear = 0.1;

        let f = 1.0 / (fov / 2.0).tan();

        // note: remember that this is column-major, so the lines of code are actually columns
        [
            [f / self.aspect_ratio,    0.0,              0.0              ,   0.0],
            [         0.0         ,     f ,              0.0              ,   0.0],
            [         0.0         ,    0.0,  (zfar+znear)/(znear-zfar)    ,  -1.0],
            [         0.0         ,    0.0,  (2.0*zfar*znear)/(znear-zfar),   0.0],
        ]
    }

    pub fn get_view(&self) -> [[f32; 4]; 4] {
        let f = {
            let f = self.direction;
            let len = f.0 * f.0 + f.1 * f.1 + f.2 * f.2;
            let len = len.sqrt();
            (f.0 / len, f.1 / len, f.2 / len)
        };

        let up = (0.0, 1.0, 0.0);

        let s = (f.1 * up.2 - f.2 * up.1,
                 f.2 * up.0 - f.0 * up.2,
                 f.0 * up.1 - f.1 * up.0);

        let s_norm = {
            let len = s.0 * s.0 + s.1 * s.1 + s.2 * s.2;
            let len = len.sqrt();
            (s.0 / len, s.1 / len, s.2 / len)
        };

        let u = (s_norm.1 * f.2 - s_norm.2 * f.1,
                 s_norm.2 * f.0 - s_norm.0 * f.2,
                 s_norm.0 * f.1 - s_norm.1 * f.0);

        // note: remember that this is column-major, so the lines of code are actually columns
        [
            [s.0, u.0, -f.0, 0.0],
            [s.1, u.1, -f.1, 0.0],
            [s.2, u.2, -f.2, 0.0],
            [-self.position.0, -self.position.1, -self.position.2, 1.0],
        ]
    }

    pub fn update(&mut self) {
        if self.moving_up {
            self.position.1 += 0.01;
        }

        if self.moving_left {
            self.position.0 -= 0.01;
        }

        if self.moving_down {
            self.position.1 -= 0.01;
        }

        if self.moving_right {
            self.position.0 += 0.01;
        }

        if self.moving_forward {
            self.position.0 += self.direction.0 * 0.01;
            self.position.1 += self.direction.1 * 0.01;
            self.position.2 += self.direction.2 * 0.01;
        }

        if self.moving_backward {
            self.position.0 -= self.direction.0 * 0.01;
            self.position.1 -= self.direction.1 * 0.01;
            self.position.2 -= self.direction.2 * 0.01;
        }
    }

    pub fn process_input(&mut self, event: &glutin::Event) {
        match event {
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Space)) => {
                self.moving_up = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Space)) => {
                self.moving_up = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Down)) => {
                self.moving_down = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Down)) => {
                self.moving_down = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::A)) => {
                self.moving_left = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::A)) => {
                self.moving_left = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::D)) => {
                self.moving_right = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::D)) => {
                self.moving_right = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::W)) => {
                self.moving_forward = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::W)) => {
                self.moving_forward = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::S)) => {
                self.moving_backward = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::S)) => {
                self.moving_backward = false;
            },
            _ => {}
        }
    }
}
<commit_msg>Fix the camera handling the examples<commit_after>extern crate glutin;

pub struct CameraState {
    aspect_ratio: f32,
    position: (f32, f32, f32),
    direction: (f32, f32, f32),

    moving_up: bool,
    moving_left: bool,
    moving_down: bool,
    moving_right: bool,
    moving_forward: bool,
    moving_backward: bool,
}

impl CameraState {
    pub fn new() -> CameraState {
        CameraState {
            aspect_ratio: 1024.0 / 768.0,
            position: (0.1, 0.1, 1.0),
            direction: (0.0, 0.0, 1.0),
            moving_up: false,
            moving_left: false,
            moving_down: false,
            moving_right: false,
            moving_forward: false,
            moving_backward: false,
        }
    }

    pub fn set_position(&mut self, pos: (f32, f32, f32)) {
        self.position = pos;
    }

    pub fn set_direction(&mut self, dir: (f32, f32, f32)) {
        self.direction = dir;
    }

    pub fn get_perspective(&self) -> [[f32; 4]; 4] {
        let fov: f32 = 3.141592 / 2.0;
        let zfar = 1024.0;
        let znear = 0.1;

        let f = 1.0 / (fov / 2.0).tan();

        // note: remember that this is column-major, so the lines of code are actually columns
        [
            [f / self.aspect_ratio,    0.0,              0.0              ,   0.0],
            [         0.0         ,     f ,              0.0              ,   0.0],
            [         0.0         ,    0.0,  (zfar+znear)/(znear-zfar)    ,  -1.0],
            [         0.0         ,    0.0,  (2.0*zfar*znear)/(znear-zfar),   0.0],
        ]
    }

    pub fn get_view(&self) -> [[f32; 4]; 4] {
        let f = {
            let f = self.direction;
            let len = f.0 * f.0 + f.1 * f.1 + f.2 * f.2;
            let len = len.sqrt();
            (f.0 / len, f.1 / len, f.2 / len)
        };

        let up = (0.0, 1.0, 0.0);

        let s = (f.1 * up.2 - f.2 * up.1,
                 f.2 * up.0 - f.0 * up.2,
                 f.0 * up.1 - f.1 * up.0);

        let s_norm = {
            let len = s.0 * s.0 + s.1 * s.1 + s.2 * s.2;
            let len = len.sqrt();
            (s.0 / len, s.1 / len, s.2 / len)
        };

        let u = (s_norm.1 * f.2 - s_norm.2 * f.1,
                 s_norm.2 * f.0 - s_norm.0 * f.2,
                 s_norm.0 * f.1 - s_norm.1 * f.0);

        let p = (-self.position.0 * s.0 - self.position.1 * s.1 - self.position.2 * s.2,
                 -self.position.0 * u.0 - self.position.1 * u.1 - self.position.2 * u.2,
                 -self.position.0 * f.0 - self.position.1 * f.1 - self.position.2 * f.2);

        // note: remember that this is column-major, so the lines of code are actually columns
        [
            [s.0, u.0, -f.0, 0.0],
            [s.1, u.1, -f.1, 0.0],
            [s.2, u.2, -f.2, 0.0],
            [p.0, p.1,  p.2, 1.0],
        ]
    }

    pub fn update(&mut self) {
        let f = {
            let f = self.direction;
            let len = f.0 * f.0 + f.1 * f.1 + f.2 * f.2;
            let len = len.sqrt();
            (f.0 / len, f.1 / len, f.2 / len)
        };

        let up = (0.0, 1.0, 0.0);

        let s = (f.1 * up.2 - f.2 * up.1,
                 f.2 * up.0 - f.0 * up.2,
                 f.0 * up.1 - f.1 * up.0);

        let s = {
            let len = s.0 * s.0 + s.1 * s.1 + s.2 * s.2;
            let len = len.sqrt();
            (s.0 / len, s.1 / len, s.2 / len)
        };

        let u = (s.1 * f.2 - s.2 * f.1,
                 s.2 * f.0 - s.0 * f.2,
                 s.0 * f.1 - s.1 * f.0);

        if self.moving_up {
            self.position.0 += u.0 * 0.01;
            self.position.1 += u.1 * 0.01;
            self.position.2 += u.2 * 0.01;
        }

        if self.moving_left {
            self.position.0 -= s.0 * 0.01;
            self.position.1 -= s.1 * 0.01;
            self.position.2 -= s.2 * 0.01;
        }

        if self.moving_down {
            self.position.0 -= u.0 * 0.01;
            self.position.1 -= u.1 * 0.01;
            self.position.2 -= u.2 * 0.01;
        }

        if self.moving_right {
            self.position.0 += s.0 * 0.01;
            self.position.1 += s.1 * 0.01;
            self.position.2 += s.2 * 0.01;
        }

        if self.moving_forward {
            // TODO: to be honest, I don't understand why this is the wrong way
            self.position.0 -= f.0 * 0.01;
            self.position.1 -= f.1 * 0.01;
            self.position.2 -= f.2 * 0.01;
        }

        if self.moving_backward {
            // TODO: to be honest, I don't understand why this is the wrong way
            self.position.0 += f.0 * 0.01;
            self.position.1 += f.1 * 0.01;
            self.position.2 += f.2 * 0.01;
        }
    }

    pub fn process_input(&mut self, event: &glutin::Event) {
        match event {
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Space)) => {
                self.moving_up = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Space)) => {
                self.moving_up = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Down)) => {
                self.moving_down = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Down)) => {
                self.moving_down = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::A)) => {
                self.moving_left = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::A)) => {
                self.moving_left = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::D)) => {
                self.moving_right = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::D)) => {
                self.moving_right = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::W)) => {
                self.moving_forward = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::W)) => {
                self.moving_forward = false;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::S)) => {
                self.moving_backward = true;
            },
            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::S)) => {
                self.moving_backward = false;
            },
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use futures::{Future, Sink, Stream};
use futures::stream::Wait;
use futures::sync::mpsc;
use tokio_core::reactor::Core;
use tokio_timer::{TimeoutStream, Timer};

use std::net::SocketAddr;
use std::thread;
use std::time::{self, Duration};

use crypto::{gen_keypair, PublicKey, Signature};
use messages::{Connect, Message, MessageWriter, RawMessage};
use events::{NetworkEvent, NetworkRequest};
use events::network::{NetworkConfiguration, NetworkPart};
use node::{EventsPoolCapacity, NodeChannel};

#[derive(Debug)]
pub struct TestHandler {
    listen_address: SocketAddr,
    network_events_rx: Wait<TimeoutStream<mpsc::Receiver<NetworkEvent>>>,
    network_requests_tx: mpsc::Sender<NetworkRequest>,
}

impl TestHandler {
    pub fn new(
        listen_address: SocketAddr,
        network_requests_tx: mpsc::Sender<NetworkRequest>,
        network_events_rx: mpsc::Receiver<NetworkEvent>,
    ) -> TestHandler {
        let timer = Timer::default();
        let receiver = timer.timeout_stream(network_events_rx, Duration::from_secs(30));
        TestHandler {
            listen_address,
            network_requests_tx,
            network_events_rx: receiver.wait(),
        }
    }

    pub fn wait_for_event(&mut self) -> Result<NetworkEvent, ()> {
        let event = self.network_events_rx.next().unwrap()?;
        Ok(event)
    }

    pub fn connect_with(&self, addr: SocketAddr) {
        let connect = connect_message(self.listen_address);
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, connect.raw().clone()))
            .wait()
            .unwrap();
    }

    pub fn disconnect_with(&self, addr: SocketAddr) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::DisconnectWithPeer(addr))
            .wait()
            .unwrap();
    }

    pub fn send_to(&self, addr: SocketAddr, raw: RawMessage) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, raw))
            .wait()
            .unwrap();
    }

    pub fn wait_for_connect(&mut self) -> Connect {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerConnected(_addr, connect)) => connect,
            Ok(other) => panic!("Unexpected connect received, {:?}", other),
            Err(e) => panic!("An error during wait for connect occured, {:?}", e),
        }
    }

    pub fn wait_for_disconnect(&mut self) -> SocketAddr {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerDisconnected(addr)) => addr,
            Ok(other) => panic!("Unexpected disconnect received, {:?}", other),
            Err(e) => panic!("An error during wait for disconnect occured, {:?}", e),
        }
    }

    pub fn wait_for_message(&mut self) -> RawMessage {
        match self.wait_for_event() {
            Ok(NetworkEvent::MessageReceived(_addr, msg)) => msg,
            Ok(other) => panic!("Unexpected message received, {:?}", other),
            Err(e) => panic!("An error during wait for message occured, {:?}", e),
        }
    }
}

impl Drop for TestHandler {
    fn drop(&mut self) {
        if !::std::thread::panicking() {
            self.network_requests_tx
                .clone()
                .send(NetworkRequest::Shutdown)
                .wait()
                .unwrap();
        }
    }
}

#[derive(Debug)]
pub struct TestEvents {
    pub listen_address: SocketAddr,
    pub network_config: NetworkConfiguration,
    pub events_config: EventsPoolCapacity,
}

impl TestEvents {
    pub fn with_addr(listen_address: SocketAddr) -> TestEvents {
        TestEvents {
            listen_address,
            network_config: NetworkConfiguration::default(),
            events_config: EventsPoolCapacity::default(),
        }
    }

    pub fn spawn(self) -> TestHandler
    {
        use tokio_core::reactor::Timeout;
        use std::time::Duration;
        let (handler_part, network_part) = self.into_reactor();
        thread::spawn(move || {
            let mut core = Core::new().unwrap();
            let fut = network_part.run(core.handle());
            core.run(fut)
        });
        handler_part
    }

    fn into_reactor(self) -> (TestHandler, NetworkPart) {
        let channel = NodeChannel::new(self.events_config);
        let network_config = self.network_config;
        let (network_tx, network_rx) = channel.network_events;
        let network_requests_tx = channel.network_requests.0.clone();

        let network_part = NetworkPart {
            listen_address: self.listen_address,
            network_config,
            network_requests: channel.network_requests,
            network_tx: network_tx.clone(),
        };

        let handler_part =
            TestHandler::new(self.listen_address, network_requests_tx, network_rx);
        (handler_part, network_part)
    }
}

pub fn connect_message(addr: SocketAddr) -> Connect {
    let time = time::UNIX_EPOCH;
    Connect::new_with_signature(&PublicKey::zero(), addr, time, &Signature::zero())
}

pub fn raw_message(id: u16, len: usize) -> RawMessage {
    let writer = MessageWriter::new(
        ::messages::PROTOCOL_MAJOR_VERSION,
        ::messages::TEST_NETWORK_ID,
        0,
        id,
        len,
    );
    RawMessage::new(writer.sign(&gen_keypair().1))
}

#[test]
fn test_network_handshake() {
    extern crate env_logger;
    drop(env_logger::init());
    use std::{thread, time};
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17230".parse().unwrap(), "127.0.0.1:17231".parse().unwrap()];

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);

    let mut e1 = e1.spawn();
    let mut e2 = e2.spawn();

    e1.connect_with(addrs[1]);
    assert_eq!(e2.wait_for_connect(), c1);

    e2.connect_with(addrs[0]);
    assert_eq!(e1.wait_for_connect(), c2);

    e1.disconnect_with(addrs[1]);
    assert_eq!(e1.wait_for_disconnect(), addrs[1]);

    e2.disconnect_with(addrs[0]);
    assert_eq!(e2.wait_for_disconnect(), addrs[0]);
}

/*
#[test]
fn test_network_big_message() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17200".parse().unwrap(), "127.0.0.1:17201".parse().unwrap()];

    let msg1 = raw_message(15, 100000);
    let msg2 = raw_message(16, 400);

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let m1 = msg1.clone();
    let m2 = msg2.clone();
    let t1 = e1.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[1]);
        e.wait_for_connect();

        e.send_to(addrs[1], m1.clone());
        e.send_to(addrs[1], m2.clone());
        e.send_to(addrs[1], m1.clone());

        assert_eq!(e.wait_for_message(), m2);
        assert_eq!(e.wait_for_message(), m1);
        assert_eq!(e.wait_for_message(), m2);

        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });

    let m1 = msg1.clone();
    let m2 = msg2.clone();
    let t2 = e2.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[0]);
        e.wait_for_connect();

        e.send_to(addrs[0], m2.clone());
        e.send_to(addrs[0], m1.clone());
        e.send_to(addrs[0], m2.clone());

        assert_eq!(e.wait_for_message(), m1);
        assert_eq!(e.wait_for_message(), m2);
        assert_eq!(e.wait_for_message(), m1);

        e.disconnect_with(addrs[0]);
        assert_eq!(e.wait_for_disconnect(), addrs[0]);
    });

    t2.join().unwrap();
    t1.join().unwrap();
}

#[test]
fn test_network_reconnect() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:19100".parse().unwrap(), "127.0.0.1:19101".parse().unwrap()];

    let msg = raw_message(11, 1000);
    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);
    let msg_cloned = msg.clone();
    let t1 = TestEvents::with_addr(addrs[0]).spawn(move |e: &mut TestHandler| {
        // Handle first attempt
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_connect(), c2);
        assert_eq!(e.wait_for_message(), msg_cloned);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
        // Handle second attempt
        assert_eq!(e.wait_for_connect(), c2);
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_message(), msg_cloned);
        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });
    // First connect attempt.
    let c1_cloned = c1.clone();
    let msg_cloned = msg.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.connect_with(addrs[0]);
            e.send_to(addrs[0], msg_cloned.clone());
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Second connect attempt.
    let c1_cloned = c1.clone();
    let msg_cloned = msg.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            e.connect_with(addrs[0]);
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.send_to(addrs[0], msg_cloned.clone());
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Wait for first server
    t1.join().unwrap();
}
*/
<commit_msg>Fix test_network_big_message<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use futures::{Future, Sink, Stream};
use futures::stream::Wait;
use futures::sync::mpsc;
use tokio_core::reactor::Core;
use tokio_timer::{TimeoutStream, Timer};

use std::net::SocketAddr;
use std::thread;
use std::time::{self, Duration};

use crypto::{gen_keypair, PublicKey, Signature};
use messages::{Connect, Message, MessageWriter, RawMessage};
use events::{NetworkEvent, NetworkRequest};
use events::network::{NetworkConfiguration, NetworkPart};
use node::{EventsPoolCapacity, NodeChannel};

#[derive(Debug)]
pub struct TestHandler {
    listen_address: SocketAddr,
    network_events_rx: Wait<TimeoutStream<mpsc::Receiver<NetworkEvent>>>,
    network_requests_tx: mpsc::Sender<NetworkRequest>,
}

impl TestHandler {
    pub fn new(
        listen_address: SocketAddr,
        network_requests_tx: mpsc::Sender<NetworkRequest>,
        network_events_rx: mpsc::Receiver<NetworkEvent>,
    ) -> TestHandler {
        let timer = Timer::default();
        let receiver = timer.timeout_stream(network_events_rx, Duration::from_secs(30));
        TestHandler {
            listen_address,
            network_requests_tx,
            network_events_rx: receiver.wait(),
        }
    }

    pub fn wait_for_event(&mut self) -> Result<NetworkEvent, ()> {
        let event = self.network_events_rx.next().unwrap()?;
        Ok(event)
    }

    pub fn connect_with(&self, addr: SocketAddr) {
        let connect = connect_message(self.listen_address);
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, connect.raw().clone()))
            .wait()
            .unwrap();
    }

    pub fn disconnect_with(&self, addr: SocketAddr) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::DisconnectWithPeer(addr))
            .wait()
            .unwrap();
    }

    pub fn send_to(&self, addr: SocketAddr, raw: RawMessage) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, raw))
            .wait()
            .unwrap();
    }

    pub fn wait_for_connect(&mut self) -> Connect {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerConnected(_addr, connect)) => connect,
            Ok(other) => panic!("Unexpected connect received, {:?}", other),
            Err(e) => panic!("An error during wait for connect occured, {:?}", e),
        }
    }

    pub fn wait_for_disconnect(&mut self) -> SocketAddr {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerDisconnected(addr)) => addr,
            Ok(other) => panic!("Unexpected disconnect received, {:?}", other),
            Err(e) => panic!("An error during wait for disconnect occured, {:?}", e),
        }
    }

    pub fn wait_for_message(&mut self) -> RawMessage {
        match self.wait_for_event() {
            Ok(NetworkEvent::MessageReceived(_addr, msg)) => msg,
            Ok(other) => panic!("Unexpected message received, {:?}", other),
            Err(e) => panic!("An error during wait for message occured, {:?}", e),
        }
    }
}

impl Drop for TestHandler {
    fn drop(&mut self) {
        if !::std::thread::panicking() {
            self.network_requests_tx
                .clone()
                .send(NetworkRequest::Shutdown)
                .wait()
                .unwrap();
        }
    }
}

#[derive(Debug)]
pub struct TestEvents {
    pub listen_address: SocketAddr,
    pub network_config: NetworkConfiguration,
    pub events_config: EventsPoolCapacity,
}

impl TestEvents {
    pub fn with_addr(listen_address: SocketAddr) -> TestEvents {
        TestEvents {
            listen_address,
            network_config: NetworkConfiguration::default(),
            events_config: EventsPoolCapacity::default(),
        }
    }

    pub fn spawn(self) -> TestHandler
    {
        let (handler_part, network_part) = self.into_reactor();
        thread::spawn(move || {
            let mut core = Core::new().unwrap();
            let fut = network_part.run(core.handle());
            core.run(fut)
        });
        handler_part
    }

    fn into_reactor(self) -> (TestHandler, NetworkPart) {
        let channel = NodeChannel::new(self.events_config);
        let network_config = self.network_config;
        let (network_tx, network_rx) = channel.network_events;
        let network_requests_tx = channel.network_requests.0.clone();

        let network_part = NetworkPart {
            listen_address: self.listen_address,
            network_config,
            network_requests: channel.network_requests,
            network_tx: network_tx.clone(),
        };

        let handler_part =
            TestHandler::new(self.listen_address, network_requests_tx, network_rx);
        (handler_part, network_part)
    }
}

pub fn connect_message(addr: SocketAddr) -> Connect {
    let time = time::UNIX_EPOCH;
    Connect::new_with_signature(&PublicKey::zero(), addr, time, &Signature::zero())
}

pub fn raw_message(id: u16, len: usize) -> RawMessage {
    let writer = MessageWriter::new(
        ::messages::PROTOCOL_MAJOR_VERSION,
        ::messages::TEST_NETWORK_ID,
        0,
        id,
        len,
    );
    RawMessage::new(writer.sign(&gen_keypair().1))
}

#[test]
fn test_network_handshake() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17230".parse().unwrap(), "127.0.0.1:17231".parse().unwrap()];

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);

    let mut e1 = e1.spawn();
    let mut e2 = e2.spawn();

    e1.connect_with(addrs[1]);
    assert_eq!(e2.wait_for_connect(), c1);

    e2.connect_with(addrs[0]);
    assert_eq!(e1.wait_for_connect(), c2);

    e1.disconnect_with(addrs[1]);
    assert_eq!(e1.wait_for_disconnect(), addrs[1]);

    e2.disconnect_with(addrs[0]);
    assert_eq!(e2.wait_for_disconnect(), addrs[0]);
}

#[test]
fn test_network_big_message() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17200".parse().unwrap(), "127.0.0.1:17201".parse().unwrap()];

    let m1 = raw_message(15, 100000);
    let m2 = raw_message(16, 400);

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let mut e1 = e1.spawn();
    let mut e2 = e2.spawn();

    e1.connect_with(addrs[1]);
    e2.wait_for_connect();

    e2.connect_with(addrs[0]);
    e1.wait_for_connect();

    e1.send_to(addrs[1], m1.clone());
    assert_eq!(e2.wait_for_message(), m1);

    e1.send_to(addrs[1], m2.clone());
    assert_eq!(e2.wait_for_message(), m2);

    e1.send_to(addrs[1], m1.clone());
    assert_eq!(e2.wait_for_message(), m1);

    e2.send_to(addrs[0], m2.clone());
    assert_eq!(e1.wait_for_message(), m2);

    e2.send_to(addrs[0], m1.clone());
    assert_eq!(e1.wait_for_message(), m1);

    e2.send_to(addrs[0], m2.clone());
    assert_eq!(e1.wait_for_message(), m2);

    e1.disconnect_with(addrs[1]);
    assert_eq!(e1.wait_for_disconnect(), addrs[1]);

    e2.disconnect_with(addrs[0]);
    assert_eq!(e2.wait_for_disconnect(), addrs[0]);
}

/*
#[test]
fn test_network_reconnect() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:19100".parse().unwrap(), "127.0.0.1:19101".parse().unwrap()];

    let msg = raw_message(11, 1000);
    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);
    let msg_cloned = msg.clone();
    let t1 = TestEvents::with_addr(addrs[0]).spawn(move |e: &mut TestHandler| {
        // Handle first attempt
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_connect(), c2);
        assert_eq!(e.wait_for_message(), msg_cloned);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
        // Handle second attempt
        assert_eq!(e.wait_for_connect(), c2);
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_message(), msg_cloned);
        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });
    // First connect attempt.
    let c1_cloned = c1.clone();
    let msg_cloned = msg.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.connect_with(addrs[0]);
            e.send_to(addrs[0], msg_cloned.clone());
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Second connect attempt.
    let c1_cloned = c1.clone();
    let msg_cloned = msg.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            e.connect_with(addrs[0]);
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.send_to(addrs[0], msg_cloned.clone());
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Wait for first server
    t1.join().unwrap();
}
*/
<|endoftext|>


<commit_before>//! Test serialization and deserialization of `BigUint` and `BigInt`
//!
//! The serialized formats should not change, even if we change our
//! internal representation, because we want to preserve forward and
//! backward compatibility of serialized data!

#![cfg(feature = "serde")]

extern crate num_bigint;
extern crate num_traits;
extern crate serde_test;

use num_bigint::{BigInt, BigUint};
use num_traits::{One, Zero};
use serde_test::{assert_tokens, Token};

#[test]
fn biguint_zero() {
    let tokens = [Token::Seq { len: Some(0) }, Token::SeqEnd];
    assert_tokens(&BigUint::zero(), &tokens);
}

#[test]
fn bigint_zero() {
    let tokens = [
        Token::Tuple { len: 2 },
        Token::I8(0),
        Token::Seq { len: Some(0) },
        Token::SeqEnd,
        Token::TupleEnd,
    ];
    assert_tokens(&BigInt::zero(), &tokens);
}

#[test]
fn biguint_one() {
    let tokens = [Token::Seq { len: Some(1) }, Token::U32(1), Token::SeqEnd];
    assert_tokens(&BigUint::one(), &tokens);
}

#[test]
fn bigint_one() {
    let tokens = [
        Token::Tuple { len: 2 },
        Token::I8(1),
        Token::Seq { len: Some(1) },
        Token::U32(1),
        Token::SeqEnd,
        Token::TupleEnd,
    ];
    assert_tokens(&BigInt::one(), &tokens);
}

#[test]
fn bigint_negone() {
    let tokens = [
        Token::Tuple { len: 2 },
        Token::I8(-1),
        Token::Seq { len: Some(1) },
        Token::U32(1),
        Token::SeqEnd,
        Token::TupleEnd,
    ];
    assert_tokens(&-BigInt::one(), &tokens);
}

// Generated independently from python `hex(factorial(100))`
const FACTORIAL_100: &'static [u32] = &[
    0x00000000, 0x00000000, 0x00000000, 0x2735c61a, 0xee8b02ea, 0xb3b72ed2, 0x9420c6ec, 0x45570cca,
    0xdf103917, 0x943a321c, 0xeb21b5b2, 0x66ef9a70, 0xa40d16e9, 0x28d54bbd, 0xdc240695, 0x964ec395,
    0x1b30,
];

#[test]
fn biguint_factorial_100() {
    let n: BigUint = (1u8..101).product();

    let mut tokens = vec![];
    tokens.push(Token::Seq {
        len: Some(FACTORIAL_100.len()),
    });
    tokens.extend(FACTORIAL_100.iter().map(|&u| Token::U32(u)));
    tokens.push(Token::SeqEnd);

    assert_tokens(&n, &tokens);
}

#[test]
fn bigint_factorial_100() {
    let n: BigInt = (1i8..101).product();

    let mut tokens = vec![];
    tokens.push(Token::Tuple { len: 2 });
    tokens.push(Token::I8(1));
    tokens.push(Token::Seq {
        len: Some(FACTORIAL_100.len()),
    });
    tokens.extend(FACTORIAL_100.iter().map(|&u| Token::U32(u)));
    tokens.push(Token::SeqEnd);
    tokens.push(Token::TupleEnd);

    assert_tokens(&n, &tokens);
}
<commit_msg>sources shouldn't be executable<commit_after>//! Test serialization and deserialization of `BigUint` and `BigInt`
//!
//! The serialized formats should not change, even if we change our
//! internal representation, because we want to preserve forward and
//! backward compatibility of serialized data!

#![cfg(feature = "serde")]

extern crate num_bigint;
extern crate num_traits;
extern crate serde_test;

use num_bigint::{BigInt, BigUint};
use num_traits::{One, Zero};
use serde_test::{assert_tokens, Token};

#[test]
fn biguint_zero() {
    let tokens = [Token::Seq { len: Some(0) }, Token::SeqEnd];
    assert_tokens(&BigUint::zero(), &tokens);
}

#[test]
fn bigint_zero() {
    let tokens = [
        Token::Tuple { len: 2 },
        Token::I8(0),
        Token::Seq { len: Some(0) },
        Token::SeqEnd,
        Token::TupleEnd,
    ];
    assert_tokens(&BigInt::zero(), &tokens);
}

#[test]
fn biguint_one() {
    let tokens = [Token::Seq { len: Some(1) }, Token::U32(1), Token::SeqEnd];
    assert_tokens(&BigUint::one(), &tokens);
}

#[test]
fn bigint_one() {
    let tokens = [
        Token::Tuple { len: 2 },
        Token::I8(1),
        Token::Seq { len: Some(1) },
        Token::U32(1),
        Token::SeqEnd,
        Token::TupleEnd,
    ];
    assert_tokens(&BigInt::one(), &tokens);
}

#[test]
fn bigint_negone() {
    let tokens = [
        Token::Tuple { len: 2 },
        Token::I8(-1),
        Token::Seq { len: Some(1) },
        Token::U32(1),
        Token::SeqEnd,
        Token::TupleEnd,
    ];
    assert_tokens(&-BigInt::one(), &tokens);
}

// Generated independently from python `hex(factorial(100))`
const FACTORIAL_100: &'static [u32] = &[
    0x00000000, 0x00000000, 0x00000000, 0x2735c61a, 0xee8b02ea, 0xb3b72ed2, 0x9420c6ec, 0x45570cca,
    0xdf103917, 0x943a321c, 0xeb21b5b2, 0x66ef9a70, 0xa40d16e9, 0x28d54bbd, 0xdc240695, 0x964ec395,
    0x1b30,
];

#[test]
fn biguint_factorial_100() {
    let n: BigUint = (1u8..101).product();

    let mut tokens = vec![];
    tokens.push(Token::Seq {
        len: Some(FACTORIAL_100.len()),
    });
    tokens.extend(FACTORIAL_100.iter().map(|&u| Token::U32(u)));
    tokens.push(Token::SeqEnd);

    assert_tokens(&n, &tokens);
}

#[test]
fn bigint_factorial_100() {
    let n: BigInt = (1i8..101).product();

    let mut tokens = vec![];
    tokens.push(Token::Tuple { len: 2 });
    tokens.push(Token::I8(1));
    tokens.push(Token::Seq {
        len: Some(FACTORIAL_100.len()),
    });
    tokens.extend(FACTORIAL_100.iter().map(|&u| Token::U32(u)));
    tokens.push(Token::SeqEnd);
    tokens.push(Token::TupleEnd);

    assert_tokens(&n, &tokens);
}
<|endoftext|>


<commit_before>// Copyright 2014, 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
// Copyright 2012 The Rust Project Developers
// See the COPYRIGHT file at the top-level directory of this distribution
// and at http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(test)]

#[macro_use]
extern crate c_string;

extern crate test;
extern crate libc;

use std::ffi::CStr;
use std::io::Error as IoError;
use std::io::ErrorKind::InvalidInput;
use std::iter::Iterator;
use std::ptr;

use c_string::{CStrBuf, OwnedCString, CChars};
use c_string::{libc_free, parse_c_multistring};

pub fn check_c_str(c_str: &CStr, expected: &[u8]) {
    let buf = c_str.as_ptr();
    let len = expected.len();
    for i in (0 .. len) {
        let byte = unsafe { *buf.offset(i as isize) as u8 };
        assert_eq!(byte, expected[i]);
    }
    let term = unsafe { *buf.offset(len as isize) as u8 };
    assert_eq!(term, 0);
}

unsafe fn bytes_dup_raw(s: &[u8]) -> *const libc::c_char {
    let len = s.len();
    let dup = libc::malloc((len + 1) as libc::size_t) as *mut u8;
    ptr::copy_nonoverlapping(s.as_ptr(), dup, len);
    *dup.offset(len as isize) = 0;
    dup as *const libc::c_char
}

fn bytes_dup(s: &[u8]) -> OwnedCString {
    unsafe {
        OwnedCString::new(bytes_dup_raw(s), libc_free)
    }
}

fn str_dup(s: &str) -> OwnedCString {
    bytes_dup(s.as_bytes())
}

#[test]
fn test_parse_c_multistring() {
    unsafe {
        let input = b"zero\0one\0\0";
        let ptr = input.as_ptr();
        let expected = ["zero", "one"];
        let mut it = expected.iter();
        let result = parse_c_multistring(ptr as *const libc::c_char, None,
            |cbytes| {
                assert_eq!(cbytes, it.next().unwrap().as_bytes());
            });
        assert_eq!(result, 2);
        assert!(it.next().is_none());
    }
}

#[test]
fn test_c_str_macro() {
    let c_str = c_str!("hello");
    check_c_str(c_str, b"hello");
}

#[test]
fn test_owned_c_string_deref() {
    let c_str = str_dup("hello");
    check_c_str(&c_str, b"hello");
}

#[test]
fn test_owned_c_string_as_ptr() {
    let c_str = str_dup("hello");
    let len = unsafe { libc::strlen(c_str.as_ptr()) };
    assert_eq!(len, 5);
}

#[test]
fn test_iterator() {
    let c_string = str_dup("");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), None);

    let c_string = str_dup("hello");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), Some('h' as libc::c_char));
    assert_eq!(iter.next(), Some('e' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('o' as libc::c_char));
    assert_eq!(iter.next(), None);
}

#[test]
fn test_c_str_buf_from_iter() {
    let test_strings: &[&'static [u8]] = &[
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings: &[&'static [u8]] = &[
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_iter(bytes.iter().cloned());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.iter().position(|b| *b == 0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_c_str_buf_from_str() {
    let c_str = CStrBuf::from_str("").unwrap();
    check_c_str(&c_str, b"");

    let c_str = CStrBuf::from_str("hello").unwrap();
    check_c_str(&c_str, b"hello");

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    check_c_str(&c_str, b"Mary had a little lamb, Little lamb");

    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    assert_eq!(err.nul_position(), 3);
    let bytes = err.into_bytes();
    assert_eq!(bytes, b"got\0nul");
}

#[test]
fn test_io_error_from_nul_error() {
    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    let io_err = IoError::from(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_from_vec() {
    let test_strings: &[&'static [u8]] = &[
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_vec(bytes.to_vec()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings: &[&'static [u8]] = &[
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_vec(bytes.to_vec());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.iter().position(|b| *b == 0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_io_error_from_into_c_str_error() {
    let res = CStrBuf::from_vec(b"got\0nul".to_vec());
    let err = res.err().unwrap();
    let io_err = IoError::from(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_into_vec() {
    let c_str = CStrBuf::from_str("").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"");
    let c_str = CStrBuf::from_str("hello").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"hello");
    let bytes = b"foo\xFF";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], &b"Mary had a little lamb, Little lamb"[..]);
    let bytes = b"Mary had a little \xD0\x0D, Little \xD0\x0D";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);
}

#[test]
fn test_owned_c_string_to_bytes() {
    let c_str = str_dup("hello");
    assert_eq!(c_str.to_bytes(), b"hello");
    let c_str = str_dup("");
    assert_eq!(c_str.to_bytes(), b"");
    let c_str = bytes_dup(b"foo\xFF");
    assert_eq!(c_str.to_bytes(), b"foo\xFF");
}

#[test]
fn test_owned_c_string_debug() {
    let c_str = str_dup("hello");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"hello\"");
    let c_str = str_dup("");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"\"");
    let c_str = bytes_dup(b"foo\xFF");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, r#""foo\xff""#);
}

#[test]
#[should_panic]
fn test_c_string_new_fail() {
    let _c_str: OwnedCString = unsafe {
        OwnedCString::new(ptr::null(), libc_free)
    };
}
<commit_msg>No need to explicitly link the test crate<commit_after>// Copyright 2014, 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
// Copyright 2012 The Rust Project Developers
// See the COPYRIGHT file at the top-level directory of this distribution
// and at http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate c_string;

extern crate libc;

use std::ffi::CStr;
use std::io::Error as IoError;
use std::io::ErrorKind::InvalidInput;
use std::iter::Iterator;
use std::ptr;

use c_string::{CStrBuf, OwnedCString, CChars};
use c_string::{libc_free, parse_c_multistring};

pub fn check_c_str(c_str: &CStr, expected: &[u8]) {
    let buf = c_str.as_ptr();
    let len = expected.len();
    for i in (0 .. len) {
        let byte = unsafe { *buf.offset(i as isize) as u8 };
        assert_eq!(byte, expected[i]);
    }
    let term = unsafe { *buf.offset(len as isize) as u8 };
    assert_eq!(term, 0);
}

unsafe fn bytes_dup_raw(s: &[u8]) -> *const libc::c_char {
    let len = s.len();
    let dup = libc::malloc((len + 1) as libc::size_t) as *mut u8;
    ptr::copy_nonoverlapping(s.as_ptr(), dup, len);
    *dup.offset(len as isize) = 0;
    dup as *const libc::c_char
}

fn bytes_dup(s: &[u8]) -> OwnedCString {
    unsafe {
        OwnedCString::new(bytes_dup_raw(s), libc_free)
    }
}

fn str_dup(s: &str) -> OwnedCString {
    bytes_dup(s.as_bytes())
}

#[test]
fn test_parse_c_multistring() {
    unsafe {
        let input = b"zero\0one\0\0";
        let ptr = input.as_ptr();
        let expected = ["zero", "one"];
        let mut it = expected.iter();
        let result = parse_c_multistring(ptr as *const libc::c_char, None,
            |cbytes| {
                assert_eq!(cbytes, it.next().unwrap().as_bytes());
            });
        assert_eq!(result, 2);
        assert!(it.next().is_none());
    }
}

#[test]
fn test_c_str_macro() {
    let c_str = c_str!("hello");
    check_c_str(c_str, b"hello");
}

#[test]
fn test_owned_c_string_deref() {
    let c_str = str_dup("hello");
    check_c_str(&c_str, b"hello");
}

#[test]
fn test_owned_c_string_as_ptr() {
    let c_str = str_dup("hello");
    let len = unsafe { libc::strlen(c_str.as_ptr()) };
    assert_eq!(len, 5);
}

#[test]
fn test_iterator() {
    let c_string = str_dup("");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), None);

    let c_string = str_dup("hello");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), Some('h' as libc::c_char));
    assert_eq!(iter.next(), Some('e' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('o' as libc::c_char));
    assert_eq!(iter.next(), None);
}

#[test]
fn test_c_str_buf_from_iter() {
    let test_strings: &[&'static [u8]] = &[
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings: &[&'static [u8]] = &[
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_iter(bytes.iter().cloned());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.iter().position(|b| *b == 0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_c_str_buf_from_str() {
    let c_str = CStrBuf::from_str("").unwrap();
    check_c_str(&c_str, b"");

    let c_str = CStrBuf::from_str("hello").unwrap();
    check_c_str(&c_str, b"hello");

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    check_c_str(&c_str, b"Mary had a little lamb, Little lamb");

    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    assert_eq!(err.nul_position(), 3);
    let bytes = err.into_bytes();
    assert_eq!(bytes, b"got\0nul");
}

#[test]
fn test_io_error_from_nul_error() {
    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    let io_err = IoError::from(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_from_vec() {
    let test_strings: &[&'static [u8]] = &[
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_vec(bytes.to_vec()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings: &[&'static [u8]] = &[
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_vec(bytes.to_vec());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.iter().position(|b| *b == 0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_io_error_from_into_c_str_error() {
    let res = CStrBuf::from_vec(b"got\0nul".to_vec());
    let err = res.err().unwrap();
    let io_err = IoError::from(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_into_vec() {
    let c_str = CStrBuf::from_str("").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"");
    let c_str = CStrBuf::from_str("hello").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"hello");
    let bytes = b"foo\xFF";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], &b"Mary had a little lamb, Little lamb"[..]);
    let bytes = b"Mary had a little \xD0\x0D, Little \xD0\x0D";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);
}

#[test]
fn test_owned_c_string_to_bytes() {
    let c_str = str_dup("hello");
    assert_eq!(c_str.to_bytes(), b"hello");
    let c_str = str_dup("");
    assert_eq!(c_str.to_bytes(), b"");
    let c_str = bytes_dup(b"foo\xFF");
    assert_eq!(c_str.to_bytes(), b"foo\xFF");
}

#[test]
fn test_owned_c_string_debug() {
    let c_str = str_dup("hello");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"hello\"");
    let c_str = str_dup("");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"\"");
    let c_str = bytes_dup(b"foo\xFF");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, r#""foo\xff""#);
}

#[test]
#[should_panic]
fn test_c_string_new_fail() {
    let _c_str: OwnedCString = unsafe {
        OwnedCString::new(ptr::null(), libc_free)
    };
}
<|endoftext|>


<commit_before>use handlebars::RenderError;

use super::*;

impl TaskHandler {
    /// Users can specify a callback that's fired whenever a task finishes.
    /// Execute the callback by spawning a new subprocess.
    pub fn spawn_callback(&mut self, task: &Task) {
        // Return early, if there's no callback specified
        let template_string = if let Some(callback) = &self.callback {
            callback
        } else {
            return;
        };

        // Build the command to be called from the template string in the configuration file.
        let callback_command = match self.build_callback_command(task, &template_string) {
            Ok(callback_command) => callback_command,
            Err(err) => {
                error!(
                    "Failed to create callback command from template with error: {}",
                    err
                );
                return;
            }
        };

        let mut command = compile_shell_command(&callback_command);

        // Spawn the callback subprocess and log if it fails.
        let spawn_result = command.spawn();
        let child = match spawn_result {
            Err(error) => {
                error!("Failed to spawn callback with error: {}", error);
                return;
            }
            Ok(child) => child,
        };

        debug!("Spawned callback for task {}", task.id);
        self.callbacks.push(child);
    }

    /// Take the callback template string from the configuration and insert all parameters from the
    /// finished task.
    pub fn build_callback_command(
        &self,
        task: &Task,
        template_string: &str,
    ) -> Result<String, RenderError> {
        // Init Handlebars. We set to strict, as we want to show an error on missing variables.
        let mut handlebars = Handlebars::new();
        handlebars.set_strict_mode(true);

        // Add templating variables.
        let mut parameters = HashMap::new();
        parameters.insert("id", task.id.to_string());
        parameters.insert("command", task.command.clone());
        parameters.insert("path", task.path.clone());
        parameters.insert("group", task.group.clone());

        // Result takes the TaskResult Enum strings, unless it didn't finish yet.
        if let TaskStatus::Done(result) = &task.status {
            parameters.insert("result", result.to_string());
        } else {
            parameters.insert("result", "None".into());
        }

        // Format and insert start and end times.
        let print_time = |time: Option<DateTime<Local>>| {
            time.map(|time| time.timestamp().to_string())
                .unwrap_or_else(String::new)
        };
        parameters.insert("start", print_time(task.start));
        parameters.insert("end", print_time(task.end));

        // Read the last lines of the process' output and make it available.
        if let Ok((stdout, stderr)) =
            read_last_log_file_lines(task.id, &self.pueue_directory, self.callback_log_lines)
        {
            parameters.insert("stdout", stdout);
            parameters.insert("stderr", stderr);
        } else {
            parameters.insert("stdout", "".to_string());
            parameters.insert("stderr", "".to_string());
        }

        // Get the exit code
        if let TaskStatus::Done(result) = &task.status {
            match result {
                TaskResult::Success => parameters.insert("exit_code", "0".into()),
                TaskResult::Failed(code) => parameters.insert("exit_code", code.to_string()),
                _ => parameters.insert("exit_code", "None".into()),
            };
        } else {
            parameters.insert("exit_code", "None".into());
        }

        handlebars.render_template(template_string, &parameters)
    }

    /// Look at all running callbacks and log any errors.
    /// If everything went smoothly, simply remove them from the list.
    pub fn check_callbacks(&mut self) {
        let mut finished = Vec::new();
        for (id, child) in self.callbacks.iter_mut().enumerate() {
            match child.try_wait() {
                // Handle a child error.
                Err(error) => {
                    error!("Callback failed with error {:?}", error);
                    finished.push(id);
                }
                // Child process did not exit yet.
                Ok(None) => continue,
                Ok(exit_status) => {
                    info!("Callback finished with exit code {:?}", exit_status);
                    finished.push(id);
                }
            }
        }

        finished.reverse();
        for id in finished.iter() {
            self.callbacks.remove(*id);
        }
    }
}
<commit_msg>fix: Clippy issues<commit_after>use handlebars::RenderError;

use super::*;

impl TaskHandler {
    /// Users can specify a callback that's fired whenever a task finishes.
    /// Execute the callback by spawning a new subprocess.
    pub fn spawn_callback(&mut self, task: &Task) {
        // Return early, if there's no callback specified
        let template_string = if let Some(callback) = &self.callback {
            callback
        } else {
            return;
        };

        // Build the command to be called from the template string in the configuration file.
        let callback_command = match self.build_callback_command(task, template_string) {
            Ok(callback_command) => callback_command,
            Err(err) => {
                error!(
                    "Failed to create callback command from template with error: {}",
                    err
                );
                return;
            }
        };

        let mut command = compile_shell_command(&callback_command);

        // Spawn the callback subprocess and log if it fails.
        let spawn_result = command.spawn();
        let child = match spawn_result {
            Err(error) => {
                error!("Failed to spawn callback with error: {}", error);
                return;
            }
            Ok(child) => child,
        };

        debug!("Spawned callback for task {}", task.id);
        self.callbacks.push(child);
    }

    /// Take the callback template string from the configuration and insert all parameters from the
    /// finished task.
    pub fn build_callback_command(
        &self,
        task: &Task,
        template_string: &str,
    ) -> Result<String, RenderError> {
        // Init Handlebars. We set to strict, as we want to show an error on missing variables.
        let mut handlebars = Handlebars::new();
        handlebars.set_strict_mode(true);

        // Add templating variables.
        let mut parameters = HashMap::new();
        parameters.insert("id", task.id.to_string());
        parameters.insert("command", task.command.clone());
        parameters.insert("path", task.path.clone());
        parameters.insert("group", task.group.clone());

        // Result takes the TaskResult Enum strings, unless it didn't finish yet.
        if let TaskStatus::Done(result) = &task.status {
            parameters.insert("result", result.to_string());
        } else {
            parameters.insert("result", "None".into());
        }

        // Format and insert start and end times.
        let print_time = |time: Option<DateTime<Local>>| {
            time.map(|time| time.timestamp().to_string())
                .unwrap_or_else(String::new)
        };
        parameters.insert("start", print_time(task.start));
        parameters.insert("end", print_time(task.end));

        // Read the last lines of the process' output and make it available.
        if let Ok((stdout, stderr)) =
            read_last_log_file_lines(task.id, &self.pueue_directory, self.callback_log_lines)
        {
            parameters.insert("stdout", stdout);
            parameters.insert("stderr", stderr);
        } else {
            parameters.insert("stdout", "".to_string());
            parameters.insert("stderr", "".to_string());
        }

        // Get the exit code
        if let TaskStatus::Done(result) = &task.status {
            match result {
                TaskResult::Success => parameters.insert("exit_code", "0".into()),
                TaskResult::Failed(code) => parameters.insert("exit_code", code.to_string()),
                _ => parameters.insert("exit_code", "None".into()),
            };
        } else {
            parameters.insert("exit_code", "None".into());
        }

        handlebars.render_template(template_string, &parameters)
    }

    /// Look at all running callbacks and log any errors.
    /// If everything went smoothly, simply remove them from the list.
    pub fn check_callbacks(&mut self) {
        let mut finished = Vec::new();
        for (id, child) in self.callbacks.iter_mut().enumerate() {
            match child.try_wait() {
                // Handle a child error.
                Err(error) => {
                    error!("Callback failed with error {:?}", error);
                    finished.push(id);
                }
                // Child process did not exit yet.
                Ok(None) => continue,
                Ok(exit_status) => {
                    info!("Callback finished with exit code {:?}", exit_status);
                    finished.push(id);
                }
            }
        }

        finished.reverse();
        for id in finished.iter() {
            self.callbacks.remove(*id);
        }
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use self::rand::Rng;

#[derive(Debug, PartialEq)]
pub enum AliasDistributionError {
    InvalidWeights,
    NullDistribution,
}

impl ::std::fmt::Display for AliasDistributionError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match *self {
            AliasDistributionError::InvalidWeights => write!(f, "InvalidWeights"),
            AliasDistributionError::NullDistribution => write!(f, "NullDistribution"),
        }
    }
}

impl ::std::error::Error for AliasDistributionError {
    fn description(&self) -> &str {
        match *self {
            AliasDistributionError::InvalidWeights => "Negative weights are not allowed",
            AliasDistributionError::NullDistribution => "Sum of weights must not be zero",
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        None
    }
}

#[derive(Debug)]
pub struct AliasDistribution {
    probability_table: Vec<f64>,
    alias_table: Vec<usize>,
    pub entropy: f64,
}

impl AliasDistribution {
    pub fn new(weights: &Vec<f64>) -> Result<AliasDistribution, AliasDistributionError> {
        if weights.iter().any(|&w| w < 0.0) {
            return Err(AliasDistributionError::InvalidWeights);
        };
        let size = weights.len();
        let total = weights.iter().fold(0.0, |sum, x| sum + x);
        if total == 0.0 {
            return Err(AliasDistributionError::NullDistribution);
        };
        let mut entropy = 0.0;

        let mut probability_table = Vec::with_capacity(size);
        for weight in weights.iter() {
            let prob = weight / total;
            entropy -= prob * prob.log(2.0);
            probability_table.push(prob * (size as f64));
        }

        let mut alias_table: Vec<usize> = (0..size).collect();
        let mut overfull: Vec<usize> = Vec::new();
        let mut underfull: Vec<usize> = Vec::new();
        for (i, prob) in probability_table.iter().enumerate() {
            if *prob < 1.0 {
                underfull.push(i);
            } else {
                overfull.push(i);
            }
        }
        while !(overfull.is_empty() | underfull.is_empty()) {
            let i = underfull.pop().unwrap();
            let j = overfull.pop().unwrap();
            alias_table[i] = j;
            probability_table[j] += probability_table[i] - 1.0;
            if probability_table[j] < 1.0 {
                underfull.push(j)
            } else {
                overfull.push(j)
            };
        }

        Ok(AliasDistribution {
            probability_table: probability_table,
            alias_table: alias_table,
            entropy: entropy,
        })
    }

    pub fn choice(&self) -> usize {
        let mut rng = rand::OsRng::new().unwrap();
        let i = rng.gen_range(0, self.probability_table.len());
        let y = rng.gen();
        let choice = if self.probability_table[i] >= y {
            i
        } else {
            self.alias_table[i]
        };

        choice
    }
}

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

    macro_rules! assert_approx_eq {
        ($a:expr, $b:expr) => {{
            let (a, b) = (&$a, &$b);
            assert!(
                (*a - *b).abs() < 1.0e-6,
                "{} is not approximately equal to {}",
                *a,
                *b
            );
        }};
    }

    #[test]
    fn test_new() {
        let mut test_cases = Vec::new();
        test_cases.push(vec![1.0, 2.0, 3.0, 4.0]);
        test_cases.push(vec![0.2, 0.2, 0.2, 0.2, 0.2]);
        test_cases.push(vec![3.0, 0.0, 5.0]);
        test_cases.push(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);

        for weights in test_cases {
            let total = weights.iter().fold(0.0, |x, sum| sum + x);
            let count = weights.len() as f64;
            let dist = AliasDistribution::new(&weights).unwrap();
            let mut ps = vec![0.0; weights.len()];
            for (i, (&j, p)) in dist
                .alias_table
                .iter()
                .zip(dist.probability_table)
                .enumerate()
            {
                ps[i] += p / count;
                ps[j] += (1.0 - p) / count;
            }
            for (p, w) in ps.iter().zip(weights) {
                assert_approx_eq!(p, w / total);
            }
        }
    }

    #[test]
    fn test_negative_weight() {
        let err = AliasDistribution::new(&vec![3.2, -0.3, 4.5]).unwrap_err();
        assert_eq!(err, AliasDistributionError::InvalidWeights);
    }

    #[test]
    fn test_zero_distribution() {
        let err = AliasDistribution::new(&vec![0.0, 0.0, 0.0]).unwrap_err();
        assert_eq!(err, AliasDistributionError::NullDistribution);
    }

    #[test]
    fn test_empty_distribution() {
        let err = AliasDistribution::new(&Vec::new()).unwrap_err();
        assert_eq!(err, AliasDistributionError::NullDistribution);
    }

    #[test]
    fn test_entropy() {
        let dist = AliasDistribution::new(&vec![1.0, 1.0]).unwrap();
        assert_approx_eq!(dist.entropy, 1.0);
        let dist = AliasDistribution::new(&vec![0.5, 0.5, 1.0, 2.0]).unwrap();
        assert_approx_eq!(dist.entropy, 1.75);
    }

    #[test]
    fn test_choice() {
        let dist = AliasDistribution::new(&vec![1.0, 2.0, 3.0]).unwrap();
        let choice = dist.choice();
        assert!(choice < 3, "{} is too large");
    }
}
<commit_msg>Tweak some AliasDistribution reference handling.<commit_after>extern crate rand;

use self::rand::Rng;

#[derive(Debug, PartialEq)]
pub enum AliasDistributionError {
    InvalidWeights,
    NullDistribution,
}

impl ::std::fmt::Display for AliasDistributionError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match *self {
            AliasDistributionError::InvalidWeights => write!(f, "InvalidWeights"),
            AliasDistributionError::NullDistribution => write!(f, "NullDistribution"),
        }
    }
}

impl ::std::error::Error for AliasDistributionError {
    fn description(&self) -> &str {
        match *self {
            AliasDistributionError::InvalidWeights => "Negative weights are not allowed",
            AliasDistributionError::NullDistribution => "Sum of weights must not be zero",
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        None
    }
}

#[derive(Debug)]
pub struct AliasDistribution {
    probability_table: Vec<f64>,
    alias_table: Vec<usize>,
    pub entropy: f64,
}

impl AliasDistribution {
    pub fn new(weights: &Vec<f64>) -> Result<AliasDistribution, AliasDistributionError> {
        if weights.iter().any(|&w| w < 0.0) {
            return Err(AliasDistributionError::InvalidWeights);
        };
        let size = weights.len();
        let total = weights.iter().fold(0.0, |sum, x| sum + x);
        if total == 0.0 {
            return Err(AliasDistributionError::NullDistribution);
        };
        let mut entropy = 0.0;

        let mut probability_table = Vec::with_capacity(size);
        for weight in weights {
            let prob = weight / total;
            entropy -= prob * prob.log(2.0);
            probability_table.push(prob * (size as f64));
        }

        let mut alias_table: Vec<usize> = (0..size).collect();
        let mut overfull: Vec<usize> = Vec::new();
        let mut underfull: Vec<usize> = Vec::new();
        for (i, &prob) in probability_table.iter().enumerate() {
            if prob < 1.0 {
                underfull.push(i);
            } else {
                overfull.push(i);
            }
        }
        while !(overfull.is_empty() | underfull.is_empty()) {
            let i = underfull.pop().unwrap();
            let j = overfull.pop().unwrap();
            alias_table[i] = j;
            probability_table[j] += probability_table[i] - 1.0;
            if probability_table[j] < 1.0 {
                underfull.push(j)
            } else {
                overfull.push(j)
            };
        }

        Ok(AliasDistribution {
            probability_table: probability_table,
            alias_table: alias_table,
            entropy: entropy,
        })
    }

    pub fn choice(&self) -> usize {
        let mut rng = rand::OsRng::new().unwrap();
        let i = rng.gen_range(0, self.probability_table.len());
        let y = rng.gen();
        let choice = if self.probability_table[i] >= y {
            i
        } else {
            self.alias_table[i]
        };

        choice
    }
}

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

    macro_rules! assert_approx_eq {
        ($a:expr, $b:expr) => {{
            let (a, b) = (&$a, &$b);
            assert!(
                (*a - *b).abs() < 1.0e-6,
                "{} is not approximately equal to {}",
                *a,
                *b
            );
        }};
    }

    #[test]
    fn test_new() {
        let mut test_cases = Vec::new();
        test_cases.push(vec![1.0, 2.0, 3.0, 4.0]);
        test_cases.push(vec![0.2, 0.2, 0.2, 0.2, 0.2]);
        test_cases.push(vec![3.0, 0.0, 5.0]);
        test_cases.push(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);

        for weights in test_cases {
            let total = weights.iter().fold(0.0, |x, sum| sum + x);
            let count = weights.len() as f64;
            let dist = AliasDistribution::new(&weights).unwrap();
            let mut ps = vec![0.0; weights.len()];
            for (i, (&j, p)) in dist
                .alias_table
                .iter()
                .zip(dist.probability_table)
                .enumerate()
            {
                ps[i] += p / count;
                ps[j] += (1.0 - p) / count;
            }
            for (p, w) in ps.iter().zip(weights) {
                assert_approx_eq!(p, w / total);
            }
        }
    }

    #[test]
    fn test_negative_weight() {
        let err = AliasDistribution::new(&vec![3.2, -0.3, 4.5]).unwrap_err();
        assert_eq!(err, AliasDistributionError::InvalidWeights);
    }

    #[test]
    fn test_zero_distribution() {
        let err = AliasDistribution::new(&vec![0.0, 0.0, 0.0]).unwrap_err();
        assert_eq!(err, AliasDistributionError::NullDistribution);
    }

    #[test]
    fn test_empty_distribution() {
        let err = AliasDistribution::new(&Vec::new()).unwrap_err();
        assert_eq!(err, AliasDistributionError::NullDistribution);
    }

    #[test]
    fn test_entropy() {
        let dist = AliasDistribution::new(&vec![1.0, 1.0]).unwrap();
        assert_approx_eq!(dist.entropy, 1.0);
        let dist = AliasDistribution::new(&vec![0.5, 0.5, 1.0, 2.0]).unwrap();
        assert_approx_eq!(dist.entropy, 1.75);
    }

    #[test]
    fn test_choice() {
        let dist = AliasDistribution::new(&vec![1.0, 2.0, 3.0]).unwrap();
        let choice = dist.choice();
        assert!(choice < 3, "{} is too large");
    }
}
<|endoftext|>


<commit_before>#![deny(warnings)]
extern crate hyper;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

use hyper::Client;
use hyper::rt::{self, Future, Stream};

fn main() {
    let url = "http://jsonplaceholder.typicode.com/users".parse().unwrap();

    let fut = fetch_json(url)
        // use the parsed vector
        .map(|users| {
            // print users
            println!("users: {:#?}", users);

            // print the sum of ids
            let sum = users.iter().fold(0, |acc, user| acc + user.id);
            println!("sum of ids: {}", sum);
        })
        // if there was an error print it
        .map_err(|e| {
            match e {
                FetchError::Http(e) => eprintln!("http error: {}", e),
                FetchError::Json(e) => eprintln!("json parsing error: {}", e),
            }
        });

    // Run the runtime with the future trying to fetch, parse and print json.
    //
    // Note that in more complicated use cases, the runtime should probably
    // run on its own, and futures should just be spawned into it.
    rt::run(fut);
}

fn fetch_json(url: hyper::Uri) -> impl Future<Item=Vec<User>, Error=FetchError> {
    let client = Client::new();

    client
        // Fetch the url...
        .get(url)
        // And then, if we get a response back...
        .and_then(|res| {
            // asynchronously concatenate chunks of the body
            res.into_body().concat2()
        })
        .from_err::<FetchError>()
        // use the body after concatenation
        .and_then(|body| {
            // try to parse as json with serde_json
            let users = serde_json::from_slice(&body)?;

            Ok(users)
        })
        .from_err()
}

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

// Define a type so we can return multile types of errors
enum FetchError {
    Http(hyper::Error),
    Json(serde_json::Error),
}

impl From<hyper::Error> for FetchError {
    fn from(err: hyper::Error) -> FetchError {
        FetchError::Http(err)
    }
}

impl From<serde_json::Error> for FetchError {
    fn from(err: serde_json::Error) -> FetchError {
        FetchError::Json(err)
    }
}<commit_msg>docs(examples): Fix typo in client_json example comment<commit_after>#![deny(warnings)]
extern crate hyper;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

use hyper::Client;
use hyper::rt::{self, Future, Stream};

fn main() {
    let url = "http://jsonplaceholder.typicode.com/users".parse().unwrap();

    let fut = fetch_json(url)
        // use the parsed vector
        .map(|users| {
            // print users
            println!("users: {:#?}", users);

            // print the sum of ids
            let sum = users.iter().fold(0, |acc, user| acc + user.id);
            println!("sum of ids: {}", sum);
        })
        // if there was an error print it
        .map_err(|e| {
            match e {
                FetchError::Http(e) => eprintln!("http error: {}", e),
                FetchError::Json(e) => eprintln!("json parsing error: {}", e),
            }
        });

    // Run the runtime with the future trying to fetch, parse and print json.
    //
    // Note that in more complicated use cases, the runtime should probably
    // run on its own, and futures should just be spawned into it.
    rt::run(fut);
}

fn fetch_json(url: hyper::Uri) -> impl Future<Item=Vec<User>, Error=FetchError> {
    let client = Client::new();

    client
        // Fetch the url...
        .get(url)
        // And then, if we get a response back...
        .and_then(|res| {
            // asynchronously concatenate chunks of the body
            res.into_body().concat2()
        })
        .from_err::<FetchError>()
        // use the body after concatenation
        .and_then(|body| {
            // try to parse as json with serde_json
            let users = serde_json::from_slice(&body)?;

            Ok(users)
        })
        .from_err()
}

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

// Define a type so we can return multiple types of errors
enum FetchError {
    Http(hyper::Error),
    Json(serde_json::Error),
}

impl From<hyper::Error> for FetchError {
    fn from(err: hyper::Error) -> FetchError {
        FetchError::Http(err)
    }
}

impl From<serde_json::Error> for FetchError {
    fn from(err: serde_json::Error) -> FetchError {
        FetchError::Json(err)
    }
}
<|endoftext|>