<commit_before>extern crate wild;

pub fn args() -> impl Iterator<Item=String> {
    wild::args()
}

#[cfg(feature = "libc")]
pub extern crate libc;
#[cfg(feature = "winapi")]
pub extern crate winapi;
#[cfg(feature = "failure")]
extern crate failure;
#[cfg(feature = "failure_derive")]
#[macro_use]
extern crate failure_derive;
#[cfg(feature = "nix")]
extern crate nix;
#[cfg(all(feature = "lazy_static", target_os = "linux"))]
#[macro_use]
extern crate lazy_static;
#[cfg(feature = "platform-info")]
extern crate platform_info;

#[macro_use]
mod macros;

#[macro_use]
pub mod coreopts;

pub mod panic;

#[cfg(feature = "fs")]
pub mod fs;
#[cfg(feature = "encoding")]
pub mod encoding;
#[cfg(feature = "parse_time")]
pub mod parse_time;

#[cfg(all(not(windows), feature = "mode"))]
pub mod mode;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "utmpx"))]
pub mod utmpx;
#[cfg(all(unix, feature = "entries"))]
pub mod entries;
#[cfg(all(unix, feature = "process"))]
pub mod process;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
pub mod signals;

#[cfg(feature = "zero-copy")]
pub mod zero_copy;

#[cfg(all(windows, feature = "wide"))]
pub mod wide;
<commit_msg>fix ~ 'musl' environment doesn't support utmpx<commit_after>extern crate wild;

pub fn args() -> impl Iterator<Item=String> {
    wild::args()
}

#[cfg(feature = "libc")]
pub extern crate libc;
#[cfg(feature = "winapi")]
pub extern crate winapi;
#[cfg(feature = "failure")]
extern crate failure;
#[cfg(feature = "failure_derive")]
#[macro_use]
extern crate failure_derive;
#[cfg(feature = "nix")]
extern crate nix;
#[cfg(all(feature = "lazy_static", target_os = "linux"))]
#[macro_use]
extern crate lazy_static;
#[cfg(feature = "platform-info")]
extern crate platform_info;

#[macro_use]
mod macros;

#[macro_use]
pub mod coreopts;

pub mod panic;

#[cfg(feature = "fs")]
pub mod fs;
#[cfg(feature = "encoding")]
pub mod encoding;
#[cfg(feature = "parse_time")]
pub mod parse_time;

#[cfg(all(not(windows), feature = "mode"))]
pub mod mode;
#[cfg(all(unix, not(target_os = "fuchsia"), not(target_env="musl"), feature = "utmpx"))]
pub mod utmpx;
#[cfg(all(unix, feature = "entries"))]
pub mod entries;
#[cfg(all(unix, feature = "process"))]
pub mod process;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
pub mod signals;

#[cfg(feature = "zero-copy")]
pub mod zero_copy;

#[cfg(all(windows, feature = "wide"))]
pub mod wide;
<|endoftext|>


<commit_before>extern crate specs;

#[derive(Clone, Debug)]
struct CompInt(i8);
impl specs::Component for CompInt {
    // Storage is used to store all data for components of this type
    // VecStorage is meant to be used for components that are in almost every entity
    type Storage = specs::VecStorage<CompInt>;
}
#[derive(Clone, Debug)]
struct CompBool(bool);
impl specs::Component for CompBool {
    // HashMapStorage is better for componets that are met rarely
    type Storage = specs::HashMapStorage<CompBool>;
}

fn main() {
    let (e, mut planner) = {
        let mut w = specs::World::new();
        // All components types should be registered before working with them
        w.register::<CompInt>();
        w.register::<CompBool>();
        // create_now() of World provides with an EntityBuilder to add components to an Entity
        w.create_now().with(CompInt(4)).with(CompBool(false)).build();
        // build() returns an entity, we will use it later to perform a deletion
        let e = w.create_now().with(CompInt(9)).with(CompBool(true)).build();
        w.create_now().with(CompInt(-1)).with(CompBool(false)).build();
        w.create_now().with(CompInt(127)).build();
        w.create_now().with(CompBool(false)).build();
        // Planner is used to run systems on the specified world with a specified number of threads
        (e, specs::Planner::new(w, 4))
    };

    // Planner only runs closure on entites with specified components, for example:
    // We have 5 entities and this will print only 4 of them
    println!("Only entities with CompBool present:");
    planner.run0w1r(|b: &CompBool| {
        println!("Entity {}", b.0);
    });
    // wait waits for all scheduled systems to finish
    // If wait is not called, all systems are run in parallel, waiting on locks
    planner.wait();

    planner.run1w1r(|b: &mut CompBool, a: &CompInt| {
        b.0 = a.0 > 0;
    });
    // Deletes an entity instantly
    planner.world.delete_now(e);

    // Instead of using macros you can use run() to build a system precisely
    planner.run(|arg| {
        use specs::Storage;
        // fetch() borrows a world, so a system could lock neccessary storages
        // Can be called only once
        let (mut sa, sb, entities) = arg.fetch(|w| {
            (w.write::<CompInt>(),
             w.read::<CompBool>(),
             w.entities())
        });

        for ent in entities {
            // Will only run for entities with both components present
            if let (Some(a), Some(b)) = (sa.get_mut(ent), sb.get(ent)) {
                a.0 = if b.0 {2} else {0};
            }
        }

        // Dynamically creating and deleting entites
        let e0 = arg.create();
        sa.insert(e0, CompInt(-4));
        let e1 = arg.create();
        sa.insert(e1, CompInt(-5));
        arg.delete(e0);
    });
    println!("Only entities with CompInt and CompBool present:");
    planner.run0w2r(|a: &CompInt, b: &CompBool| {
        println!("Entity {} {}", a.0, b.0);
    });
    planner.wait();
    if false {   // some debug output
        let w = &planner.world;
        //println!("Generations: {:?}", &*w.get_generations());
        //println!("{:?}", &*w.read::<CompInt>());
        //println!("{:?}", &*w.read::<CompBool>());
        for e in w.entities() {
            println!("{:?}", e);
        }
    }
}
<commit_msg>Updated example<commit_after>extern crate specs;

#[derive(Clone, Debug)]
struct CompInt(i8);
impl specs::Component for CompInt {
    // Storage is used to store all data for components of this type
    // VecStorage is meant to be used for components that are in almost every entity
    type Storage = specs::VecStorage<CompInt>;
}
#[derive(Clone, Debug)]
struct CompBool(bool);
impl specs::Component for CompBool {
    // HashMapStorage is better for componets that are met rarely
    type Storage = specs::HashMapStorage<CompBool>;
}

