<commit_before>use cocoa::base::{id, nil};
use cocoa::foundation::{NSString, NSUInteger};
use objc::runtime::YES;
use sys::{MTLCopyAllDevices, MTLCreateSystemDefaultDevice, MTLDevice};
use std::borrow::Cow;
use std::convert::{AsRef, From};
use std::error::Error;
use std::ffi::CStr;
use std::fmt::{self, Display, Formatter};
use std::path::Path;
use {CommandQueue, CommandQueueError, CompileOptions, FromRaw, FromRawError, Library,
     LibraryError, Size};

pub struct Device(id);

impl Device {
    pub fn system_default_device() -> Result<Self, DeviceError> {
        let device = unsafe { MTLCreateSystemDefaultDevice() };
        if device != nil { Ok(Device(device)) } else { Err(DeviceError::ConstructionFailed) }
    }

    #[allow(unused_mut, unused_variables, unreachable_code)]
    pub fn enumerate_all_system_devices() -> Vec<Result<Self, DeviceError>> {
        let all_devices = unsafe { MTLCopyAllDevices() };
        let mut devices_vec = vec![];

        unimplemented!();

        devices_vec
    }

    pub fn new_command_queue(&mut self) -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe { self.0.newCommandQueue() };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    pub fn new_command_queue_with_max_buffer_count(&mut self, max_command_buffer_count: usize)
                                                   -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe {
            self.0.newCommandQueueWithMaxCommandBufferCount(max_command_buffer_count as NSUInteger)
        };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    #[allow(unused_variables)]
    pub fn new_default_library(&mut self) -> Result<Library, LibraryError> {
        unsafe {
            let library = self.0.newDefaultLibrary();
            Ok(try!(FromRaw::from_raw(library)))
        }
    }

    #[allow(unused_variables)]
    pub fn new_library_with_file<P: AsRef<Path>>(&mut self, file_path: P)
                                                 -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn new_library_with_source<S: AsRef<str>>(&mut self, source: S,
                                                  compile_options: &CompileOptions)
                                                  -> Result<Library, LibraryError> {
        unsafe {
            let source = NSString::alloc(nil).init_str(source.as_ref());
            let options = compile_options.mtl_compile_options();
            let error = nil;
            let library = self.0.newLibraryWithSource_options_error(source, options, error);
            if error != nil {
                // Todo(George): Should use the `error` variable to get more info
                Err(LibraryError::SourceError)
            } else {
                Ok(try!(FromRaw::from_raw(library)))
            }
        }
    }

    #[allow(unused_variables)]
    // Todo(George): `data` parameter should be of the correct type
    pub fn new_library_with_data(&mut self, data: ()) -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn is_depth24_stencil8_pixel_format_supported(&self) -> bool {
        unsafe { self.0.depth24Stencil8PixelFormatSupported() == YES }
    }

    pub fn is_headless(&self) -> bool {
        unsafe { self.0.headless() == YES }
    }

    pub fn is_low_power(&self) -> bool {
        unsafe { self.0.lowPower() == YES }
    }

    pub fn max_threads_per_group(&self) -> Size {
        unsafe { self.0.maxThreadsPerGroup().into() }
    }

    pub fn name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn supports_texture_sample_count(&self, sample_count: usize) -> bool {
        unsafe { self.0.supportsTextureSampleCount(sample_count as NSUInteger) == YES }
    }
}

impl_from_into_raw!(Device, "MTLDevice");

/// Internal utility function to get a Device's id without consuming it.
/// Not exported publicly from this crate.
#[doc(hidden)]
pub unsafe fn _device_get_raw(device: &Device) -> id {
    device.0
}

#[derive(Clone, Debug)]
pub enum DeviceError {
    ConstructionFailed,
    RawError(FromRawError)
}

impl From<FromRawError> for DeviceError {
    fn from(error: FromRawError) -> Self {
        DeviceError::RawError(error)
    }
}

impl Display for DeviceError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let descr = match *self {
            DeviceError::ConstructionFailed => "DeviceError::ConstructionFailed",
            DeviceError::RawError(_) => "DeviceError::ConstructionFailed",
        };
        write!(f, "{}", descr)
    }
}

impl Error for DeviceError {
    fn description(&self) -> &str {
        match *self {
            DeviceError::ConstructionFailed => {
                "Could not create a default device. Please ensure that you are using at least OSX \
                 10.11 or iOS 8.0"
            }
            DeviceError::RawError(_) => "There was an error with the device pointer",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &DeviceError::ConstructionFailed => None,
            &DeviceError::RawError(ref raw_err) => Some(raw_err),
        }
    }
}
<commit_msg>Remove unnecessary allow(unused_variables) annotation on Device::new_default_library<commit_after>use cocoa::base::{id, nil};
use cocoa::foundation::{NSString, NSUInteger};
use objc::runtime::YES;
use sys::{MTLCopyAllDevices, MTLCreateSystemDefaultDevice, MTLDevice};
use std::borrow::Cow;
use std::convert::{AsRef, From};
use std::error::Error;
use std::ffi::CStr;
use std::fmt::{self, Display, Formatter};
use std::path::Path;
use {CommandQueue, CommandQueueError, CompileOptions, FromRaw, FromRawError, Library,
     LibraryError, Size};

pub struct Device(id);

impl Device {
    pub fn system_default_device() -> Result<Self, DeviceError> {
        let device = unsafe { MTLCreateSystemDefaultDevice() };
        if device != nil { Ok(Device(device)) } else { Err(DeviceError::ConstructionFailed) }
    }

    #[allow(unused_mut, unused_variables, unreachable_code)]
    pub fn enumerate_all_system_devices() -> Vec<Result<Self, DeviceError>> {
        let all_devices = unsafe { MTLCopyAllDevices() };
        let mut devices_vec = vec![];

        unimplemented!();

        devices_vec
    }

    pub fn new_command_queue(&mut self) -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe { self.0.newCommandQueue() };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    pub fn new_command_queue_with_max_buffer_count(&mut self, max_command_buffer_count: usize)
                                                   -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe {
            self.0.newCommandQueueWithMaxCommandBufferCount(max_command_buffer_count as NSUInteger)
        };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    pub fn new_default_library(&mut self) -> Result<Library, LibraryError> {
        unsafe {
            let library = self.0.newDefaultLibrary();
            Ok(try!(FromRaw::from_raw(library)))
        }
    }

    #[allow(unused_variables)]
    pub fn new_library_with_file<P: AsRef<Path>>(&mut self, file_path: P)
                                                 -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn new_library_with_source<S: AsRef<str>>(&mut self, source: S,
                                                  compile_options: &CompileOptions)
                                                  -> Result<Library, LibraryError> {
        unsafe {
            let source = NSString::alloc(nil).init_str(source.as_ref());
            let options = compile_options.mtl_compile_options();
            let error = nil;
            let library = self.0.newLibraryWithSource_options_error(source, options, error);
            if error != nil {
                // Todo(George): Should use the `error` variable to get more info
                Err(LibraryError::SourceError)
            } else {
                Ok(try!(FromRaw::from_raw(library)))
            }
        }
    }

    #[allow(unused_variables)]
    // Todo(George): `data` parameter should be of the correct type
    pub fn new_library_with_data(&mut self, data: ()) -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn is_depth24_stencil8_pixel_format_supported(&self) -> bool {
        unsafe { self.0.depth24Stencil8PixelFormatSupported() == YES }
    }

    pub fn is_headless(&self) -> bool {
        unsafe { self.0.headless() == YES }
    }

    pub fn is_low_power(&self) -> bool {
        unsafe { self.0.lowPower() == YES }
    }

    pub fn max_threads_per_group(&self) -> Size {
        unsafe { self.0.maxThreadsPerGroup().into() }
    }

    pub fn name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn supports_texture_sample_count(&self, sample_count: usize) -> bool {
        unsafe { self.0.supportsTextureSampleCount(sample_count as NSUInteger) == YES }
    }
}

impl_from_into_raw!(Device, "MTLDevice");

/// Internal utility function to get a Device's id without consuming it.
/// Not exported publicly from this crate.
#[doc(hidden)]
pub unsafe fn _device_get_raw(device: &Device) -> id {
    device.0
}

#[derive(Clone, Debug)]
pub enum DeviceError {
    ConstructionFailed,
    RawError(FromRawError)
}

impl From<FromRawError> for DeviceError {
    fn from(error: FromRawError) -> Self {
        DeviceError::RawError(error)
    }
}

impl Display for DeviceError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let descr = match *self {
            DeviceError::ConstructionFailed => "DeviceError::ConstructionFailed",
            DeviceError::RawError(_) => "DeviceError::ConstructionFailed",
        };
        write!(f, "{}", descr)
    }
}

