<commit_before>use crate::core::{Target, Workspace};
use crate::ops::CompileOptions;
use crate::util::CargoResult;

use std::fmt::Write;

fn get_available_targets<'a>(
    filter_fn: fn(&Target) -> bool,
    ws: &'a Workspace<'_>,
    options: &'a CompileOptions<'_>,
) -> CargoResult<Vec<&'a Target>> {
    let packages = options.spec.get_packages(ws)?;

    let targets: Vec<_> = packages
        .into_iter()
        .flat_map(|pkg| {
            pkg.manifest()
                .targets()
                .into_iter()
                .filter(|target| filter_fn(target))
        })
        .collect();
    Ok(targets)
}

fn print_available(
    filter_fn: fn(&Target) -> bool,
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
    option_name: &str,
    plural_name: &str,
) -> CargoResult<()> {
    let targets = get_available_targets(filter_fn, ws, options)?;

    let mut output = String::new();
    writeln!(output, "\"{}\" takes one argument.", option_name)?;

    if targets.is_empty() {
        writeln!(output, "No {} available.", plural_name)?;
    } else {
        writeln!(output, "Available {}:", plural_name)?;
        for target in targets {
            writeln!(output, "    {}", target.name())?;
        }
    }
    Err(failure::err_msg(output))?
}

pub fn print_available_examples(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_example, ws, options, "--example", "examples")
}

pub fn print_available_binaries(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_bin, ws, options, "--bin", "binaries")
}

pub fn print_available_benches(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_bench, ws, options, "--bench", "benches")
}

pub fn print_available_tests(ws: &Workspace<'_>, options: &CompileOptions<'_>) -> CargoResult<()> {
    print_available(Target::is_test, ws, options, "--test", "tests")
}
<commit_msg>Sorting<commit_after>use crate::core::{Target, Workspace};
use crate::ops::CompileOptions;
use crate::util::CargoResult;

use std::fmt::Write;

fn get_available_targets<'a>(
    filter_fn: fn(&Target) -> bool,
    ws: &'a Workspace<'_>,
    options: &'a CompileOptions<'_>,
) -> CargoResult<Vec<&'a Target>> {
    let packages = options.spec.get_packages(ws)?;

    let mut targets: Vec<_> = packages
        .into_iter()
        .flat_map(|pkg| {
            pkg.manifest()
                .targets()
                .into_iter()
                .filter(|target| filter_fn(target))
        })
        .collect();

    targets.sort();

    Ok(targets)
}

fn print_available(
    filter_fn: fn(&Target) -> bool,
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
    option_name: &str,
    plural_name: &str,
) -> CargoResult<()> {
    let targets = get_available_targets(filter_fn, ws, options)?;

    let mut output = String::new();
    writeln!(output, "\"{}\" takes one argument.", option_name)?;

    if targets.is_empty() {
        writeln!(output, "No {} available.", plural_name)?;
    } else {
        writeln!(output, "Available {}:", plural_name)?;
        for target in targets {
            writeln!(output, "    {}", target.name())?;
        }
    }
    Err(failure::err_msg(output))?
}

pub fn print_available_examples(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_example, ws, options, "--example", "examples")
}

pub fn print_available_binaries(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_bin, ws, options, "--bin", "binaries")
}

pub fn print_available_benches(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_bench, ws, options, "--bench", "benches")
}

pub fn print_available_tests(ws: &Workspace<'_>, options: &CompileOptions<'_>) -> CargoResult<()> {
    print_available(Target::is_test, ws, options, "--test", "tests")
}
<|endoftext|>


<commit_before>// Copyright 2015 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.

// ignore-cloudabi no environment variables present
// ignore-emscripten env vars don't work?

#![feature(path)]

use std::env::*;
use std::path::PathBuf;

/// When HOME is not set, some platforms return `None`, but others return `Some` with a default.
/// Just check that it is not "/home/MountainView".

#[cfg(unix)]
fn main() {
    let oldhome = var("HOME");

    set_var("HOME", "/home/MountainView");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));

    remove_var("HOME");
    if cfg!(target_os = "android") {
        assert!(home_dir().is_none());
    } else {
        assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
    }
}

#[cfg(windows)]
fn main() {
    let oldhome = var("HOME");
    let olduserprofile = var("USERPROFILE");

    remove_var("HOME");
    remove_var("USERPROFILE");

    assert!(home_dir().is_some());

    set_var("HOME", "/home/MountainView");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));

    remove_var("HOME");

    set_var("USERPROFILE", "/home/MountainView");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));

    set_var("HOME", "/home/MountainView");
    set_var("USERPROFILE", "/home/PaloAlto");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
}
<commit_msg>move comment right onto the line in question<commit_after>// Copyright 2015 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.

// ignore-cloudabi no environment variables present
// ignore-emscripten env vars don't work?

#![feature(path)]

use std::env::*;
use std::path::PathBuf;

#[cfg(unix)]
fn main() {
    let oldhome = var("HOME");

    set_var("HOME", "/home/MountainView");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));

    remove_var("HOME");
    if cfg!(target_os = "android") {
        assert!(home_dir().is_none());
    } else {
        // When HOME is not set, some platforms return `None`,
        // but others return `Some` with a default.
        // Just check that it is not "/home/MountainView".
        assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
    }
}

#[cfg(windows)]
fn main() {
    let oldhome = var("HOME");
    let olduserprofile = var("USERPROFILE");

    remove_var("HOME");
    remove_var("USERPROFILE");

    assert!(home_dir().is_some());

    set_var("HOME", "/home/MountainView");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));

    remove_var("HOME");

    set_var("USERPROFILE", "/home/MountainView");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));

    set_var("HOME", "/home/MountainView");
    set_var("USERPROFILE", "/home/PaloAlto");
    assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
}
<|endoftext|>


<commit_before>// revisions: noopt opt opt_with_overflow_checks
//[noopt]compile-flags: -C opt-level=0
//[opt]compile-flags: -O
//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O

#![crate_type="lib"]

use std::i32;

pub trait Foo {
    const NEG: i32;
    const ADD: i32;
    const DIV: i32;
    const OOB: i32;
}

// These constants cannot be evaluated already (they depend on `T::N`), so
// they can just be linted like normal run-time code.  But codegen works
// a bit different in const context, so this test makes sure that we still catch overflow.
impl<T: Foo> Foo for Vec<T> {
    const NEG: i32 = -i32::MIN + T::NEG;
    //~^ ERROR arithmetic operation will overflow
    const ADD: i32 = (i32::MAX+1) + T::ADD;
    //~^ ERROR arithmetic operation will overflow
    const DIV: i32 = (1/0) + T::DIV;
    //~^ ERROR operation will panic
    const OOB: i32 = [1][1] + T::OOB;
    //~^ ERROR operation will panic
}
<commit_msg>Extend #69020 test to include reversed order.<commit_after>// revisions: noopt opt opt_with_overflow_checks
//[noopt]compile-flags: -C opt-level=0
//[opt]compile-flags: -O
//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O

#![crate_type="lib"]

use std::i32;

pub trait Foo {
    const NEG: i32;
    const GEN: i32;

    const ADD: i32;
    const DDA: i32;

    const DIV: i32;
    const VID: i32;

    const OOB: i32;
    const BOO: i32;
}

// These constants cannot be evaluated already (they depend on `T::N`), so
// they can just be linted like normal run-time code.  But codegen works
// a bit different in const context, so this test makes sure that we still catch overflow.
impl<T: Foo> Foo for Vec<T> {
    const NEG: i32 = -i32::MIN + T::NEG;
    //~^ ERROR arithmetic operation will overflow
    const GEN: i32 = T::NEG + (-i32::MIN);
    //~^ ERROR arithmetic operation will overflow

    const ADD: i32 = (i32::MAX+1) + T::ADD;
    //~^ ERROR arithmetic operation will overflow
    const DDA: i32 =  T::ADD + (i32::MAX+1);
    //~^ ERROR arithmetic operation will overflow

    const DIV: i32 = (1/0) + T::DIV;
    //~^ ERROR operation will panic
    const VID: i32 = T::DIV + (1/0);
    //~^ ERROR operation will panic

    const OOB: i32 = [1][1] + T::OOB;
    //~^ ERROR operation will panic
    const BOO: i32 = T::OOB + [1][1];
    //~^ ERROR operation will panic
}
<|endoftext|>


<commit_before>use cortexm3;
use main::Chip;
use usb;

pub struct Hotel {
    mpu: cortexm3::mpu::MPU,
    systick: &'static cortexm3::systick::SysTick,
}

impl Hotel {
    pub unsafe fn new() -> Hotel {
        Hotel {
            mpu: cortexm3::mpu::MPU::new(),
            systick: cortexm3::systick::SysTick::new(),
        }
    }
}

impl Chip for Hotel {
    type MPU = cortexm3::mpu::MPU;
    type SysTick = cortexm3::systick::SysTick;

    fn has_pending_interrupts(&self) -> bool {
        unsafe { cortexm3::nvic::next_pending().is_some() }
    }

    fn service_pending_interrupts(&mut self) {
        unsafe {
            loop {
                match cortexm3::nvic::next_pending() {
                    Some(nvic_num) => {
                        match nvic_num {
                            193 => usb::USB0.handle_interrupt(),
                            _   => panic!("No handler for interrupt #{}", nvic_num)
                        }
                        cortexm3::nvic::Nvic::new(nvic_num).clear_pending();
                        cortexm3::nvic::Nvic::new(nvic_num).enable();
                    },
                    None => break
                }
            }
        }
    }

    fn mpu(&self) -> &Self::MPU {
        &self.mpu
    }

    fn systick(&self) -> &Self::SysTick {
        &self.systick
    }
}
<commit_msg>Simplify Hotel interrupt service routine<commit_after>use cortexm3;
use main::Chip;
use usb;

pub struct Hotel {
    mpu: cortexm3::mpu::MPU,
    systick: &'static cortexm3::systick::SysTick,
}

impl Hotel {
    pub unsafe fn new() -> Hotel {
        Hotel {
            mpu: cortexm3::mpu::MPU::new(),
            systick: cortexm3::systick::SysTick::new(),
        }
    }
}

impl Chip for Hotel {
    type MPU = cortexm3::mpu::MPU;
    type SysTick = cortexm3::systick::SysTick;

    fn has_pending_interrupts(&self) -> bool {
        unsafe { cortexm3::nvic::next_pending().is_some() }
    }

    fn service_pending_interrupts(&mut self) {
        unsafe {
            while let Some(nvic_num) = cortexm3::nvic::next_pending() {
                match nvic_num {
                    193 => usb::USB0.handle_interrupt(),
                    _   => panic!("No handler for interrupt #{}", nvic_num)
                }
                cortexm3::nvic::Nvic::new(nvic_num).clear_pending();
                cortexm3::nvic::Nvic::new(nvic_num).enable();
            }
        }
    }

    fn mpu(&self) -> &Self::MPU {
        &self.mpu
    }

    fn systick(&self) -> &Self::SysTick {
        &self.systick
    }
}
<|endoftext|>


<commit_before>/// Traits required for parsing
pub use crate::types::parsing::traits;
use crate::{
    frame::*,
    protocol::{basic::parse_properties, *},
    types::parsing::*,
};
use nom::{
    bytes::streaming::{tag, take},
    combinator::{all_consuming, flat_map, map, map_opt, map_res},
    error::context,
    sequence::{pair, tuple},
};
use traits::ParsableInput;

/// Parse a channel id
pub fn parse_channel<I: ParsableInput>(i: I) -> ParserResult<I, AMQPChannel> {
    context("parse_channel", map(parse_id, From::from))(i)
}