fn main() {
    let (e, mut planner) = {
        let mut w = specs::World::new();
        // All components types should be registered before working with them
        w.register::<CompInt>();
        w.register::<CompBool>();
        // create_now() of World provides with an EntityBuilder to add components to an Entity
        w.create_now().with(CompInt(4)).with(CompBool(false)).build();
        // build() returns an entity, we will use it later to perform a deletion
        let e = w.create_now().with(CompInt(9)).with(CompBool(true)).build();
        w.create_now().with(CompInt(-1)).with(CompBool(false)).build();
        w.create_now().with(CompInt(127)).build();
        w.create_now().with(CompBool(false)).build();
        // Planner is used to run systems on the specified world with a specified number of threads
        (e, specs::Planner::new(w, 4))
    };

    // Planner only runs closure on entites with specified components, for example:
    // We have 5 entities and this will print only 4 of them
    println!("Only entities with CompBool present:");
    planner.run0w1r(|b: &CompBool| {
        println!("Entity {}", b.0);
    });
    // wait waits for all scheduled systems to finish
    // If wait is not called, all systems are run in parallel, waiting on locks
    planner.wait();

    planner.run1w1r(|b: &mut CompBool, a: &CompInt| {
        b.0 = a.0 > 0;
    });
    // Deletes an entity instantly
    planner.world.delete_now(e);

    // Instead of using macros you can use run() to build a system precisely
    planner.run(|arg| {
        use specs::{Storage, Join};
        // fetch() borrows a world, so a system could lock neccessary storages
        // Can be called only once
        let (mut sa, sb, entities) = arg.fetch(|w| {
            (w.write::<CompInt>(),
             w.read::<CompBool>(),
             w.entities())
        });

        for ent in entities {
            // Will only run for entities with both components present
            if let (Some(a), Some(b)) = (sa.get_mut(ent), sb.get(ent)) {
                a.0 = if b.0 {1} else {0};
            }
        }

        // Instead of using the `entities` array you can
        // use the `Join` trait that is an optimized way of
        // doing the `get/get_mut` across entities.
        for (a, b) in (&mut *sa, &*sb).join() {
            a.0 += if b.0 {1} else {0};
        }

        // Dynamically creating and deleting entities
        let e0 = arg.create();
        sa.insert(e0, CompInt(-4));
        let e1 = arg.create();
        sa.insert(e1, CompInt(-5));
        arg.delete(e0);
    });
    println!("Only entities with CompInt and CompBool present:");
    planner.run0w2r(|a: &CompInt, b: &CompBool| {
        println!("Entity {} {}", a.0, b.0);
    });
    planner.wait();
    if false {   // some debug output
        let w = &planner.world;
        //println!("Generations: {:?}", &*w.get_generations());
        //println!("{:?}", &*w.read::<CompInt>());
        //println!("{:?}", &*w.read::<CompBool>());
        for e in w.entities() {
            println!("{:?}", e);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust-Windows Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// 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.

#![allow(unstable)]

#[macro_use]
extern crate log;

#[macro_use]
extern crate "rust-windows" as windows;

use std::ptr;
use std::cell::RefCell;
use std::default::Default;

use windows::main_window_loop;
use windows::ll::types::{UINT, HBRUSH};
use windows::ll::all::CREATESTRUCT;
use windows::instance::Instance;
use windows::resource::*;
use windows::window::{WindowImpl, Window, WndClass, WindowParams};
use windows::window::{OnCreate, OnSize, OnDestroy, OnPaint, OnFocus};
use windows::window;
use windows::gdi::PaintDc;
use windows::font::Font;
use windows::font;

// TODO duplicate of hello.rc
static IDI_ICON: isize = 0x101;
static MENU_MAIN: isize = 0x201;
//static MENU_NEW: isize = 0x202;
//static MENU_EXIT: isize = 0x203;

struct MainFrame {
    win: Window,
    title: String,
    text_height: isize,
    edit: RefCell<Option<Window>>,
    font: RefCell<Option<Font>>,
}

wnd_proc!(MainFrame, win, WM_CREATE, WM_DESTROY, WM_SIZE, WM_SETFOCUS, WM_PAINT);

impl OnCreate for MainFrame {
    fn on_create(&self, _cs: &CREATESTRUCT) -> bool {
        let rect = self.win.client_rect().unwrap();
        let params = WindowParams {
            window_name: "Hello World".to_string(),
            style: window::WS_CHILD | window::WS_VISIBLE | window::WS_BORDER | window::WS_VSCROLL |
                window::ES_AUTOVSCROLL | window::ES_MULTILINE | window::ES_NOHIDESEL,
            x: 0,
            y: self.text_height,
            width: rect.right as isize,
            height: rect.bottom as isize - self.text_height,
            parent: self.win,
            menu: ptr::null_mut(),
            ex_style: 0,
        };
        let edit = Window::new(Instance::main_instance(), None, "EDIT", &params);
        match edit {
            None => false,
            Some(e) => {
                let font_attr = Default::default();
                let font = font::Font::new(&font_attr);
                match font {
                    None => false,
                    Some(f) => {
                        static WM_SETFONT: UINT = 0x0030;
                        unsafe {
                            e.send_message(WM_SETFONT, std::mem::transmute(f.font), 0);
                        }
                        *self.edit.borrow_mut() = Some(e);
                        *self.font.borrow_mut() = Some(f);
                        true
                    }
                }
            }
        }
    }
}

impl OnSize for MainFrame {
    fn on_size(&self, width: isize, height: isize) {
        // SWP_NOOWNERZORDER | SWP_NOZORDER
        let h = self.text_height;
        self.edit.borrow().expect("edit is empty")
            .set_window_pos(0, h, width, height - h, 0x200 | 0x4);
    }
}

impl OnDestroy for MainFrame {}

impl OnPaint for MainFrame {
    fn on_paint(&self) {
        let font = self.font.borrow();
        let pdc = PaintDc::new(self).expect("Paint DC");
        pdc.dc.select_font(&font.expect("font is empty"));
        pdc.dc.text_out(0, 0, self.title.as_slice());
    }
}

impl OnFocus for MainFrame {
    fn on_focus(&self, _w: Window) {
        self.edit.borrow().expect("edit is empty").set_focus();
    }
}

impl MainFrame {
    fn new(instance: Instance, title: String, text_height: isize) -> Option<Window> {
        let icon = Image::load_resource(instance, IDI_ICON, ImageType::IMAGE_ICON, 0, 0);
        let wnd_class = WndClass {
            classname: "MainFrame".to_string(),
            style: 0x0001 | 0x0002, // CS_HREDRAW | CS_VREDRAW
            icon: icon,
            icon_small: None,
            cursor: Image::load_cursor_resource(32514), // hourglass
            background: (5i + 1) as HBRUSH,
            menu: MenuResource::MenuId(MENU_MAIN),
            cls_extra: 0,
            wnd_extra: 0,
        };
        let res = wnd_class.register(instance);
        if !res {
            return None;
        }

        let wproc = Box::new(MainFrame {
            win: Window::null(),
            title: title.clone(),
            text_height: text_height,
            edit: RefCell::new(None),
            font: RefCell::new(None),
        });

        let win_params = WindowParams {
            window_name: title,
            style: window::WS_OVERLAPPEDWINDOW,
            x: 0,
            y: 0,
            width: 400,
            height: 400,
            parent: Window::null(),
            menu: ptr::null_mut(),
            ex_style: 0,
        };

        Window::new(instance, Some(wproc as Box<WindowImpl + 'static>),
                    wnd_class.classname.as_slice(), &win_params)
    }
}

fn main() {
    let instance = Instance::main_instance();
    let main = MainFrame::new(instance, "Hello Rust".to_string(), 20);
    let main = main.unwrap();

    main.show(1);
    main.update();

    let exit_code = main_window_loop();
    std::os::set_exit_status(exit_code as isize);
}
<commit_msg>remove 'i' suffix in integer literal<commit_after>// Copyright 2015 The Rust-Windows Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// 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.

#![allow(unstable)]

#[macro_use]
extern crate log;

#[macro_use]
extern crate "rust-windows" as windows;

use std::ptr;
use std::cell::RefCell;
use std::default::Default;

use windows::main_window_loop;
use windows::ll::types::{UINT, HBRUSH};
use windows::ll::all::CREATESTRUCT;
use windows::instance::Instance;
use windows::resource::*;
use windows::window::{WindowImpl, Window, WndClass, WindowParams};
use windows::window::{OnCreate, OnSize, OnDestroy, OnPaint, OnFocus};
use windows::window;
use windows::gdi::PaintDc;
use windows::font::Font;
use windows::font;

// TODO duplicate of hello.rc
static IDI_ICON: isize = 0x101;
static MENU_MAIN: isize = 0x201;
//static MENU_NEW: isize = 0x202;
//static MENU_EXIT: isize = 0x203;

struct MainFrame {
    win: Window,
    title: String,
    text_height: isize,
    edit: RefCell<Option<Window>>,
    font: RefCell<Option<Font>>,
}

wnd_proc!(MainFrame, win, WM_CREATE, WM_DESTROY, WM_SIZE, WM_SETFOCUS, WM_PAINT);

impl OnCreate for MainFrame {
    fn on_create(&self, _cs: &CREATESTRUCT) -> bool {
        let rect = self.win.client_rect().unwrap();
        let params = WindowParams {
            window_name: "Hello World".to_string(),
            style: window::WS_CHILD | window::WS_VISIBLE | window::WS_BORDER | window::WS_VSCROLL |
                window::ES_AUTOVSCROLL | window::ES_MULTILINE | window::ES_NOHIDESEL,
            x: 0,
            y: self.text_height,
            width: rect.right as isize,
            height: rect.bottom as isize - self.text_height,
            parent: self.win,
            menu: ptr::null_mut(),
            ex_style: 0,
        };
        let edit = Window::new(Instance::main_instance(), None, "EDIT", &params);
        match edit {
            None => false,
            Some(e) => {
                let font_attr = Default::default();
                let font = font::Font::new(&font_attr);
                match font {
                    None => false,
                    Some(f) => {
                        static WM_SETFONT: UINT = 0x0030;
                        unsafe {
                            e.send_message(WM_SETFONT, std::mem::transmute(f.font), 0);
                        }
                        *self.edit.borrow_mut() = Some(e);
                        *self.font.borrow_mut() = Some(f);
                        true
                    }
                }
            }
        }
    }
}

impl OnSize for MainFrame {
    fn on_size(&self, width: isize, height: isize) {
        // SWP_NOOWNERZORDER | SWP_NOZORDER
        let h = self.text_height;
        self.edit.borrow().expect("edit is empty")
            .set_window_pos(0, h, width, height - h, 0x200 | 0x4);
    }
}

impl OnDestroy for MainFrame {}

impl OnPaint for MainFrame {
    fn on_paint(&self) {
        let font = self.font.borrow();
        let pdc = PaintDc::new(self).expect("Paint DC");
        pdc.dc.select_font(&font.expect("font is empty"));
        pdc.dc.text_out(0, 0, self.title.as_slice());
    }
}

impl OnFocus for MainFrame {
    fn on_focus(&self, _w: Window) {
        self.edit.borrow().expect("edit is empty").set_focus();
    }
}

impl MainFrame {
    fn new(instance: Instance, title: String, text_height: isize) -> Option<Window> {
        let icon = Image::load_resource(instance, IDI_ICON, ImageType::IMAGE_ICON, 0, 0);
        let wnd_class = WndClass {
            classname: "MainFrame".to_string(),
            style: 0x0001 | 0x0002, // CS_HREDRAW | CS_VREDRAW
            icon: icon,
            icon_small: None,
            cursor: Image::load_cursor_resource(32514), // hourglass
            background: (5 + 1) as HBRUSH,
            menu: MenuResource::MenuId(MENU_MAIN),
            cls_extra: 0,
            wnd_extra: 0,
        };
        let res = wnd_class.register(instance);
        if !res {
            return None;
        }

        let wproc = Box::new(MainFrame {
            win: Window::null(),
            title: title.clone(),
            text_height: text_height,
            edit: RefCell::new(None),
            font: RefCell::new(None),
        });

        let win_params = WindowParams {
            window_name: title,
            style: window::WS_OVERLAPPEDWINDOW,
            x: 0,
            y: 0,
            width: 400,
            height: 400,
            parent: Window::null(),
            menu: ptr::null_mut(),
            ex_style: 0,
        };

        Window::new(instance, Some(wproc as Box<WindowImpl + 'static>),
                    wnd_class.classname.as_slice(), &win_params)
    }
}

fn main() {
    let instance = Instance::main_instance();
    let main = MainFrame::new(instance, "Hello Rust".to_string(), 20);
    let main = main.unwrap();

    main.show(1);
    main.update();

    let exit_code = main_window_loop();
    std::os::set_exit_status(exit_code as isize);
}
<|endoftext|>


<commit_before>//! MySQL Proxy Server

#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate tokio_core;
extern crate futures_cpupool;
extern crate mysql_proxy;

use mysql_proxy::*;

use std::cell::RefCell;
use std::rc::Rc;
use std::env;
use std::io::{self, Read, Write};
use std::net::{SocketAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use std::net::Shutdown;
use std::str;
use std::time::Duration;

use futures::{Future, Poll};
use futures::stream::Stream;
use futures_cpupool::CpuPool;
use tokio_core::{Loop, LoopHandle, TcpStream};
use tokio_core::io::{read_exact, write_all, Window};

fn main() {
    drop(env_logger::init());

    let addr = env::args().nth(1).unwrap_or("127.0.0.1:3307".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();

    let mut lp = Loop::new().unwrap();
    let pool = CpuPool::new(4);
    let buffer = Rc::new(RefCell::new(vec![0; 64 * 1024]));
    let handle = lp.handle();
    let listener = lp.run(handle.clone().tcp_listen(&addr)).unwrap();
    let pin = lp.pin();

    println!("Listening for MySQL proxy connections on {}", addr);
    let clients = listener.incoming().map(move |(socket, addr)| {
        (Client {
            pool: pool.clone(),
            handle: handle.clone(),
        }.serve(socket, MyHandler {}, MyHandler {} ), addr)
    });
    let server = clients.for_each(|(client, addr)| {
        pin.spawn(client.then(move |res| {
            match res {
                Ok((a, b)) => {
                    println!("proxied {}/{} bytes for {}", a, b, addr)
                }
                Err(e) => println!("error for {}: {}", addr, e),
            }
            futures::finished(())
        }));
        Ok(())
    });

    lp.run(server).unwrap();
}

#[derive(Debug)]
enum Direction {
    Request, Response
}

struct MyHandler {}

impl PacketHandler for MyHandler {
    fn handle(&self, p: &Packet) {
        println!("handling packet");
        print_packet_chars(&p.bytes);
    }
}

#[allow(dead_code)]
fn print_packet_chars(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        print!("{} ", buf[i] as char);
    }
    println!("]");
}

#[allow(dead_code)]
fn print_packet_bytes(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        if i%8==0 { println!(""); }
        print!("{:#04x} ",buf[i]);
    }
    println!("]");
}

<commit_msg>add handler<commit_after>//! MySQL Proxy Server

#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate tokio_core;
extern crate futures_cpupool;
extern crate mysql_proxy;

use mysql_proxy::*;

use std::cell::RefCell;
use std::rc::Rc;
use std::env;
use std::io::{self, Read, Write};
use std::net::{SocketAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use std::net::Shutdown;
use std::str;
use std::time::Duration;

use futures::{Future, Poll};
use futures::stream::Stream;
use futures_cpupool::CpuPool;
use tokio_core::{Loop, LoopHandle, TcpStream};
use tokio_core::io::{read_exact, write_all, Window};

fn main() {
    drop(env_logger::init());

    let addr = env::args().nth(1).unwrap_or("127.0.0.1:3307".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();

    let mut lp = Loop::new().unwrap();
    let pool = CpuPool::new(4);
    let buffer = Rc::new(RefCell::new(vec![0; 64 * 1024]));
    let handle = lp.handle();
    let listener = lp.run(handle.clone().tcp_listen(&addr)).unwrap();
    let pin = lp.pin();

    println!("Listening for MySQL proxy connections on {}", addr);
    let clients = listener.incoming().map(move |(socket, addr)| {
        (Client {
            pool: pool.clone(),
            handle: handle.clone(),
        }.serve(socket,
                MyHandler { direction: Direction::Request }, // our request handler
                MyHandler { direction: Direction::Response } // our response handler
        ), addr)
    });
    let server = clients.for_each(|(client, addr)| {
        pin.spawn(client.then(move |res| {
            match res {
                Ok((a, b)) => {
                    println!("proxied {}/{} bytes for {}", a, b, addr)
                }
                Err(e) => println!("error for {}: {}", addr, e),
            }
            futures::finished(())
        }));
        Ok(())
    });

    lp.run(server).unwrap();
}

#[derive(Debug)]
pub enum Direction {
    Request, Response
}

struct MyHandler {
    direction: Direction
}

impl PacketHandler for MyHandler {
    fn handle(&self, p: &Packet) {
        println!("Handling {:?} packet:", self.direction);
        print_packet_chars(&p.bytes);
    }
}

impl Drop for MyHandler {
    fn drop(&mut self) {
        println!("Dropping {:?} handler", self.direction);
    }
}

#[allow(dead_code)]
fn print_packet_chars(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        print!("{} ", buf[i] as char);
    }
    println!("]");
}

#[allow(dead_code)]
fn print_packet_bytes(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        if i%8==0 { println!(""); }
        print!("{:#04x} ",buf[i]);
    }
    println!("]");
}

<|endoftext|>


<commit_before>//! A small snake game done after watching
//! <https://www.youtube.com/watch?v=HCwMb0KslX8>
//! to showcase ggez and how it relates/differs from piston.
//!
//! Author: @termhn
//! Original repo: https://github.com/termhn/ggez_snake

extern crate ggez;
extern crate rand;

use ggez::{event, graphics, GameResult, Context};
use ggez::event::Keycode;

use std::collections::LinkedList;
use std::time::{Instant, Duration};

use rand::{Rng};

const GRID_SIZE: (i16, i16) = (30, 20);
const GRID_CELL_SIZE: (i16, i16) = (32, 32);

const SCREEN_SIZE: (u32, u32) = (GRID_SIZE.0 as u32 * GRID_CELL_SIZE.0 as u32,
                                 GRID_SIZE.1 as u32 * GRID_CELL_SIZE.1 as u32);

const UPDATES_PER_SECOND: f32 = 8.0;
const MILLIS_PER_UPDATE: u64 = (1.0 / UPDATES_PER_SECOND * 1000.0) as u64;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
struct GridPosition {
    x: i16,
    y: i16,
}

/// A trait that provides a modulus function that works for negative values
/// rather than just the standard remainder op (%) which does not.
trait ModuloSigned {
    fn modulo(&self, n: Self) -> Self;
}

impl<T> ModuloSigned for T
    where T: std::ops::Add<Output = T> + std::ops::Rem<Output = T> + Clone
{
    fn modulo(&self, n: T) -> T {
        (self.clone() % n.clone() + n.clone()) % n.clone()
    }
}

impl GridPosition {
    pub fn new(x: i16, y: i16) -> Self {
        GridPosition { x, y }
    }

    pub fn random(max_x: i16, max_y: i16) -> Self {
        let mut rng = rand::thread_rng();
        (rng.gen_range::<i16>(0, max_x),
         rng.gen_range::<i16>(0, max_y)).into()
    }

    pub fn new_from_move(pos: GridPosition, dir: Direction) -> Self {
        match dir {
            Direction::Up => GridPosition::new(pos.x, (pos.y - 1).modulo(GRID_SIZE.1)),
            Direction::Down => GridPosition::new(pos.x, (pos.y + 1).modulo(GRID_SIZE.1)),
            Direction::Left => GridPosition::new((pos.x - 1).modulo(GRID_SIZE.0), pos.y),
            Direction::Right => GridPosition::new((pos.x + 1).modulo(GRID_SIZE.0), pos.y),
        }
    }
}

impl From<GridPosition> for graphics::Rect {
    fn from(pos: GridPosition) -> Self {
        graphics::Rect::new_i32(pos.x as i32 * GRID_CELL_SIZE.0 as i32, pos.y as i32 * GRID_CELL_SIZE.1 as i32,
                                GRID_CELL_SIZE.0 as i32, GRID_CELL_SIZE.1 as i32)
    }
}

impl From<(i16, i16)> for GridPosition {
    fn from(pos: (i16, i16)) -> Self {
        GridPosition { x: pos.0, y: pos.1 }
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

impl Direction {
    pub fn inverse(&self) -> Self {
        match *self {
            Direction::Up => Direction::Down,
            Direction::Down => Direction::Up,
            Direction::Left => Direction::Right,
            Direction::Right => Direction::Left,
        }
    }

    pub fn from_keycode(key: Keycode) -> Option<Direction> {
        match key {
            Keycode::Up => Some(Direction::Up),
            Keycode::Down => Some(Direction::Down),
            Keycode::Left => Some(Direction::Left),
            Keycode::Right => Some(Direction::Right),
            _ => None
        }
    }
}

#[derive(Clone, Copy, Debug)]
struct Segment {
    pos: GridPosition,
}

impl Segment {
    pub fn new(pos: GridPosition) -> Self {
        Segment { pos }
    }
}

#[derive(Clone, Copy, Debug)]
enum Ate {
    Itself,
    Food,
}

struct Snake {
    head: Segment,
    dir: Direction,
    body: LinkedList<Segment>,
    ate: Option<Ate>,
    last_update_dir: Direction,
}

impl Snake {
    pub fn new(pos: GridPosition) -> Self {
        let mut body = LinkedList::new();
        body.push_back(Segment::new((pos.x - 1, pos.y).into()));
        Snake {
            head: Segment::new(pos),
            dir: Direction::Right,
            last_update_dir: Direction::Right,
            body: body,
            ate: None,
        }
    }

    fn eats(&self, food: &Food) -> bool {
        if self.head.pos == food.pos {
            true
        } else {
            false
        }
    }

    fn eats_self(&self) -> bool {
        for seg in self.body.iter() {
            if self.head.pos == seg.pos {
                return true;
            }
        }
        false
    }

    fn update(&mut self, food: &Food) {
        let new_head_pos = GridPosition::new_from_move(self.head.pos, self.dir);
        let new_head = Segment::new(new_head_pos);
        self.body.push_front(self.head);
        self.head = new_head;
        if self.eats_self() {
            self.ate = Some(Ate::Itself);
        } else if self.eats(food) {
            self.ate = Some(Ate::Food);
        } else {
            self.ate = None
        }
        if let None = self.ate {
            self.body.pop_back();
        }
    }

    fn draw(&self, ctx: &mut Context) -> GameResult<()> {
        for seg in self.body.iter() {
            graphics::set_color(ctx, [1.0, 0.5, 0.0, 1.0].into())?;
            graphics::rectangle(ctx, graphics::DrawMode::Fill, seg.pos.into())?;
        }
        graphics::set_color(ctx, [1.0, 0.0, 0.0, 1.0].into())?;
        graphics::rectangle(ctx, graphics::DrawMode::Fill, self.head.pos.into())?;
        Ok(())
    }
}

struct Food {
    pos: GridPosition
}

impl Food {
    pub fn new(pos: GridPosition) -> Self {
        Food { pos }
    }

    fn draw(&self, ctx: &mut Context) -> GameResult<()> {
        graphics::set_color(ctx, [0.0, 0.0, 1.0, 1.0].into())?;
        graphics::rectangle(ctx, graphics::DrawMode::Fill, self.pos.into())
    }
}

struct GameState {
    snake: Snake,
    food: Food,
    gameover: bool,
    last_update: Instant,
}

impl GameState {
    pub fn new() -> Self {
        let snake_pos = (GRID_SIZE.0 / 4, GRID_SIZE.1 / 2).into();
        let food_pos = GridPosition::random(GRID_SIZE.0, GRID_SIZE.1);

        GameState {
            snake: Snake::new(snake_pos),
            food: Food::new(food_pos),
            gameover: false,
            last_update: Instant::now(),
        }
    }
}

impl event::EventHandler for GameState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
        if Instant::now() - self.last_update >= Duration::from_millis(MILLIS_PER_UPDATE) {
            if !self.gameover {
                self.snake.update(&self.food);
                if let Some(ate) = self.snake.ate {
                    match ate {
                        Ate::Food => {
                            let new_food_pos = GridPosition::random(GRID_SIZE.0, GRID_SIZE.1);
                            self.food.pos = new_food_pos;
                        },
                        Ate::Itself => {
                            self.gameover = true;
                        }
                    }
                }
            }
            self.last_update = Instant::now();
            self.snake.last_update_dir = self.snake.dir;
        }
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);
        self.snake.draw(ctx)?;
        self.food.draw(ctx)?;
        graphics::present(ctx);
        ggez::timer::yield_now();
        Ok(())
    }

    fn key_down_event(&mut self, _ctx: &mut Context, keycode: Keycode, _keymod: event::Mod, _repeat: bool) {
        if let Some(dir) = Direction::from_keycode(keycode) {
            if dir.inverse() != self.snake.last_update_dir {
                self.snake.dir = dir;
            }
        }
    }
}

fn main() {
    let ctx = &mut ggez::ContextBuilder::new("snake", "Gray Olson")
        .window_setup(ggez::conf::WindowSetup::default().title("Snake!"))
        .window_mode(ggez::conf::WindowMode::default().dimensions(SCREEN_SIZE.0, SCREEN_SIZE.1))
        .build().expect("Failed to build ggez context");

    graphics::set_background_color(ctx, [0.0, 1.0, 0.0, 1.0].into());

    let state = &mut GameState::new();

    match event::run(ctx, state) {
        Err(e) => println!("Error encountered running game: {}", e),
        Ok(_) => println!("Game exited cleanly!")
    }
}
<commit_msg>add comments to snake example<commit_after>//! A small snake game done after watching
//! <https://www.youtube.com/watch?v=HCwMb0KslX8>
//! to showcase ggez and how it relates/differs from piston.
//!
//! Author: @termhn
//! Original repo: https://github.com/termhn/ggez_snake

// First we'll import the crates we need for our game;
// in this case that is just `ggez` and `rand`.
extern crate ggez;
extern crate rand;

// Next we need to actually `use` the pieces of ggez that we are going
// to need frequently.
use ggez::{event, graphics, GameResult, Context};
use ggez::event::Keycode;

// We'll bring in some things from `std` to help us in the future.
use std::collections::LinkedList;
use std::time::{Instant, Duration};

// And finally bring the `Rng` trait into scope so that we can generate
// some random numbers later.
use rand::{Rng};

// The first thing we want to do is set up some constants that will help us out later.

// Here we define the size of our game board in terms of how many grid
// cells it will take up. We choose to make a 30 x 20 game board.
const GRID_SIZE: (i16, i16) = (30, 20);
// Now we define the pixel size of each tile, which we make 32x32 pixels.
const GRID_CELL_SIZE: (i16, i16) = (32, 32);

// Next we define how large we want our actual window to be by multiplying
// the components of our grid size by its corresponding pixel size.
const SCREEN_SIZE: (u32, u32) = (GRID_SIZE.0 as u32 * GRID_CELL_SIZE.0 as u32,
                                 GRID_SIZE.1 as u32 * GRID_CELL_SIZE.1 as u32);

// Here we're defining how many quickly we want our game to update. This will be
// important later so that we don't have our snake fly across the screen because
// it's moving a full tile every frame.
const UPDATES_PER_SECOND: f32 = 8.0;
// And we get the milliseconds of delay that this update rate corresponds to.
const MILLIS_PER_UPDATE: u64 = (1.0 / UPDATES_PER_SECOND * 1000.0) as u64;

/// Now we define a struct that will hold an entity's position on our game board
/// or grid which we defined above. We'll use signed integers because we only want
/// to store whole numbers, and we need them to be signed so that they work properly
/// with our modulus arithmetic later.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
struct GridPosition {
    x: i16,
    y: i16,
}

/// This is a trait that provides a modulus function that works for negative values
/// rather than just the standard remainder op (%) which does not. We'll use this
/// to get our snake to wrap from one side of the game board around to the other
/// when it goes off the top, bottom, left, or right side of the screen.
trait ModuloSigned {
    fn modulo(&self, n: Self) -> Self;
}

/// Here we implement our `ModuloSigned` trait for any type T which implements
/// `Add` (the `+` operator) with an output type T and Rem (the `%` operator)
/// that also has anout put type of T, and that can be cloned. These are the bounds
/// that we need in order to implement a modulus function that works for negative numbers
/// as well.
impl<T> ModuloSigned for T
    where T: std::ops::Add<Output = T> + std::ops::Rem<Output = T> + Clone
{
    fn modulo(&self, n: T) -> T {
        // Because of our trait bounds, we can now apply these operators.
        (self.clone() % n.clone() + n.clone()) % n.clone()
    }
}

impl GridPosition {
    /// We make a standard helper function so that we can create a new `GridPosition`
    /// more easily.
    pub fn new(x: i16, y: i16) -> Self {
        GridPosition { x, y }
    }

    /// As well as a helper function that will give us a random `GridPosition` from
    /// `(0, 0)` to `(max_x, max_y)`
    pub fn random(max_x: i16, max_y: i16) -> Self {
        let mut rng = rand::thread_rng();
        // We can use `.into()` to convert from `(i16, i16)` to a `GridPosition` since
        // we implement `From<(i16, i16)>` for `GridPosition` below.
        (rng.gen_range::<i16>(0, max_x),
         rng.gen_range::<i16>(0, max_y)).into()
    }

    /// We'll make another helper function that takes one grid position and returns a new one after
    /// making one move in the direction of `dir`. We use our `SignedModulo` trait
    /// above, which is now implemented on `i16` because it satisfies the trait bounds,
    /// to automatically wrap around within our grid size if the move would have otherwise
    /// moved us off the board to the top, bottom, left, or right.
    pub fn new_from_move(pos: GridPosition, dir: Direction) -> Self {
        match dir {
            Direction::Up => GridPosition::new(pos.x, (pos.y - 1).modulo(GRID_SIZE.1)),
            Direction::Down => GridPosition::new(pos.x, (pos.y + 1).modulo(GRID_SIZE.1)),
            Direction::Left => GridPosition::new((pos.x - 1).modulo(GRID_SIZE.0), pos.y),
            Direction::Right => GridPosition::new((pos.x + 1).modulo(GRID_SIZE.0), pos.y),
        }
    }
}

/// We implement the `From` trait, which in this case allows us to convert easily between
/// a GridPosition and a ggez `graphics::Rect` which fills that grid cell.
/// Now we can just call `.into()` on a `GridPosition` where we want a
/// `Rect` that represents that grid cell.
impl From<GridPosition> for graphics::Rect {
    fn from(pos: GridPosition) -> Self {
        graphics::Rect::new_i32(pos.x as i32 * GRID_CELL_SIZE.0 as i32, pos.y as i32 * GRID_CELL_SIZE.1 as i32,
                                GRID_CELL_SIZE.0 as i32, GRID_CELL_SIZE.1 as i32)
    }
}

/// And here we implement `From` again to allow us to easily convert between
/// `(i16, i16)` and a `GridPosition`.
impl From<(i16, i16)> for GridPosition {
    fn from(pos: (i16, i16)) -> Self {
        GridPosition { x: pos.0, y: pos.1 }
    }
}

/// Next we create an enum that will represent all the possible
/// directions that our snake could move.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

impl Direction {
    /// We create a helper function that will allow us to easily get the inverse
    /// of a `Direction` which we can use later to check if the player should be
    /// able to move the snake in a certain direction.
    pub fn inverse(&self) -> Self {
        match *self {
            Direction::Up => Direction::Down,
            Direction::Down => Direction::Up,
            Direction::Left => Direction::Right,
            Direction::Right => Direction::Left,
        }
    }

    /// We also create a helper function that will let us convert between a
    /// `ggez` `Keycode` and the `Direction` that it represents. Of course,
    /// not every keycode represents a direction, so we return `None` if this
    /// is the case.
    pub fn from_keycode(key: Keycode) -> Option<Direction> {
        match key {
            Keycode::Up => Some(Direction::Up),
            Keycode::Down => Some(Direction::Down),
            Keycode::Left => Some(Direction::Left),
            Keycode::Right => Some(Direction::Right),
            _ => None
        }
    }
}

/// This is mostly just a semantic abstraction over a `GridPosition` to represent
/// a segment of the snake. It could be useful to, say, have each segment contain its
/// own color or something similar. This is an exercise left up to the reader ;)
#[derive(Clone, Copy, Debug)]
struct Segment {
    pos: GridPosition,
}

impl Segment {
    pub fn new(pos: GridPosition) -> Self {
        Segment { pos }
    }
}

/// This is again an abstraction over a `GridPosition` that represents
/// a piece of food the snake can eat. It can draw itself.
struct Food {
    pos: GridPosition
}

impl Food {
    pub fn new(pos: GridPosition) -> Self {
        Food { pos }
    }

    /// Here is the first time we see what drawing looks like with ggez.
    /// We have a function that takes in a `&mut ggez::Context` which we use
    /// with the helpers in `ggez::graphics` to do drawing. We also return a
    /// `ggez::GameResult` so that we can use the `?` operator to bubble up
    /// failure of drawing.
    fn draw(&self, ctx: &mut Context) -> GameResult<()> {
        // First we set the color to draw with, in this case all food will be
        // colored blue.
        graphics::set_color(ctx, [0.0, 0.0, 1.0, 1.0].into())?;
        // Then we draw a rectangle with the Fill draw mode, and we convert the
        // Food's position into a `ggez::Rect` using `.into()` which we can do
        // since we implemented `From<GridPosition>` for `Rect` earlier.
        graphics::rectangle(ctx, graphics::DrawMode::Fill, self.pos.into())
    }
}

/// Here we define an enum of the possible things that the snake could have "eaten"
/// during an update of the game. It could have either eaten a piece of `Food`, or
/// it could have eaten `Itself` if the head ran into its body.
#[derive(Clone, Copy, Debug)]
enum Ate {
    Itself,
    Food,
}

/// Now we make a struct that contains all the information needed to describe the
/// state of the Snake itself.
struct Snake {
    /// First we have the head of the snake, which is a single `Segment`.
    head: Segment,
    /// Then we have the current direction the snake is moving. This is
    /// the direction it will move when `update` is called on it.
    dir: Direction,
    /// Next we have the body, which we choose to represent as a `LinkedList`
    /// of `Segment`s.
    body: LinkedList<Segment>,
    /// Now we have a property that represents the result of the last update
    /// that was performed. The snake could have eaten nothing (None), Food (Some(Ate::Food)),
    /// or Itself (Some(Ate::Itself))
    ate: Option<Ate>,
    /// Finally we store the direction that the snake was traveling the last
    /// time that `update` was called, which we will use to determine valid
    /// directions that it could move the next time update is called.
    last_update_dir: Direction,
}

impl Snake {
    pub fn new(pos: GridPosition) -> Self {
        let mut body = LinkedList::new();
        // Our snake will initially have a head and one body segment,
        // and will be moving to the right.
        body.push_back(Segment::new((pos.x - 1, pos.y).into()));
        Snake {
            head: Segment::new(pos),
            dir: Direction::Right,
            last_update_dir: Direction::Right,
            body: body,
            ate: None,
        }
    }

    /// A helper function that determines whether
    /// the snake eats a given piece of Food based
    /// on its current position
    fn eats(&self, food: &Food) -> bool {
        if self.head.pos == food.pos {
            true
        } else {
            false
        }
    }

    /// A helper function that determines whether
    /// the snake eats itself based on its current position
    fn eats_self(&self) -> bool {
        for seg in self.body.iter() {
            if self.head.pos == seg.pos {
                return true;
            }
        }
        false
    }

    /// The main update function for our snake which gets called every time
    /// we want to update the game state.
    fn update(&mut self, food: &Food) {
        // First we get a new head position by using our `new_from_move` helper
        // function from earlier. We move our head in the direction we are currently
        // heading.
        let new_head_pos = GridPosition::new_from_move(self.head.pos, self.dir);
        // Next we create a new segment will be our new head segment using the
        // new position we just made.
        let new_head = Segment::new(new_head_pos);
        // Then we push our current head Segment onto the front of our body
        self.body.push_front(self.head);
        // And finally make our actual head the new Segment we created. This has
        // effectively moved the snake in the current direction.
        self.head = new_head;
        // Next we check whether the snake eats itself or some food, and if so,
        // we set our `ate` member to reflect that state.
        if self.eats_self() {
            self.ate = Some(Ate::Itself);
        } else if self.eats(food) {
            self.ate = Some(Ate::Food);
        } else {
            self.ate = None
        }
        // If we didn't eat anything this turn, we remove the last segment from our body,
        // which gives the illusion that the snake is moving. In reality, all the segments stay
        // stationary, we just add a segment to the front and remove one from the back. If we eat
        // a piece of food, then we leave the last segment so that we extend our body by one.
        if let None = self.ate {
            self.body.pop_back();
        }
        // And set our last_update_dir to the direction we just moved.
        self.last_update_dir = self.dir;
    }

    /// Here we have the Snake draw itself. This is very similar to how we saw the Food
    /// draw itself earlier.
    fn draw(&self, ctx: &mut Context) -> GameResult<()> {
        // We first iterate through the body segments and draw them.
        for seg in self.body.iter() {
            // Again we set the color (in this case an orangey color)
            graphics::set_color(ctx, [1.0, 0.5, 0.0, 1.0].into())?;
            // and then draw the Rect that we convert that Segment's position into
            graphics::rectangle(ctx, graphics::DrawMode::Fill, seg.pos.into())?;
        }
        // And then we do the same for the head, instead making it fully red to distinguish it.
        graphics::set_color(ctx, [1.0, 0.0, 0.0, 1.0].into())?;
        graphics::rectangle(ctx, graphics::DrawMode::Fill, self.head.pos.into())?;
        Ok(())
    }
}

/// Now we have the heart of our game, the GameState. This struct
/// will implement ggez's `EventHandler` trait and will therefore drive
/// everything else that happens in our game.
struct GameState {
    /// First we need a Snake
    snake: Snake,
    /// A piee of food
    food: Food,
    /// Whether the game is over or not
    gameover: bool,
    /// And we track the last time we updated so that we can limit
    /// our update rate.
    last_update: Instant,
}

impl GameState {
    /// Our new function will set up the initial state of our game.
    pub fn new() -> Self {
        // First we put our snake a quarter of the way across our grid in the x axis
        // and half way down the y axis. This works well since we start out moving to the right.
        let snake_pos = (GRID_SIZE.0 / 4, GRID_SIZE.1 / 2).into();
        // Then we choose a random place to put our piece of food using the helper we made
        // earlier.
        let food_pos = GridPosition::random(GRID_SIZE.0, GRID_SIZE.1);

        GameState {
            snake: Snake::new(snake_pos),
            food: Food::new(food_pos),
            gameover: false,
            last_update: Instant::now(),
        }
    }
}

/// Now we implement EventHandler for GameState. This provides an interface
/// that ggez will call automatically when different events happen.
impl event::EventHandler for GameState {
    /// Update will happen on every frame before it is drawn. This is where we update
    /// our game state to react to whatever is happening in the game world.
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
        // First we check to see if enough time has elapsed since our last update based on
        // the update rate we defined at the top.
        if Instant::now() - self.last_update >= Duration::from_millis(MILLIS_PER_UPDATE) {
            // Then we check to see if the game is over. If not, we'll update. If so, we'll just do nothing.
            if !self.gameover {
                // Here we do the actual updating of our game world. First we tell the snake to update itself,
                // passing in a reference to our piece of food.
                self.snake.update(&self.food);
                // Next we check if the snake ate anything as it updated.
                if let Some(ate) = self.snake.ate {
                    // If it did, we want to know what it ate.
                    match ate {
                        // If it ate a piece of food, we randomly select a new position for our piece of food
                        // and move it to this new position.
                        Ate::Food => {
                            let new_food_pos = GridPosition::random(GRID_SIZE.0, GRID_SIZE.1);
                            self.food.pos = new_food_pos;
                        },
                        // If it ate itself, we set our gameover state to true.
                        Ate::Itself => {
                            self.gameover = true;
                        }
                    }
                }
            }
            // If we updated, we set our last_update to be now
            self.last_update = Instant::now();
        }
        // Finally we return `Ok` to indicate we didn't run into any errors
        Ok(())
    }

    /// draw is where we should actually render the game's current state.
    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        // First we clear the screen
        graphics::clear(ctx);
        // Then we tell the snake and the food to draw themselves
        self.snake.draw(ctx)?;
        self.food.draw(ctx)?;
        // Finally we call graphics::present to cycle the gpu's framebuffer and display
        // the new frame we just drew.
        graphics::present(ctx);
        // We yield the current thread until the next update
        ggez::timer::yield_now();
        // And return success.
        Ok(())
    }

    /// key_down_event gets fired when a key gets pressed.
    fn key_down_event(&mut self, _ctx: &mut Context, keycode: Keycode, _keymod: event::Mod, _repeat: bool) {
        // Here we attempt to convert the Keycode into a Direction using the helper
        // we defined earlier.
        if let Some(dir) = Direction::from_keycode(keycode) {
            // If it succeeds, we check to make sure that the direction being pressed
            // is not directly opposite to the way the snake was facing last update.
            if dir.inverse() != self.snake.last_update_dir {
                // If not, we set the snake's new direction to be the direction the user pressed.
                self.snake.dir = dir;
            }
        }
    }
}

fn main() {
    // Here we use a ContextBuilder to setup metadata about our game. First the title and author
    let ctx = &mut ggez::ContextBuilder::new("snake", "Gray Olson")
        // Next we set up the window. This title will be displayed in the title bar of the window.
        .window_setup(ggez::conf::WindowSetup::default().title("Snake!"))
        // Now we get to set the size of the window, which we use our SCREEN_SIZE constant from earlier to help with
        .window_mode(ggez::conf::WindowMode::default().dimensions(SCREEN_SIZE.0, SCREEN_SIZE.1))
        // And finally we attempt to build the context and create the window. If it fails, we panic with the message
        // "Failed to build ggez context"
        .build().expect("Failed to build ggez context");

    // We set the background color of our Context to a nice (well, maybe pretty glaring ;)) green
    graphics::set_background_color(ctx, [0.0, 1.0, 0.0, 1.0].into());
    // Next we create a new instance of our GameState struct, which implements EventHandler
    let state = &mut GameState::new();
    // And finally we actually run our game, passing in our context and state.
    match event::run(ctx, state) {
        // If we encounter an error, we print it before exiting
        Err(e) => println!("Error encountered running game: {}", e),
        // And if not, we print a message saying we ran cleanly. Hooray!
        Ok(_) => println!("Game exited cleanly!")
    }
}
<|endoftext|>


<commit_before>extern crate termion;
extern crate tui;

use std::io;

use termion::event;
use termion::input::TermRead;

use tui::Terminal;
use tui::backend::MouseBackend;
use tui::widgets::{Block, Borders, Row, Table, Widget};
use tui::layout::{Direction, Group, Rect, Size};
use tui::style::{Color, Modifier, Style};

struct App<'a> {
    size: Rect,
    items: Vec<Vec<&'a str>>,
    selected: usize,
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
            size: Rect::default(),
            items: vec![
                vec!["Row12", "Row12", "Row13"],
                vec!["Row21", "Row22", "Row23"],
                vec!["Row31", "Row32", "Row33"],
                vec!["Row41", "Row42", "Row43"],
                vec!["Row51", "Row52", "Row53"],
                vec!["Row61", "Row62", "Row63"],
            ],
            selected: 0,
        }
    }
}