impl Error for DeviceError {
    fn description(&self) -> &str {
        match *self {
            DeviceError::ConstructionFailed => {
                "Could not create a default device. Please ensure that you are using at least OSX \
                 10.11 or iOS 8.0"
            }
            DeviceError::RawError(_) => "There was an error with the device pointer",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &DeviceError::ConstructionFailed => None,
            &DeviceError::RawError(ref raw_err) => Some(raw_err),
        }
    }
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, Compilation, CompilerCalls, RustcDefaultCalls};
use rustc::session::{config, CompileIncomplete, Session};
use rustc::session::config::{ErrorOutputType, Input};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        Self {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType,
    ) -> Compilation {
        self.default
            .early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry,
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default
            .no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(
        &mut self,
        matches: &getopts::Matches,
        sess: &Session,
        crate_stores: &rustc::middle::cstore::CrateStore,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
    ) -> Compilation {
        self.default
            .late_callback(matches, sess, crate_stores, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(
                        state.session,
                        state
                            .krate
                            .as_ref()
                            .expect(
                                "at this compilation stage \
                                 the crate must be parsed",
                            )
                            .span,
                    );
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry {
                        early_lint_passes,
                        late_lint_passes,
                        lint_groups,
                        llvm_passes,
                        attributes,
                        ..
                    } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    use std::env;

    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    let sys_root = option_env!("SYSROOT")
        .map(String::from)
        .or_else(|| std::env::var("SYSROOT").ok())
        .or_else(|| {
            let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
            let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
            home.and_then(|home| toolchain.map(|toolchain| format!("{}/toolchains/{}", home, toolchain)))
        })
        .or_else(|| {
            Command::new("rustc")
                .arg("--print")
                .arg("sysroot")
                .output()
                .ok()
                .and_then(|out| String::from_utf8(out.stdout).ok())
                .map(|s| s.trim().to_owned())
        })
        .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");

    rustc_driver::in_rustc_thread(|| {
        // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
        // We're invoking the compiler programmatically, so we ignore this/
        let mut orig_args: Vec<String> = env::args().collect();
        if orig_args.len() <= 1 {
            std::process::exit(1);
        }
        if orig_args[1] == "rustc" {
            // we still want to be able to invoke it normally though
            orig_args.remove(1);
        }
        // this conditional check for the --sysroot flag is there so users can call
        // `clippy_driver` directly
        // without having to pass --sysroot or anything
        let mut args: Vec<String> = if orig_args.iter().any(|s| s == "--sysroot") {
            orig_args.clone()
        } else {
            orig_args
                .clone()
                .into_iter()
                .chain(Some("--sysroot".to_owned()))
                .chain(Some(sys_root))
                .collect()
        };

        // this check ensures that dependencies are built but not linted and the final
        // crate is
        // linted but not built
        let clippy_enabled = env::var("CLIPPY_TESTS")
            .ok()
            .map_or(false, |val| val == "true")
            || orig_args.iter().any(|s| s == "--emit=metadata");

        if clippy_enabled {
            args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
        }

        let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
        if let Err(CompileIncomplete::Errored(_)) = result {
            std::process::exit(1);
        }
    }).expect("rustc_thread failed");
}
<commit_msg>Use rustc_driver::run (fixes #2303)<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, Compilation, CompilerCalls, RustcDefaultCalls};
use rustc::session::{config, Session};
use rustc::session::config::{ErrorOutputType, Input};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        Self {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType,
    ) -> Compilation {
        self.default
            .early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry,
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default
            .no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(
        &mut self,
        matches: &getopts::Matches,
        sess: &Session,
        crate_stores: &rustc::middle::cstore::CrateStore,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
    ) -> Compilation {
        self.default
            .late_callback(matches, sess, crate_stores, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(
                        state.session,
                        state
                            .krate
                            .as_ref()
                            .expect(
                                "at this compilation stage \
                                 the crate must be parsed",
                            )
                            .span,
                    );
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry {
                        early_lint_passes,
                        late_lint_passes,
                        lint_groups,
                        llvm_passes,
                        attributes,
                        ..
                    } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    use std::env;

    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    let sys_root = option_env!("SYSROOT")
        .map(String::from)
        .or_else(|| std::env::var("SYSROOT").ok())
        .or_else(|| {
            let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
            let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
            home.and_then(|home| toolchain.map(|toolchain| format!("{}/toolchains/{}", home, toolchain)))
        })
        .or_else(|| {
            Command::new("rustc")
                .arg("--print")
                .arg("sysroot")
                .output()
                .ok()
                .and_then(|out| String::from_utf8(out.stdout).ok())
                .map(|s| s.trim().to_owned())
        })
        .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");

    // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
    // We're invoking the compiler programmatically, so we ignore this/
    let mut orig_args: Vec<String> = env::args().collect();
    if orig_args.len() <= 1 {
        std::process::exit(1);
    }
    if orig_args[1] == "rustc" {
        // we still want to be able to invoke it normally though
        orig_args.remove(1);
    }
    // this conditional check for the --sysroot flag is there so users can call
    // `clippy_driver` directly
    // without having to pass --sysroot or anything
    let mut args: Vec<String> = if orig_args.iter().any(|s| s == "--sysroot") {
        orig_args.clone()
    } else {
        orig_args
            .clone()
            .into_iter()
            .chain(Some("--sysroot".to_owned()))
            .chain(Some(sys_root))
            .collect()
    };

    // this check ensures that dependencies are built but not linted and the final
    // crate is
    // linted but not built
    let clippy_enabled = env::var("CLIPPY_TESTS")
        .ok()
        .map_or(false, |val| val == "true")
        || orig_args.iter().any(|s| s == "--emit=metadata");

    if clippy_enabled {
        args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
    }

    let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
    rustc_driver::run(move || {
        rustc_driver::run_compiler(&args, &mut ccc, None, None)
    });
}
<|endoftext|>


<commit_before>use bit_vec::BitVec;
use std::slice::Iter;
use lfsr;
use lfsr::LFSR;

#[derive(PartialEq, Debug)]
pub struct GaloisLFSR {
    state: BitVec,
    mask: BitVec,
}

impl GaloisLFSR {
    pub fn from_iter(iter: Iter<usize>) -> Self {
        let &len = iter.clone().max().unwrap();

        let state = BitVec::from_elem(len, true);
        let mut mask = BitVec::from_elem(len, false);

        for &t in iter {
            if t < len {
                // Set the _counterpart_ mask index
                mask.set(len - t, true);
            }
        }
        mask.set(0, true);

        GaloisLFSR { state: state, mask: mask, }
    }

    fn shift(&mut self) {
        lfsr::shift(&mut self.state);
    }

    fn feedback(&mut self) {
        for (i, mb) in self.mask.iter().enumerate() {
            let sb = self.state[i];
            self.state.set(i, mb ^ sb);
        }
    }

    pub fn iter(&mut self) -> lfsr::Iter<GaloisLFSR> {
        lfsr::Iter { lfsr: self }
    }
}

impl LFSR for GaloisLFSR {
    fn output(&self) -> bool {
        let len = self.state.len();
        self.state[len - 1]
    }

    fn step(&mut self) {
        let output = self.output();

        self.shift();

        if output {
            self.feedback();
        }
    }
}

impl IntoIterator for GaloisLFSR {
    type Item = bool;
    type IntoIter = lfsr::IntoIter<GaloisLFSR>;

    fn into_iter(self) -> Self::IntoIter {
        lfsr::IntoIter { lfsr: self }
    }
}

impl<'a> IntoIterator for &'a mut GaloisLFSR {
    type Item = bool;
    type IntoIter = lfsr::Iter<'a, GaloisLFSR>;

    fn into_iter(self) -> Self::IntoIter {
        lfsr::Iter { lfsr: self }
    }
}
<commit_msg>Remove extra import<commit_after>use bit_vec::BitVec;
use std::slice::Iter;
use lfsr;

#[derive(PartialEq, Debug)]
pub struct GaloisLFSR {
    state: BitVec,
    mask: BitVec,
}

impl GaloisLFSR {
    pub fn from_iter(iter: Iter<usize>) -> Self {
        let &len = iter.clone().max().unwrap();

        let state = BitVec::from_elem(len, true);
        let mut mask = BitVec::from_elem(len, false);

        for &t in iter {
            if t < len {
                // Set the _counterpart_ mask index
                mask.set(len - t, true);
            }
        }
        mask.set(0, true);

        GaloisLFSR { state: state, mask: mask, }
    }

    fn shift(&mut self) {
        lfsr::shift(&mut self.state);
    }

    fn feedback(&mut self) {
        for (i, mb) in self.mask.iter().enumerate() {
            let sb = self.state[i];
            self.state.set(i, mb ^ sb);
        }
    }

    pub fn iter(&mut self) -> lfsr::Iter<GaloisLFSR> {
        lfsr::Iter { lfsr: self }
    }
}

impl lfsr::LFSR for GaloisLFSR {
    fn output(&self) -> bool {
        let len = self.state.len();
        self.state[len - 1]
    }

    fn step(&mut self) {
        let output = self.output();

        self.shift();

        if output {
            self.feedback();
        }
    }
}

impl IntoIterator for GaloisLFSR {
    type Item = bool;
    type IntoIter = lfsr::IntoIter<GaloisLFSR>;

    fn into_iter(self) -> Self::IntoIter {
        lfsr::IntoIter { lfsr: self }
    }
}

impl<'a> IntoIterator for &'a mut GaloisLFSR {
    type Item = bool;
    type IntoIter = lfsr::Iter<'a, GaloisLFSR>;

    fn into_iter(self) -> Self::IntoIter {
        lfsr::Iter { lfsr: self }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(maud_macros)]

extern crate maud;

#[test]
fn literals() {
    let s = html!("du\tcks" -23 3.14 '\n' "geese").to_string();
    assert_eq!(s, "du\tcks-233.14\ngeese");
}

#[test]
fn escaping() {
    let s = html!("<flim&flam>").to_string();
    assert_eq!(s, "<flim&flam>");
}

#[test]
fn semicolons() {
    let s = html! {
        "one";
        "two";
        "three";
        ;;;;;;;;;;;;;;;;;;;;;;;;
        "four";
    }.to_string();
    assert_eq!(s, "onetwothreefour");
}

#[test]
fn blocks() {
    let s = html! {
        "hello"
        {
            " ducks" " geese"
        }
        " swans"
    }.to_string();
    assert_eq!(s, "hello ducks geese swans");
}

mod elements {
    #[test]
    fn simple() {
        let s = html! {
            p { b { "pickle" } "barrel" i { "kumquat" } }
        }.to_string();
        assert_eq!(s, "
picklebarrelkumquat
");
    }

    #[test]
    fn nesting() {
        let s = html!(html body div p sup "butts").to_string();
        assert_eq!(s, "

butts

");
    }

    #[test]
    fn empty() {
        let s = html!("pinkie" br/ "pie").to_string();
        assert_eq!(s, "pinkie
pie");
    }

    #[test]
    fn attributes() {
        let s = html! {
            link rel="stylesheet" href="styles.css"/
            section id="midriff" {
                p class="hotpink" "Hello!"
            }
        }.to_string();
        assert_eq!(s, concat!(
                r#"<link rel="stylesheet" href="styles.css">"#,
                r#"

Hello!

"#));
    }

    #[test]
    fn empty_attributes() {
        let s = html! { div readonly? input type="checkbox" checked? / }.to_string();
        assert_eq!(s, r#"
<input type="checkbox" checked>
"#);
    }
}

mod splices {
    #[test]
    fn literals() {
        let s = html! { $"<pinkie>" }.to_string();
        assert_eq!(s, "<pinkie>");
    }

    #[test]
    fn raw_literals() {
        let s = html! { $$"<pinkie>" }.to_string();
        assert_eq!(s, "<pinkie>");
    }

    #[test]
    fn blocks() {
        let s = html! {
            ${
                let mut result = 1i32;
                for i in 2..11 {
                    result *= i;
                }
                result
            }
        }.to_string();
        assert_eq!(s, "3628800");
    }

    #[test]
    fn attributes() {
        let rocks = true;
        let s = html! {
            input checked?=true /
            input checked?=false /
            input checked?=rocks /
            input checked?=(!rocks) /
        }.to_string();
        assert_eq!(s, concat!(
                r#"<input checked>"#,
                r#"<input>"#,
                r#"<input checked>"#,
                r#"<input>"#));
    }

    static BEST_PONY: &'static str = "Pinkie Pie";

    #[test]
    fn statics() {
        let s = html! { $BEST_PONY }.to_string();
        assert_eq!(s, "Pinkie Pie");
    }

    #[test]
    fn closures() {
        let best_pony = "Pinkie Pie";
        let s = html! { $best_pony }.to_string();
        assert_eq!(s, "Pinkie Pie");
    }

    /// An example struct, for testing purposes only
    struct Creature {
        name: &'static str,
        /// Rating out of 10, where:
        /// * 0 is a naked mole rat with dysentery
        /// * 10 is Sweetie Belle in a milkshake
        adorableness: u8,
    }

    impl Creature {
        fn repugnance(&self) -> u8 {
            10 - self.adorableness
        }
    }

    #[test]
    fn structs() {
        let pinkie = Creature {
            name: "Pinkie Pie",
            adorableness: 9,
        };
        let s = html! {
            "Name: " $pinkie.name ". Rating: " $pinkie.repugnance()
        }.to_string();
        assert_eq!(s, "Name: Pinkie Pie. Rating: 1");
    }

    // FIXME: See <https://github.com/rust-lang/rust/issues/16617>
    // for why this is commented out
    /*
    #[test]
    fn nested_macro_invocation() {
        let best_pony = "Pinkie Pie";
        let s = html! { $(format!("{}", best_pony)) }.to_string();
        assert_eq!(s, "Pinkie Pie");
    }
    */
}

#[test]
fn issue_1() {
    let markup = html! { "Test" };
    let _ = markup.to_string();
}

mod control {
    #[test]
    fn if_expr() {
        for (number, &name) in (1..4).zip(["one", "two", "three"].iter()) {
            let s = html! {
                $if number == 1 {
                    "one"
                } $else if number == 2 {
                    "two"
                } $else if number == 3 {
                    "three"
                } $else {
                    "oh noes"
                }
            }.to_string();
            assert_eq!(s, name);
        }
    }
}
<commit_msg>Switch from u8 to u32, as per style guidelines<commit_after>#![feature(plugin)]
#![plugin(maud_macros)]

extern crate maud;

#[test]
fn literals() {
    let s = html!("du\tcks" -23 3.14 '\n' "geese").to_string();
    assert_eq!(s, "du\tcks-233.14\ngeese");
}

#[test]
fn escaping() {
    let s = html!("<flim&flam>").to_string();
    assert_eq!(s, "<flim&flam>");
}

#[test]
fn semicolons() {
    let s = html! {
        "one";
        "two";
        "three";
        ;;;;;;;;;;;;;;;;;;;;;;;;
        "four";
    }.to_string();
    assert_eq!(s, "onetwothreefour");
}

#[test]
fn blocks() {
    let s = html! {
        "hello"
        {
            " ducks" " geese"
        }
        " swans"
    }.to_string();
    assert_eq!(s, "hello ducks geese swans");
}

mod elements {
    #[test]
    fn simple() {
        let s = html! {
            p { b { "pickle" } "barrel" i { "kumquat" } }
        }.to_string();
        assert_eq!(s, "
picklebarrelkumquat
");
    }

    #[test]
    fn nesting() {
        let s = html!(html body div p sup "butts").to_string();
        assert_eq!(s, "

butts

");
    }

    #[test]
    fn empty() {
        let s = html!("pinkie" br/ "pie").to_string();
        assert_eq!(s, "pinkie
pie");
    }

    #[test]
    fn attributes() {
        let s = html! {
            link rel="stylesheet" href="styles.css"/
            section id="midriff" {
                p class="hotpink" "Hello!"
            }
        }.to_string();
        assert_eq!(s, concat!(
                r#"<link rel="stylesheet" href="styles.css">"#,
                r#"

Hello!

"#));
    }

    #[test]
    fn empty_attributes() {
        let s = html! { div readonly? input type="checkbox" checked? / }.to_string();
        assert_eq!(s, r#"
<input type="checkbox" checked>
"#);
    }
}

mod splices {
    #[test]
    fn literals() {
        let s = html! { $"<pinkie>" }.to_string();
        assert_eq!(s, "<pinkie>");
    }

    #[test]
    fn raw_literals() {
        let s = html! { $$"<pinkie>" }.to_string();
        assert_eq!(s, "<pinkie>");
    }

    #[test]
    fn blocks() {
        let s = html! {
            ${
                let mut result = 1i32;
                for i in 2..11 {
                    result *= i;
                }
                result
            }
        }.to_string();
        assert_eq!(s, "3628800");
    }

    #[test]
    fn attributes() {
        let rocks = true;
        let s = html! {
            input checked?=true /
            input checked?=false /
            input checked?=rocks /
            input checked?=(!rocks) /
        }.to_string();
        assert_eq!(s, concat!(
                r#"<input checked>"#,
                r#"<input>"#,
                r#"<input checked>"#,
                r#"<input>"#));
    }

    static BEST_PONY: &'static str = "Pinkie Pie";

    #[test]
    fn statics() {
        let s = html! { $BEST_PONY }.to_string();
        assert_eq!(s, "Pinkie Pie");
    }

    #[test]
    fn closures() {
        let best_pony = "Pinkie Pie";
        let s = html! { $best_pony }.to_string();
        assert_eq!(s, "Pinkie Pie");
    }

    /// An example struct, for testing purposes only
    struct Creature {
        name: &'static str,
        /// Rating out of 10, where:
        /// * 0 is a naked mole rat with dysentery
        /// * 10 is Sweetie Belle in a milkshake
        adorableness: u32,
    }

    impl Creature {
        fn repugnance(&self) -> u32 {
            10 - self.adorableness
        }
    }

    #[test]
    fn structs() {
        let pinkie = Creature {
            name: "Pinkie Pie",
            adorableness: 9,
        };
        let s = html! {
            "Name: " $pinkie.name ". Rating: " $pinkie.repugnance()
        }.to_string();
        assert_eq!(s, "Name: Pinkie Pie. Rating: 1");
    }

    // FIXME: See <https://github.com/rust-lang/rust/issues/16617>
    // for why this is commented out
    /*
    #[test]
    fn nested_macro_invocation() {
        let best_pony = "Pinkie Pie";
        let s = html! { $(format!("{}", best_pony)) }.to_string();
        assert_eq!(s, "Pinkie Pie");
    }
    */
}

#[test]
fn issue_1() {
    let markup = html! { "Test" };
    let _ = markup.to_string();
}

mod control {
    #[test]
    fn if_expr() {
        for (number, &name) in (1..4).zip(["one", "two", "three"].iter()) {
            let s = html! {
                $if number == 1 {
                    "one"
                } $else if number == 2 {
                    "two"
                } $else if number == 3 {
                    "three"
                } $else {
                    "oh noes"
                }
            }.to_string();
            assert_eq!(s, name);
        }
    }
}
<|endoftext|>


<commit_before>
use std::fmt;
use std::io::Read;  // Trait providing read_to_string()
use std::env;

use url;
use hyper;
use serde;
use serde_json;

// use Groups;

use ::errors::*;

pub const API_VERSION: u16 = 3;

#[derive(Default, Clone, Copy, Debug)]
pub struct Pagination {
    pub page: u16,
    pub per_page: u16,
}

pub struct GitLab {
    url: url::Url,
    private_token: String,
    pagination: Option<Pagination>,
    client: hyper::Client,
}

// Explicitly implement Debug trait for GitLab so we can hide the token.
impl fmt::Debug for GitLab {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "GitLab {{ scheme: {}, domain: {}, port: {}, private_token: XXXXXXXXXXXXXXXXXXXX, \
                pagination: {:?} }}",
               self.url.scheme(),
               self.url.domain().expect("bad hostname provided"),
               self.url.port().expect("bad port provided"),
               self.pagination)
    }
}

impl GitLab {
    pub fn _new(scheme: &str, domain: &str, port: u16, private_token: &str) -> Result<GitLab> {
        let url_string = format!("{}://{}/api/v{}/", scheme, domain, API_VERSION);
        let mut url = url::Url::parse(&url_string)
            .chain_err(|| format!("failure to parse URL '{}'", url_string))?;
        url.set_port(Some(port)).expect("bad port provided");
        Ok(GitLab {
            url: url,
            private_token: private_token.to_string(),
            pagination: None,
            client: match env::var("HTTP_PROXY") {
                Ok(proxy) => {
                    let proxy: Vec<&str> = proxy.trim_left_matches("http://").split(':').collect();
                    let hostname = proxy[0].to_string();
                    // let port = proxy[1].parse().chain_err(|| format!("failure to set port to {}", port))?;
                    let port = proxy[1].parse().unwrap();

                    hyper::Client::with_http_proxy(hostname, port)
                }
                Err(_) => hyper::Client::new(),
            },
        })
    }

    pub fn new_insecure(domain: &str, private_token: &str) -> Result<GitLab> {
        warn!("Using insecure http:// protocol: Token will be sent in clear!");
        GitLab::_new("http", domain, 80, private_token)
    }

    pub fn new(domain: &str, private_token: &str) -> Result<GitLab> {
        GitLab::_new("https", domain, 443, private_token)
    }

    pub fn port(mut self, port: u16) -> Self {
        self.url.set_port(Some(port)).unwrap();
        self
    }

    pub fn scheme(mut self, scheme: &str) -> Self {
        self.url.set_scheme(scheme).unwrap();
        self
    }

    /// Build a URL used to access GitLab instance, including some parameters.
    ///
    /// # Examples
    ///
    /// Example from GitLab: https://docs.gitlab.com/ce/api/#basic-usage
    ///
    /// ```
    /// use gitlab_api::GitLab;
    ///
    /// let expected_url = "https://gitlab.example.com\
    ///                     /api/v3/groups?order_by=path&private_token=XXXXXXXXXXXXX";
    ///
    /// let gl = GitLab::new("gitlab.example.com", "XXXXXXXXXXXXX").unwrap();
    ///
    /// assert_eq!(gl.build_url("groups?order_by=path").unwrap(), expected_url);
    /// ```
    pub fn build_url(&self, query: &str) -> Result<String> {
        let mut new_url =
            self.url.clone().join(query).chain_err(|| {
                format!("Failure to join query '{}' to url {}",
                        query,
                        self.url.as_str())
            })?;
        new_url.query_pairs_mut().append_pair("private_token", &self.private_token);
        self.pagination.as_ref().map(|pagination| {
            new_url.query_pairs_mut().append_pair("page", &pagination.page.to_string());
            new_url.query_pairs_mut().append_pair("per_page", &pagination.per_page.to_string());
        });

        Ok(new_url.into_string())
    }

    // pub fn attempt_connection(&self) -> Result<hyper::client::Response, hyper::Error> {
    //     let url = self.build_url("version");
    //     // Close connections after each GET.
    //     self.client.get(&url).header(hyper::header::Connection::close()).send()
    // }

    pub fn set_pagination(&mut self, pagination: Pagination) {
        self.pagination = Some(pagination);
    }

    pub fn get<T>(&self, query: &str) -> Result<T>
        where T: serde::Deserialize
    {
        let url = self.build_url(query).chain_err(|| format!("failure to build url for query '{}'", query))?;
        info!("url: {:?}", url);

        // Close connections after each GET.
        let mut res: hyper::client::Response = self.client
            .get(&url)
            .header(hyper::header::Connection::close())
            .send()
            .chain_err(|| format!("cannot send request '{}' to {:?}", query, self))?;
        info!("res.status: {:?}", res.status);
        debug!("res.headers: {:?}", res.headers);
        debug!("res.url: {:?}", res.url);

        let mut body = String::new();
        res.read_to_string(&mut body).chain_err(|| "cannot read response body")?;
        debug!("body:\n{:?}", body);

        // assert_eq!(res.status, hyper::status::StatusCode::Ok);
        if res.status != hyper::status::StatusCode::Ok {
            bail!(format!("status code ({}) not Ok()", res.status));
        }

        serde_json::from_str(body.as_str())
            .chain_err(|| format!("cannot build Rust struct from JSON data: {}", body))
    }

    pub fn version(&self) -> Result<::Version> {
        self.get("version").chain_err(|| "cannot query 'version'")
    }

    pub fn groups(&self) -> ::groups::GroupsLister {
        ::groups::GroupsLister::new(self)
    }

    pub fn projects(&self) -> ::projects::ProjectsLister {
        ::projects::ProjectsLister::new(self)
    }

    pub fn issues(&self) -> ::issues::IssuesLister {
        ::issues::IssuesLister::new(self)
    }

    pub fn merge_requests(&self, project_id: i64) -> ::merge_requests::MergeRequestsLister {
        ::merge_requests::MergeRequestsLister::new(self, project_id)
    }

    // pub fn groups(&mut self, listing: ::groups::Listing) -> Result<Groups, serde_json::Error> {
    //     let query = listing.build_query();
    //     // self.get(&query)
    //     unimplemented!();
    // }

    // pub fn owned_groups(&mut self) -> Result<Groups, serde_json::Error> {
    //     let query = ::groups::owned_groups::Listing::new().build_query();
    //     info!("query: {:?}", query);
    //     self.get(&query)
    // }
}

// #[cfg(test)]
// mod tests {
//
// #[test]
// fn it_works() {
// }
// }
//
<commit_msg>Use error-chain when parsing proxy port instead of unwrapping<commit_after>
use std::fmt;
use std::io::Read;  // Trait providing read_to_string()
use std::env;

use url;
use hyper;
use serde;
use serde_json;

// use Groups;

use ::errors::*;

pub const API_VERSION: u16 = 3;

#[derive(Default, Clone, Copy, Debug)]
pub struct Pagination {
    pub page: u16,
    pub per_page: u16,
}

pub struct GitLab {
    url: url::Url,
    private_token: String,
    pagination: Option<Pagination>,
    client: hyper::Client,
}

// Explicitly implement Debug trait for GitLab so we can hide the token.
impl fmt::Debug for GitLab {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "GitLab {{ scheme: {}, domain: {}, port: {}, private_token: XXXXXXXXXXXXXXXXXXXX, \
                pagination: {:?} }}",
               self.url.scheme(),
               self.url.domain().expect("bad hostname provided"),
               self.url.port().expect("bad port provided"),
               self.pagination)
    }
}

impl GitLab {
    pub fn _new(scheme: &str, domain: &str, port: u16, private_token: &str) -> Result<GitLab> {
        let url_string = format!("{}://{}/api/v{}/", scheme, domain, API_VERSION);
        let mut url = url::Url::parse(&url_string)
            .chain_err(|| format!("failure to parse URL '{}'", url_string))?;
        url.set_port(Some(port)).expect("bad port provided");
        Ok(GitLab {
            url: url,
            private_token: private_token.to_string(),
            pagination: None,
            client: match env::var("HTTP_PROXY") {
                Ok(proxy) => {
                    let proxy: Vec<&str> = proxy.trim_left_matches("http://").split(':').collect();
                    let hostname = proxy[0].to_string();
                    let port = proxy[1].parse().chain_err(|| format!("failure to set port to {}", port))?;

                    hyper::Client::with_http_proxy(hostname, port)
                }
                Err(_) => hyper::Client::new(),
            },
        })
    }

    pub fn new_insecure(domain: &str, private_token: &str) -> Result<GitLab> {
        warn!("Using insecure http:// protocol: Token will be sent in clear!");
        GitLab::_new("http", domain, 80, private_token)
    }

    pub fn new(domain: &str, private_token: &str) -> Result<GitLab> {
        GitLab::_new("https", domain, 443, private_token)
    }

    pub fn port(mut self, port: u16) -> Self {
        self.url.set_port(Some(port)).unwrap();
        self
    }

    pub fn scheme(mut self, scheme: &str) -> Self {
        self.url.set_scheme(scheme).unwrap();
        self
    }

    /// Build a URL used to access GitLab instance, including some parameters.
    ///
    /// # Examples
    ///
    /// Example from GitLab: https://docs.gitlab.com/ce/api/#basic-usage
    ///
    /// ```
    /// use gitlab_api::GitLab;
    ///
    /// let expected_url = "https://gitlab.example.com\
    ///                     /api/v3/groups?order_by=path&private_token=XXXXXXXXXXXXX";
    ///
    /// let gl = GitLab::new("gitlab.example.com", "XXXXXXXXXXXXX").unwrap();
    ///
    /// assert_eq!(gl.build_url("groups?order_by=path").unwrap(), expected_url);
    /// ```
    pub fn build_url(&self, query: &str) -> Result<String> {
        let mut new_url =
            self.url.clone().join(query).chain_err(|| {
                format!("Failure to join query '{}' to url {}",
                        query,
                        self.url.as_str())
            })?;
        new_url.query_pairs_mut().append_pair("private_token", &self.private_token);
        self.pagination.as_ref().map(|pagination| {
            new_url.query_pairs_mut().append_pair("page", &pagination.page.to_string());
            new_url.query_pairs_mut().append_pair("per_page", &pagination.per_page.to_string());
        });

        Ok(new_url.into_string())
    }

    // pub fn attempt_connection(&self) -> Result<hyper::client::Response, hyper::Error> {
    //     let url = self.build_url("version");
    //     // Close connections after each GET.
    //     self.client.get(&url).header(hyper::header::Connection::close()).send()
    // }

    pub fn set_pagination(&mut self, pagination: Pagination) {
        self.pagination = Some(pagination);
    }

    pub fn get<T>(&self, query: &str) -> Result<T>
        where T: serde::Deserialize
    {
        let url = self.build_url(query).chain_err(|| format!("failure to build url for query '{}'", query))?;
        info!("url: {:?}", url);

        // Close connections after each GET.
        let mut res: hyper::client::Response = self.client
            .get(&url)
            .header(hyper::header::Connection::close())
            .send()
            .chain_err(|| format!("cannot send request '{}' to {:?}", query, self))?;
        info!("res.status: {:?}", res.status);
        debug!("res.headers: {:?}", res.headers);
        debug!("res.url: {:?}", res.url);

        let mut body = String::new();
        res.read_to_string(&mut body).chain_err(|| "cannot read response body")?;
        debug!("body:\n{:?}", body);

        // assert_eq!(res.status, hyper::status::StatusCode::Ok);
        if res.status != hyper::status::StatusCode::Ok {
            bail!(format!("status code ({}) not Ok()", res.status));
        }

        serde_json::from_str(body.as_str())
            .chain_err(|| format!("cannot build Rust struct from JSON data: {}", body))
    }

    pub fn version(&self) -> Result<::Version> {
        self.get("version").chain_err(|| "cannot query 'version'")
    }

    pub fn groups(&self) -> ::groups::GroupsLister {
        ::groups::GroupsLister::new(self)
    }

    pub fn projects(&self) -> ::projects::ProjectsLister {
        ::projects::ProjectsLister::new(self)
    }

    pub fn issues(&self) -> ::issues::IssuesLister {
        ::issues::IssuesLister::new(self)
    }

    pub fn merge_requests(&self, project_id: i64) -> ::merge_requests::MergeRequestsLister {
        ::merge_requests::MergeRequestsLister::new(self, project_id)
    }

    // pub fn groups(&mut self, listing: ::groups::Listing) -> Result<Groups, serde_json::Error> {
    //     let query = listing.build_query();
    //     // self.get(&query)
    //     unimplemented!();
    // }

    // pub fn owned_groups(&mut self) -> Result<Groups, serde_json::Error> {
    //     let query = ::groups::owned_groups::Listing::new().build_query();
    //     info!("query: {:?}", query);
    //     self.get(&query)
    // }
}

// #[cfg(test)]
// mod tests {
//
// #[test]
// fn it_works() {
// }
// }
//
<|endoftext|>


<commit_before>use std::io::{Cursor, Error, ErrorKind};
use tokio_codec::{Encoder, Decoder};
use bytes::{Buf, BufMut, BytesMut};
use std::io::Read;
use serializer::*;

use blockchain::Properties;
use tx::TxVariant;
use net::rpc::*;

// 5 MiB limit
const MAX_PAYLOAD_LEN: u32 = 5_242_880;

#[derive(Default)]
pub struct RpcCodec {
    msg_len: u32
}

impl RpcCodec {
    pub fn new() -> RpcCodec {
        RpcCodec::default()
    }
}

impl Encoder for RpcCodec {
    type Item = RpcPayload;
    type Error = Error;

    fn encode(&mut self, pl: Self::Item, buf: &mut BytesMut) -> Result<(), Error> {
        let mut payload = Vec::<u8>::with_capacity(10240);
        payload.push_u32(pl.id);
        if let Some(msg) = pl.msg {
            match msg {
                RpcMsg::Error(err) => {
                    payload.push_u32(err.len() as u32);
                    payload.push_bytes(err.as_bytes());
                },
                RpcMsg::Event(evt) => {
                    payload.push(RpcMsgType::Event as u8);
                    match evt {
                        RpcEvent::Tx(tx) => {
                            payload.push(RpcEventType::TX as u8);
                            tx.encode_with_sigs(&mut payload);
                        },
                        RpcEvent::Block(block) => {
                            payload.push(RpcEventType::BLOCK as u8);
                            block.encode_with_tx(&mut payload);
                        }
                    }
                },
                RpcMsg::Handshake(peer_type) => {
                    payload.push(RpcMsgType::Handshake as u8);
                    payload.push(peer_type as u8);
                },
                RpcMsg::Broadcast(tx) => {
                    payload.push(RpcMsgType::Broadcast as u8);
                    tx.encode_with_sigs(&mut payload);
                },
                RpcMsg::Properties(rpc) => {
                    payload.push(RpcMsgType::Properties as u8);
                    if let Some(props) = rpc.response() {
                        payload.push(RpcVariantType::Res as u8);
                        payload.push_u64(props.height);
                    } else {
                        payload.push(RpcVariantType::Req as u8);
                    }
                },
                RpcMsg::Block(io) => {
                    payload.push(RpcMsgType::Block as u8);
                    match io {
                        RpcVariant::Req(height) => {
                            payload.push(RpcVariantType::Req as u8);
                            payload.push_u64(height);
                        },
                        RpcVariant::Res(block) => {
                            payload.push(RpcVariantType::Res as u8);
                            block.encode_with_tx(&mut payload);
                        }
                    }
                },
                RpcMsg::Balance(io) => {
                    payload.push(RpcMsgType::Balance as u8);
                    match io {
                        RpcVariant::Req(addr) => {
                            payload.push(RpcVariantType::Req as u8);
                            payload.push_pub_key(&addr);
                        },
                        RpcVariant::Res(bal) => {
                            payload.push(RpcVariantType::Res as u8);
                            payload.push_asset(&bal.gold);
                            payload.push_asset(&bal.silver);
                        }
                    }
                },
                RpcMsg::TotalFee(io) => {
                    payload.push(RpcMsgType::Balance as u8);
                    match io {
                        RpcVariant::Req(addr) => {
                            payload.push(RpcVariantType::Req as u8);
                            payload.push_pub_key(&addr);
                        },
                        RpcVariant::Res(bal) => {
                            payload.push(RpcVariantType::Res as u8);
                            payload.push_asset(&bal.gold);
                            payload.push_asset(&bal.silver);
                        }
                    }
                }
            }
        }

        buf.reserve(4 + payload.len());
        buf.put_u32_be(4 + (payload.len() as u32));
        buf.put_slice(&payload);
        debug_assert!((buf.capacity() as u32) < MAX_PAYLOAD_LEN);
        let mut v = Vec::<u8>::with_capacity(buf.len());
        v.extend_from_slice(buf);
        Ok(())
    }
}

impl Decoder for RpcCodec {
    type Item = RpcPayload;
    type Error = Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Error> {
        if self.msg_len == 0 && buf.len() >= 4 {
            let buf = buf.split_to(4);
            self.msg_len = u32_from_buf!(buf);
            if self.msg_len <= 4 {
                return Err(Error::new(ErrorKind::Other, "payload must be >4 bytes"))
            } else if self.msg_len > MAX_PAYLOAD_LEN {
                return Err(Error::new(ErrorKind::Other, format!("payload must be <={} bytes", MAX_PAYLOAD_LEN)))
            }
            self.msg_len -= 4;
        }
        if self.msg_len != 0 && buf.len() >= self.msg_len as usize {
            let msg_len = self.msg_len;
            let split = buf.split_to(msg_len as usize);
            let mut cur = Cursor::new(split.as_ref());
            self.msg_len = 0;

            let id = cur.get_u32_be();
            if msg_len == 4 {
                return Ok(Some(RpcPayload {
                    id,
                    msg: None
                }))
            }

            let msg = match cur.get_u8() {
                t if t == RpcMsgType::Error as u8 => {
                    let len = cur.get_u32_be();
                    if len > MAX_PAYLOAD_LEN {
                        return Err(Error::new(ErrorKind::Other, "error string too large"))
                    }
                    let mut buf = Vec::with_capacity(len as usize);
                    cur.read_exact(&mut buf).map_err(|_| {
                        Error::new(ErrorKind::Other, "failed to read error string")
                    })?;
                    RpcMsg::Error(String::from_utf8_lossy(&buf).into_owned())
                },
                t if t == RpcMsgType::Event as u8 => {
                    let event_type = cur.get_u8();
                    match event_type {
                        t if t == RpcEventType::TX as u8 => {
                            let tx = TxVariant::decode_with_sigs(&mut cur).ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode tx")
                            })?;
                            RpcMsg::Event(RpcEvent::Tx(tx))
                        },
                        t if t == RpcEventType::BLOCK as u8 => {
                            let block = SignedBlock::decode_with_tx(&mut cur).ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode signed block")
                            })?;
                            RpcMsg::Event(RpcEvent::Block(block))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid event type"))
                    }
                },
                t if t == RpcMsgType::Handshake as u8 => {
                    let peer_type = match cur.get_u8() {
                        t if t == PeerType::NODE as u8 => PeerType::NODE,
                        t if t == PeerType::WALLET as u8 => PeerType::WALLET,
                        _ => return Err(Error::new(ErrorKind::Other, "invalid peer type"))
                    };
                    RpcMsg::Handshake(peer_type)
                },
                t if t == RpcMsgType::Broadcast as u8 => {
                    let tx = TxVariant::decode_with_sigs(&mut cur).ok_or_else(|| {
                        Error::new(ErrorKind::Other, "failed to decode broadcast tx")
                    })?;
                    RpcMsg::Broadcast(tx)
                },
                t if t == RpcMsgType::Properties as u8 => {
                    let io = cur.get_u8();
                    match io {
                        t if t == RpcVariantType::Req as u8 => {
                            RpcMsg::Properties(RpcVariant::Req(()))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let height = cur.get_u64_be();
                            RpcMsg::Properties(RpcVariant::Res(Properties { height }))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid io type"))
                    }
                },
                t if t == RpcMsgType::Block as u8 => {
                    let io = cur.get_u8();
                    match io {
                        t if t == RpcVariantType::Req as u8 => {
                            let height = cur.get_u64_be();
                            RpcMsg::Block(RpcVariant::Req(height))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let block = SignedBlock::decode_with_tx(&mut cur).ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode block")
                            })?;
                            RpcMsg::Block(RpcVariant::Res(block))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid io type"))
                    }
                },
                t if t == RpcMsgType::Balance as u8 => {
                    let io = cur.get_u8();
                    match io {
                        t if t == RpcVariantType::Req as u8 => {
                            let addr = cur.take_pub_key().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode public key")
                            })?;
                            RpcMsg::Balance(RpcVariant::Req(addr))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let gold = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode gold asset")
                            })?;
                            let silver = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode silver asset")
                            })?;
                            RpcMsg::Balance(RpcVariant::Res(Balance { gold, silver }))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid io type"))
                    }
                },
                t if t == RpcMsgType::TotalFee as u8 => {
                    let io = cur.get_u8();
                    match io {
                        t if t == RpcVariantType::Req as u8 => {
                            let addr = cur.take_pub_key().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode public key")
                            })?;
                            RpcMsg::TotalFee(RpcVariant::Req(addr))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let gold = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode gold asset")
                            })?;
                            let silver = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode silver asset")
                            })?;
                            RpcMsg::TotalFee(RpcVariant::Res(Balance { gold, silver }))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid io type"))
                    }
                },
                _ => return Err(Error::new(ErrorKind::Other, "invalid msg type"))
            };

            Ok(Some(RpcPayload {
                id,
                msg: Some(msg)
            }))
        } else {
            Ok(None)
        }
    }
}
<commit_msg>Refactor variables from io -> rpc<commit_after>use std::io::{Cursor, Error, ErrorKind};
use tokio_codec::{Encoder, Decoder};
use bytes::{Buf, BufMut, BytesMut};
use std::io::Read;
use serializer::*;

use blockchain::Properties;
use tx::TxVariant;
use net::rpc::*;

// 5 MiB limit
const MAX_PAYLOAD_LEN: u32 = 5_242_880;

#[derive(Default)]
pub struct RpcCodec {
    msg_len: u32
}

impl RpcCodec {
    pub fn new() -> RpcCodec {
        RpcCodec::default()
    }
}

impl Encoder for RpcCodec {
    type Item = RpcPayload;
    type Error = Error;

    fn encode(&mut self, pl: Self::Item, buf: &mut BytesMut) -> Result<(), Error> {
        let mut payload = Vec::<u8>::with_capacity(10240);
        payload.push_u32(pl.id);
        if let Some(msg) = pl.msg {
            match msg {
                RpcMsg::Error(err) => {
                    payload.push_u32(err.len() as u32);
                    payload.push_bytes(err.as_bytes());
                },
                RpcMsg::Event(evt) => {
                    payload.push(RpcMsgType::Event as u8);
                    match evt {
                        RpcEvent::Tx(tx) => {
                            payload.push(RpcEventType::TX as u8);
                            tx.encode_with_sigs(&mut payload);
                        },
                        RpcEvent::Block(block) => {
                            payload.push(RpcEventType::BLOCK as u8);
                            block.encode_with_tx(&mut payload);
                        }
                    }
                },
                RpcMsg::Handshake(peer_type) => {
                    payload.push(RpcMsgType::Handshake as u8);
                    payload.push(peer_type as u8);
                },
                RpcMsg::Broadcast(tx) => {
                    payload.push(RpcMsgType::Broadcast as u8);
                    tx.encode_with_sigs(&mut payload);
                },
                RpcMsg::Properties(rpc) => {
                    payload.push(RpcMsgType::Properties as u8);
                    if let Some(props) = rpc.response() {
                        payload.push(RpcVariantType::Res as u8);
                        payload.push_u64(props.height);
                    } else {
                        payload.push(RpcVariantType::Req as u8);
                    }
                },
                RpcMsg::Block(rpc) => {
                    payload.push(RpcMsgType::Block as u8);
                    match rpc {
                        RpcVariant::Req(height) => {
                            payload.push(RpcVariantType::Req as u8);
                            payload.push_u64(height);
                        },
                        RpcVariant::Res(block) => {
                            payload.push(RpcVariantType::Res as u8);
                            block.encode_with_tx(&mut payload);
                        }
                    }
                },
                RpcMsg::Balance(rpc) => {
                    payload.push(RpcMsgType::Balance as u8);
                    match rpc {
                        RpcVariant::Req(addr) => {
                            payload.push(RpcVariantType::Req as u8);
                            payload.push_pub_key(&addr);
                        },
                        RpcVariant::Res(bal) => {
                            payload.push(RpcVariantType::Res as u8);
                            payload.push_asset(&bal.gold);
                            payload.push_asset(&bal.silver);
                        }
                    }
                },
                RpcMsg::TotalFee(rpc) => {
                    payload.push(RpcMsgType::Balance as u8);
                    match rpc {
                        RpcVariant::Req(addr) => {
                            payload.push(RpcVariantType::Req as u8);
                            payload.push_pub_key(&addr);
                        },
                        RpcVariant::Res(bal) => {
                            payload.push(RpcVariantType::Res as u8);
                            payload.push_asset(&bal.gold);
                            payload.push_asset(&bal.silver);
                        }
                    }
                }
            }
        }

        buf.reserve(4 + payload.len());
        buf.put_u32_be(4 + (payload.len() as u32));
        buf.put_slice(&payload);
        debug_assert!((buf.capacity() as u32) < MAX_PAYLOAD_LEN);
        let mut v = Vec::<u8>::with_capacity(buf.len());
        v.extend_from_slice(buf);
        Ok(())
    }
}

impl Decoder for RpcCodec {
    type Item = RpcPayload;
    type Error = Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Error> {
        if self.msg_len == 0 && buf.len() >= 4 {
            let buf = buf.split_to(4);
            self.msg_len = u32_from_buf!(buf);
            if self.msg_len <= 4 {
                return Err(Error::new(ErrorKind::Other, "payload must be >4 bytes"))
            } else if self.msg_len > MAX_PAYLOAD_LEN {
                return Err(Error::new(ErrorKind::Other, format!("payload must be <={} bytes", MAX_PAYLOAD_LEN)))
            }
            self.msg_len -= 4;
        }
        if self.msg_len != 0 && buf.len() >= self.msg_len as usize {
            let msg_len = self.msg_len;
            let split = buf.split_to(msg_len as usize);
            let mut cur = Cursor::new(split.as_ref());
            self.msg_len = 0;

            let id = cur.get_u32_be();
            if msg_len == 4 {
                return Ok(Some(RpcPayload {
                    id,
                    msg: None
                }))
            }

            let msg = match cur.get_u8() {
                t if t == RpcMsgType::Error as u8 => {
                    let len = cur.get_u32_be();
                    if len > MAX_PAYLOAD_LEN {
                        return Err(Error::new(ErrorKind::Other, "error string too large"))
                    }
                    let mut buf = Vec::with_capacity(len as usize);
                    cur.read_exact(&mut buf).map_err(|_| {
                        Error::new(ErrorKind::Other, "failed to read error string")
                    })?;
                    RpcMsg::Error(String::from_utf8_lossy(&buf).into_owned())
                },
                t if t == RpcMsgType::Event as u8 => {
                    let event_type = cur.get_u8();
                    match event_type {
                        t if t == RpcEventType::TX as u8 => {
                            let tx = TxVariant::decode_with_sigs(&mut cur).ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode tx")
                            })?;
                            RpcMsg::Event(RpcEvent::Tx(tx))
                        },
                        t if t == RpcEventType::BLOCK as u8 => {
                            let block = SignedBlock::decode_with_tx(&mut cur).ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode signed block")
                            })?;
                            RpcMsg::Event(RpcEvent::Block(block))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid event type"))
                    }
                },
                t if t == RpcMsgType::Handshake as u8 => {
                    let peer_type = match cur.get_u8() {
                        t if t == PeerType::NODE as u8 => PeerType::NODE,
                        t if t == PeerType::WALLET as u8 => PeerType::WALLET,
                        _ => return Err(Error::new(ErrorKind::Other, "invalid peer type"))
                    };
                    RpcMsg::Handshake(peer_type)
                },
                t if t == RpcMsgType::Broadcast as u8 => {
                    let tx = TxVariant::decode_with_sigs(&mut cur).ok_or_else(|| {
                        Error::new(ErrorKind::Other, "failed to decode broadcast tx")
                    })?;
                    RpcMsg::Broadcast(tx)
                },
                t if t == RpcMsgType::Properties as u8 => {
                    let rpc = cur.get_u8();
                    match rpc {
                        t if t == RpcVariantType::Req as u8 => {
                            RpcMsg::Properties(RpcVariant::Req(()))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let height = cur.get_u64_be();
                            RpcMsg::Properties(RpcVariant::Res(Properties { height }))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid rpc type"))
                    }
                },
                t if t == RpcMsgType::Block as u8 => {
                    let rpc = cur.get_u8();
                    match rpc {
                        t if t == RpcVariantType::Req as u8 => {
                            let height = cur.get_u64_be();
                            RpcMsg::Block(RpcVariant::Req(height))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let block = SignedBlock::decode_with_tx(&mut cur).ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode block")
                            })?;
                            RpcMsg::Block(RpcVariant::Res(block))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid rpc type"))
                    }
                },
                t if t == RpcMsgType::Balance as u8 => {
                    let rpc = cur.get_u8();
                    match rpc {
                        t if t == RpcVariantType::Req as u8 => {
                            let addr = cur.take_pub_key().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode public key")
                            })?;
                            RpcMsg::Balance(RpcVariant::Req(addr))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let gold = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode gold asset")
                            })?;
                            let silver = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode silver asset")
                            })?;
                            RpcMsg::Balance(RpcVariant::Res(Balance { gold, silver }))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid rpc type"))
                    }
                },
                t if t == RpcMsgType::TotalFee as u8 => {
                    let rpc = cur.get_u8();
                    match rpc {
                        t if t == RpcVariantType::Req as u8 => {
                            let addr = cur.take_pub_key().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode public key")
                            })?;
                            RpcMsg::TotalFee(RpcVariant::Req(addr))
                        },
                        t if t == RpcVariantType::Res as u8 => {
                            let gold = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode gold asset")
                            })?;
                            let silver = cur.take_asset().ok_or_else(|| {
                                Error::new(ErrorKind::Other, "failed to decode silver asset")
                            })?;
                            RpcMsg::TotalFee(RpcVariant::Res(Balance { gold, silver }))
                        },
                        _ => return Err(Error::new(ErrorKind::Other, "invalid rpc type"))
                    }
                },
                _ => return Err(Error::new(ErrorKind::Other, "invalid msg type"))
            };

            Ok(Some(RpcPayload {
                id,
                msg: Some(msg)
            }))
        } else {
            Ok(None)
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::slice::Iter;

use layout::Layout;
use stack::Stack;
use window::Window;
use x::{Connection, WindowId};

#[derive(Clone)]
pub struct GroupBuilder {
    name: String,
    default_layout: String,
}

impl GroupBuilder {
    pub fn new(name: String, default_layout: String) -> GroupBuilder {
        GroupBuilder {
            name,
            default_layout,
        }
    }

    pub fn build(self, connection: Rc<Connection>, layouts: Vec<Box<Layout>>) -> Group {
        let mut layouts_stack = Stack::from(layouts);
        layouts_stack.focus(|layout| layout.name() == &self.default_layout);

        Group {
            name: self.name.clone(),
            connection: connection,
            stack: Stack::new(),
            layouts: layouts_stack,
        }
    }
}

pub struct Group {
    name: String,
    connection: Rc<Connection>,
    stack: Stack<WindowId>,
    layouts: Stack<Box<Layout>>,
}

impl Group {
    pub fn name(&self) -> &str {
        &self.name
    }

    fn layout(&mut self) {
        let (width, height) = self.connection
            .get_window_geometry(&self.connection.root_window_id());

        let focused = self.stack
            .focused()
            .map(|window_id| {
                     GroupWindow {
                         connection: &self.connection,
                         window_id: &window_id,
                     }
                 });

        self.layouts
            .focused()
            .map(|l| l.layout(width, height, focused, self.iter()));
    }

    pub fn activate(&mut self) {
        self.layout();
    }

    pub fn deactivate(&mut self) {
        for window in self.iter() {
            window.unmap();
        }
    }

    pub fn add_window(&mut self, window_id: WindowId) {
        self.stack.push(window_id);
        self.layout();
    }

    pub fn remove_window(&mut self, window_id: &WindowId) -> WindowId {
        let removed = self.stack.remove(|w| w == window_id);
        self.apply_focus_to_window();
        removed
    }

    pub fn contains(&self, window_id: &WindowId) -> bool {
        self.stack.iter().any(|w| w == window_id)
    }

    pub fn focus(&mut self, window_id: &WindowId) {
        self.stack.focus(|id| id == window_id);
        self.apply_focus_to_window();
    }

    fn iter<'a>(&'a self) -> GroupIter<'a> {
        GroupIter {
            connection: &self.connection,
            inner: self.stack.iter(),
        }
    }

    pub fn get_focused<'a>(&'a self) -> Option<GroupWindow<'a>> {
        self.stack
            .focused()
            .map(move |ref id| {
                     GroupWindow {
                         connection: &self.connection,
                         window_id: &id,
                     }
                 })
    }

    fn apply_focus_to_window(&mut self) {
        self.stack
            .focused()
            .map(|window_id| self.connection.focus_window(&window_id));
        self.layout();
    }

    pub fn focus_next(&mut self) {
        self.stack.focus_next();
        self.apply_focus_to_window();
    }

    pub fn focus_previous(&mut self) {
        self.stack.focus_previous();
        self.apply_focus_to_window();
    }

    pub fn shuffle_next(&mut self) {
        self.stack.shuffle_next();
        self.layout();
    }

    pub fn shuffle_previous(&mut self) {
        self.stack.shuffle_previous();
        self.layout();
    }

    pub fn layout_next(&mut self) {
        self.layouts.focus_next();
        self.layout();
    }

    pub fn layout_previous(&mut self) {
        self.layouts.focus_previous();
        self.layout();
    }
}