/// Parse the protocol header
pub fn parse_protocol_header<I: ParsableInput>(i: I) -> ParserResult<I, ()> {
    context(
        "parse_protocol_header",
        map(
            pair(
                tag(metadata::NAME.as_bytes()),
                tag(&[
                    0,
                    metadata::MAJOR_VERSION,
                    metadata::MINOR_VERSION,
                    metadata::REVISION,
                ][..]),
            ),
            |_| (),
        ),
    )(i)
}

/// Parse the frame type
pub fn parse_frame_type<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrameType> {
    context(
        "parse_frame_type",
        map_opt(parse_short_short_uint, |method| match method {
            constants::FRAME_METHOD => Some(AMQPFrameType::Method),
            constants::FRAME_HEADER => Some(AMQPFrameType::Header),
            constants::FRAME_BODY => Some(AMQPFrameType::Body),
            constants::FRAME_HEARTBEAT => Some(AMQPFrameType::Heartbeat),
            _ => None,
        }),
    )(i)
}

/// Parse a full AMQP Frame (with contents)
pub fn parse_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrame> {
    context(
        "parse_frame",
        map_res(
            parse_raw_frame,
            |AMQPRawFrame {
                 channel_id,
                 frame_type,
                 payload,
             }: AMQPRawFrame<I>| match frame_type {
                AMQPFrameType::Method => all_consuming(parse_class)(payload)
                    .map(|(_, m)| AMQPFrame::Method(channel_id, m)),
                AMQPFrameType::Header => all_consuming(parse_content_header)(payload)
                    .map(|(_, h)| AMQPFrame::Header(channel_id, h.class_id, Box::new(h))),
                AMQPFrameType::Body => Ok(AMQPFrame::Body(
                    channel_id,
                    payload.iter_elements().collect(),
                )),
                AMQPFrameType::Heartbeat => Ok(AMQPFrame::Heartbeat(channel_id)),
            },
        ),
    )(i)
}

/// Parse a raw AMQP frame
pub fn parse_raw_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPRawFrame<I>> {
    context(
        "parse_raw_frame",
        flat_map(
            tuple((parse_frame_type, parse_id, parse_long_uint)),
            move |(frame_type, channel_id, size)| {
                map(
                    pair(take(size), tag(&[constants::FRAME_END][..])),
                    move |(payload, _)| AMQPRawFrame {
                        frame_type,
                        channel_id,
                        payload,
                    },
                )
            },
        ),
    )(i)
}

/// Parse a content header frame
pub fn parse_content_header<I: ParsableInput>(i: I) -> ParserResult<I, AMQPContentHeader> {
    context(
        "parse_content_header",
        map(
            tuple((
                parse_id,
                parse_short_uint,
                parse_long_long_uint,
                context("parse_properties", parse_properties),
            )),
            |(class_id, weight, body_size, properties)| AMQPContentHeader {
                class_id,
                weight,
                body_size,
                properties,
            },
        ),
    )(i)
}
<commit_msg>parse protocol version in protocol header<commit_after>/// Traits required for parsing
pub use crate::types::parsing::traits;
use crate::{
    frame::*,
    protocol::{basic::parse_properties, *},
    types::parsing::*,
};
use nom::{
    bytes::streaming::{tag, take},
    combinator::{all_consuming, flat_map, map, map_opt, map_res},
    error::context,
    sequence::{pair, tuple},
};
use traits::ParsableInput;

/// Parse a channel id
pub fn parse_channel<I: ParsableInput>(i: I) -> ParserResult<I, AMQPChannel> {
    context("parse_channel", map(parse_id, From::from))(i)
}

/// Parse the protocol header
pub fn parse_protocol_header<I: ParsableInput>(i: I) -> ParserResult<I, ProtocolVersion> {
    context(
        "parse_protocol_header",
        map(
            tuple((
                tag(metadata::NAME.as_bytes()),
                tag(&[0][..]),
                parse_short_short_uint,
                parse_short_short_uint,
                parse_short_short_uint,
            )),
            |(_, _, major, minor, revision)| ProtocolVersion {
                major,
                minor,
                revision,
            },
        ),
    )(i)
}

/// Parse the frame type
pub fn parse_frame_type<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrameType> {
    context(
        "parse_frame_type",
        map_opt(parse_short_short_uint, |method| match method {
            constants::FRAME_METHOD => Some(AMQPFrameType::Method),
            constants::FRAME_HEADER => Some(AMQPFrameType::Header),
            constants::FRAME_BODY => Some(AMQPFrameType::Body),
            constants::FRAME_HEARTBEAT => Some(AMQPFrameType::Heartbeat),
            _ => None,
        }),
    )(i)
}

/// Parse a full AMQP Frame (with contents)
pub fn parse_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrame> {
    context(
        "parse_frame",
        map_res(
            parse_raw_frame,
            |AMQPRawFrame {
                 channel_id,
                 frame_type,
                 payload,
             }: AMQPRawFrame<I>| match frame_type {
                AMQPFrameType::Method => all_consuming(parse_class)(payload)
                    .map(|(_, m)| AMQPFrame::Method(channel_id, m)),
                AMQPFrameType::Header => all_consuming(parse_content_header)(payload)
                    .map(|(_, h)| AMQPFrame::Header(channel_id, h.class_id, Box::new(h))),
                AMQPFrameType::Body => Ok(AMQPFrame::Body(
                    channel_id,
                    payload.iter_elements().collect(),
                )),
                AMQPFrameType::Heartbeat => Ok(AMQPFrame::Heartbeat(channel_id)),
            },
        ),
    )(i)
}

/// Parse a raw AMQP frame
pub fn parse_raw_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPRawFrame<I>> {
    context(
        "parse_raw_frame",
        flat_map(
            tuple((parse_frame_type, parse_id, parse_long_uint)),
            move |(frame_type, channel_id, size)| {
                map(
                    pair(take(size), tag(&[constants::FRAME_END][..])),
                    move |(payload, _)| AMQPRawFrame {
                        frame_type,
                        channel_id,
                        payload,
                    },
                )
            },
        ),
    )(i)
}

/// Parse a content header frame
pub fn parse_content_header<I: ParsableInput>(i: I) -> ParserResult<I, AMQPContentHeader> {
    context(
        "parse_content_header",
        map(
            tuple((
                parse_id,
                parse_short_uint,
                parse_long_long_uint,
                context("parse_properties", parse_properties),
            )),
            |(class_id, weight, body_size, properties)| AMQPContentHeader {
                class_id,
                weight,
                body_size,
                properties,
            },
        ),
    )(i)
}
<|endoftext|>


<commit_before>//! TODO documentation

use wlroots_sys::{wlr_output_cursor, wlr_output_cursor_create, wlr_output_cursor_destroy,
                  wlr_output_cursor_move, wlr_output_cursor_set_image,
                  wlr_output_cursor_set_surface};

use {Output, OutputHandle, Surface, UpgradeHandleErr};

#[derive(Debug, Eq, PartialEq)]
pub struct OutputCursor {
    cursor: *mut wlr_output_cursor,
    output_handle: OutputHandle
}

impl OutputCursor {
    /// Creates a new `OutputCursor` that's bound to the given `Output`.
    ///
    /// When the `Output` is destroyed, this can no longer be used.
    ///
    /// # Ergonomics
    /// TODO Put in module documentation
    ///
    /// To make this easier for you, I would suggest putting the `OutputCursor` in your
    /// `OutputHandler` implementor's state so that when the `Output` is removed you
    /// just don't have to think about it and it will clean itself up by itself.
    pub fn new<'output>(output: &'output mut Output) -> Option<OutputCursor> {
        unsafe {
            let output_handle = output.weak_reference();
            let cursor = wlr_output_cursor_create(output.as_ptr());
            if cursor.is_null() {
                None
            } else {
                Some(OutputCursor { cursor,
                                    output_handle })
            }
        }
    }

    /// Sets the hardware cursor's image.
    pub fn set_image(&mut self,
                     pixels: &[u8],
                     stride: i32,
                     width: u32,
                     height: u32,
                     hotspot_x: i32,
                     hotspot_y: i32)
                     -> bool {
        unsafe {
            let cursor = self.cursor;
            let res = self.output_handle.run(|_| {
                                                 // TODO Ensure the buffer is correct?
                                                 wlr_output_cursor_set_image(cursor,
                                                                             pixels.as_ptr(),
                                                                             stride,
                                                                             width,
                                                                             height,
                                                                             hotspot_x,
                                                                             hotspot_y)
                                             });
            match res {
                Ok(res) => res,
                Err(UpgradeHandleErr::AlreadyDropped) => false,
                err @ Err(UpgradeHandleErr::AlreadyBorrowed) => panic!(err)
            }
        }
    }

    /// Sets the hardware cursor's surface.
    pub fn set_surface(&mut self, surface: Surface, hotspot_x: i32, hotspot_y: i32) {
        unsafe {
            let cursor = self.cursor;
            let res = self.output_handle.run(|_| {
                                                 wlr_output_cursor_set_surface(cursor,
                                                                               surface.as_ptr(),
                                                                               hotspot_x,
                                                                               hotspot_y)
                                             });
            match res {
                Ok(_) | Err(UpgradeHandleErr::AlreadyDropped) => {}
                err @ Err(UpgradeHandleErr::AlreadyBorrowed) => panic!(err)
            }
        }
    }

    /// Moves the hardware cursor to the desired location
    pub fn move_to(&mut self, x: f64, y: f64) -> bool {
        unsafe {
            let cursor = self.cursor;
            let res = self.output_handle.run(|_| wlr_output_cursor_move(cursor, x, y));
            match res {
                Ok(res) => res,
                Err(UpgradeHandleErr::AlreadyDropped) => false,
                err @ Err(UpgradeHandleErr::AlreadyBorrowed) => panic!(err)
            }
        }
    }
}

impl Drop for OutputCursor {
    fn drop(&mut self) {
        unsafe { wlr_output_cursor_destroy(self.cursor) }
    }
}
<commit_msg>Added getters for OutputCursor<commit_after>//! TODO documentation

use wlroots_sys::{wlr_output_cursor, wlr_output_cursor_create, wlr_output_cursor_destroy,
                  wlr_output_cursor_move, wlr_output_cursor_set_image,
                  wlr_output_cursor_set_surface};

use {Output, OutputHandle, Surface, UpgradeHandleErr};

#[derive(Debug, Eq, PartialEq)]
pub struct OutputCursor {
    cursor: *mut wlr_output_cursor,
    output_handle: OutputHandle
}