fn main() {
    // Terminal initialization
    let backend = MouseBackend::new().unwrap();
    let mut terminal = Terminal::new(backend).unwrap();

    // App
    let mut app = App::new();

    // First draw call
    terminal.clear().unwrap();
    terminal.hide_cursor().unwrap();
    app.size = terminal.size().unwrap();
    draw(&mut terminal, &app);

    // Input
    let stdin = io::stdin();
    for c in stdin.keys() {
        let size = terminal.size().unwrap();
        if size != app.size {
            terminal.resize(size).unwrap();
            app.size = size;
        }

        let evt = c.unwrap();
        match evt {
            event::Key::Char('q') => {
                break;
            }
            event::Key::Down => {
                app.selected += 1;
                if app.selected > app.items.len() - 1 {
                    app.selected = 0;
                }
            }
            event::Key::Up => if app.selected > 0 {
                app.selected -= 1;
            } else {
                app.selected = app.items.len() - 1;
            },
            _ => {}
        };
        draw(&mut terminal, &app);
    }

    terminal.show_cursor().unwrap();
    terminal.clear().unwrap();
}

fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
    Group::default()
        .direction(Direction::Horizontal)
        .sizes(&[Size::Percent(100)])
        .margin(5)
        .render(t, &app.size, |t, chunks| {
            let selected_style = Style::default().fg(Color::Yellow).modifier(Modifier::Bold);
            let normal_style = Style::default().fg(Color::White);
            Table::new(
                ["Header1", "Header2", "Header3"].into_iter(),
                app.items.iter().enumerate().map(|(i, item)| {
                    if i == app.selected {
                        Row::StyledData(item.into_iter(), &selected_style)
                    } else {
                        Row::StyledData(item.into_iter(), &normal_style)
                    }
                }),
            ).block(Block::default().borders(Borders::ALL).title("Table"))
                .widths(&[10, 10, 10])
                .render(t, &chunks[0]);
        });

    t.draw().unwrap();
}
<commit_msg>[examples] Update table example<commit_after>extern crate termion;
extern crate tui;