pub struct GroupIter<'a> {
    connection: &'a Connection,
    inner: Iter<'a, WindowId>,
}

impl<'a> Iterator for GroupIter<'a> {
    type Item = GroupWindow<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner
            .next()
            .map(|window_id| {
                     GroupWindow {
                         connection: self.connection,
                         window_id: window_id,
                     }
                 })
    }
}

impl<'a> ExactSizeIterator for GroupIter<'a> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

pub struct GroupWindow<'a> {
    connection: &'a Connection,
    window_id: &'a WindowId,
}

impl<'a> Window for GroupWindow<'a> {
    fn connection(&self) -> &Connection {
        self.connection
    }

    fn id(&self) -> &WindowId {
        self.window_id
    }
}
<commit_msg>Groups should only perform layout if they're activated.<commit_after>use std::rc::Rc;
use std::slice::Iter;

use layout::Layout;
use stack::Stack;
use window::Window;
use x::{Connection, WindowId};

#[derive(Clone)]
pub struct GroupBuilder {
    name: String,
    default_layout: String,
}

impl GroupBuilder {
    pub fn new(name: String, default_layout: String) -> GroupBuilder {
        GroupBuilder {
            name,
            default_layout,
        }
    }

    pub fn build(self, connection: Rc<Connection>, layouts: Vec<Box<Layout>>) -> Group {
        let mut layouts_stack = Stack::from(layouts);
        layouts_stack.focus(|layout| layout.name() == &self.default_layout);

        Group {
            name: self.name.clone(),
            connection: connection,
            active: false,
            stack: Stack::new(),
            layouts: layouts_stack,
        }
    }
}