impl OutputCursor {
    /// Creates a new `OutputCursor` that's bound to the given `Output`.
    ///
    /// When the `Output` is destroyed, this can no longer be used.
    ///
    /// # Ergonomics
    /// TODO Put in module documentation
    ///
    /// To make this easier for you, I would suggest putting the `OutputCursor` in your
    /// `OutputHandler` implementor's state so that when the `Output` is removed you
    /// just don't have to think about it and it will clean itself up by itself.
    pub fn new<'output>(output: &'output mut Output) -> Option<OutputCursor> {
        unsafe {
            let output_handle = output.weak_reference();
            let cursor = wlr_output_cursor_create(output.as_ptr());
            if cursor.is_null() {
                None
            } else {
                Some(OutputCursor { cursor,
                                    output_handle })
            }
        }
    }

    /// Sets the hardware cursor's image.
    pub fn set_image(&mut self,
                     pixels: &[u8],
                     stride: i32,
                     width: u32,
                     height: u32,
                     hotspot_x: i32,
                     hotspot_y: i32)
                     -> bool {
        unsafe {
            let cursor = self.cursor;
            let res = self.output_handle.run(|_| {
                                                 // TODO Ensure the buffer is correct?
                                                 wlr_output_cursor_set_image(cursor,
                                                                             pixels.as_ptr(),
                                                                             stride,
                                                                             width,
                                                                             height,
                                                                             hotspot_x,
                                                                             hotspot_y)
                                             });
            match res {
                Ok(res) => res,
                Err(UpgradeHandleErr::AlreadyDropped) => false,
                err @ Err(UpgradeHandleErr::AlreadyBorrowed) => panic!(err)
            }
        }
    }

    /// Sets the hardware cursor's surface.
    pub fn set_surface(&mut self, surface: Surface, hotspot_x: i32, hotspot_y: i32) {
        unsafe {
            let cursor = self.cursor;
            let res = self.output_handle.run(|_| {
                                                 wlr_output_cursor_set_surface(cursor,
                                                                               surface.as_ptr(),
                                                                               hotspot_x,
                                                                               hotspot_y)
                                             });
            match res {
                Ok(_) | Err(UpgradeHandleErr::AlreadyDropped) => {}
                err @ Err(UpgradeHandleErr::AlreadyBorrowed) => panic!(err)
            }
        }
    }

    /// Moves the hardware cursor to the desired location
    pub fn move_to(&mut self, x: f64, y: f64) -> bool {
        unsafe {
            let cursor = self.cursor;
            let res = self.output_handle.run(|_| wlr_output_cursor_move(cursor, x, y));
            match res {
                Ok(res) => res,
                Err(UpgradeHandleErr::AlreadyDropped) => false,
                err @ Err(UpgradeHandleErr::AlreadyBorrowed) => panic!(err)
            }
        }
    }

    /// Get the coordinates of the cursor.
    ///
    /// Returned value is in (x, y) format.
    pub fn coords(&self) -> (f64, f64) {
        unsafe { ((*self.cursor).x, (*self.cursor).y) }
    }

    /// Determines if the hardware cursor is enabled or not.
    pub fn enabled(&self) -> bool {
        unsafe { (*self.cursor).enabled }
    }

    /// Determines if the hardware cursor is visible or not.
    pub fn visible(&self) -> bool {
        unsafe { (*self.cursor).visible }
    }

    /// Gets the width and height of the hardware cursor.
    ///
    /// Returned value is in (width, height) format.
    pub fn size(&self) -> (u32, u32) {
        unsafe { ((*self.cursor).width, (*self.cursor).height) }
    }

    /// Gets the hotspot coordinates of the hardware cursor.
    ///
    /// Returned value is in (x, y) coordinates.
    pub fn hotspots(&self) -> (i32, i32) {
        unsafe { ((*self.cursor).hotspot_x, (*self.cursor).hotspot_y) }
    }
}

impl Drop for OutputCursor {
    fn drop(&mut self) {
        unsafe { wlr_output_cursor_destroy(self.cursor) }
    }
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate piston_window;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use opengl_graphics::{GlGraphics, OpenGL};
use glutin_window::GlutinWindow;
use piston::window::WindowSettings;
use piston::event_loop::{Events, EventSettings};
use piston::input::*;

struct Point {
    x: f64,
    y: f64,
    z: f64
}

impl Point {
    fn rotate(&self, x: f64, y: f64, z: f64) -> Point {
        let mut rp = Point { x: self.x, y: self.y, z: self.z };

        let xn = rp.x * z.cos() - rp.y * z.sin();
        let yn = rp.x * z.sin() + rp.y * z.cos();
        rp.x = xn;
        rp.y = yn;

        let xn = rp.x * y.cos() - rp.z * y.sin();
        let zn = rp.x * y.sin() + rp.z * y.cos();
        rp.x = xn;
        rp.z = zn;

        let zn = rp.z * x.cos() - rp.y * x.sin();
        let yn = rp.z * x.sin() + rp.y * x.cos();
        rp.z = zn;
        rp.y = yn;

        rp
    }

    fn translate(&self, x: f64, y: f64, z: f64) -> Point {
        let rp = Point { x: self.x + x, y: self.y + y, z: self.z + z };
        rp
    }
}

struct Edge<'a> {
    p1: &'a Point,
    p2: &'a Point
}

struct Model<'a> {
    edges: Vec<Edge<'a>>
}

struct Viewport {
    x_rot: f64,
    y_rot: f64,
    z_rot: f64
}

pub struct App<'a> {
    gl: GlGraphics,
    model: Model<'a>,
    vp: Viewport
}

impl<'a> App<'a> {
    fn render(&mut self, args: &RenderArgs) {
        let ref model = self.model;
        let ref vp = self.vp;
        self.gl.draw(args.viewport(), |c, gl| {
            // Clear the screen.
            graphics::clear([0.7, 0.6, 0.75, 1.0], gl);

            for edge in &model.edges {
                let p1_t = edge.p1.rotate(vp.x_rot, vp.y_rot, vp.z_rot);
                let p2_t = edge.p2.rotate(vp.x_rot, vp.y_rot, vp.z_rot);

                let p1_x = p1_t.x;
                let p1_y = p1_t.y;
                let p2_x = p2_t.x;
                let p2_y = p2_t.y;
                graphics::line([0.0, 0.0, 0.0, 1.0],
                               0.5,
                               [p1_x + 400.0, p1_y + 300.0, p2_x + 400.0, p2_y + 300.0],
                               c.transform, gl);
            }
        });
    }

    fn update(&mut self, button: piston_window::Button) {
        use piston_window::Button::Keyboard;
        use piston_window::Key;

        if button == Keyboard(Key::W) {
            self.vp.x_rot += 0.05;
        } else if button == Keyboard(Key::S) {
            self.vp.x_rot -= 0.05;
        } else if button == Keyboard(Key::A) {
            self.vp.y_rot += 0.05;
        } else if button == Keyboard(Key::D) {
            self.vp.y_rot -= 0.05;
        } else if button == Keyboard(Key::Q) {
            self.vp.z_rot += 0.05;
        } else if button == Keyboard(Key::E) {
            self.vp.z_rot -= 0.05;
        }
    }
}

fn main() {
    let nodes = vec![
        Point {x: -50.0, y: 50.0, z: 50.0},
        Point {x: -50.0, y: 50.0, z: -50.0},
        Point {x: -50.0, y: -50.0, z: 50.0},
        Point {x: -50.0, y: -50.0, z: -50.0},
        Point {x: 50.0, y: 50.0, z: 50.0},
        Point {x: 50.0, y: 50.0, z: -50.0},
        Point {x: 50.0, y: -50.0, z: 50.0},
        Point {x: 50.0, y: -50.0, z: -50.0}
    ];
    let edges = vec![
        Edge { p1: &nodes[0], p2: &nodes[1] },
        Edge { p1: &nodes[2], p2: &nodes[3] },
        Edge { p1: &nodes[4], p2: &nodes[5] },
        Edge { p1: &nodes[6], p2: &nodes[7] },
        Edge { p1: &nodes[0], p2: &nodes[2] },
        Edge { p1: &nodes[4], p2: &nodes[6] },
        Edge { p1: &nodes[1], p2: &nodes[3] },
        Edge { p1: &nodes[5], p2: &nodes[7] },
        Edge { p1: &nodes[0], p2: &nodes[4] },
        Edge { p1: &nodes[2], p2: &nodes[6] },
        Edge { p1: &nodes[1], p2: &nodes[5] },
        Edge { p1: &nodes[3], p2: &nodes[7] }
    ];
    let cube = Model { edges: edges };

    // Rendering stuff

    let opengl = OpenGL::V3_2;

    // Create an Glutin window.
    let mut window: GlutinWindow = WindowSettings::new(
            "Viewer",
            [800, 600]
        )
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let vp = Viewport {
        x_rot: 0.0,
        y_rot: 0.0,
        z_rot: 0.0
    };

    let mut app = App {
        gl: GlGraphics::new(opengl),
        model: cube,
        vp: vp
    };

    let mut events = Events::new(EventSettings::new());

    while let Some(e) = events.next(&mut window) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
        if let Some(button) = e.press_args() {
            app.update(button);
        }
    }
}
<commit_msg>Add moving camera translation to renderer<commit_after>extern crate piston;
extern crate piston_window;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use opengl_graphics::{GlGraphics, OpenGL};
use glutin_window::GlutinWindow;
use piston::window::WindowSettings;
use piston::event_loop::{Events, EventSettings};
use piston::input::*;

struct Point {
    x: f64,
    y: f64,
    z: f64
}

impl Point {
    fn rotate(&self, x: f64, y: f64, z: f64) -> Point {
        let mut rp = Point { x: self.x, y: self.y, z: self.z };

        let xn = rp.x * z.cos() - rp.y * z.sin();
        let yn = rp.x * z.sin() + rp.y * z.cos();
        rp.x = xn;
        rp.y = yn;

        let xn = rp.x * y.cos() - rp.z * y.sin();
        let zn = rp.x * y.sin() + rp.z * y.cos();
        rp.x = xn;
        rp.z = zn;

        let zn = rp.z * x.cos() - rp.y * x.sin();
        let yn = rp.z * x.sin() + rp.y * x.cos();
        rp.z = zn;
        rp.y = yn;

        rp
    }

    fn translate(&self, x: f64, y: f64, z: f64) -> Point {
        let rp = Point { x: self.x + x, y: self.y + y, z: self.z + z };
        rp
    }
}

struct Edge<'a> {
    p1: &'a Point,
    p2: &'a Point
}

struct Model<'a> {
    edges: Vec<Edge<'a>>
}

struct Viewport {
    x_rot: f64,
    y_rot: f64,
    z_rot: f64,
    x_trans: f64,
    y_trans: f64,
    z_trans: f64
}

pub struct App<'a> {
    gl: GlGraphics,
    model: Model<'a>,
    vp: Viewport
}

impl<'a> App<'a> {
    fn render(&mut self, args: &RenderArgs) {
        let ref model = self.model;
        let ref vp = self.vp;
        self.gl.draw(args.viewport(), |c, gl| {
            // Clear the screen.
            graphics::clear([0.7, 0.6, 0.75, 1.0], gl);

            for edge in &model.edges {
                let p1_t = edge.p1.translate(vp.x_trans, vp.y_trans, vp.z_trans).rotate(vp.x_rot, vp.y_rot, vp.z_rot);
                let p2_t = edge.p2.translate(vp.x_trans, vp.y_trans, vp.z_trans).rotate(vp.x_rot, vp.y_rot, vp.z_rot);

                let p1_x = p1_t.x * 256.0 / p1_t.z;
                let p1_y = p1_t.y * 256.0 / p1_t.z;
                let p2_x = p2_t.x * 256.0 / p2_t.z;
                let p2_y = p2_t.y * 256.0 / p2_t.z;
                graphics::line([0.0, 0.0, 0.0, 1.0],
                               0.5,
                               [p1_x + 400.0, p1_y + 300.0, p2_x + 400.0, p2_y + 300.0],
                               c.transform, gl);
            }
        });
    }

    fn update(&mut self, button: piston_window::Button) {
        use piston_window::Button::Keyboard;
        use piston_window::Key;

        if button == Keyboard(Key::W) {
            self.vp.x_rot += 0.05;
        } else if button == Keyboard(Key::S) {
            self.vp.x_rot -= 0.05;
        } else if button == Keyboard(Key::A) {
            self.vp.y_rot += 0.05;
        } else if button == Keyboard(Key::D) {
            self.vp.y_rot -= 0.05;
        } else if button == Keyboard(Key::Q) {
            self.vp.z_rot += 0.05;
        } else if button == Keyboard(Key::E) {
            self.vp.z_rot -= 0.05;
        } else if button == Keyboard(Key::I) {
            self.vp.z_trans += 1.0;
        } else if button == Keyboard(Key::K) {
            self.vp.z_trans -= 1.0;
        }
    }
}