use std::io;

use termion::event;
use termion::input::TermRead;

use tui::Terminal;
use tui::backend::MouseBackend;
use tui::widgets::{Block, Borders, Row, Table, Widget};
use tui::layout::{Direction, Group, Rect, Size};
use tui::style::{Color, Modifier, Style};

struct App<'a> {
    size: Rect,
    items: Vec<Vec<&'a str>>,
    selected: usize,
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
            size: Rect::default(),
            items: vec![
                vec!["Row12", "Row12", "Row13"],
                vec!["Row21", "Row22", "Row23"],
                vec!["Row31", "Row32", "Row33"],
                vec!["Row41", "Row42", "Row43"],
                vec!["Row51", "Row52", "Row53"],
                vec!["Row61", "Row62", "Row63"],
            ],
            selected: 0,
        }
    }
}

fn main() {
    // Terminal initialization
    let backend = MouseBackend::new().unwrap();
    let mut terminal = Terminal::new(backend).unwrap();

    // App
    let mut app = App::new();

    // First draw call
    terminal.clear().unwrap();
    terminal.hide_cursor().unwrap();
    app.size = terminal.size().unwrap();
    draw(&mut terminal, &app);

    // Input
    let stdin = io::stdin();
    for c in stdin.keys() {
        let size = terminal.size().unwrap();
        if size != app.size {
            terminal.resize(size).unwrap();
            app.size = size;
        }

        let evt = c.unwrap();
        match evt {
            event::Key::Char('q') => {
                break;
            }
            event::Key::Down => {
                app.selected += 1;
                if app.selected > app.items.len() - 1 {
                    app.selected = 0;
                }
            }
            event::Key::Up => if app.selected > 0 {
                app.selected -= 1;
            } else {
                app.selected = app.items.len() - 1;
            },
            _ => {}
        };
        draw(&mut terminal, &app);
    }

    terminal.show_cursor().unwrap();
    terminal.clear().unwrap();
}

fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
    let selected_style = Style::default().fg(Color::Yellow).modifier(Modifier::Bold);
    let normal_style = Style::default().fg(Color::White);
    let header = ["Header1", "Header2", "Header3"];
    let rows = app.items.iter().enumerate().map(|(i, item)| {
        if i == app.selected {
            Row::StyledData(item.into_iter(), &selected_style)
        } else {
            Row::StyledData(item.into_iter(), &normal_style)
        }
    });
    Group::default()
        .direction(Direction::Horizontal)
        .sizes(&[Size::Percent(100)])
        .margin(5)
        .render(t, &app.size, |t, chunks| {
            Table::new(header.into_iter(), rows)
                .block(Block::default().borders(Borders::ALL).title("Table"))
                .widths(&[10, 10, 10])
                .render(t, &chunks[0]);
        });

    t.draw().unwrap();
}
<|endoftext|>


<commit_before>use core::error::*;
use core::typedef::*;
use pest::Parser;
use std::fs::File;
use std::io::Read;
use std::path::Path;

const _GRAMMAR: &str = include_str!("../src/beast.pest");

#[derive(Parser)]
#[grammar = "beast.pest"]
pub struct BeastParser;

pub fn compile(file_name: String) -> Result<ImageData> {
    let orig_path = Path::new(&file_name)
        .canonicalize()
        .chain_err(|| "unable to canonicalize path")?;

    let mut file = File::open(orig_path).chain_err(|| "unable to open file")?;

    let mut buf = String::new();

    file.read_to_string(&mut buf)
        .chain_err(|| "unable to read file")?;

    let parser_res = BeastParser::parse(Rule::file, &buf);

    if let Err(err) = parser_res {
        bail!("{:?}", err);
    }

    bail!("Beast compiler is not implemented yet!")
}