pub struct Group {
    name: String,
    connection: Rc<Connection>,
    active: bool,
    stack: Stack<WindowId>,
    layouts: Stack<Box<Layout>>,
}

impl Group {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn activate(&mut self) {
        self.active = true;
        self.perform_layout();
    }

    pub fn deactivate(&mut self) {
        for window in self.iter() {
            window.unmap();
        }
        self.active = false;
    }

    fn perform_layout(&mut self) {
        if !self.active {
            return;
        }

        // Tell X to focus the focused window for this group.
        self.stack
            .focused()
            .map(|window_id| self.connection.focus_window(&window_id));

        // Allow the layout to map and position windows it cares about.
        let (width, height) = self.connection
            .get_window_geometry(&self.connection.root_window_id());
        let focused = self.stack
            .focused()
            .map(|window_id| {
                     GroupWindow {
                         connection: &self.connection,
                         window_id: &window_id,
                     }
                 });
        self.layouts
            .focused()
            .map(|l| l.layout(width, height, focused, self.iter()));
    }

    pub fn add_window(&mut self, window_id: WindowId) {
        self.stack.push(window_id);
        self.perform_layout();
    }

    pub fn remove_window(&mut self, window_id: &WindowId) -> WindowId {
        let removed = self.stack.remove(|w| w == window_id);
        self.perform_layout();
        removed
    }