fn main() {
    let nodes = vec![
        Point {x: -50.0, y: 50.0, z: 50.0},
        Point {x: -50.0, y: 50.0, z: -50.0},
        Point {x: -50.0, y: -50.0, z: 50.0},
        Point {x: -50.0, y: -50.0, z: -50.0},
        Point {x: 50.0, y: 50.0, z: 50.0},
        Point {x: 50.0, y: 50.0, z: -50.0},
        Point {x: 50.0, y: -50.0, z: 50.0},
        Point {x: 50.0, y: -50.0, z: -50.0}
    ];
    let edges = vec![
        Edge { p1: &nodes[0], p2: &nodes[1] },
        Edge { p1: &nodes[2], p2: &nodes[3] },
        Edge { p1: &nodes[4], p2: &nodes[5] },
        Edge { p1: &nodes[6], p2: &nodes[7] },
        Edge { p1: &nodes[0], p2: &nodes[2] },
        Edge { p1: &nodes[4], p2: &nodes[6] },
        Edge { p1: &nodes[1], p2: &nodes[3] },
        Edge { p1: &nodes[5], p2: &nodes[7] },
        Edge { p1: &nodes[0], p2: &nodes[4] },
        Edge { p1: &nodes[2], p2: &nodes[6] },
        Edge { p1: &nodes[1], p2: &nodes[5] },
        Edge { p1: &nodes[3], p2: &nodes[7] }
    ];
    let cube = Model { edges: edges };

    // Rendering stuff

    let opengl = OpenGL::V3_2;

    // Create an Glutin window.
    let mut window: GlutinWindow = WindowSettings::new(
            "Viewer",
            [800, 600]
        )
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let vp = Viewport {
        x_rot: 0.0,
        y_rot: 0.0,
        z_rot: 0.0,
        x_trans: 0.0,
        y_trans: 0.0,
        z_trans: 500.0
    };

    let mut app = App {
        gl: GlGraphics::new(opengl),
        model: cube,
        vp: vp
    };

    let mut events = Events::new(EventSettings::new());

    while let Some(e) = events.next(&mut window) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
        if let Some(button) = e.press_args() {
            app.update(button);
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate rmp_serde as rmps;

use std::collections::BTreeMap;

use serde_bytes::ByteBuf;

use rmpv::Value;
use rmpv::decode;
use rmpv::ext::from_value;

/// Tests that a `Value` is properly decoded from bytes using two different mechanisms: direct
/// deserialization using `rmp::decode::read_value` and using `serde`.
fn test_decode(buf: &[u8], v: Value) {
    let val0: Value = decode::read_value(&mut &buf[..]).unwrap();
    assert_eq!(v, val0);

    let val1: Value = rmps::from_slice(buf).unwrap();
    assert_eq!(v, val1);
}

#[test]
fn test_stack_depth_checking() {
    let mut buf: Vec<u8> = (0..decode::MAX_DEPTH).map(|_| 0x91).collect();
    buf.push(0xc3);

    match decode::read_value(&mut &buf[..]) {
        Ok(_) => panic!("expected max stack depth to be exceeded"),
        Err(decode::Error::DepthLimitExceeded) => {},
        Err(err) => panic!("unexpected error: {}", err),
    }
}

#[test]
fn pass_null() {
    test_decode(&[0xc0], Value::Nil);
}

#[test]
fn pass_bool() {
    test_decode(&[0xc3], Value::Boolean(true));
    test_decode(&[0xc2], Value::Boolean(false));
}

#[test]
fn pass_uint() {
    test_decode(&[0x00], Value::from(u8::min_value()));
    test_decode(&[0xcc, 0xff], Value::from(u8::max_value()));
    test_decode(&[0xcd, 0xff, 0xff], Value::from(u16::max_value()));
    test_decode(&[0xce, 0xff, 0xff, 0xff, 0xff], Value::from(u32::max_value()));
    test_decode(&[0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], Value::from(u64::max_value()));
}

#[test]
fn pass_sint() {
    test_decode(&[0xd0, 0x80], Value::from(i8::min_value()));
    test_decode(&[0x7f], Value::from(i8::max_value()));
    test_decode(&[0xd1, 0x80, 0x00], Value::from(i16::min_value()));
    test_decode(&[0xcd, 0x7f, 0xff], Value::from(i16::max_value()));
    test_decode(&[0xd2, 0x80, 0x00, 0x00, 0x00], Value::from(i32::min_value()));
    test_decode(&[0xce, 0x7f, 0xff, 0xff, 0xff], Value::from(i32::max_value()));
    test_decode(&[0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Value::from(i64::min_value()));
    test_decode(&[0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], Value::from(i64::max_value()));
}

#[test]
fn pass_f32() {
    test_decode(&[0xca, 0x7f, 0x7f, 0xff, 0xff], Value::from(3.4028234e38f32));
}

#[test]
fn pass_f64() {
    test_decode(&[0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Value::from(0.00));
    test_decode(&[0xcb, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Value::from(42.0));
}

#[test]
fn pass_str() {
    test_decode(&[0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65],
        Value::from("le message"));
}

#[test]
fn pass_bin() {
    test_decode(&[0xc4, 0x02, 0xcc, 0x80], Value::from(&[0xcc, 0x80][..]));
}

#[test]
fn pass_array() {
    test_decode(&[0x92, 0xa2, 0x6c, 0x65, 0xa4, 0x73, 0x68, 0x69, 0x74],
        Value::Array(vec![Value::from("le"), Value::from("shit")]));
}

#[test]
fn pass_value_map() {
    let val = Value::Map(vec![
        (Value::from(0), Value::from("le")),
        (Value::from(1), Value::from("shit")),
    ]);

    test_decode(&[0x82, 0x00, 0xa2, 0x6c, 0x65, 0x01, 0xa4, 0x73, 0x68, 0x69, 0x74], val);
}

#[test]
fn pass_uint_from_value() {
    assert_eq!(i8::min_value(), from_value(Value::from(i8::min_value())).unwrap());
    assert_eq!(i8::max_value(), from_value(Value::from(i8::max_value())).unwrap());
    assert_eq!(i16::min_value(), from_value(Value::from(i16::min_value())).unwrap());
    assert_eq!(i16::max_value(), from_value(Value::from(i16::max_value())).unwrap());
    assert_eq!(i32::min_value(), from_value(Value::from(i32::min_value())).unwrap());
    assert_eq!(i32::max_value(), from_value(Value::from(i32::max_value())).unwrap());
    assert_eq!(i64::min_value(), from_value(Value::from(i64::min_value())).unwrap());
    assert_eq!(i64::max_value(), from_value(Value::from(i64::max_value())).unwrap());
}

#[test]
fn pass_sint_from_value() {
    assert_eq!(0, from_value(Value::from(0)).unwrap());
    assert_eq!(u8::max_value(), from_value(Value::from(u8::max_value())).unwrap());
    assert_eq!(u16::max_value(), from_value(Value::from(u16::max_value())).unwrap());
    assert_eq!(u32::max_value(), from_value(Value::from(u32::max_value())).unwrap());
    assert_eq!(u64::max_value(), from_value(Value::from(u64::max_value())).unwrap());
}

#[test]
fn pass_f32_from_value() {
    assert_eq!(0.0f32, from_value(Value::from(0.0f32)).unwrap());
    assert_eq!(std::f32::consts::PI, from_value(Value::from(std::f32::consts::PI)).unwrap());
}

#[test]
fn pass_f64_from_value() {
    assert_eq!(0.0, from_value(Value::from(0.0)).unwrap());
    assert_eq!(std::f64::consts::PI, from_value(Value::from(std::f64::consts::PI)).unwrap());
}

#[test]
fn pass_char_from_value() {
    assert_eq!('c', from_value(Value::from("c")).unwrap());
}

#[test]
fn pass_str_from_value() {
    let v: String = from_value(Value::from("le message")).unwrap();
    assert_eq!("le message".to_string(), v);
}

#[test]
fn pass_bin_from_value() {
    assert_eq!(
        ByteBuf::from(&[0, 1, 2][..]),
        from_value::<ByteBuf>(Value::from(vec![0, 1, 2])).unwrap()
    );
}

#[test]
fn pass_vec_from_value() {
    let v: Vec<String> = from_value(Value::from(vec![Value::from("John"), Value::from("Smith")])).unwrap();
    assert_eq!(vec!["John".to_string(), "Smith".to_string()], v);
}

#[test]
fn pass_map_from_value() {
    let mut map = BTreeMap::new();
    map.insert("name".to_string(), "John".to_string());
    map.insert("surname".to_string(), "Smith".to_string());

    let val = Value::from(vec![
        (Value::from("name"), Value::from("John")),
        (Value::from("surname"), Value::from("Smith"))
    ]);

    let v: BTreeMap<String, String> = from_value(val).unwrap();

    assert_eq!(map, v);
}

#[test]
fn pass_option_from_value() {
    assert_eq!(None::<i32>, from_value(Value::Nil).unwrap());
    // TODO: assert_eq!(Some(None::<i32>), from_value(Value::Nil).unwrap());
    assert_eq!(Some(42), from_value(Value::from(42)).unwrap());
    assert_eq!(Some(Some(42)), from_value(Value::from(42)).unwrap());
}

#[test]
fn pass_seq_from_value() {
    let v: Vec<u64> = from_value(Value::Array(vec![Value::from(0), Value::from(42)])).unwrap();
    assert_eq!(vec![0, 42], v);
}

#[test]
fn pass_tuple_from_value() {
    let v: (String, u8) = from_value(Value::Array(vec![Value::from("John"), Value::from(42)])).unwrap();
    assert_eq!(("John".into(), 42), v);
}

#[test]
fn pass_unit_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Unit;

    assert_eq!(Unit, from_value(Value::Array(vec![])).unwrap());
}

#[test]
fn pass_newtype_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Newtype(String);

    assert_eq!(Newtype("John".into()), from_value(Value::from("John")).unwrap());
}

#[test]
fn pass_tuple_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Newtype(String, u8);

    assert_eq!(Newtype("John".into(), 42),
        from_value(Value::Array(vec![Value::from("John"), Value::from(42)])).unwrap());
}

#[test]
fn pass_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Struct {
        name: String,
        age: u8
    }

    assert_eq!(Struct { name: "John".into(), age: 42 },
        from_value(Value::Array(vec![Value::from("John"), Value::from(42)])).unwrap());
}

#[test]
fn pass_enum_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    enum Enum {
        Unit,
        Newtype(String),
        Tuple(String, u32),
        Struct { name: String, age: u32 },
    }

    assert_eq!(Enum::Unit,
        from_value(Value::Array(vec![Value::from(0), Value::Array(vec![])])).unwrap());
    assert_eq!(Enum::Newtype("John".into()),
        from_value(Value::Array(vec![Value::from(1), Value::Array(vec![Value::from("John")])])).unwrap());
    assert_eq!(Enum::Tuple("John".into(), 42),
        from_value(Value::Array(vec![Value::from(2), Value::Array(vec![Value::from("John"), Value::from(42)])])).unwrap());
    assert_eq!(Enum::Struct { name: "John".into(), age: 42 },
        from_value(Value::Array(vec![Value::from(3), Value::Array(vec![Value::from("John"), Value::from(42)])])).unwrap());
}