#[cfg(test)]
mod tests {
    use super::*;
    use pest::Parser;
    use pest::Token;
    use pest::iterators::Pairs;

    #[test]
    fn simple() {
        BeastParser::parse(
            Rule::file,
            include_str!("../examples/beast/simple/simple.beast"),
        ).unwrap_or_else(|e| panic!("{}", e));
    }

    #[test]
    fn signals() {
        BeastParser::parse(
            Rule::file,
            include_str!("../examples/beast/signals/basic.beast"),
        ).unwrap_or_else(|e| panic!("{}", e));
    }

    #[test]
    fn else_if() {
        BeastParser::parse(
            Rule::file,
            include_str!("../examples/beast/simple/else_if.beast"),
        ).unwrap_or_else(|e| panic!("{}", e));
    }
}
<commit_msg>Refined error message<commit_after>use core::error::*;
use core::typedef::*;
use pest::Parser;
use std::fs::File;
use std::io::Read;
use std::path::Path;

const _GRAMMAR: &str = include_str!("../src/beast.pest");

#[derive(Parser)]
#[grammar = "beast.pest"]
pub struct BeastParser;

pub fn compile(file_name: String) -> Result<ImageData> {
    let orig_path = Path::new(&file_name)
        .canonicalize()
        .chain_err(|| "unable to canonicalize path")?;

    let mut file = File::open(orig_path).chain_err(|| "unable to open file")?;

    let mut buf = String::new();

    file.read_to_string(&mut buf)
        .chain_err(|| "unable to read file")?;

    let parser_res = BeastParser::parse(Rule::file, &buf);

    if let Err(err) = parser_res {
        bail!("{}", err);
    }

    bail!("Beast compiler is not implemented yet!")
}

#[cfg(test)]
mod tests {
    use super::*;
    use pest::Parser;
    use pest::Token;
    use pest::iterators::Pairs;

    #[test]
    fn simple() {
        BeastParser::parse(
            Rule::file,
            include_str!("../examples/beast/simple/simple.beast"),
        ).unwrap_or_else(|e| panic!("{}", e));
    }

    #[test]
    fn signals() {
        BeastParser::parse(
            Rule::file,
            include_str!("../examples/beast/signals/basic.beast"),
        ).unwrap_or_else(|e| panic!("{}", e));
    }

    #[test]
    fn else_if() {
        BeastParser::parse(
            Rule::file,
            include_str!("../examples/beast/simple/else_if.beast"),
        ).unwrap_or_else(|e| panic!("{}", e));
    }
}
<|endoftext|>


<commit_before>
use state::LuaState;