    pub fn contains(&self, window_id: &WindowId) -> bool {
        self.stack.iter().any(|w| w == window_id)
    }

    pub fn focus(&mut self, window_id: &WindowId) {
        self.stack.focus(|id| id == window_id);
        self.perform_layout();
    }

    fn iter<'a>(&'a self) -> GroupIter<'a> {
        GroupIter {
            connection: &self.connection,
            inner: self.stack.iter(),
        }
    }

    pub fn get_focused<'a>(&'a self) -> Option<GroupWindow<'a>> {
        self.stack
            .focused()
            .map(move |ref id| {
                     GroupWindow {
                         connection: &self.connection,
                         window_id: &id,
                     }
                 })
    }

    pub fn focus_next(&mut self) {
        self.stack.focus_next();
        self.perform_layout();
    }

    pub fn focus_previous(&mut self) {
        self.stack.focus_previous();
        self.perform_layout();
    }

    pub fn shuffle_next(&mut self) {
        self.stack.shuffle_next();
        self.perform_layout();
    }

    pub fn shuffle_previous(&mut self) {
        self.stack.shuffle_previous();
        self.perform_layout();
    }

    pub fn layout_next(&mut self) {
        self.layouts.focus_next();
        self.perform_layout();
    }

    pub fn layout_previous(&mut self) {
        self.layouts.focus_previous();
        self.perform_layout();
    }
}