#[test]
fn pass_tuple_struct_from_ext() {
    #[derive(Debug, PartialEq)]
    struct ExtStruct(i8, Vec<u8>);

    struct ExtStructVisitor;

    impl<'de> serde::de::Visitor<'de> for ExtStructVisitor {
        type Value = ExtStruct;

        fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            formatter.write_str("msgpack ext")
        }

        fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where D: serde::de::Deserializer<'de>,
        {
            deserializer.deserialize_tuple(2, self)
        }

        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
            where A: serde::de::SeqAccess<'de>,
        {

            let tag = seq.next_element()?
                .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
            let bytes: serde_bytes::ByteBuf = seq.next_element()?
                .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;

            Ok(ExtStruct(tag, bytes.to_vec()))
        }
    }

    impl<'de> serde::de::Deserialize<'de> for ExtStruct {
        fn deserialize<D>(deserializer: D) -> Result<ExtStruct, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(ExtStructVisitor)
        }
    }

    assert_eq!(ExtStruct(42, vec![255]),
        from_value(Value::Ext(42, vec![255])).unwrap());
}
<commit_msg>Give a big stack to the stack overflow test<commit_after>#[macro_use]
extern crate serde_derive;
extern crate rmp_serde as rmps;

use std::collections::BTreeMap;

use serde_bytes::ByteBuf;

use rmpv::Value;
use rmpv::decode;
use rmpv::ext::from_value;

/// Tests that a `Value` is properly decoded from bytes using two different mechanisms: direct
/// deserialization using `rmp::decode::read_value` and using `serde`.
fn test_decode(buf: &[u8], v: Value) {
    let val0: Value = decode::read_value(&mut &buf[..]).unwrap();
    assert_eq!(v, val0);

    let val1: Value = rmps::from_slice(buf).unwrap();
    assert_eq!(v, val1);
}

#[test]
fn test_stack_depth_checking() {
    std::thread::Builder::new()
    .name("test_stack_depth_checking".into())
    .stack_size(10_000_000)
    .spawn(|| {
        let mut buf: Vec<u8> = (0..decode::MAX_DEPTH).map(|_| 0x91).collect();
        buf.push(0xc3);

        match decode::read_value(&mut &buf[..]) {
            Ok(_) => panic!("expected max stack depth to be exceeded"),
            Err(decode::Error::DepthLimitExceeded) => {},
            Err(err) => panic!("unexpected error: {}", err),
        }
    }).unwrap().join().unwrap()
}

#[test]
fn pass_null() {
    test_decode(&[0xc0], Value::Nil);
}

#[test]
fn pass_bool() {
    test_decode(&[0xc3], Value::Boolean(true));
    test_decode(&[0xc2], Value::Boolean(false));
}

#[test]
fn pass_uint() {
    test_decode(&[0x00], Value::from(u8::min_value()));
    test_decode(&[0xcc, 0xff], Value::from(u8::max_value()));
    test_decode(&[0xcd, 0xff, 0xff], Value::from(u16::max_value()));
    test_decode(&[0xce, 0xff, 0xff, 0xff, 0xff], Value::from(u32::max_value()));
    test_decode(&[0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], Value::from(u64::max_value()));
}

#[test]
fn pass_sint() {
    test_decode(&[0xd0, 0x80], Value::from(i8::min_value()));
    test_decode(&[0x7f], Value::from(i8::max_value()));
    test_decode(&[0xd1, 0x80, 0x00], Value::from(i16::min_value()));
    test_decode(&[0xcd, 0x7f, 0xff], Value::from(i16::max_value()));
    test_decode(&[0xd2, 0x80, 0x00, 0x00, 0x00], Value::from(i32::min_value()));
    test_decode(&[0xce, 0x7f, 0xff, 0xff, 0xff], Value::from(i32::max_value()));
    test_decode(&[0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Value::from(i64::min_value()));
    test_decode(&[0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], Value::from(i64::max_value()));
}

#[test]
fn pass_f32() {
    test_decode(&[0xca, 0x7f, 0x7f, 0xff, 0xff], Value::from(3.4028234e38f32));
}

#[test]
fn pass_f64() {
    test_decode(&[0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Value::from(0.00));
    test_decode(&[0xcb, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Value::from(42.0));
}

#[test]
fn pass_str() {
    test_decode(&[0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65],
        Value::from("le message"));
}

#[test]
fn pass_bin() {
    test_decode(&[0xc4, 0x02, 0xcc, 0x80], Value::from(&[0xcc, 0x80][..]));
}

#[test]
fn pass_array() {
    test_decode(&[0x92, 0xa2, 0x6c, 0x65, 0xa4, 0x73, 0x68, 0x69, 0x74],
        Value::Array(vec![Value::from("le"), Value::from("shit")]));
}

#[test]
fn pass_value_map() {
    let val = Value::Map(vec![
        (Value::from(0), Value::from("le")),
        (Value::from(1), Value::from("shit")),
    ]);

    test_decode(&[0x82, 0x00, 0xa2, 0x6c, 0x65, 0x01, 0xa4, 0x73, 0x68, 0x69, 0x74], val);
}

#[test]
fn pass_uint_from_value() {
    assert_eq!(i8::min_value(), from_value(Value::from(i8::min_value())).unwrap());
    assert_eq!(i8::max_value(), from_value(Value::from(i8::max_value())).unwrap());
    assert_eq!(i16::min_value(), from_value(Value::from(i16::min_value())).unwrap());
    assert_eq!(i16::max_value(), from_value(Value::from(i16::max_value())).unwrap());
    assert_eq!(i32::min_value(), from_value(Value::from(i32::min_value())).unwrap());
    assert_eq!(i32::max_value(), from_value(Value::from(i32::max_value())).unwrap());
    assert_eq!(i64::min_value(), from_value(Value::from(i64::min_value())).unwrap());
    assert_eq!(i64::max_value(), from_value(Value::from(i64::max_value())).unwrap());
}

#[test]
fn pass_sint_from_value() {
    assert_eq!(0, from_value(Value::from(0)).unwrap());
    assert_eq!(u8::max_value(), from_value(Value::from(u8::max_value())).unwrap());
    assert_eq!(u16::max_value(), from_value(Value::from(u16::max_value())).unwrap());
    assert_eq!(u32::max_value(), from_value(Value::from(u32::max_value())).unwrap());
    assert_eq!(u64::max_value(), from_value(Value::from(u64::max_value())).unwrap());
}

#[test]
fn pass_f32_from_value() {
    assert_eq!(0.0f32, from_value(Value::from(0.0f32)).unwrap());
    assert_eq!(std::f32::consts::PI, from_value(Value::from(std::f32::consts::PI)).unwrap());
}

#[test]
fn pass_f64_from_value() {
    assert_eq!(0.0, from_value(Value::from(0.0)).unwrap());
    assert_eq!(std::f64::consts::PI, from_value(Value::from(std::f64::consts::PI)).unwrap());
}

#[test]
fn pass_char_from_value() {
    assert_eq!('c', from_value(Value::from("c")).unwrap());
}

#[test]
fn pass_str_from_value() {
    let v: String = from_value(Value::from("le message")).unwrap();
    assert_eq!("le message".to_string(), v);
}

#[test]
fn pass_bin_from_value() {
    assert_eq!(
        ByteBuf::from(&[0, 1, 2][..]),
        from_value::<ByteBuf>(Value::from(vec![0, 1, 2])).unwrap()
    );
}

#[test]
fn pass_vec_from_value() {
    let v: Vec<String> = from_value(Value::from(vec![Value::from("John"), Value::from("Smith")])).unwrap();
    assert_eq!(vec!["John".to_string(), "Smith".to_string()], v);
}

#[test]
fn pass_map_from_value() {
    let mut map = BTreeMap::new();
    map.insert("name".to_string(), "John".to_string());
    map.insert("surname".to_string(), "Smith".to_string());

    let val = Value::from(vec![
        (Value::from("name"), Value::from("John")),
        (Value::from("surname"), Value::from("Smith"))
    ]);

    let v: BTreeMap<String, String> = from_value(val).unwrap();

    assert_eq!(map, v);
}

#[test]
fn pass_option_from_value() {
    assert_eq!(None::<i32>, from_value(Value::Nil).unwrap());
    // TODO: assert_eq!(Some(None::<i32>), from_value(Value::Nil).unwrap());
    assert_eq!(Some(42), from_value(Value::from(42)).unwrap());
    assert_eq!(Some(Some(42)), from_value(Value::from(42)).unwrap());
}

#[test]
fn pass_seq_from_value() {
    let v: Vec<u64> = from_value(Value::Array(vec![Value::from(0), Value::from(42)])).unwrap();
    assert_eq!(vec![0, 42], v);
}

#[test]
fn pass_tuple_from_value() {
    let v: (String, u8) = from_value(Value::Array(vec![Value::from("John"), Value::from(42)])).unwrap();
    assert_eq!(("John".into(), 42), v);
}

#[test]
fn pass_unit_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Unit;

    assert_eq!(Unit, from_value(Value::Array(vec![])).unwrap());
}

#[test]
fn pass_newtype_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Newtype(String);

    assert_eq!(Newtype("John".into()), from_value(Value::from("John")).unwrap());
}

#[test]
fn pass_tuple_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Newtype(String, u8);

    assert_eq!(Newtype("John".into(), 42),
        from_value(Value::Array(vec![Value::from("John"), Value::from(42)])).unwrap());
}

#[test]
fn pass_struct_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    struct Struct {
        name: String,
        age: u8
    }

    assert_eq!(Struct { name: "John".into(), age: 42 },
        from_value(Value::Array(vec![Value::from("John"), Value::from(42)])).unwrap());
}

#[test]
fn pass_enum_from_value() {
    #[derive(Debug, PartialEq, Deserialize)]
    enum Enum {
        Unit,
        Newtype(String),
        Tuple(String, u32),
        Struct { name: String, age: u32 },
    }

    assert_eq!(Enum::Unit,
        from_value(Value::Array(vec![Value::from(0), Value::Array(vec![])])).unwrap());
    assert_eq!(Enum::Newtype("John".into()),
        from_value(Value::Array(vec![Value::from(1), Value::Array(vec![Value::from("John")])])).unwrap());
    assert_eq!(Enum::Tuple("John".into(), 42),
        from_value(Value::Array(vec![Value::from(2), Value::Array(vec![Value::from("John"), Value::from(42)])])).unwrap());
    assert_eq!(Enum::Struct { name: "John".into(), age: 42 },
        from_value(Value::Array(vec![Value::from(3), Value::Array(vec![Value::from("John"), Value::from(42)])])).unwrap());
}

#[test]
fn pass_tuple_struct_from_ext() {
    #[derive(Debug, PartialEq)]
    struct ExtStruct(i8, Vec<u8>);

    struct ExtStructVisitor;

    impl<'de> serde::de::Visitor<'de> for ExtStructVisitor {
        type Value = ExtStruct;

        fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            formatter.write_str("msgpack ext")
        }

        fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where D: serde::de::Deserializer<'de>,
        {
            deserializer.deserialize_tuple(2, self)
        }

        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
            where A: serde::de::SeqAccess<'de>,
        {

            let tag = seq.next_element()?
                .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
            let bytes: serde_bytes::ByteBuf = seq.next_element()?
                .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;

            Ok(ExtStruct(tag, bytes.to_vec()))
        }
    }

    impl<'de> serde::de::Deserialize<'de> for ExtStruct {
        fn deserialize<D>(deserializer: D) -> Result<ExtStruct, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(ExtStructVisitor)
        }
    }

    assert_eq!(ExtStruct(42, vec![255]),
        from_value(Value::Ext(42, vec![255])).unwrap());
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (eliza@elizas.website)
//
//  Copyright (c) 2015-2017 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! `x86_64` architecture-specific implementation.
// pub mod cpu;
pub mod drivers;
pub mod interrupts;