/// An interned string.  String interning guarantees that only
/// one copy of a string exists in the runtime at any given time.
pub struct InString {
  string: String,        // TODO: use &str and .as_ptr() instead?
  intern: *const String
}

impl InString {
  pub fn new(ls: &mut LuaState, s: &String) -> InString {
    let insert : bool;

    {
      let val = ls.strings.get(s);
      match val {
        Some(_) => insert = false,
        None => insert = true,
      }
    }

    if insert {
      ls.strings.insert(s.clone(), s.clone());
    }

    let x = &ls.strings[s];

    InString {
      string: s.clone(),
      intern: x as *const String
    }
  }
}

// Comparison for interned strings is just pointer comparison.
impl PartialEq for InString {
  fn eq(&self, other: &InString) -> bool {
    self.intern == other.intern
  }
}

// TODO: impl Hash for InString

impl ToString for InString {
  fn to_string(&self) -> String {
    self.string.clone()
  }
}

<commit_msg>impl Eq for InString<commit_after>
use state::LuaState;

/// An interned string.  String interning guarantees that only
/// one copy of a string exists in the runtime at any given time.
pub struct InString {
  string: String,        // TODO: use &str and .as_ptr() instead?
  intern: *const String
}

impl InString {
  pub fn new(ls: &mut LuaState, s: &String) -> InString {
    let insert : bool;

    {
      let val = ls.strings.get(s);
      match val {
        Some(_) => insert = false,
        None => insert = true,
      }
    }

    if insert {
      ls.strings.insert(s.clone(), s.clone());
    }

    let x = &ls.strings[s];

    InString {
      string: s.clone(),
      intern: x as *const String
    }
  }
}

// Comparison for interned strings is just pointer comparison.
impl PartialEq for InString {
  fn eq(&self, other: &InString) -> bool {
    self.intern == other.intern
  }
}

impl Eq for InString {}

// TODO: impl Hash for InString

impl ToString for InString {
  fn to_string(&self) -> String {
    self.string.clone()
  }
}

<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader};
use std::net::IpAddr;
use std::os::unix::io::AsRawFd;

use blake2::{self, Digest};
use failure::{Error, ResultExt};
use ipnetwork::IpNetwork;
use nix::sched::{setns, CLONE_NEWNET};
use serde_json::to_vec;
use unshare;

use lithos::sandbox_config::{SandboxConfig, BridgedNetwork};
use lithos::child_config::ChildConfig;
use lithos::container_config::InstantiatedConfig;

pub fn setup(sandbox: &SandboxConfig, child: &ChildConfig,
    container: &InstantiatedConfig)
    -> Result<(), String>
{
    _setup(sandbox, child, container)
    .map_err(|e| e.to_string())
}

fn interface_name(network: &BridgedNetwork, ip: &IpAddr) -> String {
    #[derive(Serialize)]
    struct HashSource<'a> {
        bridge: &'a str,
        ip: &'a IpAddr,
    }
    let (ip1, ip2) = match *ip {
        IpAddr::V4(ip) => (ip.octets()[2], ip.octets()[3]),
        IpAddr::V6(ip) => (ip.octets()[14], ip.octets()[15]),
    };
    let name = format!("li_{:.6}_{:02x}{:02x}",
        // double formatting because of a bug in generic array
        format!("{:06x}", blake2::Blake2b::digest(&to_vec(&HashSource {
            bridge: &network.bridge,
            ip: ip,
        }).expect("can always serialize"))),
        ip1, ip2);
    assert!(name.len() <= 15);
    return name;
}

fn get_real_pids() -> Result<(u32, u32), Error> {
    let mut pid = None::<u32>;
    let mut ppid = None::<u32>;
    let f = BufReader::new(File::open("/proc/self/status")
        .context("can open /proc/self/status")?);
    for line in f.lines() {
        let line = line.context("can open /proc/self/status")?;
        if line.starts_with("Pid:") {
            pid = Some(line[5..].trim().parse::<u32>()
                .context("can parse pid in /proc/sef/status")?);
        } else if line.starts_with("PPid:") {
            ppid = Some(line[5..].trim().parse::<u32>()
                .context("can parse pid in /proc/sef/status")?);
        } else {
            continue;
        }
        match (pid, ppid) {
            (Some(pid), Some(ppid)) => return Ok((pid, ppid)),
            _ => continue,
        }
    }
    bail!("can't find ppid");
}

fn _setup(sandbox: &SandboxConfig, child: &ChildConfig,
    _container: &InstantiatedConfig)
    -> Result<(), Error>
{
    let net = sandbox.bridged_network.as_ref().expect("bridged network");
    let ip = child.ip_addresses.get(0).expect("ip address");
    let (pid, ppid) = get_real_pids()?;
    let my_ns = File::open("/proc/self/ns/net")
        .context("can't open namespace")?;
    let parent_ns = File::open(&format!("/proc/{}/ns/net", ppid))
        .context("can't open parent namespace")?;
    setns(parent_ns.as_raw_fd(), CLONE_NEWNET)?;
    let interface = interface_name(net, ip);
    let iinterface = interface.replace("_", "-");
    assert!(iinterface != interface);

    let mut cmd = unshare::Command::new("/bin/ip");
    cmd.arg("link").arg("add");
    cmd.arg(&interface);
    cmd.arg("type").arg("veth");
    cmd.arg("peer").arg("name").arg(&iinterface);
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("link").arg("set");
    cmd.arg("dev").arg(&iinterface);
    // Note: this is a bit of hack bit it's known to work.
    // 1. We opened our namespace first so `/proc/<PID>/ns/net` is associated
    //    with that namespace even if we change namespace
    // 2. Then we set namespace to a parent one
    // 3. We move interface to ours namespace
    // 4. Then switch our namespace back to expected one
    cmd.arg("netns").arg(&format!("/proc/{}/ns/net", pid));
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/brctl");
    cmd.arg("addif").arg(&net.bridge).arg(&interface);
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("brctl failed: {}", s),
        Err(e) => bail!("brctl failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("link").arg("set");
    cmd.arg(&interface);
    cmd.arg("up");
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    setns(my_ns.as_raw_fd(), CLONE_NEWNET)?;

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("addr").arg("add");
    cmd.arg(&format!("{}",
        IpNetwork::new(*ip, net.network.prefix())
        .expect("network asways valid")));
    cmd.arg("dev").arg(&iinterface);
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("link").arg("set");
    cmd.arg(&iinterface);
    cmd.arg("up");
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    if let Some(gw) = net.default_gateway {
        let mut cmd = unshare::Command::new("/sbin/ip");
        cmd.arg("route").arg("add");
        cmd.arg("default");
        cmd.arg("via").arg(&format!("{}", gw));
        match cmd.status() {
            Ok(s) if s.success() => {}
            Ok(s) => bail!("ip route failed: {}", s),
            Err(e) => bail!("ip route failed: {}", e),
        }
    }
    Ok(())
}
<commit_msg>Typo fixed<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader};
use std::net::IpAddr;
use std::os::unix::io::AsRawFd;

use blake2::{self, Digest};
use failure::{Error, ResultExt};
use ipnetwork::IpNetwork;
use nix::sched::{setns, CLONE_NEWNET};
use serde_json::to_vec;
use unshare;

use lithos::sandbox_config::{SandboxConfig, BridgedNetwork};
use lithos::child_config::ChildConfig;
use lithos::container_config::InstantiatedConfig;

pub fn setup(sandbox: &SandboxConfig, child: &ChildConfig,
    container: &InstantiatedConfig)
    -> Result<(), String>
{
    _setup(sandbox, child, container)
    .map_err(|e| e.to_string())
}

fn interface_name(network: &BridgedNetwork, ip: &IpAddr) -> String {
    #[derive(Serialize)]
    struct HashSource<'a> {
        bridge: &'a str,
        ip: &'a IpAddr,
    }
    let (ip1, ip2) = match *ip {
        IpAddr::V4(ip) => (ip.octets()[2], ip.octets()[3]),
        IpAddr::V6(ip) => (ip.octets()[14], ip.octets()[15]),
    };
    let name = format!("li_{:.6}_{:02x}{:02x}",
        // double formatting because of a bug in generic array
        format!("{:06x}", blake2::Blake2b::digest(&to_vec(&HashSource {
            bridge: &network.bridge,
            ip: ip,
        }).expect("can always serialize"))),
        ip1, ip2);
    assert!(name.len() <= 15);
    return name;
}

fn get_real_pids() -> Result<(u32, u32), Error> {
    let mut pid = None::<u32>;
    let mut ppid = None::<u32>;
    let f = BufReader::new(File::open("/proc/self/status")
        .context("can open /proc/self/status")?);
    for line in f.lines() {
        let line = line.context("can open /proc/self/status")?;
        if line.starts_with("Pid:") {
            pid = Some(line[5..].trim().parse::<u32>()
                .context("can parse pid in /proc/self/status")?);
        } else if line.starts_with("PPid:") {
            ppid = Some(line[5..].trim().parse::<u32>()
                .context("can parse pid in /proc/self/status")?);
        } else {
            continue;
        }
        match (pid, ppid) {
            (Some(pid), Some(ppid)) => return Ok((pid, ppid)),
            _ => continue,
        }
    }
    bail!("can't find ppid");
}