pub struct GroupIter<'a> {
    connection: &'a Connection,
    inner: Iter<'a, WindowId>,
}

impl<'a> Iterator for GroupIter<'a> {
    type Item = GroupWindow<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner
            .next()
            .map(|window_id| {
                     GroupWindow {
                         connection: self.connection,
                         window_id: window_id,
                     }
                 })
    }
}

impl<'a> ExactSizeIterator for GroupIter<'a> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

pub struct GroupWindow<'a> {
    connection: &'a Connection,
    window_id: &'a WindowId,
}

impl<'a> Window for GroupWindow<'a> {
    fn connection(&self) -> &Connection {
        self.connection
    }

    fn id(&self) -> &WindowId {
        self.window_id
    }
}
<|endoftext|>


<commit_before>//! Las headers.

use std::io::Read;

use byteorder::ReadBytesExt;
use byteorder::LittleEndian;
use rustc_serialize::hex::ToHex;

use Error;
use Result;
use io::LasStringExt;

/// Three f64 values in x, y, z order.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Triplet {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

/// Project ID newtype.
#[derive(Clone, Debug, PartialEq)]
pub struct ProjectId(pub [u8; 4], pub [u8; 2], pub [u8; 2], pub [u8; 8]);

impl ProjectId {
    /// Returns a hexadecimal string representation of the project ID.
    ///
    /// The format for this string was derived from libLAS's output.
    ///
    /// # Examples
    ///
    /// ```
    /// # use las::header::ProjectId;
    /// let project_id = ProjectId([0; 4], [0; 2], [0; 2], [0; 8]);
    /// assert_eq!("00000000-0000-0000-0000-000000000000", project_id.as_string());
    /// ```
    pub fn as_string(&self) -> String {
        let mut s = self.0.to_hex();
        s.push_str("-");
        s.push_str(&self.1.to_hex());
        s.push_str("-");
        s.push_str(&self.2.to_hex());
        s.push_str("-");
        s.push_str(&self.3[0..2].to_hex());
        s.push_str("-");
        s.push_str(&self.3[2..8].to_hex());
        s
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct Header {
    pub file_signature: [u8; 4],
    pub file_source_id: u16,
    pub global_encoding: u16,
    pub project_id: ProjectId,
    pub version_major: u8,
    pub version_minor: u8,
    pub system_identifier: String,
    pub generating_software: String,
    pub file_creation_day_of_year: u16,
    pub file_creation_year: u16,
    pub header_size: u16,
    pub offset_to_point_data: u32,
    pub number_of_variable_length_records: u32,
    pub point_data_format_id: u8,
    pub point_data_record_length: u16,
    pub number_of_point_records: u32,
    pub number_of_points_by_return: [u32; 5],
    pub scale: Triplet,
    pub offset: Triplet,
    pub min: Triplet,
    pub max: Triplet,
}

impl Default for Header {
    fn default() -> Header {
        Header {
            file_signature: *b"LASF",
            file_source_id: 0,
            global_encoding: 0,
            project_id: ProjectId([0; 4], [0; 2], [0; 2], [0; 8]),
            version_major: 0,
            version_minor: 0,
            system_identifier: "".to_string(),
            generating_software: "".to_string(),
            file_creation_day_of_year: 0,
            file_creation_year: 0,
            header_size: 0,
            offset_to_point_data: 0,
            number_of_variable_length_records: 0,
            point_data_format_id: 0,
            point_data_record_length: 0,
            number_of_point_records: 0,
            number_of_points_by_return: [0; 5],
            scale: Default::default(),
            offset: Default::default(),
            min: Default::default(),
            max: Default::default(),
        }
    }
}

impl Header {
    /// Creates a new header from a `Read` object.
    ///
    /// # Examples
    ///
    /// ```
    /// # use las::header::Header;
    /// let mut reader = std::fs::File::open("data/1.2_0.las").unwrap();
    /// let header = Header::new(&mut reader);
    /// ```
    pub fn new<R: Read>(reader: &mut R) -> Result<Header> {
        let mut header: Header = Default::default();
        try_read_n!(reader, header.file_signature, 4);
        header.file_source_id = try!(reader.read_u16::<LittleEndian>());
        header.global_encoding = try!(reader.read_u16::<LittleEndian>());
        try_read_n!(reader, header.project_id.0, 4);
        try_read_n!(reader, header.project_id.1, 2);
        try_read_n!(reader, header.project_id.2, 2);
        try_read_n!(reader, header.project_id.3, 8);
        header.version_major = try!(reader.read_u8());
        header.version_minor = try!(reader.read_u8());
        header.system_identifier = try!(reader.read_las_string(32));
        header.generating_software = try!(reader.read_las_string(32));
        header.file_creation_day_of_year = try!(reader.read_u16::<LittleEndian>());
        header.file_creation_year = try!(reader.read_u16::<LittleEndian>());
        header.header_size = try!(reader.read_u16::<LittleEndian>());
        header.offset_to_point_data = try!(reader.read_u32::<LittleEndian>());
        header.number_of_variable_length_records = try!(reader.read_u32::<LittleEndian>());
        header.point_data_format_id = try!(reader.read_u8());
        header.point_data_record_length = try!(reader.read_u16::<LittleEndian>());
        header.number_of_point_records = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[0] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[1] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[2] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[3] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[4] = try!(reader.read_u32::<LittleEndian>());
        header.scale.x = try!(reader.read_f64::<LittleEndian>());
        header.scale.y = try!(reader.read_f64::<LittleEndian>());
        header.scale.z = try!(reader.read_f64::<LittleEndian>());
        header.offset.x = try!(reader.read_f64::<LittleEndian>());
        header.offset.y = try!(reader.read_f64::<LittleEndian>());
        header.offset.z = try!(reader.read_f64::<LittleEndian>());
        header.max.x = try!(reader.read_f64::<LittleEndian>());
        header.min.x = try!(reader.read_f64::<LittleEndian>());
        header.max.y = try!(reader.read_f64::<LittleEndian>());
        header.min.y = try!(reader.read_f64::<LittleEndian>());
        header.max.z = try!(reader.read_f64::<LittleEndian>());
        header.min.z = try!(reader.read_f64::<LittleEndian>());
        Ok(header)
    }
}

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

    use std::fs::File;

    #[test]
    fn header() {
        let mut reader = File::open("data/1.2_0.las").unwrap();
        let header = Header::new(&mut reader).unwrap();
        assert_eq!(*b"LASF", header.file_signature);
        assert_eq!(0, header.file_source_id);
        assert_eq!(0, header.global_encoding);
        assert_eq!("b8f18883-1baa-0841-bca3-6bc68e7b062e", header.project_id.as_string());
        assert_eq!(1, header.version_major);
        assert_eq!(2, header.version_minor);
        assert_eq!("libLAS", header.system_identifier);
        assert_eq!("libLAS 1.2", header.generating_software);
        assert_eq!(78, header.file_creation_day_of_year);
        assert_eq!(2008, header.file_creation_year);
        assert_eq!(227, header.header_size);
        assert_eq!(438, header.offset_to_point_data);
        assert_eq!(2, header.number_of_variable_length_records);
        assert_eq!(0, header.point_data_format_id);
        assert_eq!(20, header.point_data_record_length);
        assert_eq!(1, header.number_of_point_records);
        assert_eq!([0, 1, 0, 0, 0], header.number_of_points_by_return);
        assert_eq!(0.01, header.scale.x);
        assert_eq!(0.01, header.scale.y);
        assert_eq!(0.01, header.scale.z);
        assert_eq!(0.0, header.offset.x);
        assert_eq!(0.0, header.offset.y);
        assert_eq!(0.0, header.offset.z);
        assert_eq!(470692.447538, header.min.x);
        assert_eq!(4602888.904642, header.min.y);
        assert_eq!(16.0, header.min.z);
        assert_eq!(470692.447538, header.max.x);
        assert_eq!(4602888.904642, header.max.y);
        assert_eq!(16.0, header.max.z);
    }
}
<commit_msg>Impl default for ProjectId<commit_after>//! Las headers.

use std::io::Read;

use byteorder::ReadBytesExt;
use byteorder::LittleEndian;
use rustc_serialize::hex::ToHex;

use Error;
use Result;
use io::LasStringExt;

/// Three f64 values in x, y, z order.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Triplet {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

/// Project ID newtype.
#[derive(Clone, Debug, PartialEq)]
pub struct ProjectId(pub [u8; 4], pub [u8; 2], pub [u8; 2], pub [u8; 8]);

impl Default for ProjectId {
    fn default() -> ProjectId {
        ProjectId([0; 4], [0; 2], [0; 2], [0; 8])
    }
}

impl ProjectId {
    /// Returns a hexadecimal string representation of the project ID.
    ///
    /// The format for this string was derived from libLAS's output.
    ///
    /// # Examples
    ///
    /// ```
    /// # use las::header::ProjectId;
    /// let project_id = ProjectId([0; 4], [0; 2], [0; 2], [0; 8]);
    /// assert_eq!("00000000-0000-0000-0000-000000000000", project_id.as_string());
    /// ```
    pub fn as_string(&self) -> String {
        let mut s = self.0.to_hex();
        s.push_str("-");
        s.push_str(&self.1.to_hex());
        s.push_str("-");
        s.push_str(&self.2.to_hex());
        s.push_str("-");
        s.push_str(&self.3[0..2].to_hex());
        s.push_str("-");
        s.push_str(&self.3[2..8].to_hex());
        s
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct Header {
    pub file_signature: [u8; 4],
    pub file_source_id: u16,
    pub global_encoding: u16,
    pub project_id: ProjectId,
    pub version_major: u8,
    pub version_minor: u8,
    pub system_identifier: String,
    pub generating_software: String,
    pub file_creation_day_of_year: u16,
    pub file_creation_year: u16,
    pub header_size: u16,
    pub offset_to_point_data: u32,
    pub number_of_variable_length_records: u32,
    pub point_data_format_id: u8,
    pub point_data_record_length: u16,
    pub number_of_point_records: u32,
    pub number_of_points_by_return: [u32; 5],
    pub scale: Triplet,
    pub offset: Triplet,
    pub min: Triplet,
    pub max: Triplet,
}

impl Default for Header {
    fn default() -> Header {
        Header {
            file_signature: *b"LASF",
            file_source_id: 0,
            global_encoding: 0,
            project_id: Default::default(),
            version_major: 0,
            version_minor: 0,
            system_identifier: "".to_string(),
            generating_software: "".to_string(),
            file_creation_day_of_year: 0,
            file_creation_year: 0,
            header_size: 0,
            offset_to_point_data: 0,
            number_of_variable_length_records: 0,
            point_data_format_id: 0,
            point_data_record_length: 0,
            number_of_point_records: 0,
            number_of_points_by_return: [0; 5],
            scale: Default::default(),
            offset: Default::default(),
            min: Default::default(),
            max: Default::default(),
        }
    }
}

impl Header {
    /// Creates a new header from a `Read` object.
    ///
    /// # Examples
    ///
    /// ```
    /// # use las::header::Header;
    /// let mut reader = std::fs::File::open("data/1.2_0.las").unwrap();
    /// let header = Header::new(&mut reader);
    /// ```
    pub fn new<R: Read>(reader: &mut R) -> Result<Header> {
        let mut header: Header = Default::default();
        try_read_n!(reader, header.file_signature, 4);
        header.file_source_id = try!(reader.read_u16::<LittleEndian>());
        header.global_encoding = try!(reader.read_u16::<LittleEndian>());
        try_read_n!(reader, header.project_id.0, 4);
        try_read_n!(reader, header.project_id.1, 2);
        try_read_n!(reader, header.project_id.2, 2);
        try_read_n!(reader, header.project_id.3, 8);
        header.version_major = try!(reader.read_u8());
        header.version_minor = try!(reader.read_u8());
        header.system_identifier = try!(reader.read_las_string(32));
        header.generating_software = try!(reader.read_las_string(32));
        header.file_creation_day_of_year = try!(reader.read_u16::<LittleEndian>());
        header.file_creation_year = try!(reader.read_u16::<LittleEndian>());
        header.header_size = try!(reader.read_u16::<LittleEndian>());
        header.offset_to_point_data = try!(reader.read_u32::<LittleEndian>());
        header.number_of_variable_length_records = try!(reader.read_u32::<LittleEndian>());
        header.point_data_format_id = try!(reader.read_u8());
        header.point_data_record_length = try!(reader.read_u16::<LittleEndian>());
        header.number_of_point_records = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[0] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[1] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[2] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[3] = try!(reader.read_u32::<LittleEndian>());
        header.number_of_points_by_return[4] = try!(reader.read_u32::<LittleEndian>());
        header.scale.x = try!(reader.read_f64::<LittleEndian>());
        header.scale.y = try!(reader.read_f64::<LittleEndian>());
        header.scale.z = try!(reader.read_f64::<LittleEndian>());
        header.offset.x = try!(reader.read_f64::<LittleEndian>());
        header.offset.y = try!(reader.read_f64::<LittleEndian>());
        header.offset.z = try!(reader.read_f64::<LittleEndian>());
        header.max.x = try!(reader.read_f64::<LittleEndian>());
        header.min.x = try!(reader.read_f64::<LittleEndian>());
        header.max.y = try!(reader.read_f64::<LittleEndian>());
        header.min.y = try!(reader.read_f64::<LittleEndian>());
        header.max.z = try!(reader.read_f64::<LittleEndian>());
        header.min.z = try!(reader.read_f64::<LittleEndian>());
        Ok(header)
    }
}

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

    use std::fs::File;

    #[test]
    fn header() {
        let mut reader = File::open("data/1.2_0.las").unwrap();
        let header = Header::new(&mut reader).unwrap();
        assert_eq!(*b"LASF", header.file_signature);
        assert_eq!(0, header.file_source_id);
        assert_eq!(0, header.global_encoding);
        assert_eq!("b8f18883-1baa-0841-bca3-6bc68e7b062e", header.project_id.as_string());
        assert_eq!(1, header.version_major);
        assert_eq!(2, header.version_minor);
        assert_eq!("libLAS", header.system_identifier);
        assert_eq!("libLAS 1.2", header.generating_software);
        assert_eq!(78, header.file_creation_day_of_year);
        assert_eq!(2008, header.file_creation_year);
        assert_eq!(227, header.header_size);
        assert_eq!(438, header.offset_to_point_data);
        assert_eq!(2, header.number_of_variable_length_records);
        assert_eq!(0, header.point_data_format_id);
        assert_eq!(20, header.point_data_record_length);
        assert_eq!(1, header.number_of_point_records);
        assert_eq!([0, 1, 0, 0, 0], header.number_of_points_by_return);
        assert_eq!(0.01, header.scale.x);
        assert_eq!(0.01, header.scale.y);
        assert_eq!(0.01, header.scale.z);
        assert_eq!(0.0, header.offset.x);
        assert_eq!(0.0, header.offset.y);
        assert_eq!(0.0, header.offset.z);
        assert_eq!(470692.447538, header.min.x);
        assert_eq!(4602888.904642, header.min.y);
        assert_eq!(16.0, header.min.z);
        assert_eq!(470692.447538, header.max.x);
        assert_eq!(4602888.904642, header.max.y);
        assert_eq!(16.0, header.max.z);
    }
}
<|endoftext|>