#[path = "../x86_all/bda.rs"] pub mod bda;
#[path = "../x86_all/multiboot2.rs"] pub mod multiboot2;

pub const ARCH_BITS: u8 = 64;

extern {
    // TODO: It would be really nice if there was a less ugly way of doing
    // this... (read: after the Revolution when we add memory regions to the
    // heap programmatically.)
    #[link_name = "heap_base_addr"]
    #[linkage = "external"]
    pub static HEAP_BASE: *mut u8;
    #[link_name = "heap_top_addr"]
    #[linkage = "external"]
    pub static HEAP_TOP: *mut u8;
    // Of course, we will still need to export the kernel stack addresses like
    // this, but it would be nice if they could be, i dont know, not mut u8s
    // pointers, like God intended.
    #[link_name = "stack_base"]
    pub static STACK_BASE: *mut u8;
    #[link_name = "stack_top"]
    pub static STACK_TOP: *mut u8;
}

use memory::PAddr;

/// Trampoline to ensure we have a correct stack frame for calling [`arch_init`]
///
/// I have no idea why this works, but it does.
///
/// [`arch_init`]: fn.arch_init
#[naked]
#[no_mangle]
pub unsafe extern "C" fn long_mode_init() {
    asm!("movabsq $$(stack_top), %rsp");
    asm!("mov ax, 0
          mov ss, ax
          mov ds, ax
          mov es, ax
          mov fs, ax
          mov gs, ax
          call arch_init"
        :::: "intel");

}

/// Entry point for architecture-specific kernel init
///
/// This expects to be passed the address of a valid
/// Multiboot 2 info struct. It's the bootloader's responsibility to ensure
/// that this is passed in the correct register as expected by the calling
/// convention (`edi` on x86). If this isn't there, you can expect to have a
/// bad problem and not go to space today.
#[no_mangle]
pub extern "C" fn arch_init(multiboot_addr: PAddr) {
    use cpu::{control_regs, msr};
    use elf;
    use params::InitParams;

    kinfoln!(dots: " . ", "Beginning `arch_init()` for x86_64");

    ::io::term::CONSOLE.lock().clear();
    ::logger::initialize()
        .expect("Could not initialize logger!");

    // -- Unpack multiboot tag ------------------------------------------------
    kinfoln!( dots: " . "
            , "trying to unpack multiboot info at {:?}"
            , multiboot_addr);

    // try to interpret the structure at the multiboot address as a multiboot
    // info struct. if it's invalid, fail.
    let boot_info
        = unsafe { multiboot2::Info::from(multiboot_addr)
                    .expect("Could not unpack multiboot2 information!") };

    // Extract the memory map tag from the multiboot info
    let mem_map = boot_info.mem_map()
                           .expect("Memory map tag required!");

    kinfoln!(dots: " . ", "Detected memory areas:");
    for area in mem_map {
        kinfoln!( dots: " . . ", "{}", area);
        // TODO: add memory map to init params here
    }

    // Extract ELF sections tag from the multiboot info
    let elf_sections_tag
        = boot_info.elf_sections()
                   .expect("ELF sections tag required!");

    kinfoln!(dots: " . ", "Detecting kernel ELF sections:");

    // Extract kernel ELF sections from  multiboot info
    let mut n_elf_sections = 0;

    let kernel_begin
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| {
                kinfoln!( dots: " . . ", "{}", s );
                kinfoln!( dots: " . . . ", "flags: [ {:?} ]", s.flags());
                s.address() })
            .min()
            .expect("Could not find kernel start section!\
                    \nSomething is deeply wrong.");

    let kernel_end
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| { n_elf_sections += 1; s.address() })
            .max()
            .expect("Could not find kernel end section!\
                    \nSomething is deeply wrong.");

    kinfoln!( dots: " . ", "Detected {} kernel ELF sections.", n_elf_sections);
    kinfoln!( dots: " . . ", "Kernel begins at {:#p} and ends at {:#p}."
            , kernel_begin, kernel_end );

    let multiboot_end = multiboot_addr + boot_info.length as u64;

    kinfoln!( dots: " . . ", "Multiboot info begins at {:#x} and ends at {:#x}."
            , multiboot_addr, multiboot_end);

    let params = InitParams { kernel_base: kernel_begin
                            , kernel_top: kernel_end
                            , multiboot_start: Some(multiboot_addr)
                            , multiboot_end: Some(multiboot_end)
                            , heap_base: unsafe { PAddr::from(HEAP_BASE) }
                            , heap_top: unsafe { PAddr::from(HEAP_TOP) }
                            , stack_base: unsafe { PAddr::from(STACK_BASE) }
                            , stack_top: unsafe { PAddr::from(STACK_TOP) }
                            , ..Default::default()
                            };

     // -- enable flags needed for paging ------------------------------------
     unsafe {
         control_regs::cr0::enable_write_protect(true);
         kinfoln!(dots: " . ", "Page write protect ENABED" );

         msr::enable_nxe();
         kinfoln!(dots: " . ", "Page no execute bit ENABLED");
     }

    kinfoln!(dots: " . ", "Transferring to `kernel_init()`.");
    ::kernel_init(&params);
}
<commit_msg>fix(x86_64::arch_init): format the multiboot tag address as a pointer<commit_after>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (eliza@elizas.website)
//
//  Copyright (c) 2015-2017 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! `x86_64` architecture-specific implementation.
// pub mod cpu;
pub mod drivers;
pub mod interrupts;

#[path = "../x86_all/bda.rs"] pub mod bda;
#[path = "../x86_all/multiboot2.rs"] pub mod multiboot2;

pub const ARCH_BITS: u8 = 64;

extern {
    // TODO: It would be really nice if there was a less ugly way of doing
    // this... (read: after the Revolution when we add memory regions to the
    // heap programmatically.)
    #[link_name = "heap_base_addr"]
    #[linkage = "external"]
    pub static HEAP_BASE: *mut u8;
    #[link_name = "heap_top_addr"]
    #[linkage = "external"]
    pub static HEAP_TOP: *mut u8;
    // Of course, we will still need to export the kernel stack addresses like
    // this, but it would be nice if they could be, i dont know, not mut u8s
    // pointers, like God intended.
    #[link_name = "stack_base"]
    pub static STACK_BASE: *mut u8;
    #[link_name = "stack_top"]
    pub static STACK_TOP: *mut u8;
}

use memory::PAddr;

/// Trampoline to ensure we have a correct stack frame for calling [`arch_init`]
///
/// I have no idea why this works, but it does.
///
/// [`arch_init`]: fn.arch_init
#[naked]
#[no_mangle]
pub unsafe extern "C" fn long_mode_init() {
    asm!("movabsq $$(stack_top), %rsp");
    asm!("mov ax, 0
          mov ss, ax
          mov ds, ax
          mov es, ax
          mov fs, ax
          mov gs, ax
          call arch_init"
        :::: "intel");

}

/// Entry point for architecture-specific kernel init
///
/// This expects to be passed the address of a valid
/// Multiboot 2 info struct. It's the bootloader's responsibility to ensure
/// that this is passed in the correct register as expected by the calling
/// convention (`edi` on x86). If this isn't there, you can expect to have a
/// bad problem and not go to space today.
#[no_mangle]
pub extern "C" fn arch_init(multiboot_addr: PAddr) {
    use cpu::{control_regs, msr};
    use elf;
    use params::InitParams;

    kinfoln!(dots: " . ", "Beginning `arch_init()` for x86_64");

    ::io::term::CONSOLE.lock().clear();
    ::logger::initialize()
        .expect("Could not initialize logger!");

    // -- Unpack multiboot tag ------------------------------------------------
    kinfoln!( dots: " . "
            , "trying to unpack multiboot info at {:#p}"
            , multiboot_addr);

    // try to interpret the structure at the multiboot address as a multiboot
    // info struct. if it's invalid, fail.
    let boot_info
        = unsafe { multiboot2::Info::from(multiboot_addr)
                    .expect("Could not unpack multiboot2 information!") };

    // Extract the memory map tag from the multiboot info
    let mem_map = boot_info.mem_map()
                           .expect("Memory map tag required!");

    kinfoln!(dots: " . ", "Detected memory areas:");
    for area in mem_map {
        kinfoln!( dots: " . . ", "{}", area);
        // TODO: add memory map to init params here
    }

    // Extract ELF sections tag from the multiboot info
    let elf_sections_tag
        = boot_info.elf_sections()
                   .expect("ELF sections tag required!");

    kinfoln!(dots: " . ", "Detecting kernel ELF sections:");

    // Extract kernel ELF sections from  multiboot info
    let mut n_elf_sections = 0;

    let kernel_begin
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| {
                kinfoln!( dots: " . . ", "{}", s );
                kinfoln!( dots: " . . . ", "flags: [ {:?} ]", s.flags());
                s.address() })
            .min()
            .expect("Could not find kernel start section!\
                    \nSomething is deeply wrong.");

    let kernel_end
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| { n_elf_sections += 1; s.address() })
            .max()
            .expect("Could not find kernel end section!\
                    \nSomething is deeply wrong.");

    kinfoln!( dots: " . ", "Detected {} kernel ELF sections.", n_elf_sections);
    kinfoln!( dots: " . . ", "Kernel begins at {:#p} and ends at {:#p}."
            , kernel_begin, kernel_end );

    let multiboot_end = multiboot_addr + boot_info.length as u64;

    kinfoln!( dots: " . . ", "Multiboot info begins at {:#x} and ends at {:#x}."
            , multiboot_addr, multiboot_end);

    let params = InitParams { kernel_base: kernel_begin
                            , kernel_top: kernel_end
                            , multiboot_start: Some(multiboot_addr)
                            , multiboot_end: Some(multiboot_end)
                            , heap_base: unsafe { PAddr::from(HEAP_BASE) }
                            , heap_top: unsafe { PAddr::from(HEAP_TOP) }
                            , stack_base: unsafe { PAddr::from(STACK_BASE) }
                            , stack_top: unsafe { PAddr::from(STACK_TOP) }
                            , ..Default::default()
                            };

     // -- enable flags needed for paging ------------------------------------
     unsafe {
         control_regs::cr0::enable_write_protect(true);
         kinfoln!(dots: " . ", "Page write protect ENABED" );

         msr::enable_nxe();
         kinfoln!(dots: " . ", "Page no execute bit ENABLED");
     }

    kinfoln!(dots: " . ", "Transferring to `kernel_init()`.");
    ::kernel_init(&params);
}
<|endoftext|>


<commit_before>use yoga_wrapper;

use super::renders::Renders;

pub trait Backend<'meas> {
    type Renderer: Renders;

    fn get_renderer(&mut self) -> &mut Self::Renderer;
    fn create_context<'text>(&'meas self, text: &'text str) -> yoga_wrapper::Context<'text, 'meas>;
}
<commit_msg>feat(Backend): add render delegation using Renders Color<commit_after>use yoga_wrapper;
use renderable::Renderable;

use super::renders::Renders;

pub trait Backend<'meas> {
    type Renderer: Renders;

    fn get_renderer(&mut self) -> &mut Self::Renderer;
    fn create_context<'text>(&'meas self, text: &'text str) -> yoga_wrapper::Context<'text, 'meas>;

    fn render(&mut self, node: &Renderable<<<Self as Backend<'meas>>::Renderer as Renders>::Color>) {
        self.get_renderer().render(node)
    }
}
<|endoftext|>