fn _setup(sandbox: &SandboxConfig, child: &ChildConfig,
    _container: &InstantiatedConfig)
    -> Result<(), Error>
{
    let net = sandbox.bridged_network.as_ref().expect("bridged network");
    let ip = child.ip_addresses.get(0).expect("ip address");
    let (pid, ppid) = get_real_pids()?;
    let my_ns = File::open("/proc/self/ns/net")
        .context("can't open namespace")?;
    let parent_ns = File::open(&format!("/proc/{}/ns/net", ppid))
        .context("can't open parent namespace")?;
    setns(parent_ns.as_raw_fd(), CLONE_NEWNET)?;
    let interface = interface_name(net, ip);
    let iinterface = interface.replace("_", "-");
    assert!(iinterface != interface);

    let mut cmd = unshare::Command::new("/bin/ip");
    cmd.arg("link").arg("add");
    cmd.arg(&interface);
    cmd.arg("type").arg("veth");
    cmd.arg("peer").arg("name").arg(&iinterface);
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("link").arg("set");
    cmd.arg("dev").arg(&iinterface);
    // Note: this is a bit of hack bit it's known to work.
    // 1. We opened our namespace first so `/proc/<PID>/ns/net` is associated
    //    with that namespace even if we change namespace
    // 2. Then we set namespace to a parent one
    // 3. We move interface to ours namespace
    // 4. Then switch our namespace back to expected one
    cmd.arg("netns").arg(&format!("/proc/{}/ns/net", pid));
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/brctl");
    cmd.arg("addif").arg(&net.bridge).arg(&interface);
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("brctl failed: {}", s),
        Err(e) => bail!("brctl failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("link").arg("set");
    cmd.arg(&interface);
    cmd.arg("up");
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    setns(my_ns.as_raw_fd(), CLONE_NEWNET)?;

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("addr").arg("add");
    cmd.arg(&format!("{}",
        IpNetwork::new(*ip, net.network.prefix())
        .expect("network asways valid")));
    cmd.arg("dev").arg(&iinterface);
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    let mut cmd = unshare::Command::new("/sbin/ip");
    cmd.arg("link").arg("set");
    cmd.arg(&iinterface);
    cmd.arg("up");
    match cmd.status() {
        Ok(s) if s.success() => {}
        Ok(s) => bail!("ip link failed: {}", s),
        Err(e) => bail!("ip link failed: {}", e),
    }

    if let Some(gw) = net.default_gateway {
        let mut cmd = unshare::Command::new("/sbin/ip");
        cmd.arg("route").arg("add");
        cmd.arg("default");
        cmd.arg("via").arg(&format!("{}", gw));
        match cmd.status() {
            Ok(s) if s.success() => {}
            Ok(s) => bail!("ip route failed: {}", s),
            Err(e) => bail!("ip route failed: {}", e),
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>extern crate config;

use std::io;
use std::error;
use std::fmt;
use std::result;

use self::config::{ConfigError};

use jsonwebtoken as jwt;

/// Helper alias for `Result` objects that return a Pathfinder error.
pub type Result<T> = result::Result<T, PathfinderError>;

#[derive(Debug)]
pub enum PathfinderError {
    /// The error that occurred during work with I/O.
    Io(io::Error),
    /// Represents all possible errors that can occur when working with
    /// configuration (reading, watching for a changes, etc.).
    SettingsError(ConfigError),
    /// Occurs when an inner structure of an endpoint is invalid.
    /// For example: missed fields or invalid format.
    InvalidEndpoint(String),
    /// Occurs when router is trying to get an access to an endpoint, that
    /// doesn't not exist.
    EndpointNotFound(String),
    /// Occurs during processing an incoming message (e.g. parsing,
    /// converting into JSON)
    DecodingError(String),
    /// The error that occurred when token isn't specified or invalid.
    AuthenticationError(String)
}

impl fmt::Display for PathfinderError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            PathfinderError::Io(ref err) => write!(f, "IO error: {}", err),
            PathfinderError::SettingsError(ref err) => write!(f, "Settings error: {}", err),
            PathfinderError::InvalidEndpoint(ref msg) => write!(f, "Parse error: {}", msg),
            PathfinderError::EndpointNotFound(ref msg) => write!(f, "Endpoint \"{}\" was not found", msg),
            PathfinderError::DecodingError(ref msg) => write!(f, "Decoding error: {}", msg),
            PathfinderError::AuthenticationError(ref msg) => write!(f, "Authentication error: {}", msg),
        }
    }
}

impl error::Error for PathfinderError {
    fn description(&self) -> &str {
        match *self {
            PathfinderError::Io(ref err) => err.description(),
            PathfinderError::SettingsError(ref err) => err.description(),
            _ => "configuration error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            PathfinderError::Io(ref err) => Some(err),
            PathfinderError::SettingsError(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<io::Error> for PathfinderError {
    fn from(err: io::Error) -> PathfinderError {
        PathfinderError::Io(err)
    }
}

impl From<config::ConfigError> for PathfinderError {
    fn from(err: config::ConfigError) -> PathfinderError {
        PathfinderError::SettingsError(err)
    }
}

impl From<jwt::errors::Error> for PathfinderError {
    fn from(err: jwt::errors::Error) -> PathfinderError {
        PathfinderError::AuthenticationError(String::from(err.description()))
    }
}
<commit_msg>Added documentation for error.rs<commit_after>//! Error handlers for an application
//!
//! This module is intended for simplifying error handling and propagating
//! them in an existing application, easy to use and quite extendable in
//! the future.
//!

extern crate config;

use std::io;
use std::error;
use std::fmt;
use std::result;

use self::config::{ConfigError};

use jsonwebtoken as jwt;

/// Type alias for `Result` objects that return a Pathfinder error.
pub type Result<T> = result::Result<T, PathfinderError>;

/// An enum of all possible errors which could occur during the work of reverse proxy.
#[derive(Debug)]
pub enum PathfinderError {
    /// The error that occurred during work with I/O.
    Io(io::Error),
    /// Represents all possible errors that can occur when working with
    /// configuration (reading, watching for a changes, etc.).
    SettingsError(ConfigError),
    /// Occurs when an inner structure of an endpoint is invalid.
    /// For example: missed fields or invalid format.
    InvalidEndpoint(String),
    /// Occurs when router is trying to get an access to an endpoint, that
    /// doesn't not exist.
    EndpointNotFound(String),
    /// Occurs during processing an incoming message (e.g. parsing,
    /// converting into JSON).
    DecodingError(String),
    /// The error that occurred when token isn't specified or invalid.
    AuthenticationError(String)
}

impl fmt::Display for PathfinderError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            PathfinderError::Io(ref err) => write!(f, "IO error: {}", err),
            PathfinderError::SettingsError(ref err) => write!(f, "Settings error: {}", err),
            PathfinderError::InvalidEndpoint(ref msg) => write!(f, "Parse error: {}", msg),
            PathfinderError::EndpointNotFound(ref msg) => write!(f, "Endpoint \"{}\" was not found", msg),
            PathfinderError::DecodingError(ref msg) => write!(f, "Decoding error: {}", msg),
            PathfinderError::AuthenticationError(ref msg) => write!(f, "Authentication error: {}", msg),
        }
    }
}

impl error::Error for PathfinderError {
    fn description(&self) -> &str {
        match *self {
            PathfinderError::Io(ref err) => err.description(),
            PathfinderError::SettingsError(ref err) => err.description(),
            _ => "configuration error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            PathfinderError::Io(ref err) => Some(err),
            PathfinderError::SettingsError(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<io::Error> for PathfinderError {
    fn from(err: io::Error) -> PathfinderError {
        PathfinderError::Io(err)
    }
}

impl From<config::ConfigError> for PathfinderError {
    fn from(err: config::ConfigError) -> PathfinderError {
        PathfinderError::SettingsError(err)
    }
}

impl From<jwt::errors::Error> for PathfinderError {
    fn from(err: jwt::errors::Error) -> PathfinderError {
        PathfinderError::AuthenticationError(String::from(err.description()))
    }
}
<|endoftext|>


<commit_before>// Check that `!Send` types fail early.

/** ```compile_fail,E0277,E0599

use rayon::prelude::*;
use std::ptr::null;

#[derive(Copy, Clone)]
struct NoSend(*const ());

unsafe impl Sync for NoSend {}

fn main() {
    let x = Some(NoSend(null()));

    x.par_iter()
        .map(|&x| x) //~ ERROR
        .count(); //~ ERROR
}

``` */
mod map {}

/** ```compile_fail,E0277,E0599

use rayon::prelude::*;
use std::ptr::null;

#[derive(Copy, Clone)]
struct NoSend(*const ());

unsafe impl Sync for NoSend {}

fn main() {
    let x = Some(NoSend(null()));

    x.par_iter()
        .filter_map(|&x| Some(x)) //~ ERROR
        .count(); //~ ERROR
}

``` */
mod filter_map {}

/** ```compile_fail,E0277,E0599

use rayon::prelude::*;
use std::ptr::null;

#[derive(Copy, Clone)]
struct NoSend(*const ());

unsafe impl Sync for NoSend {}

fn main() {
    let x = Some(NoSend(null()));

    x.par_iter()
        .cloned() //~ ERROR
        .count(); //~ ERROR
}

``` */
mod cloned {}
<commit_msg>Trim the error codes in compile_fail/no_send_par_iter.rs<commit_after>// Check that `!Send` types fail early.

/** ```compile_fail,E0277

use rayon::prelude::*;
use std::ptr::null;

#[derive(Copy, Clone)]
struct NoSend(*const ());

unsafe impl Sync for NoSend {}

fn main() {
    let x = Some(NoSend(null()));

    x.par_iter()
        .map(|&x| x) //~ ERROR
        .count(); //~ ERROR
}

``` */
mod map {}

/** ```compile_fail,E0277

use rayon::prelude::*;
use std::ptr::null;

#[derive(Copy, Clone)]
struct NoSend(*const ());

unsafe impl Sync for NoSend {}

fn main() {
    let x = Some(NoSend(null()));

    x.par_iter()
        .filter_map(|&x| Some(x)) //~ ERROR
        .count(); //~ ERROR
}

``` */
mod filter_map {}

/** ```compile_fail,E0277

use rayon::prelude::*;
use std::ptr::null;

#[derive(Copy, Clone)]
struct NoSend(*const ());

unsafe impl Sync for NoSend {}

fn main() {
    let x = Some(NoSend(null()));

    x.par_iter()
        .cloned() //~ ERROR
        .count(); //~ ERROR
}

``` */
mod cloned {}
<|endoftext|>