<commit_before><commit_msg>Supress deprecated lang feature warnings, use slice notation for strings<commit_after><|endoftext|>


<commit_before><commit_msg>Use the trick from https://github.com/bluss/indexing to keep heaps disjoint. Thanks @bluss!<commit_after><|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_name = "rs_es"]

#![feature(convert)]

#[macro_use] extern crate log;
extern crate hyper;
extern crate rustc_serialize;

use std::error::Error;
use std::io;
use std::fmt;

use rustc_serialize::json;
use rustc_serialize::json::Json;

// Error handling

#[derive(Debug)]
pub enum EsError {
    EsError(String),
    HttpError(hyper::error::HttpError),
    IoError(io::Error),
    JsonError(json::BuilderError)
}

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

impl From<hyper::error::HttpError> for EsError {
    fn from(err: hyper::error::HttpError) -> EsError {
        EsError::HttpError(err)
    }
}

impl From<json::BuilderError> for EsError {
    fn from(err: json::BuilderError) -> EsError {
        EsError::JsonError(err)
    }
}

impl Error for EsError {
    fn description(&self) -> &str {
        match *self {
            EsError::EsError(ref err) => err.as_str(),
            EsError::HttpError(ref err) => err.description(),
            EsError::IoError(ref err) => err.description(),
            EsError::JsonError(ref err) => err.description()
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            EsError::EsError(_)         => None,
            EsError::HttpError(ref err) => Some(err as &Error),
            EsError::IoError(ref err)   => Some(err as &Error),
            EsError::JsonError(ref err) => Some(err as &Error)
        }
    }
}

impl fmt::Display for EsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            EsError::EsError(ref s) => fmt::Display::fmt(s, f),
            EsError::HttpError(ref err) => fmt::Display::fmt(err, f),
            EsError::IoError(ref err) => fmt::Display::fmt(err, f),
            EsError::JsonError(ref err) => fmt::Display::fmt(err, f)
        }
    }
}

// The client

pub struct Client {
    host:        String,
    port:        u32,
    http_client: hyper::Client
}

impl Client {
    pub fn new(host: String, port: u32) -> Client {
        Client {
            host:        host,
            port:        port,
            http_client: hyper::Client::new()
        }
    }

    fn get_base_url(&self) -> String {
        format!("http://{}:{}/", self.host, self.port)
    }

    fn get(&mut self, url: &str, body: Option<&Json>) -> Result<Json, EsError> {
        let rb = self.http_client.get(url);
        let mut result = try!(match body {
            Some(json) => rb.body(json.as_string().unwrap()),
            None       => rb
        }.send());
        Ok(try!(Json::from_reader(&mut result)))
    }

    pub fn version(&mut self) -> Result<String, EsError> {
        let url = self.get_base_url();
        let json = try!(self.get(url.as_str(), None));
        match json.find_path(&["version", "number"]) {
            Some(version) => match version.as_string() {
                Some(string) => Ok(string.to_string()),
                None         => Err(EsError::EsError(format!("Cannot find version number in: {:?}",
                                                             json)))
            },
            None          => Err(EsError::EsError(format!("Cannot find version number in {:?}",
                                                          json)))
        }
    }
}

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

    #[test]
    fn it_works() {
        let mut client = Client::new("localhost".to_string(), 9200);
        assert_eq!(client.version().unwrap(), "1.3.2");
    }
}
<commit_msg>Implement document indexing<commit_after>#![crate_type = "lib"]
#![crate_name = "rs_es"]

#![feature(convert)]
#![feature(std_misc)]

#[macro_use] extern crate log;
extern crate hyper;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::error::Error;
use std::io;
use std::fmt;

use rustc_serialize::json;
use rustc_serialize::json::{Json, ToJson};

// Error handling

#[derive(Debug)]
pub enum EsError {
    EsError(String),
    HttpError(hyper::error::HttpError),
    IoError(io::Error),
    JsonBuilderError(json::BuilderError)
}

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

impl From<hyper::error::HttpError> for EsError {
    fn from(err: hyper::error::HttpError) -> EsError {
        EsError::HttpError(err)
    }
}

impl From<json::BuilderError> for EsError {
    fn from(err: json::BuilderError) -> EsError {
        EsError::JsonBuilderError(err)
    }
}

impl Error for EsError {
    fn description(&self) -> &str {
        match *self {
            EsError::EsError(ref err) => err.as_str(),
            EsError::HttpError(ref err) => err.description(),
            EsError::IoError(ref err) => err.description(),
            EsError::JsonBuilderError(ref err) => err.description()
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            EsError::EsError(_)         => None,
            EsError::HttpError(ref err) => Some(err as &Error),
            EsError::IoError(ref err)   => Some(err as &Error),
            EsError::JsonBuilderError(ref err) => Some(err as &Error)
        }
    }
}

impl fmt::Display for EsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            EsError::EsError(ref s) => fmt::Display::fmt(s, f),
            EsError::HttpError(ref err) => fmt::Display::fmt(err, f),
            EsError::IoError(ref err) => fmt::Display::fmt(err, f),
            EsError::JsonBuilderError(ref err) => fmt::Display::fmt(err, f)
        }
    }
}

// Utilities

fn format_query_string(options: &mut HashMap<&'static str, String>) -> String {
    let mut st = String::new();
    if options.is_empty() {
        return st;
    }
    st.push_str("?");
    for (k, v) in options.drain() {
        st.push_str(k);
        st.push_str("=");
        st.push_str(v.as_str());
        st.push_str("&");
    }
    st.pop();
    st
}

// The client

fn do_req<'a>(rb:   hyper::client::RequestBuilder<'a, &str>,
              body: Option<&'a str>) -> Result<Json, EsError> {
    info!("Params (body={:?})", body.unwrap());
    let mut result = match body {
        Some(json_str) => rb.body(json_str).send(),
        None           => rb.send()
    };
    info!("Result: {:?}", result);
    match result {
        Ok(ref mut r) => match Json::from_reader(r) {
            Ok(json) => Ok(json),
            Err(e)   => Err(EsError::from(e))
        },
        Err(e)        => Err(EsError::from(e))
    }
}

pub struct Client {
    host:        String,
    port:        u32,
    http_client: hyper::Client
}

macro_rules! es_op {
    ($n:ident) => {
        fn $n(&mut self, url: &str, body: Option<&Json>) -> Result<Json, EsError> {
            info!("Doing $n on {} with {:?}", url, body);
            match body {
                Some(json) => {
                    let json_string = json::encode(json).unwrap();
                    do_req(self.http_client.$n(url), Some(json_string.as_str()))
                },
                None => {
                    do_req(self.http_client.$n(url), None)
                }
            }
        }
    }
}

impl Client {
    pub fn new(host: String, port: u32) -> Client {
        Client {
            host:        host,
            port:        port,
            http_client: hyper::Client::new()
        }
    }

    fn get_base_url(&self) -> String {
        format!("http://{}:{}/", self.host, self.port)
    }

    es_op!(get);
    es_op!(post);
    es_op!(put);

    pub fn version(&mut self) -> Result<String, EsError> {
        let url = self.get_base_url();
        let json = try!(self.get(url.as_str(), None));
        match json.find_path(&["version", "number"]) {
            Some(version) => match version.as_string() {
                Some(string) => Ok(string.to_string()),
                None         => Err(EsError::EsError(format!("Cannot find version number in: {:?}",
                                                             json)))
            },
            None          => Err(EsError::EsError(format!("Cannot find version number in {:?}",
                                                          json)))
        }
    }

    pub fn index<'a>(&'a mut self, index: &'a str, doc_type: &'a str) -> IndexOperation {
        IndexOperation::new(self, index, doc_type)
    }
}

// Specific operations

type Options = HashMap<&'static str, String>;

macro_rules! add_option {
    ($n:ident, $e:expr, $t:ident) => (
        pub fn $n<T: ToString>(&'a mut self, val: &T) -> &'a mut $t {
            self.options.insert($e, val.to_string());
            self
        }
    )
}

pub struct IndexOperation<'a> {
    client:   &'a mut Client,
    index:    &'a str,
    doc_type: &'a str,
    id:       Option<&'a str>,
    options:  Options,
    document: Option<Json>
}

impl<'a> IndexOperation<'a> {
    fn new(client: &'a mut Client, index: &'a str, doc_type: &'a str) -> IndexOperation<'a> {
        IndexOperation {
            client:   client,
            index:    index,
            doc_type: doc_type,
            id:       None,
            options:  HashMap::<&'static str, String>::new(),
            document: None
        }
    }

    pub fn with_doc<T: ToJson>(&'a mut self, doc: &T) -> &'a mut IndexOperation {
        self.document = Some(doc.to_json());
        self
    }

    pub fn with_id(&'a mut self, id: &'a str) -> &'a mut IndexOperation {
        self.id = Some(id);
        self
    }

    add_option!(with_ttl, "ttl", IndexOperation);

    pub fn send(&'a mut self) -> Result<Json, EsError> {
        match self.id {
            Some(id) => {
                let url = format!("{}{}/{}/{}{}",
                                  self.client.get_base_url(),
                                  self.index,
                                  self.doc_type,
                                  id,
                                  format_query_string(&mut self.options));
                self.client.put(url.as_str(), match self.document {
                    Some(ref doc) => Some(doc),
                    None          => None
                })
            },
            None    => {
                let url = format!("{}{}/{}{}",
                                  self.client.get_base_url(),
                                  self.index,
                                  self.doc_type,
                                  format_query_string(&mut self.options));
                self.client.post(url.as_str(), match self.document {
                    Some(ref doc) => Some(doc),
                    None          => None
                })
            }
        }
    }
}

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

    use super::Client;

    use std::collections::BTreeMap;

    use rustc_serialize::json;
    use rustc_serialize::json::{Json, ToJson};

    // test setup

    fn make_client() -> Client {
        Client::new("localhost".to_string(), 9200)
    }

    struct TestDocument {
        str_field: String
    }

    impl ToJson for TestDocument {
        fn to_json(&self) -> Json {
            let mut d = BTreeMap::new();
            d.insert("str_field".to_string(), self.str_field.to_json());

            Json::Object(d)
        }
    }

    fn make_doc() -> TestDocument {
        TestDocument {
            str_field: "I am a test".to_string()
        }
    }

    // tests

    #[test]
    fn it_works() {
        let mut client = make_client();
        assert_eq!(client.version().unwrap(), "1.3.2");
    }

    #[test]
    fn test_indexing() {
        env_logger::init().unwrap();

        let mut client = make_client();
        let mut indexer = client.index("test_idx", "test_type");
        let doc = make_doc();
        let result = indexer.with_doc(&doc).with_ttl(&927500).send();
        info!("TEST RESULT: {:?}", result);
        assert_eq!(json::encode(&result.unwrap()).unwrap(), "");
    }
}
<|endoftext|>


<commit_before><commit_msg>Clean up uneeded import<commit_after><|endoftext|>


<commit_before><commit_msg>Removed the github "fork me" ribbon from API doc<commit_after><|endoftext|>


<commit_before><commit_msg>fix error handling<commit_after><|endoftext|>


<commit_before><commit_msg>Fix clippy warnings<commit_after><|endoftext|>


<commit_before><commit_msg>Reword intro to reborrow.<commit_after><|endoftext|>


<commit_before><commit_msg>Update to rust master<commit_after><|endoftext|>


<commit_before><commit_msg>Implement traits for DOM visitor API<commit_after><|endoftext|>


<commit_before><commit_msg>implemented Wait for SteadyTimeSource<commit_after><|endoftext|>


<commit_before><commit_msg>Implement `Borrow`, `AsRef`.<commit_after><|endoftext|>


<commit_before><commit_msg>Use an EncodingKey that actually matches the header.<commit_after><|endoftext|>


<commit_before><commit_msg>Add getter for `rec_count` to `Device`<commit_after><|endoftext|>


<commit_before><commit_msg>Add handlers for some more error cases, add documentation<commit_after><|endoftext|>


<commit_before><commit_msg>Append newline when writing object<commit_after><|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};

pub trait Endec {
    type T;

    fn encoded_len(value: &Self::T) -> usize;

    fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize>;
    fn decode(src: &mut Read) -> io::Result<Self::T>;
}

impl Endec for u16 {
    type T = u16;

    fn encoded_len(value: &Self::T) -> usize {
        2
    }

    fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize> {
        let mut buf = [0u8; 2];
        buf[0] = (value >> 8 & 0xffu8 as u16) as u8;
        buf[1] = (value & 0xffu8 as u16) as u8;

        assert_eq!(dst.write(&buf).is_ok(), true);
        Ok(2)
    }

    fn decode(src: &mut Read) -> io::Result<Self::T> {
        let mut buf = [0u8; 2];
        assert_eq!(src.read(&mut buf).is_ok(), true);
        Ok(((buf[0] as u16) << 8 ) | (buf[1] as u16))
    }
}

macro_rules! packets {
    ($proto_name:ident, $($id:expr => $name:ident { $($fname:ident: $fty:ty),* })+) => {
        #[derive(Debug)]
        enum $proto_name {
            $(
                $name { $($fname:$fty),* }
             ),+
        }

        impl Endec for $proto_name {
            type T = $proto_name;

            fn encoded_len(value: &Self::T) -> usize {
                let mut len: usize = 0;

                match value { $(
                    &$proto_name::$name { $($fname),* } => {$(
                        //TODO: try! is not the best thing here
                        len += <$fty as Endec>::encoded_len(&$fname);
                    )*}
                )+}

                len
            }

            fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize> {
                let mut len: usize = 0;

                match value { $(
                    &$proto_name::$name { $($fname),* } => {$(
                        //TODO: try! is not the best thing here
                        len += try!(<$fty as Endec>::encode(&$fname, dst));
                    )*}
                )+}

                Ok(len)
            }

            fn decode(src: &mut Read) -> io::Result<Self::T> {
                let id = 0;

                match id {
                    $(
                        $id => Ok($proto_name::$name {
                                    $(
                                        $fname:try!(<$fty as Endec>::decode(src))
                                    ),*
                                }),
                    )+
                        _ => Err(Error::new(ErrorKind::Other, "oh no!"))
                }
            }
        }
    }
}

macro_rules! protocol {
    ($($proto_name:ident : $header_func:expr => {
        $($id:expr => $name:ident { $($fname:ident: $fty:ty),* })+})+) => {
            $(packets!($proto_name, $($id => $name { $($fname:$fty),* })+);)+
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;
    use std::io::prelude::*;
    use std::io::{Error, ErrorKind};

    protocol! {
        Testproto : |x, y| -> [u8] { [0u8,2] } => {
            0 => Message { a: u16, b: u16 }
            1 => Msg { b: u16 }
        }
        Otherproto: |x, y| -> [u8] { [0u8, 2] } => {
            0 => Message { a: u16 }
        }
    }

    #[test]
    fn test_main() {
        let x:Testproto = Testproto::Message { a: 10, b: 15 };
        let y:Otherproto= Otherproto::Message { a: 10 };
        let mut buf:Vec<u8> = Vec::new();
        Testproto::encode(&x, &mut buf);
        println!("{:?}", buf);
        assert!(Testproto::encoded_len(&x) == 4);
    }
}
<commit_msg>encoding and decoding with multiple custom headers now works<commit_after>use std::io;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};

pub trait Endec {
    type T;

    fn encoded_len(value: &Self::T) -> usize;

    fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize>;
    fn decode(src: &mut Read) -> io::Result<Self::T>;
}

impl Endec for u16 {
    type T = u16;

    fn encoded_len(value: &Self::T) -> usize {
        2
    }

    fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize> {
        let mut buf = [0u8; 2];
        buf[0] = (value >> 8 & 0xffu8 as u16) as u8;
        buf[1] = (value & 0xffu8 as u16) as u8;

        assert_eq!(dst.write(&buf).is_ok(), true);
        Ok(2)
    }

    fn decode(src: &mut Read) -> io::Result<Self::T> {
        let mut buf = [0u8; 2];
        assert_eq!(src.read(&mut buf).is_ok(), true);
        Ok(((buf[0] as u16) << 8 ) | (buf[1] as u16))
    }
}

impl Endec for usize {
    type T = usize;

    fn encoded_len(value: &Self::T) -> usize {
        2
    }

    fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize> {
        let mut buf = [0u8; 2];
        buf[0] = (value >> 8 & 0xffu8 as usize) as u8;
        buf[1] = (value & 0xffu8 as usize) as u8;

        assert_eq!(dst.write(&buf).is_ok(), true);
        Ok(2)
    }

    fn decode(src: &mut Read) -> io::Result<Self::T> {
        let mut buf = [0u8; 2];
        assert_eq!(src.read(&mut buf).is_ok(), true);
        Ok(((buf[0] as usize) << 8 ) | (buf[1] as usize))
    }
}

macro_rules! packets {
    ($proto_name:ident, $header_func:expr, $header_dec_func:expr, $($id:expr => $name:ident { $($fname:ident: $fty:ty),* })+) => {
        #[derive(Debug)]
        enum $proto_name {
            $(
                $name { $($fname:$fty),* }
             ),+
        }

        impl Endec for $proto_name {
            type T = $proto_name;

            fn encoded_len(value: &Self::T) -> usize {
                let mut len: usize = 0;

                match value { $(
                    &$proto_name::$name { $($fname),* } => {$(
                        len += <$fty as Endec>::encoded_len(&$fname);
                    )*}
                )+}

                len
            }

            fn encode(value: &Self::T, dst: &mut Write) -> io::Result<usize> {
                let mut len: usize = 0;

                match value { $(
                    &$proto_name::$name { $($fname),* } => {
                        //TODO: try! is not the best thing here
                        len += try!(dst.write(&$header_func($id, <$proto_name as Endec>::encoded_len(value))));
                        $(len += try!(<$fty as Endec>::encode(&$fname, dst));)*
                    }
                )+}

                Ok(len)
            }

            fn decode(src: &mut Read) -> io::Result<Self::T> {
                let mut id = 0;
                let mut len = 0;
                {
                let (id, len) = $header_dec_func(src);
                }

                match id {
                    $(
                        $id => Ok($proto_name::$name {
                                    $(
                                        $fname:try!(<$fty as Endec>::decode(src))
                                    ),*
                                }),
                    )+
                        _ => Err(Error::new(ErrorKind::Other, "oh no!"))
                }
            }
        }
    }
}

macro_rules! protocol {
    ($($proto_name:ident : $header_func:expr, $header_dec_func:expr => {
        $($id:expr => $name:ident { $($fname:ident: $fty:ty),* })+})+) => {
            $(packets!($proto_name, $header_func, $header_dec_func, $($id => $name { $($fname:$fty),* })+);)+
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;
    use std::io::prelude::*;
    use std::io::{Error, ErrorKind};

    protocol! {
        Testproto : |x, y| -> Vec<u8> {
            let mut buf:Vec<u8>= Vec::new();
            <u16 as Endec>::encode(&x, &mut buf);
            <usize as Endec>::encode(&y, &mut buf);
            buf
        }, |x: &mut Read| -> (u16, usize) {
            let a:u16 = <u16 as Endec>::decode(x).unwrap();
            let b:usize = <usize as Endec>::decode(x).unwrap();
            (a, b)
        } => {
            0 => Message { a: u16, b: u16 }
            1 => Msg { b: u16 }
        }
        Otherproto: |x, y| -> [u8; 2] { [0u8, 2] }, |x: &mut Read| -> (u64, usize) { (0, 6) } => {
            0 => Message { a: u16 }
        }
    }

    #[test]
    fn test_encode() {
        let x:Testproto = Testproto::Message { a: 10, b: 15 };
        //let y:Otherproto= Otherproto::Message { a: 10 };
        let mut buf:Vec<u8> = Vec::new();
        Testproto::encode(&x, &mut buf);
        println!("{:?}", buf);
        assert!(Testproto::encoded_len(&x) == 4);
    }

    #[test]
    fn test_decode() {
        let buf:Vec<u8> = vec![0u8, 0, 0, 4, 0, 10, 0, 15];
        let msg = Testproto::decode(&mut &buf[..]);
        println!("{:?}", msg);
        //assert!(Testproto::Message { a: 10, b: 15 } == msg);
    }

}
<|endoftext|>


<commit_before><commit_msg>Update crate attributes with nightly.<commit_after><|endoftext|>


<commit_before><commit_msg>Allow box syntax<commit_after><|endoftext|>


<commit_before>
extern crate ws;

mod message;
mod user;
mod twitch;
mod kraken;
mod irc;
mod channel;
mod rfc;

macro_rules! get_arg {
	($e:expr) => (env::args().nth($e).unwrap_or(String::from("")));
}

#[cfg(test)]
mod tests {

	use std::env;
	use client::TwitchClient;
	use client::Event;

	#[test]
	fn it_works() {

		let client: TwitchClient;
		let mut user = String::from("");
		let mut pass = String::from("");
		let mut channel = String::from("");
		let mut logging = false;

		for (index, arg) in env::args().enumerate() {
			if index == 0 { continue; }

			match arg.as_ref() {
				"-u" => user = get_arg!(index + 1),
				"-p" => pass = get_arg!(index + 1),
				"-c" => channel = get_arg!(index + 1),
				"-l" => logging = true,
				_ => panic!("Unexpected argument passed: {}", arg),
			}
		}

		client = TwitchClient::from(user, pass, channel, logging);

		client.connect();

		loop {
			match client.recv_event() {
				Ok(Event::MessageReceived(m)) => {

				}
				Err(err) => println!("Error {:?}", err),
			}
		}
	}
}
<commit_msg>Added reference to new depends and new modules<commit_after>
extern crate ws;
extern crate url;
extern crate regex;

mod message;
mod user;
mod client;
mod kraken;
mod irc;
mod channel;
mod rfc;
mod subscriber;

macro_rules! get_arg {
	($e:expr) => (env::args().nth($e).unwrap_or(String::from("")));
}

#[cfg(test)]
mod tests {

	use std::env;
	use client::TwitchClient;
	use client::Event;

	#[test]
	fn it_works() {

		let client: TwitchClient;
		let mut user = String::from("");
		let mut pass = String::from("");
		let mut channel = String::from("");
		let mut logging = false;

		for (index, arg) in env::args().enumerate() {
			if index == 0 { continue; }

			match arg.as_ref() {
				"-u" => user = get_arg!(index + 1),
				"-p" => pass = get_arg!(index + 1),
				"-c" => channel = get_arg!(index + 1),
				"-l" => logging = true,
				_ => panic!("Unexpected argument passed: {}", arg),
			}
		}

		client = TwitchClient::from(user, pass, channel, logging);

		client.connect();

		loop {
			match client.recv_event() {
				Ok(Event::MessageReceived(m)) => {

				}
				Err(err) => println!("Error {:?}", err),
			}
		}
	}
}
<|endoftext|>