<commit_before>#![feature(io)]
#![feature(core)]
#![feature(collections)]

pub mod types;

#[macro_use]
pub mod utils;

pub struct File {
    pub ehdr: types::FileHeader,
    pub phdrs: Vec<types::ProgramHeader>,
    pub sections: Vec<Section>,
}

impl std::fmt::Debug for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?} {:?} {:?}", self.ehdr, self.phdrs, self.sections)
    }
}

impl std::fmt::Display for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "{{ {} }}", self.ehdr));
        try!(write!(f, "{{ "));
        for phdr in self.phdrs.iter() {
            try!(write!(f, "{}", phdr));
        }
        try!(write!(f, " }} {{ "));
        for shdr in self.sections.iter() {
            try!(write!(f, "{}", shdr));
        }
        write!(f, " }}")
    }
}

#[derive(Debug)]
pub enum ParseError {
    IoError,
    InvalidMagic,
    InvalidFormat,
    NotImplemented,
}

impl std::error::FromError<std::old_io::IoError> for ParseError {
    fn from_error(_: std::old_io::IoError) -> Self {
        ParseError::IoError
    }
}

impl std::error::FromError<std::string::FromUtf8Error> for ParseError {
    fn from_error(_: std::string::FromUtf8Error) -> Self {
        ParseError::InvalidFormat
    }
}

impl File {
    pub fn open(path: &std::old_path::Path) -> Result<File, ParseError> {
        // Open the file for reading
        let mut io_file = try!(std::old_io::File::open(path));

        // Read the platform-independent ident bytes
        let mut ident = [0u8; types::EI_NIDENT];
        let nread = try!(io_file.read(&mut ident));

        if nread != types::EI_NIDENT {
            return Err(ParseError::InvalidFormat);
        }

        // Verify the magic number
        if ident[0] != types::ELFMAG0 || ident[1] != types::ELFMAG1
                || ident[2] != types::ELFMAG2 || ident[3] != types::ELFMAG3 {
            return Err(ParseError::InvalidMagic);
        }

        // Fill in file header values from ident bytes
        let mut elf_f = File::new();
        elf_f.ehdr.class = types::Class(ident[types::EI_CLASS]);
        elf_f.ehdr.data = types::Data(ident[types::EI_DATA]);
        elf_f.ehdr.osabi = types::OSABI(ident[types::EI_OSABI]);
        elf_f.ehdr.abiversion = ident[types::EI_ABIVERSION];
        elf_f.ehdr.elftype = types::Type(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.machine = types::Machine(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.version = types::Version(try!(read_u32!(elf_f, io_file)));

        let mut phoff: u64;
        let mut shoff: u64;

        // Parse the platform-dependent file fields
        if elf_f.ehdr.class == types::ELFCLASS32 {
            elf_f.ehdr.entry = try!(read_u32!(elf_f, io_file)) as u64;
            phoff = try!(read_u32!(elf_f, io_file)) as u64;
            shoff = try!(read_u32!(elf_f, io_file)) as u64;
        } else {
            elf_f.ehdr.entry = try!(read_u64!(elf_f, io_file));
            phoff = try!(read_u64!(elf_f, io_file));
            shoff = try!(read_u64!(elf_f, io_file));
        }

        let flags = try!(read_u32!(elf_f, io_file));
        let ehsize = try!(read_u16!(elf_f, io_file));
        let phentsize = try!(read_u16!(elf_f, io_file));
        let phnum = try!(read_u16!(elf_f, io_file));
        let shentsize = try!(read_u16!(elf_f, io_file));
        let shnum = try!(read_u16!(elf_f, io_file));
        let shstrndx = try!(read_u16!(elf_f, io_file));

        // Parse the program headers
        try!(io_file.seek(phoff as i64, std::old_io::SeekStyle::SeekSet));
        for _ in 0..phnum {
            let mut progtype: types::ProgType;
            let mut offset: u64;
            let mut vaddr: u64;
            let mut paddr: u64;
            let mut filesz: u64;
            let mut memsz: u64;
            let mut flags: types::ProgFlag;
            let mut align: u64;

            progtype = types::ProgType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                vaddr = try!(read_u32!(elf_f, io_file)) as u64;
                paddr = try!(read_u32!(elf_f, io_file)) as u64;
                filesz = try!(read_u32!(elf_f, io_file)) as u64;
                memsz = try!(read_u32!(elf_f, io_file)) as u64;
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                align = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                offset = try!(read_u64!(elf_f, io_file));
                vaddr = try!(read_u64!(elf_f, io_file));
                paddr = try!(read_u64!(elf_f, io_file));
                filesz = try!(read_u64!(elf_f, io_file));
                memsz = try!(read_u64!(elf_f, io_file));
                align = try!(read_u64!(elf_f, io_file));
            }

            elf_f.phdrs.push(types::ProgramHeader {
                    progtype: progtype,
                    offset:   offset,
                    vaddr:    vaddr,
                    paddr:    paddr,
                    filesz:   filesz,
                    memsz:    memsz,
                    flags:    flags,
                    align:    align,
                });
        }

        // Parse the section headers
        let mut name_idxs: Vec<u32> = Vec::new();
        try!(io_file.seek(shoff as i64, std::old_io::SeekStyle::SeekSet));
        for _ in 0..shnum {
            let name: String = String::new();
            let mut shtype: types::SectionType;
            let mut flags: types::SectionFlag;
            let mut addr: u64;
            let mut offset: u64;
            let mut size: u64;
            let mut link: u32;
            let mut info: u32;
            let mut addralign: u64;
            let mut entsize: u64;

            name_idxs.push(try!(read_u32!(elf_f, io_file)));
            shtype = types::SectionType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                flags = types::SectionFlag(try!(read_u32!(elf_f, io_file)) as u64);
                addr = try!(read_u32!(elf_f, io_file)) as u64;
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                size = try!(read_u32!(elf_f, io_file)) as u64;
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u32!(elf_f, io_file)) as u64;
                entsize = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::SectionFlag(try!(read_u64!(elf_f, io_file)));
                addr = try!(read_u64!(elf_f, io_file));
                offset = try!(read_u64!(elf_f, io_file));
                size = try!(read_u64!(elf_f, io_file));
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u64!(elf_f, io_file));
                entsize = try!(read_u64!(elf_f, io_file));
            }

            elf_f.sections.push(Section {
                    shdr: types::SectionHeader {
                        name:      name,
                        shtype:    shtype,
                        flags:     flags,
                        addr:      addr,
                        offset:    offset,
                        size:      size,
                        link:      link,
                        info:      info,
                        addralign: addralign,
                        entsize:   entsize,
                    },
                    data: Vec::new(),
                });
        }

        // Read the section data
        for s_i in 0..shnum {
            let off = elf_f.sections[s_i as usize].shdr.offset;
            let size = elf_f.sections[s_i as usize].shdr.size;
            try!(io_file.seek(off as i64, std::old_io::SeekStyle::SeekSet));
            elf_f.sections[s_i as usize].data = try!(io_file.read_exact(size as usize));
        }

        // Parse the section names from the string header string table
        for s_i in 0..shnum {
            elf_f.sections[s_i as usize].shdr.name = try!(utils::get_string(
                    &elf_f.sections[shstrndx as usize].data,
                    name_idxs[s_i as usize] as usize));
        }

        Ok(elf_f)
    }

    pub fn get_section(&self, name: String) -> Option<&Section> {
        for s_i in 0..self.sections.len() {
            if self.sections[s_i].shdr.name == name {
                return Some(&self.sections[s_i])
            }
        }
        None
    }

    pub fn new() -> File {
        File {
            ehdr: types::FileHeader::new(),
            phdrs: Vec::new(),
            sections: Vec::new(),
        }
    }
}

#[derive(Debug)]
pub struct Section {
    pub shdr: types::SectionHeader,
    pub data: Vec<u8>,
}

impl std::fmt::Display for Section {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.shdr)
    }
}

<commit_msg>Remove stale #![feature(collections)] attribute<commit_after>#![feature(io)]
#![feature(core)]

pub mod types;

#[macro_use]
pub mod utils;

pub struct File {
    pub ehdr: types::FileHeader,
    pub phdrs: Vec<types::ProgramHeader>,
    pub sections: Vec<Section>,
}

impl std::fmt::Debug for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?} {:?} {:?}", self.ehdr, self.phdrs, self.sections)
    }
}

impl std::fmt::Display for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "{{ {} }}", self.ehdr));
        try!(write!(f, "{{ "));
        for phdr in self.phdrs.iter() {
            try!(write!(f, "{}", phdr));
        }
        try!(write!(f, " }} {{ "));
        for shdr in self.sections.iter() {
            try!(write!(f, "{}", shdr));
        }
        write!(f, " }}")
    }
}

#[derive(Debug)]
pub enum ParseError {
    IoError,
    InvalidMagic,
    InvalidFormat,
    NotImplemented,
}

impl std::error::FromError<std::old_io::IoError> for ParseError {
    fn from_error(_: std::old_io::IoError) -> Self {
        ParseError::IoError
    }
}

impl std::error::FromError<std::string::FromUtf8Error> for ParseError {
    fn from_error(_: std::string::FromUtf8Error) -> Self {
        ParseError::InvalidFormat
    }
}

impl File {
    pub fn open(path: &std::old_path::Path) -> Result<File, ParseError> {
        // Open the file for reading
        let mut io_file = try!(std::old_io::File::open(path));

        // Read the platform-independent ident bytes
        let mut ident = [0u8; types::EI_NIDENT];
        let nread = try!(io_file.read(&mut ident));

        if nread != types::EI_NIDENT {
            return Err(ParseError::InvalidFormat);
        }

        // Verify the magic number
        if ident[0] != types::ELFMAG0 || ident[1] != types::ELFMAG1
                || ident[2] != types::ELFMAG2 || ident[3] != types::ELFMAG3 {
            return Err(ParseError::InvalidMagic);
        }

        // Fill in file header values from ident bytes
        let mut elf_f = File::new();
        elf_f.ehdr.class = types::Class(ident[types::EI_CLASS]);
        elf_f.ehdr.data = types::Data(ident[types::EI_DATA]);
        elf_f.ehdr.osabi = types::OSABI(ident[types::EI_OSABI]);
        elf_f.ehdr.abiversion = ident[types::EI_ABIVERSION];
        elf_f.ehdr.elftype = types::Type(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.machine = types::Machine(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.version = types::Version(try!(read_u32!(elf_f, io_file)));

        let mut phoff: u64;
        let mut shoff: u64;

        // Parse the platform-dependent file fields
        if elf_f.ehdr.class == types::ELFCLASS32 {
            elf_f.ehdr.entry = try!(read_u32!(elf_f, io_file)) as u64;
            phoff = try!(read_u32!(elf_f, io_file)) as u64;
            shoff = try!(read_u32!(elf_f, io_file)) as u64;
        } else {
            elf_f.ehdr.entry = try!(read_u64!(elf_f, io_file));
            phoff = try!(read_u64!(elf_f, io_file));
            shoff = try!(read_u64!(elf_f, io_file));
        }

        let flags = try!(read_u32!(elf_f, io_file));
        let ehsize = try!(read_u16!(elf_f, io_file));
        let phentsize = try!(read_u16!(elf_f, io_file));
        let phnum = try!(read_u16!(elf_f, io_file));
        let shentsize = try!(read_u16!(elf_f, io_file));
        let shnum = try!(read_u16!(elf_f, io_file));
        let shstrndx = try!(read_u16!(elf_f, io_file));

        // Parse the program headers
        try!(io_file.seek(phoff as i64, std::old_io::SeekStyle::SeekSet));
        for _ in 0..phnum {
            let mut progtype: types::ProgType;
            let mut offset: u64;
            let mut vaddr: u64;
            let mut paddr: u64;
            let mut filesz: u64;
            let mut memsz: u64;
            let mut flags: types::ProgFlag;
            let mut align: u64;

            progtype = types::ProgType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                vaddr = try!(read_u32!(elf_f, io_file)) as u64;
                paddr = try!(read_u32!(elf_f, io_file)) as u64;
                filesz = try!(read_u32!(elf_f, io_file)) as u64;
                memsz = try!(read_u32!(elf_f, io_file)) as u64;
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                align = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                offset = try!(read_u64!(elf_f, io_file));
                vaddr = try!(read_u64!(elf_f, io_file));
                paddr = try!(read_u64!(elf_f, io_file));
                filesz = try!(read_u64!(elf_f, io_file));
                memsz = try!(read_u64!(elf_f, io_file));
                align = try!(read_u64!(elf_f, io_file));
            }

            elf_f.phdrs.push(types::ProgramHeader {
                    progtype: progtype,
                    offset:   offset,
                    vaddr:    vaddr,
                    paddr:    paddr,
                    filesz:   filesz,
                    memsz:    memsz,
                    flags:    flags,
                    align:    align,
                });
        }

        // Parse the section headers
        let mut name_idxs: Vec<u32> = Vec::new();
        try!(io_file.seek(shoff as i64, std::old_io::SeekStyle::SeekSet));
        for _ in 0..shnum {
            let name: String = String::new();
            let mut shtype: types::SectionType;
            let mut flags: types::SectionFlag;
            let mut addr: u64;
            let mut offset: u64;
            let mut size: u64;
            let mut link: u32;
            let mut info: u32;
            let mut addralign: u64;
            let mut entsize: u64;

            name_idxs.push(try!(read_u32!(elf_f, io_file)));
            shtype = types::SectionType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                flags = types::SectionFlag(try!(read_u32!(elf_f, io_file)) as u64);
                addr = try!(read_u32!(elf_f, io_file)) as u64;
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                size = try!(read_u32!(elf_f, io_file)) as u64;
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u32!(elf_f, io_file)) as u64;
                entsize = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::SectionFlag(try!(read_u64!(elf_f, io_file)));
                addr = try!(read_u64!(elf_f, io_file));
                offset = try!(read_u64!(elf_f, io_file));
                size = try!(read_u64!(elf_f, io_file));
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u64!(elf_f, io_file));
                entsize = try!(read_u64!(elf_f, io_file));
            }

            elf_f.sections.push(Section {
                    shdr: types::SectionHeader {
                        name:      name,
                        shtype:    shtype,
                        flags:     flags,
                        addr:      addr,
                        offset:    offset,
                        size:      size,
                        link:      link,
                        info:      info,
                        addralign: addralign,
                        entsize:   entsize,
                    },
                    data: Vec::new(),
                });
        }

        // Read the section data
        for s_i in 0..shnum {
            let off = elf_f.sections[s_i as usize].shdr.offset;
            let size = elf_f.sections[s_i as usize].shdr.size;
            try!(io_file.seek(off as i64, std::old_io::SeekStyle::SeekSet));
            elf_f.sections[s_i as usize].data = try!(io_file.read_exact(size as usize));
        }

        // Parse the section names from the string header string table
        for s_i in 0..shnum {
            elf_f.sections[s_i as usize].shdr.name = try!(utils::get_string(
                    &elf_f.sections[shstrndx as usize].data,
                    name_idxs[s_i as usize] as usize));
        }

        Ok(elf_f)
    }

    pub fn get_section(&self, name: String) -> Option<&Section> {
        for s_i in 0..self.sections.len() {
            if self.sections[s_i].shdr.name == name {
                return Some(&self.sections[s_i])
            }
        }
        None
    }

    pub fn new() -> File {
        File {
            ehdr: types::FileHeader::new(),
            phdrs: Vec::new(),
            sections: Vec::new(),
        }
    }
}

#[derive(Debug)]
pub struct Section {
    pub shdr: types::SectionHeader,
    pub data: Vec<u8>,
}

impl std::fmt::Display for Section {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.shdr)
    }
}

<|endoftext|>


<commit_before>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::{transmute, size_of};

#[link(name = "klee")]
extern {
  fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
  fn klee_int(name: *const raw::c_char) -> raw::c_int;
  fn klee_warning(name: *const raw::c_char);
  fn klee_warning_one(name: *const raw::c_char);
  fn klee_set_forking(state: raw::c_bool);
}

pub unsafe fn any(data: *const raw::c_void, length: usize, name: &str) {
  klee_make_symbolic(data, length as libc::size_t, CString::new(name).unwrap().as_ptr());
}

pub fn warning(name: &str) {
  unsafe { klee_warning(CString::new(name).unwrap().as_ptr()); }
}

pub fn warning_one(name: &str) {
  unsafe { klee_warning_once(CString::new(name).unwrap().as_ptr()); }
}

pub fn set_forking(state: bool) {
  unsafe { klee_set_forking(state as raw::c_bool); }
}

pub fn i32(name: &str) -> i32 {
  let result;
  unsafe {
    result = klee_int(CString::new(name).unwrap().as_ptr());
  }
  result
}

pub fn symbol<T>(data: &T, name: &str) {
  unsafe{ any(transmute(data as *const T), size_of::<T>(), name); }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::{transmute, size_of};

#[link(name = "klee")]
extern {
  fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
  fn klee_int(name: *const raw::c_char) -> raw::c_int;
  fn klee_warning(name: *const raw::c_char);
  fn klee_warning_one(name: *const raw::c_char);
  fn klee_set_forking(state: libc::c_bool);
}

pub unsafe fn any(data: *const raw::c_void, length: usize, name: &str) {
  klee_make_symbolic(data, length as libc::size_t, CString::new(name).unwrap().as_ptr());
}

pub fn warning(name: &str) {
  unsafe { klee_warning(CString::new(name).unwrap().as_ptr()); }
}

pub fn warning_one(name: &str) {
  unsafe { klee_warning_once(CString::new(name).unwrap().as_ptr()); }
}

pub fn set_forking(state: bool) {
  unsafe { klee_set_forking(state as raw::c_bool); }
}

pub fn i32(name: &str) -> i32 {
  let result;
  unsafe {
    result = klee_int(CString::new(name).unwrap().as_ptr());
  }
  result
}

pub fn symbol<T>(data: &T, name: &str) {
  unsafe{ any(transmute(data as *const T), size_of::<T>(), name); }
}
<|endoftext|>


<commit_before>// Copyright 2015 Jan Likar.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate failure;
extern crate cargo;
extern crate walkdir;

pub mod ops {
    use std::env;
    use std::fs;
    use std::path::{Path, PathBuf};

    use cargo::core::dependency::Dependency;
    use cargo::core::source::{Source, SourceId};
    use cargo::core::Package;
    use cargo::sources::{GitSource, PathSource, SourceConfigMap};
    use cargo::util::to_semver::ToSemver;
    use cargo::util::{CargoResult, Config};

    use walkdir::WalkDir;

    pub fn clone(
        krate: Option<&str>,
        srcid: &SourceId,
        prefix: Option<&str>,
        vers: Option<&str>,
        config: &Config,
    ) -> CargoResult<()> {
        let _lock = config.acquire_package_cache_lock()?;

        let map = SourceConfigMap::new(config)?;
        let pkg = if srcid.is_path() {
            let path = srcid.url().to_file_path().ok().expect("path must be valid");
            let mut src = PathSource::new(&path, srcid.clone(), config);
            src.update()?;

            select_pkg(config, src, krate, vers, &mut |path| path.read_packages())?
        } else if srcid.is_git() {
            select_pkg(
                config,
                GitSource::new(srcid.clone(), config)?,
                krate,
                vers,
                &mut |git| git.read_packages(),
            )?
        } else {
            select_pkg(
                config,
                map.load(srcid.clone(), &Default::default())?,
                krate,
                vers,
                &mut |_| {
                    bail!(
                        "must specify a crate to clone from \
                         crates.io, or use --path or --git to \
                         specify alternate source"
                    )
                },
            )?
        };

        // If prefix was not supplied, clone into current dir
        let mut dest_path = match prefix {
            Some(path) => PathBuf::from(path),
            None => try!(env::current_dir()),
        };

        dest_path.push(format!("{}", pkg.name()));

        try!(clone_directory(&pkg.root(), &dest_path));

        Ok(())
    }

    fn select_pkg<'a, T>(
        config: &Config,
        mut src: T,
        name: Option<&str>,
        vers: Option<&str>,
        list_all: &mut FnMut(&mut T) -> CargoResult<Vec<Package>>,
    ) -> CargoResult<Package>
    where
        T: Source + 'a,
    {
        src.update()?;

        match name {
            Some(name) => {
                let vers = match vers {
                    Some(v) => match v.to_semver() {
                        Ok(v) => Some(v.to_string()),
                        Err(e) => bail!("{}", e),
                    },
                    None => None,
                };
                let vers = vers.as_ref().map(|s| &**s);
                let dep = try!(Dependency::parse_no_deprecated(name, vers, src.source_id()));
                let mut summaries = vec![];
                try!(src.query(&dep, &mut |summary| summaries.push(summary.clone())));

                let latest = summaries.iter().max_by_key(|s| s.version());

                match latest {
                    Some(l) => {
                        let pkg = Box::new(src).download_now(l.package_id(), config)?;
                        Ok(pkg)
                    }
                    None => bail!("package '{}' not found", name),
                }
            }
            None => {
                let candidates = list_all(&mut src)?;
                Ok(candidates[0].clone())
            }
        }
    }

    fn clone_directory(from: &Path, to: &Path) -> CargoResult<()> {
        for entry in WalkDir::new(from) {
            let entry = entry.unwrap();
            let file_type = entry.file_type();
            let mut to = to.to_owned();
            to.push(entry.path().strip_prefix(from).unwrap());

            if file_type.is_file() && entry.file_name() != ".cargo-ok" {
                // .cargo-ok is not wanted in this context
                try!(fs::copy(&entry.path(), &to));
            } else if file_type.is_dir() {
                try!(fs::create_dir(&to));
            }
        }

        Ok(())
    }
}
<commit_msg>chore: run `cargo fix --edition`<commit_after>// Copyright 2015 Jan Likar.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate failure;
extern crate cargo;
extern crate walkdir;

pub mod ops {
    use std::env;
    use std::fs;
    use std::path::{Path, PathBuf};

    use cargo::core::dependency::Dependency;
    use cargo::core::source::{Source, SourceId};
    use cargo::core::Package;
    use cargo::sources::{GitSource, PathSource, SourceConfigMap};
    use cargo::util::to_semver::ToSemver;
    use cargo::util::{CargoResult, Config};

    use walkdir::WalkDir;

    pub fn clone(
        krate: Option<&str>,
        srcid: &SourceId,
        prefix: Option<&str>,
        vers: Option<&str>,
        config: &Config,
    ) -> CargoResult<()> {
        let _lock = config.acquire_package_cache_lock()?;

        let map = SourceConfigMap::new(config)?;
        let pkg = if srcid.is_path() {
            let path = srcid.url().to_file_path().ok().expect("path must be valid");
            let mut src = PathSource::new(&path, srcid.clone(), config);
            src.update()?;

            select_pkg(config, src, krate, vers, &mut |path| path.read_packages())?
        } else if srcid.is_git() {
            select_pkg(
                config,
                GitSource::new(srcid.clone(), config)?,
                krate,
                vers,
                &mut |git| git.read_packages(),
            )?
        } else {
            select_pkg(
                config,
                map.load(srcid.clone(), &Default::default())?,
                krate,
                vers,
                &mut |_| {
                    bail!(
                        "must specify a crate to clone from \
                         crates.io, or use --path or --git to \
                         specify alternate source"
                    )
                },
            )?
        };

        // If prefix was not supplied, clone into current dir
        let mut dest_path = match prefix {
            Some(path) => PathBuf::from(path),
            None => r#try!(env::current_dir()),
        };

        dest_path.push(format!("{}", pkg.name()));

        r#try!(clone_directory(&pkg.root(), &dest_path));

        Ok(())
    }

    fn select_pkg<'a, T>(
        config: &Config,
        mut src: T,
        name: Option<&str>,
        vers: Option<&str>,
        list_all: &mut dyn FnMut(&mut T) -> CargoResult<Vec<Package>>,
    ) -> CargoResult<Package>
    where
        T: Source + 'a,
    {
        src.update()?;

        match name {
            Some(name) => {
                let vers = match vers {
                    Some(v) => match v.to_semver() {
                        Ok(v) => Some(v.to_string()),
                        Err(e) => bail!("{}", e),
                    },
                    None => None,
                };
                let vers = vers.as_ref().map(|s| &**s);
                let dep = r#try!(Dependency::parse_no_deprecated(name, vers, src.source_id()));
                let mut summaries = vec![];
                r#try!(src.query(&dep, &mut |summary| summaries.push(summary.clone())));

                let latest = summaries.iter().max_by_key(|s| s.version());

                match latest {
                    Some(l) => {
                        let pkg = Box::new(src).download_now(l.package_id(), config)?;
                        Ok(pkg)
                    }
                    None => bail!("package '{}' not found", name),
                }
            }
            None => {
                let candidates = list_all(&mut src)?;
                Ok(candidates[0].clone())
            }
        }
    }

    fn clone_directory(from: &Path, to: &Path) -> CargoResult<()> {
        for entry in WalkDir::new(from) {
            let entry = entry.unwrap();
            let file_type = entry.file_type();
            let mut to = to.to_owned();
            to.push(entry.path().strip_prefix(from).unwrap());

            if file_type.is_file() && entry.file_name() != ".cargo-ok" {
                // .cargo-ok is not wanted in this context
                r#try!(fs::copy(&entry.path(), &to));
            } else if file_type.is_dir() {
                r#try!(fs::create_dir(&to));
            }
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//! Alacritty - The GPU Enhanced Terminal
#![feature(range_contains)]
#![feature(inclusive_range_syntax)]
#![feature(inclusive_range)]
#![feature(drop_types_in_const)]
#![feature(step_trait)]
#![feature(plugin)]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy))]
#![cfg_attr(feature = "clippy", deny(enum_glob_use))]
#![cfg_attr(feature = "clippy", deny(if_not_else))]
#![cfg_attr(feature = "clippy", deny(wrong_pub_self_convention))]
#![cfg_attr(test, feature(test))]
#![feature(core_intrinsics)]

#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;

extern crate cgmath;
extern crate copypasta;
extern crate errno;
extern crate font;
extern crate glutin;
extern crate libc;
extern crate mio;
extern crate notify;
extern crate parking_lot;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;
extern crate vte;
extern crate xdg;

#[macro_use]
extern crate bitflags;

#[macro_use]
pub mod macros;

pub mod ansi;
pub mod cli;
pub mod config;
pub mod display;
pub mod event;
pub mod event_loop;
pub mod grid;
pub mod index;
pub mod input;
pub mod meter;
pub mod renderer;
pub mod selection;
pub mod sync;
pub mod term;
pub mod tty;
pub mod util;
pub mod window;

pub use grid::Grid;
pub use term::Term;

#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize, Deserialize)]
pub struct Rgb {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

#[cfg_attr(feature = "clippy", allow(too_many_arguments))]
#[cfg_attr(feature = "clippy", allow(doc_markdown))]
pub mod gl {
    #![allow(non_upper_case_globals)]
    include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
}
<commit_msg>Make plugin feature optional<commit_after>// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//! Alacritty - The GPU Enhanced Terminal
#![feature(range_contains)]
#![feature(inclusive_range_syntax)]
#![feature(inclusive_range)]
#![feature(drop_types_in_const)]
#![feature(step_trait)]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy))]
#![cfg_attr(feature = "clippy", deny(enum_glob_use))]
#![cfg_attr(feature = "clippy", deny(if_not_else))]
#![cfg_attr(feature = "clippy", deny(wrong_pub_self_convention))]
#![cfg_attr(test, feature(test))]
#![feature(core_intrinsics)]

#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;

extern crate cgmath;
extern crate copypasta;
extern crate errno;
extern crate font;
extern crate glutin;
extern crate libc;
extern crate mio;
extern crate notify;
extern crate parking_lot;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;
extern crate vte;
extern crate xdg;

#[macro_use]
extern crate bitflags;

#[macro_use]
pub mod macros;

pub mod ansi;
pub mod cli;
pub mod config;
pub mod display;
pub mod event;
pub mod event_loop;
pub mod grid;
pub mod index;
pub mod input;
pub mod meter;
pub mod renderer;
pub mod selection;
pub mod sync;
pub mod term;
pub mod tty;
pub mod util;
pub mod window;

pub use grid::Grid;
pub use term::Term;

#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize, Deserialize)]
pub struct Rgb {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

#[cfg_attr(feature = "clippy", allow(too_many_arguments))]
#[cfg_attr(feature = "clippy", allow(doc_markdown))]
pub mod gl {
    #![allow(non_upper_case_globals)]
    include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate num;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate bitflags;

#[macro_use]
pub mod macros;

#[allow(non_camel_case_types, non_snake_case, raw_pointer_derive, dead_code)]
pub mod ffi;

pub mod error;
pub mod mutex;

pub mod sync {
    pub fn h5sync<T, F>(func: F) -> T where F: FnOnce() -> T,
    {
        use mutex::{RecursiveMutex};
        lazy_static! {
            static ref LOCK: RecursiveMutex = RecursiveMutex::new();
        }
        let _guard = LOCK.lock();
        func()
    }
}
<commit_msg>Remove unneeded braces<commit_after>extern crate libc;
extern crate num;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate bitflags;

#[macro_use]
pub mod macros;

#[allow(non_camel_case_types, non_snake_case, raw_pointer_derive, dead_code)]
pub mod ffi;

pub mod error;
pub mod mutex;

pub mod sync {
    pub fn h5sync<T, F>(func: F) -> T where F: FnOnce() -> T,
    {
        use mutex::RecursiveMutex;
        lazy_static! {
            static ref LOCK: RecursiveMutex = RecursiveMutex::new();
        }
        let _guard = LOCK.lock();
        func()
    }
}
<|endoftext|>


<commit_before>pub struct Nil;
pub struct Cons<H, T>(pub H, pub T);

#[allow(dead_code)]
pub enum Here {}
#[allow(dead_code)]
pub struct There<T>(std::marker::PhantomData<T>);

impl Nil {
    pub fn push<N>(self, item: N) -> Cons<N, Self> {
        Cons(item, self)
    }
}

impl<H, T> Cons<H, T> {
    pub fn push<N>(self, item: N) -> Cons<N, Self> {
        Cons(item, self)
    }
}

pub trait Find<T, I> {
    fn get(&self) -> &T;
    fn get_mut(&mut self) -> &mut T;
}

impl<T, Tail> Find<T, Here> for Cons<T, Tail> {
    fn get(&self) -> &T {
        &self.0
    }
    fn get_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<Head, T, Tail, TailIndex> Find<T, There<TailIndex>> for Cons<Head, Tail>
    where Tail: Find<T, TailIndex> {
    fn get(&self) -> &T {
        self.1.get()
    }
    fn get_mut(&mut self) -> &mut T {
        self.1.get_mut()
    }
}

#[test]
fn test_get() {
    let list = Nil.push(5i32).push("Foo");
    let a: i32 = *list.get();
    let b: &str = *list.get();
    assert!(a == 5i32);
    assert!(b == "Foo");
}

#[test]
fn test_get_mut() {
    let mut list = Nil.push(5i32).push("Foo");
    *list.get_mut() = 6i32;
    *list.get_mut() = "Bar";
    let a: i32 = *list.get();
    let b: &str = *list.get();
    assert!(a == 6i32);
    assert!(b == "Bar");
}

#[test]
fn test_index_as_type_parameter() {
    fn foo<I, L: Find<i32, I>>(list: &L) -> i32 {
        *list.get()
    }
    let list = Nil.push("foo").push(5i32).push("bar");
    assert!(foo(&list) == 5);
}
<commit_msg>Add some documentation. Incomplete.<commit_after>pub struct Nil;
pub struct Cons<H, T>(pub H, pub T);

/// Used as an index into an `HList`.
///
/// `Here` is 0, pointing to the head of the HList.
///
/// Users should normally allow type inference to deal with this type
#[allow(dead_code)]
pub enum Here {}

/// Used as an index into an `HList`.
///
/// `There<T>` is 1 + `T`.
///
/// Users should normally allow type inference to deal with this type.
#[allow(dead_code)]
pub struct There<T>(std::marker::PhantomData<T>);

impl Nil {
    pub fn push<N>(self, item: N) -> Cons<N, Self> {
        Cons(item, self)
    }
}

impl<H, T> Cons<H, T> {
    pub fn push<N>(self, item: N) -> Cons<N, Self> {
        Cons(item, self)
    }
}

pub trait Find<T, I> {
    fn get(&self) -> &T;
    fn get_mut(&mut self) -> &mut T;
}

impl<T, Tail> Find<T, Here> for Cons<T, Tail> {
    fn get(&self) -> &T {
        &self.0
    }
    fn get_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<Head, T, Tail, TailIndex> Find<T, There<TailIndex>> for Cons<Head, Tail>
    where Tail: Find<T, TailIndex> {
    fn get(&self) -> &T {
        self.1.get()
    }
    fn get_mut(&mut self) -> &mut T {
        self.1.get_mut()
    }
}

#[test]
fn test_get() {
    let list = Nil.push(5i32).push("Foo");
    let a: i32 = *list.get();
    let b: &str = *list.get();
    assert!(a == 5i32);
    assert!(b == "Foo");
}

#[test]
fn test_get_mut() {
    let mut list = Nil.push(5i32).push("Foo");
    *list.get_mut() = 6i32;
    *list.get_mut() = "Bar";
    let a: i32 = *list.get();
    let b: &str = *list.get();
    assert!(a == 6i32);
    assert!(b == "Bar");
}

#[test]
fn test_index_as_type_parameter() {
    fn foo<I, L: Find<i32, I>>(list: &L) -> i32 {
        *list.get()
    }
    let list = Nil.push("foo").push(5i32).push("bar");
    assert!(foo(&list) == 5);
}
<|endoftext|>


<commit_before>//! A library for controlling i3-wm through its ipc interface.

extern crate unix_socket;
extern crate byteorder;
extern crate serde;

use std::process;
use unix_socket::UnixStream;
use std::io;
use std::io::prelude::*;
use std::collections::HashMap;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use serde::json;

mod readhelp;
pub mod reply;

pub enum Event {
    // none of these are complete
    Workspace,
    Output,
    Mode,
    Window,
    BarConfigUpdate,
    Binding
}

/// An error while instantiating an I3Connection. Creating an I3Connection involves first getting
/// the i3 socket path, then connecting to the socket. Either part could go wrong, which is why
/// there are two possibilities here.
#[derive(Debug)]
pub enum I3ConnectError {
    /// An error while getting the socket path
    GetSocketPathError(io::Error),
    /// An error while accessing the socket
    SocketError(io::Error)
}

pub struct I3Connection {
    stream: UnixStream
}

impl I3Connection {

    /// Establishes an IPC connection to i3.
    pub fn connect() -> Result<I3Connection, I3ConnectError> {
        fn get_socket_path() -> io::Result<String> {
            let output = try!(process::Command::new("i3")
                                               .arg("--get-socketpath")
                                               .output());
            if output.status.success() {
                Ok(String::from_utf8_lossy(&output.stdout)
                          .trim_right_matches('\n')
                          .to_owned())
            } else {
                let prefix = "i3 --getsocketpath didn't return 0";
                let error_text = if output.stderr.len() > 0 {
                    format!("{}. stderr: {:?}", prefix, output.stderr)
                } else {
                    prefix.to_owned()
                };
                let error = io::Error::new(io::ErrorKind::Other, error_text);
                Err(error)
            }
        }

        return match get_socket_path() {
            Ok(path) => {
                match UnixStream::connect(path) {
                    Ok(stream) => Ok(I3Connection { stream: stream }),
                    Err(error) => Err(I3ConnectError::SocketError(error))
                }
            }
            Err(error) => Err(I3ConnectError::GetSocketPathError(error))
        }
    }

    fn send_message(&mut self, message_type: u32, payload: &str) -> io::Result<()> {
        let mut bytes = Vec::with_capacity(14 + payload.len());
        bytes.extend("i3-ipc".bytes());                              // 6 bytes
        try!(bytes.write_u32::<LittleEndian>(payload.len() as u32)); // 4 bytes
        try!(bytes.write_u32::<LittleEndian>(message_type));         // 4 bytes
        bytes.extend(payload.bytes());                               // payload.len() bytes
        self.stream.write_all(&bytes[..])
    }

    fn receive_message(&mut self) -> io::Result<String> {
        let magic_data = try!(readhelp::read_exact(&mut self.stream, 6));
        let magic_string = String::from_utf8_lossy(&magic_data);
        if magic_string != "i3-ipc" {
            let error_text = format!("unexpected magic string: expected 'i3-ipc' but got {}",
                                      magic_string);
            return Err(io::Error::new(io::ErrorKind::Other, error_text));
        }
        let payload_len = try!(self.stream.read_u32::<LittleEndian>());
        let message_type = try!(self.stream.read_u32::<LittleEndian>());
        let payload_data = try!(readhelp::read_exact(&mut self.stream, payload_len as usize));
        Ok(String::from_utf8_lossy(&payload_data).into_owned())
    }

    /// The payload of the message is a command for i3 (like the commands you can bind to keys
    /// in the configuration file) and will be executed directly after receiving it.
    pub fn command(&mut self, string: &str) -> io::Result<reply::Command> {
        try!(self.send_message(0, string));
        let payload = try!(self.receive_message());

        // assumes valid json
        let j: json::Value = json::from_str(&payload).unwrap();
        let commands = j.as_array().unwrap();
        let vec: Vec<_>
            = commands.iter()
                      .map(|c|
                           reply::CommandOutcome {
                               success: c.find("success").unwrap().as_boolean().unwrap(),
                               error: match c.find("error") {
                                   Some(val) => Some(val.as_string().unwrap().to_owned()),
                                   None => None
                               }
                           })
                      .collect();

        Ok(reply::Command { outcomes: vec })
    }

    fn unpack_rect(jrect: &json::Value) -> (i32, i32, i32, i32) {
        let x = jrect.find("x").unwrap().as_i64().unwrap() as i32;
        let y = jrect.find("y").unwrap().as_i64().unwrap() as i32;
        let width = jrect.find("width").unwrap().as_i64().unwrap() as i32;
        let height = jrect.find("height").unwrap().as_i64().unwrap() as i32;
        (x, y, width, height)
    }

    /// Gets the current workspaces.
    pub fn get_workspaces(&mut self) -> io::Result<reply::Workspaces> {
        try!(self.send_message(1, ""));
        let payload = try!(self.receive_message());

        let j: json::Value = json::from_str(&payload).unwrap();
        let jworkspaces = j.as_array().unwrap();
        let workspaces: Vec<_>
            = jworkspaces.iter()
                         .map(|w|
                              reply::Workspace {
                                  num: w.find("num").unwrap().as_i64().unwrap() as i32,
                                  name: w.find("name").unwrap().as_string().unwrap().to_owned(),
                                  visible: w.find("visible").unwrap().as_boolean().unwrap(),
                                  focused: w.find("focused").unwrap().as_boolean().unwrap(),
                                  urgent: w.find("urgent").unwrap().as_boolean().unwrap(),
                                  rect: I3Connection::unpack_rect(w.find("rect").unwrap()),
                                  output: w.find("output").unwrap().as_string().unwrap().to_owned()
                              })
                         .collect();
        Ok(reply::Workspaces { workspaces: workspaces })
    }

    /// Subscribes your connection to certain events.
    pub fn subscribe(&mut self) -> io::Result<reply::Subscribe> {
        panic!("not implemented");
    }

    /// Gets the current outputs.
    pub fn get_outputs(&mut self) -> io::Result<reply::Outputs> {
        try!(self.send_message(3, ""));
        let payload = try!(self.receive_message());

        let j: json::Value = json::from_str(&payload).unwrap();
        let joutputs = j.as_array().unwrap();
        let outputs: Vec<_>
            = joutputs.iter()
                      .map(|o|
                           reply::Output {
                               name: o.find("name").unwrap().as_string().unwrap().to_owned(),
                               active: o.find("active").unwrap().as_boolean().unwrap(),
                               current_workspace: match o.find("current_workspace").unwrap().clone() {
                                   json::Value::String(c_w) => Some(c_w),
                                   json::Value::Null => None,
                                   _ => unreachable!()
                               },
                               rect: I3Connection::unpack_rect(o.find("rect").unwrap())
                           })
                      .collect();
        Ok(reply::Outputs { outputs: outputs })
    }

    /// Gets the layout tree. i3 uses a tree as data structure which includes every container.
    pub fn get_tree(&mut self) -> io::Result<reply::Tree> {
        panic!("not implemented");
    }

    /// Gets a list of marks (identifiers for containers to easily jump to them later).
    pub fn get_marks(&mut self) -> io::Result<reply::Marks> {
        try!(self.send_message(5, ""));
        let payload = try!(self.receive_message());
        let marks: Vec<String> = json::from_str(&payload).unwrap();
        Ok(reply::Marks { marks: marks })
    }

    /// Gets an array with all configured bar IDs.
    pub fn get_bar_ids(&mut self) -> io::Result<reply::BarIds> {
        try!(self.send_message(6, ""));
        let payload = try!(self.receive_message());
        let ids: Vec<String> = json::from_str(&payload).unwrap();
        Ok(reply::BarIds { ids: ids })
    }

    /// Gets the configuration of the workspace bar with the given ID.
    pub fn get_bar_config(&mut self, id: &str) -> io::Result<reply::BarConfig> {
        try!(self.send_message(6, id));
        let payload = try!(self.receive_message());
        let j: json::Value = json::from_str(&payload).unwrap();
        Ok(reply::BarConfig {
            id: j.find("id").unwrap().as_string().unwrap().to_owned(),
            mode: j.find("mode").unwrap().as_string().unwrap().to_owned(),
            position: j.find("position").unwrap().as_string().unwrap().to_owned(),
            status_command: j.find("status_command").unwrap().as_string().unwrap().to_owned(),
            font: j.find("font").unwrap().as_string().unwrap().to_owned(),
            workspace_buttons: j.find("workspace_buttons").unwrap().as_boolean().unwrap(),
            binding_mode_indicator: j.find("binding_mode_indicator").unwrap().as_boolean().unwrap(),
            verbose: j.find("verbose").unwrap().as_boolean().unwrap(),
            colors: {
                let colors = j.find("colors").unwrap().as_object().unwrap();
                let mut map = HashMap::new();
                for c in colors.keys() {
                    let enum_key = match c.as_ref() {
                        "background" => reply::ColorableBarPart::Background,
                        "statusline" => reply::ColorableBarPart::Statusline,
                        "separator" => reply::ColorableBarPart::Separator,
                        "focused_workspace_text" => reply::ColorableBarPart::FocusedWorkspaceText,
                        "focused_workspace_bg" => reply::ColorableBarPart::FocusedWorkspaceBg,
                        "active_workspace_bg" => reply::ColorableBarPart::ActiveWorkspaceBg,
                        "inactive_workspace_text" => reply::ColorableBarPart::InactiveWorkspaceText,
                        "inactive_workspace_bg" => reply::ColorableBarPart::InactiveWorkspaceBg,
                        "urgent_workspace_text" => reply::ColorableBarPart::UrgentWorkspaceText,
                        "urgent_workspace_bar" => reply::ColorableBarPart::UrgentWorkspaceBar,
                        other => reply::ColorableBarPart::Undocumented(other.to_owned())
                    };
                    let hex = colors.get(c).unwrap().as_string().unwrap().to_owned();
                    map.insert(enum_key, hex);
                }
                map
            }
        })
    }

    /// Gets the version of i3. The reply will include the major, minor, patch and human-readable
    /// version.
    pub fn get_version(&mut self) -> io::Result<reply::Version> {
        panic!("not implemented");
    }
}

#[cfg(test)]
mod test {
    use I3Connection;

    // for the following tests send a request and get the reponse.
    // response types are specific so often getting them at all indicates success.
    // can't do much better without mocking an i3 installation.

    #[test]
    fn connect() {
        I3Connection::connect().unwrap();
    }

    #[test]
    fn command_nothing() {
        let mut connection = I3Connection::connect().unwrap();
        let result = connection.command("").unwrap();
        assert_eq!(result.outcomes.len(), 0);
    }

    #[test]
    fn command_single_sucess() {
        let mut connection = I3Connection::connect().unwrap();
        let a = connection.command("exec /bin/true").unwrap();
        assert_eq!(a.outcomes.len(), 1);
        assert!(a.outcomes[0].success);
    }

    #[test]
    fn command_multiple_success() {
        let mut connection = I3Connection::connect().unwrap();
        let result = connection.command("exec /bin/true; exec /bin/true").unwrap();
        assert_eq!(result.outcomes.len(), 2);
        assert!(result.outcomes[0].success);
        assert!(result.outcomes[1].success);
    }

    #[test]
    fn command_fail() {
        let mut connection = I3Connection::connect().unwrap();
        let result = connection.command("ThisIsClearlyNotACommand").unwrap();
        assert_eq!(result.outcomes.len(), 1);
        assert!(!result.outcomes[0].success);
    }

    #[test]
    fn get_workspaces() {
        I3Connection::connect().unwrap().get_workspaces().unwrap();
    }

    #[test]
    fn subscribe() {
        I3Connection::connect().unwrap().subscribe().unwrap();
    }

    #[test]
    fn get_outputs() {
        I3Connection::connect().unwrap().get_outputs().unwrap();
    }

    #[test]
    fn get_tree() {
        I3Connection::connect().unwrap().get_tree().unwrap();
    }

    #[test]
    fn get_marks() {
        I3Connection::connect().unwrap().get_marks().unwrap();
    }

    #[test]
    fn get_bar_ids() {
        I3Connection::connect().unwrap().get_bar_ids().unwrap();
    }

    #[test]
    fn get_bar_ids_and_one_config() {
        let mut connection = I3Connection::connect().unwrap();
        let ids = connection.get_bar_ids().unwrap().ids;
        let oneconfig = connection.get_bar_config(&ids[0]).unwrap();
    }

    #[test]
    fn get_version() {
        I3Connection::connect().unwrap().get_version().unwrap();
    }
}
<commit_msg>Implement get_version<commit_after>//! A library for controlling i3-wm through its ipc interface.

extern crate unix_socket;
extern crate byteorder;
extern crate serde;

use std::process;
use unix_socket::UnixStream;
use std::io;
use std::io::prelude::*;
use std::collections::HashMap;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use serde::json;

mod readhelp;
pub mod reply;

pub enum Event {
    // none of these are complete
    Workspace,
    Output,
    Mode,
    Window,
    BarConfigUpdate,
    Binding
}

/// An error while instantiating an I3Connection. Creating an I3Connection involves first getting
/// the i3 socket path, then connecting to the socket. Either part could go wrong, which is why
/// there are two possibilities here.
#[derive(Debug)]
pub enum I3ConnectError {
    /// An error while getting the socket path
    GetSocketPathError(io::Error),
    /// An error while accessing the socket
    SocketError(io::Error)
}

pub struct I3Connection {
    stream: UnixStream
}

impl I3Connection {

    /// Establishes an IPC connection to i3.
    pub fn connect() -> Result<I3Connection, I3ConnectError> {
        fn get_socket_path() -> io::Result<String> {
            let output = try!(process::Command::new("i3")
                                               .arg("--get-socketpath")
                                               .output());
            if output.status.success() {
                Ok(String::from_utf8_lossy(&output.stdout)
                          .trim_right_matches('\n')
                          .to_owned())
            } else {
                let prefix = "i3 --getsocketpath didn't return 0";
                let error_text = if output.stderr.len() > 0 {
                    format!("{}. stderr: {:?}", prefix, output.stderr)
                } else {
                    prefix.to_owned()
                };
                let error = io::Error::new(io::ErrorKind::Other, error_text);
                Err(error)
            }
        }

        return match get_socket_path() {
            Ok(path) => {
                match UnixStream::connect(path) {
                    Ok(stream) => Ok(I3Connection { stream: stream }),
                    Err(error) => Err(I3ConnectError::SocketError(error))
                }
            }
            Err(error) => Err(I3ConnectError::GetSocketPathError(error))
        }
    }

    fn send_message(&mut self, message_type: u32, payload: &str) -> io::Result<()> {
        let mut bytes = Vec::with_capacity(14 + payload.len());
        bytes.extend("i3-ipc".bytes());                              // 6 bytes
        try!(bytes.write_u32::<LittleEndian>(payload.len() as u32)); // 4 bytes
        try!(bytes.write_u32::<LittleEndian>(message_type));         // 4 bytes
        bytes.extend(payload.bytes());                               // payload.len() bytes
        self.stream.write_all(&bytes[..])
    }

    fn receive_message(&mut self) -> io::Result<String> {
        let magic_data = try!(readhelp::read_exact(&mut self.stream, 6));
        let magic_string = String::from_utf8_lossy(&magic_data);
        if magic_string != "i3-ipc" {
            let error_text = format!("unexpected magic string: expected 'i3-ipc' but got {}",
                                      magic_string);
            return Err(io::Error::new(io::ErrorKind::Other, error_text));
        }
        let payload_len = try!(self.stream.read_u32::<LittleEndian>());
        let message_type = try!(self.stream.read_u32::<LittleEndian>());
        let payload_data = try!(readhelp::read_exact(&mut self.stream, payload_len as usize));
        Ok(String::from_utf8_lossy(&payload_data).into_owned())
    }

    /// The payload of the message is a command for i3 (like the commands you can bind to keys
    /// in the configuration file) and will be executed directly after receiving it.
    pub fn command(&mut self, string: &str) -> io::Result<reply::Command> {
        try!(self.send_message(0, string));
        let payload = try!(self.receive_message());

        // assumes valid json
        let j: json::Value = json::from_str(&payload).unwrap();
        let commands = j.as_array().unwrap();
        let vec: Vec<_>
            = commands.iter()
                      .map(|c|
                           reply::CommandOutcome {
                               success: c.find("success").unwrap().as_boolean().unwrap(),
                               error: match c.find("error") {
                                   Some(val) => Some(val.as_string().unwrap().to_owned()),
                                   None => None
                               }
                           })
                      .collect();

        Ok(reply::Command { outcomes: vec })
    }

    fn unpack_rect(jrect: &json::Value) -> (i32, i32, i32, i32) {
        let x = jrect.find("x").unwrap().as_i64().unwrap() as i32;
        let y = jrect.find("y").unwrap().as_i64().unwrap() as i32;
        let width = jrect.find("width").unwrap().as_i64().unwrap() as i32;
        let height = jrect.find("height").unwrap().as_i64().unwrap() as i32;
        (x, y, width, height)
    }

    /// Gets the current workspaces.
    pub fn get_workspaces(&mut self) -> io::Result<reply::Workspaces> {
        try!(self.send_message(1, ""));
        let payload = try!(self.receive_message());

        let j: json::Value = json::from_str(&payload).unwrap();
        let jworkspaces = j.as_array().unwrap();
        let workspaces: Vec<_>
            = jworkspaces.iter()
                         .map(|w|
                              reply::Workspace {
                                  num: w.find("num").unwrap().as_i64().unwrap() as i32,
                                  name: w.find("name").unwrap().as_string().unwrap().to_owned(),
                                  visible: w.find("visible").unwrap().as_boolean().unwrap(),
                                  focused: w.find("focused").unwrap().as_boolean().unwrap(),
                                  urgent: w.find("urgent").unwrap().as_boolean().unwrap(),
                                  rect: I3Connection::unpack_rect(w.find("rect").unwrap()),
                                  output: w.find("output").unwrap().as_string().unwrap().to_owned()
                              })
                         .collect();
        Ok(reply::Workspaces { workspaces: workspaces })
    }

    /// Subscribes your connection to certain events.
    pub fn subscribe(&mut self) -> io::Result<reply::Subscribe> {
        panic!("not implemented");
    }

    /// Gets the current outputs.
    pub fn get_outputs(&mut self) -> io::Result<reply::Outputs> {
        try!(self.send_message(3, ""));
        let payload = try!(self.receive_message());

        let j: json::Value = json::from_str(&payload).unwrap();
        let joutputs = j.as_array().unwrap();
        let outputs: Vec<_>
            = joutputs.iter()
                      .map(|o|
                           reply::Output {
                               name: o.find("name").unwrap().as_string().unwrap().to_owned(),
                               active: o.find("active").unwrap().as_boolean().unwrap(),
                               current_workspace: match o.find("current_workspace").unwrap().clone() {
                                   json::Value::String(c_w) => Some(c_w),
                                   json::Value::Null => None,
                                   _ => unreachable!()
                               },
                               rect: I3Connection::unpack_rect(o.find("rect").unwrap())
                           })
                      .collect();
        Ok(reply::Outputs { outputs: outputs })
    }

    /// Gets the layout tree. i3 uses a tree as data structure which includes every container.
    pub fn get_tree(&mut self) -> io::Result<reply::Tree> {
        panic!("not implemented");
    }

    /// Gets a list of marks (identifiers for containers to easily jump to them later).
    pub fn get_marks(&mut self) -> io::Result<reply::Marks> {
        try!(self.send_message(5, ""));
        let payload = try!(self.receive_message());
        let marks: Vec<String> = json::from_str(&payload).unwrap();
        Ok(reply::Marks { marks: marks })
    }

    /// Gets an array with all configured bar IDs.
    pub fn get_bar_ids(&mut self) -> io::Result<reply::BarIds> {
        try!(self.send_message(6, ""));
        let payload = try!(self.receive_message());
        let ids: Vec<String> = json::from_str(&payload).unwrap();
        Ok(reply::BarIds { ids: ids })
    }

    /// Gets the configuration of the workspace bar with the given ID.
    pub fn get_bar_config(&mut self, id: &str) -> io::Result<reply::BarConfig> {
        try!(self.send_message(6, id));
        let payload = try!(self.receive_message());
        let j: json::Value = json::from_str(&payload).unwrap();
        Ok(reply::BarConfig {
            id: j.find("id").unwrap().as_string().unwrap().to_owned(),
            mode: j.find("mode").unwrap().as_string().unwrap().to_owned(),
            position: j.find("position").unwrap().as_string().unwrap().to_owned(),
            status_command: j.find("status_command").unwrap().as_string().unwrap().to_owned(),
            font: j.find("font").unwrap().as_string().unwrap().to_owned(),
            workspace_buttons: j.find("workspace_buttons").unwrap().as_boolean().unwrap(),
            binding_mode_indicator: j.find("binding_mode_indicator").unwrap().as_boolean().unwrap(),
            verbose: j.find("verbose").unwrap().as_boolean().unwrap(),
            colors: {
                let colors = j.find("colors").unwrap().as_object().unwrap();
                let mut map = HashMap::new();
                for c in colors.keys() {
                    let enum_key = match c.as_ref() {
                        "background" => reply::ColorableBarPart::Background,
                        "statusline" => reply::ColorableBarPart::Statusline,
                        "separator" => reply::ColorableBarPart::Separator,
                        "focused_workspace_text" => reply::ColorableBarPart::FocusedWorkspaceText,
                        "focused_workspace_bg" => reply::ColorableBarPart::FocusedWorkspaceBg,
                        "active_workspace_bg" => reply::ColorableBarPart::ActiveWorkspaceBg,
                        "inactive_workspace_text" => reply::ColorableBarPart::InactiveWorkspaceText,
                        "inactive_workspace_bg" => reply::ColorableBarPart::InactiveWorkspaceBg,
                        "urgent_workspace_text" => reply::ColorableBarPart::UrgentWorkspaceText,
                        "urgent_workspace_bar" => reply::ColorableBarPart::UrgentWorkspaceBar,
                        other => reply::ColorableBarPart::Undocumented(other.to_owned())
                    };
                    let hex = colors.get(c).unwrap().as_string().unwrap().to_owned();
                    map.insert(enum_key, hex);
                }
                map
            }
        })
    }

    /// Gets the version of i3. The reply will include the major, minor, patch and human-readable
    /// version.
    pub fn get_version(&mut self) -> io::Result<reply::Version> {
        try!(self.send_message(7, ""));
        let payload = try!(self.receive_message());
        let j: json::Value = json::from_str(&payload).unwrap();
        Ok(reply::Version {
            major: j.find("major").unwrap().as_i64().unwrap() as i32,
            minor: j.find("minor").unwrap().as_i64().unwrap() as i32,
            patch: j.find("patch").unwrap().as_i64().unwrap() as i32,
            human_readable: j.find("human_readable").unwrap().as_string().unwrap().to_owned()
        })
    }
}

#[cfg(test)]
mod test {
    use I3Connection;

    // for the following tests send a request and get the reponse.
    // response types are specific so often getting them at all indicates success.
    // can't do much better without mocking an i3 installation.

    #[test]
    fn connect() {
        I3Connection::connect().unwrap();
    }

    #[test]
    fn command_nothing() {
        let mut connection = I3Connection::connect().unwrap();
        let result = connection.command("").unwrap();
        assert_eq!(result.outcomes.len(), 0);
    }

    #[test]
    fn command_single_sucess() {
        let mut connection = I3Connection::connect().unwrap();
        let a = connection.command("exec /bin/true").unwrap();
        assert_eq!(a.outcomes.len(), 1);
        assert!(a.outcomes[0].success);
    }

    #[test]
    fn command_multiple_success() {
        let mut connection = I3Connection::connect().unwrap();
        let result = connection.command("exec /bin/true; exec /bin/true").unwrap();
        assert_eq!(result.outcomes.len(), 2);
        assert!(result.outcomes[0].success);
        assert!(result.outcomes[1].success);
    }

    #[test]
    fn command_fail() {
        let mut connection = I3Connection::connect().unwrap();
        let result = connection.command("ThisIsClearlyNotACommand").unwrap();
        assert_eq!(result.outcomes.len(), 1);
        assert!(!result.outcomes[0].success);
    }

    #[test]
    fn get_workspaces() {
        I3Connection::connect().unwrap().get_workspaces().unwrap();
    }

    #[test]
    fn subscribe() {
        I3Connection::connect().unwrap().subscribe().unwrap();
    }

    #[test]
    fn get_outputs() {
        I3Connection::connect().unwrap().get_outputs().unwrap();
    }

    #[test]
    fn get_tree() {
        I3Connection::connect().unwrap().get_tree().unwrap();
    }

    #[test]
    fn get_marks() {
        I3Connection::connect().unwrap().get_marks().unwrap();
    }

    #[test]
    fn get_bar_ids() {
        I3Connection::connect().unwrap().get_bar_ids().unwrap();
    }

    #[test]
    fn get_bar_ids_and_one_config() {
        let mut connection = I3Connection::connect().unwrap();
        let ids = connection.get_bar_ids().unwrap().ids;
        let oneconfig = connection.get_bar_config(&ids[0]).unwrap();
    }

    #[test]
    fn get_version() {
        I3Connection::connect().unwrap().get_version().unwrap();
    }
}
<|endoftext|>


<commit_before>
pub extern crate crypto;

use crypto::digest::Digest;

pub trait Hashable {
    fn to_bytes(&self) -> &[u8];
}

impl Hashable for String {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

impl Hashable for str {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

enum Tree<T> where T: Hashable + Clone {
    Leaf {
        hash: Vec<u8>,
        value: T
    },

    Node {
        hash: Vec<u8>,
        left: Box<Tree<T>>,
        right: Box<Tree<T>>
    }
}

impl <T> Tree<T> where T: Hashable + Clone {
    fn get_hash<'a>(&'a self) -> &'a Vec<u8> {
        match *self {
            Tree::Leaf { hash: ref hash, value: _ }          => hash,
            Tree::Node { hash: ref hash, left: _, right: _ } => hash
        }
    }
}

pub struct MerkleTree<D, T> where D: Digest + Clone, T: Hashable + Clone {
    digest: D,
    tree: Tree<T>
}

impl <T> Tree<T> where T: Hashable + Clone {

    // fn from_chunks<D>(digest: D, iter: Chunks<Tree<T>>) -> Tree<T> where D: Digest {

    // }

}

fn make_hash<D, T>(mut digest: D, bytes: &[u8]) -> Vec<u8> where D: Digest, T: Hashable + Clone {
    let mut hash = Vec::with_capacity(digest.output_bytes());
    digest.reset();
    digest.input(bytes);
    digest.result(hash.as_mut_slice());
    digest.reset();
    return hash;
}

fn combine_hashes<D>(mut digest: D, left: &[u8], right: &[u8]) -> Vec<u8> where D: Digest {
    let mut hash = Vec::with_capacity(digest.output_bytes());
    digest.reset();
    digest.input(left);
    digest.input(right);
    digest.result(hash.as_mut_slice());
    digest.reset();
    return hash;
}

fn make_leaf<D, T>(digest: D, value: T) -> Tree<T> where D: Digest + Clone, T: Hashable + Clone {
    return Tree::Leaf {
        hash: make_hash::<D, T>(digest, value.to_bytes()),
        value: value
    };
}

impl <D, T> MerkleTree<D, T> where D: Digest + Clone, T: Hashable + Clone {

    // TODO: Don't clone all the things
    pub fn from_vec(digest: D, values: Vec<T>) -> MerkleTree<D, T> {
        let leafs: Vec<Box<Tree<T>>> = values.iter().map(|v| Box::new(make_leaf::<D, T>(digest.clone(), v.clone()))).collect();

        for chunk in leafs.chunks(2) {
            if chunk.len() == 1 {

            } else {
                let left  = chunk[0].clone();
                let right = chunk[1].clone();

                let combined_hash = combine_hashes::<D>(digest.clone(), left.get_hash().as_slice(), right.get_hash().as_slice());
                let node = Tree::Node {
                   hash: combined_hash,
                   left: left,
                   right: right
                };
            }
        }

        return MerkleTree {
            digest: digest.clone(),
            tree: make_leaf::<D, T>(digest, values[0].clone())
        };

    }

}

#[cfg(test)]
use crypto::sha3::Sha3;

#[test]
fn test_stuff() {
}

#[cfg(test)]
pub mod tests;

<commit_msg>Clone wars<commit_after>
pub extern crate crypto;

use crypto::digest::Digest;

pub trait Hashable {
    fn to_bytes(&self) -> &[u8];
}

impl Hashable for String {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

impl Hashable for str {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

#[derive(Clone)]
enum Tree<T> where T: Hashable + Clone {
    Leaf {
        hash: Vec<u8>,
        value: T
    },

    Node {
        hash: Vec<u8>,
        left: Box<Tree<T>>,
        right: Box<Tree<T>>
    }
}

impl <T> Tree<T> where T: Hashable + Clone {
    fn get_hash<'a>(&'a self) -> &'a Vec<u8> {
        match *self {
            Tree::Leaf { hash: ref hash, value: _ }          => hash,
            Tree::Node { hash: ref hash, left: _, right: _ } => hash
        }
    }
}

pub struct MerkleTree<D, T> where D: Digest + Clone, T: Hashable + Clone {
    digest: D,
    tree: Tree<T>
}

impl <T> Tree<T> where T: Hashable + Clone {

    // fn from_chunks<D>(digest: D, iter: Chunks<Tree<T>>) -> Tree<T> where D: Digest {

    // }

}

fn make_hash<D, T>(mut digest: D, bytes: &[u8]) -> Vec<u8> where D: Digest, T: Hashable + Clone {
    let mut hash = Vec::with_capacity(digest.output_bytes());
    digest.reset();
    digest.input(bytes);
    digest.result(hash.as_mut_slice());
    digest.reset();
    return hash;
}

fn combine_hashes<D>(mut digest: D, left: &[u8], right: &[u8]) -> Vec<u8> where D: Digest {
    let mut hash = Vec::with_capacity(digest.output_bytes());
    digest.reset();
    digest.input(left);
    digest.input(right);
    digest.result(hash.as_mut_slice());
    digest.reset();
    return hash;
}

fn make_leaf<D, T>(digest: D, value: T) -> Tree<T> where D: Digest + Clone, T: Hashable + Clone {
    return Tree::Leaf {
        hash: make_hash::<D, T>(digest, value.to_bytes()),
        value: value
    };
}

impl <D, T> MerkleTree<D, T> where D: Digest + Clone, T: Hashable + Clone {

    // TODO: Don't clone all the things
    pub fn from_vec(digest: D, values: Vec<T>) -> MerkleTree<D, T> {
        let leafs: Vec<Tree<T>> = values.iter().map(|v| make_leaf::<D, T>(digest.clone(), v.clone())).collect();

        for chunk in leafs.chunks(2) {
            if chunk.len() == 1 {

            } else {
                let left: Tree<T>  = chunk[0].clone();
                let right: Tree<T> = chunk[1].clone();

                let combined_hash = combine_hashes::<D>(digest.clone(), left.get_hash().as_slice(), right.get_hash().as_slice());
                let node = Tree::Node {
                   hash: combined_hash,
                   left: Box::new(left),
                   right: Box::new(right)
                };
            }
        }

        return MerkleTree {
            digest: digest.clone(),
            tree: make_leaf::<D, T>(digest, values[0].clone())
        };

    }

}

#[cfg(test)]
use crypto::sha3::Sha3;

#[test]
fn test_stuff() {
}

#[cfg(test)]
pub mod tests;
<|endoftext|>


<commit_before>#![feature(associated_types, macro_rules)]

//! Machine scalar casting that meets your expectations

/// Overflow error
pub struct Overflow;

/// Underflow error
pub struct Underflow;

/// Errors that may arise when casting from integers
pub enum FromInteger {
    Overflow,
    Underflow,
}

/// Errors that may arise when casting from floats
pub enum FromFloat {
    NaN,
    Overflow,
    Underflow,
}

/// The "casting from" operation
pub trait CastFrom<Src> {
    type Output;

    fn from(src: Src) -> Output;
}

/// The "casting to" operation
pub trait CastTo {
    fn to<Dst: CastFrom<Self>>() -> Dst::Output {
        Dst::from(self)
    }
}

macro_rules! impl_cast_to {
    ($($ty:ty),+) => {$(
        impl CastTo for $ty {})+
    }
}

impl_cast_to!(int, i8, i16, i32, i64, uint, u8, u16, u32, u64, f32, f64)

macro_rules! promotion {
    ($($src:ty -> $($dst: ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = $dst;

            #[inline(always)]
            fn from(src: $src) -> $dst {
                 // NB Sanity check
                debug_assert!(mem::size_of::<$src>() <= mem::size_of::<$dst>());

                src as $dst
            }
        })+)+
    }
}

macro_rules! half_promotion {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, Underflow>;

            fn from(src: $src) -> Result<$dst, Underflow> {
                 // NB Sanity check
                debug_assert!(mem::size_of::<$src>() <= mem::size_of::<$dst>());

                if self < 0 {
                    Err(Underflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

macro_rules! from_unsigned {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, Overflow>;

            fn from(src: $src) -> Result<$dst, Overflow> {
                // NB Sanity check
                debug_assert!(mem::size_of::<$src>() >= mem::size_of::<$dst>());

                if self > $dst::max_value() as $src {
                    Err(Overflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

macro_rules! from_signed {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, FromInteger>;

            fn cast(self) -> Result<$dst, FromInteger> {
                // NB Sanity check
                debug_assert!(mem::size_of::<$src>() > mem::size_of::<$dst>());

                if src < $dst::min_value() as $src {
                    Err(FromInteger::Underflow)
                } else if src > $dst::max_value() as $src {
                    Err(FromInteger::Overflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

macro_rules! from_float {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, FromFloat>;

            fn from(src: $src) -> Result<$dst, FromFloat> {
                if src.is_nan() {
                    Err(FromFloat::Nan)
                } else if src < $dst::min_value() as $src {
                    Err(FromFloat::Underflow)
                } else if src > $dst::max_value() as $src {
                    Err(FromFloat::Overflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

// Signed
promotion!{
    i8   -> f32, f64, i8, i16, i32, i64;
    i16  -> f32, f64,     i16, i32, i64;
    i32  -> f32, f64,          i32, i64;
    i64  -> f32, f64,               i64;
}

half_promotion!{
    i8   ->                              u8, u16, u32, u64;
    i16  ->                                  u16, u32, u64;
    i32  ->                                       u32, u64;
    i64  ->                                            u64;
}

from_signed!{

    i16  ->           i8,                u8;
    i32  ->           i8, i16,           u8, u16;
    i64  ->           i8, i16, i32,      u8, u16, u32;
}

// Unsigned
promotion!{
    u8   -> f32, f64,     i16, i32, i64, u8, u16, u32, u64;
    u16  -> f32, f64,          i32, i64,     u16, u32, u64;
    u32  -> f32, f64,               i64,          u32, u64;
    u64  -> f32, f64,                                  u64;
}

from_unsigned!{
    u8   ->           i8;
    u16  ->           i8, i16,           u8;
    u32  ->           i8, i16, i32,      u8, u16;
    u64  ->           i8, i16, i32, i64, u8, u16, u32;
}

// Float
promotion!{
    f32  -> f32, f64;
    f64  ->      f64;
}

from_float!{
    f32  ->           i8, i16, i32, i64, u8, u16, u32, u64;
    f64  -> f32,      i8, i16, i32, i64, u8, u16, u32, u64;
}

// Machine dependent scalars
#[cfg(any(target_arch = "x86", target_arch = "arm"))]
promotion!{
    int  -> f32, f64,          i32, i64;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
half_promotion!{
    int  ->                                       u32, u64;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
from_signed!{
    int  ->           i8, i16,           u8, u16;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
promotion!{
    uint -> f32, f64,               i64,          u32, u64;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
from_unsigned!{
    uint ->           i8, i16, i32,      u8, u16;
}

#[cfg(any(target_arch = "x86_64"))]
promotion!{
    int  -> f32, f64,               i64;
}

#[cfg(any(target_arch = "x86_64"))]
half_promotion!{
    int  ->                                            u64;
}

#[cfg(any(target_arch = "x86_64"))]
from_signed!{
    int  ->           i8, i16, i32,      u8, u16, u32;
}

#[cfg(any(target_arch = "x86_64"))]
promotion!{
    uint -> f32, f64,                                  u64;
}

#[cfg(any(target_arch = "x86_64"))]
from_unsigned!{
    uint ->           i8, i16, i32, i64, u8, u16, u32;
}
<commit_msg>fix(CastTo): add missing `self` parameter<commit_after>#![feature(associated_types, macro_rules)]

//! Machine scalar casting that meets your expectations

/// Overflow error
pub struct Overflow;

/// Underflow error
pub struct Underflow;

/// Errors that may arise when casting from integers
pub enum FromInteger {
    Overflow,
    Underflow,
}

/// Errors that may arise when casting from floats
pub enum FromFloat {
    NaN,
    Overflow,
    Underflow,
}

/// The "casting from" operation
pub trait CastFrom<Src> {
    type Output;

    fn from(src: Src) -> Output;
}

/// The "casting to" operation
pub trait CastTo {
    fn to<Dst: CastFrom<Self>>(self) -> Dst::Output {
        Dst::from(self)
    }
}

macro_rules! impl_cast_to {
    ($($ty:ty),+) => {$(
        impl CastTo for $ty {})+
    }
}

impl_cast_to!(int, i8, i16, i32, i64, uint, u8, u16, u32, u64, f32, f64)

macro_rules! promotion {
    ($($src:ty -> $($dst: ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = $dst;

            #[inline(always)]
            fn from(src: $src) -> $dst {
                 // NB Sanity check
                debug_assert!(mem::size_of::<$src>() <= mem::size_of::<$dst>());

                src as $dst
            }
        })+)+
    }
}

macro_rules! half_promotion {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, Underflow>;

            fn from(src: $src) -> Result<$dst, Underflow> {
                 // NB Sanity check
                debug_assert!(mem::size_of::<$src>() <= mem::size_of::<$dst>());

                if self < 0 {
                    Err(Underflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

macro_rules! from_unsigned {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, Overflow>;

            fn from(src: $src) -> Result<$dst, Overflow> {
                // NB Sanity check
                debug_assert!(mem::size_of::<$src>() >= mem::size_of::<$dst>());

                if self > $dst::max_value() as $src {
                    Err(Overflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

macro_rules! from_signed {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, FromInteger>;

            fn cast(self) -> Result<$dst, FromInteger> {
                // NB Sanity check
                debug_assert!(mem::size_of::<$src>() > mem::size_of::<$dst>());

                if src < $dst::min_value() as $src {
                    Err(FromInteger::Underflow)
                } else if src > $dst::max_value() as $src {
                    Err(FromInteger::Overflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

macro_rules! from_float {
    ($($src:ty -> $($dst:ty),+);+;) => {$($(
        impl CastFrom<$src> for $dst {
            type Output = Result<$dst, FromFloat>;

            fn from(src: $src) -> Result<$dst, FromFloat> {
                if src.is_nan() {
                    Err(FromFloat::Nan)
                } else if src < $dst::min_value() as $src {
                    Err(FromFloat::Underflow)
                } else if src > $dst::max_value() as $src {
                    Err(FromFloat::Overflow)
                } else {
                    Ok(src as $dst)
                }
            }
        })+)+
    }
}

// Signed
promotion!{
    i8   -> f32, f64, i8, i16, i32, i64;
    i16  -> f32, f64,     i16, i32, i64;
    i32  -> f32, f64,          i32, i64;
    i64  -> f32, f64,               i64;
}

half_promotion!{
    i8   ->                              u8, u16, u32, u64;
    i16  ->                                  u16, u32, u64;
    i32  ->                                       u32, u64;
    i64  ->                                            u64;
}

from_signed!{

    i16  ->           i8,                u8;
    i32  ->           i8, i16,           u8, u16;
    i64  ->           i8, i16, i32,      u8, u16, u32;
}

// Unsigned
promotion!{
    u8   -> f32, f64,     i16, i32, i64, u8, u16, u32, u64;
    u16  -> f32, f64,          i32, i64,     u16, u32, u64;
    u32  -> f32, f64,               i64,          u32, u64;
    u64  -> f32, f64,                                  u64;
}

from_unsigned!{
    u8   ->           i8;
    u16  ->           i8, i16,           u8;
    u32  ->           i8, i16, i32,      u8, u16;
    u64  ->           i8, i16, i32, i64, u8, u16, u32;
}

// Float
promotion!{
    f32  -> f32, f64;
    f64  ->      f64;
}

from_float!{
    f32  ->           i8, i16, i32, i64, u8, u16, u32, u64;
    f64  -> f32,      i8, i16, i32, i64, u8, u16, u32, u64;
}

// Machine dependent scalars
#[cfg(any(target_arch = "x86", target_arch = "arm"))]
promotion!{
    int  -> f32, f64,          i32, i64;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
half_promotion!{
    int  ->                                       u32, u64;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
from_signed!{
    int  ->           i8, i16,           u8, u16;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
promotion!{
    uint -> f32, f64,               i64,          u32, u64;
}

#[cfg(any(target_arch = "x86", target_arch = "arm"))]
from_unsigned!{
    uint ->           i8, i16, i32,      u8, u16;
}

#[cfg(any(target_arch = "x86_64"))]
promotion!{
    int  -> f32, f64,               i64;
}

#[cfg(any(target_arch = "x86_64"))]
half_promotion!{
    int  ->                                            u64;
}

#[cfg(any(target_arch = "x86_64"))]
from_signed!{
    int  ->           i8, i16, i32,      u8, u16, u32;
}

#[cfg(any(target_arch = "x86_64"))]
promotion!{
    uint -> f32, f64,                                  u64;
}

#[cfg(any(target_arch = "x86_64"))]
from_unsigned!{
    uint ->           i8, i16, i32, i64, u8, u16, u32;
}
<|endoftext|>


<commit_before>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;

// Crates used to reexport.
extern crate "ai_behavior" as ai_behavior_lib;
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "window" as window_lib;
extern crate "cam" as cam_lib;
extern crate "current" as current_lib;
extern crate "quack" as quack_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;

// Reexports.
pub use current_lib as current;
pub use quack_lib as quack;
pub use ai_behavior_lib as ai_behavior;
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use window_lib as window;
pub use cam_lib as cam;
pub use fps_counter_lib as fps_counter;
pub use drag_controller_lib as drag_controller;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    WindowSettings,
};

pub use quack::{
    Action,
    ActOn,
    Get,
    GetFrom,
    Set,
    SetAt,
};
pub use current::{
    Current,
    CurrentGuard,
};

#[cfg(feature = "include_gfx")]
use gfx_graphics::G2D;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceHelper };
use opengl_graphics::Gl;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;
use std::ops::Deref;

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

fn start_window(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut gl = Rc::new(RefCell::new(Gl::new(opengl)));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    let window_guard = CurrentGuard::new(&mut window);
    let gl_guard = CurrentGuard::new(&mut gl);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(gl_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_gfx")]
fn start_gfx(f: ||) {
    let window = current_window();

    let mut device = Rc::new(RefCell::new(gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    })));
    let mut g2d = Rc::new(RefCell::new(G2D::new(device.borrow_mut().deref_mut())));
    let mut renderer = Rc::new(RefCell::new(device.borrow_mut().create_renderer()));
    let event::window::Size([w, h]) = window.get();
    let mut frame = Rc::new(RefCell::new(gfx::Frame::new(w as u16, h as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx(f: ||) {
    f();
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    start_window(opengl, window_settings, || {
        if cfg!(feature = "include_gfx") {
            start_gfx(|| f());
        } else {
            f();
        }
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<gfx::GlDevice>> {
    unsafe {
        Current::<Rc<RefCell<gfx::GlDevice>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
pub fn current_gl() -> Rc<RefCell<Gl>> {
    unsafe {
        Current::<Rc<RefCell<Gl>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<G2D>> {
    unsafe {
        Current::<Rc<RefCell<G2D>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_frame() -> Rc<RefCell<gfx::Frame>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Frame>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Rc<RefCell<WindowBackEnd>>, event::Event> {
    event::events(current_window())
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    current_fps_counter().borrow_mut().tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    current_window().set_mut(window::Title(text));
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use window::ShouldClose;
    let ShouldClose(val) = current_window().get();
    val
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx(
    bg_color: Option<[f32; 4]>,
    f: |graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = renderer.deref_mut();
    current_g2d().borrow_mut().draw(
        renderer,
        current_frame().borrow_mut().deref_mut(),
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    current_gfx_device().borrow_mut().submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
pub fn render_2d_opengl(
    bg_color: Option<[f32; 4]>,
    f: |graphics::Context,
        &mut opengl_graphics::Gl|
) {
    use std::ops::Deref;

    let window::Size([w, h]) = current_window().borrow().deref().get();
    current_gl().borrow_mut().draw([0, 0, w as i32, h as i32], |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<commit_msg>Upgraded to latest Rust<commit_after>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;

// Crates used to reexport.
extern crate "ai_behavior" as ai_behavior_lib;
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "window" as window_lib;
extern crate "cam" as cam_lib;
extern crate "current" as current_lib;
extern crate "quack" as quack_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;

// Reexports.
pub use current_lib as current;
pub use quack_lib as quack;
pub use ai_behavior_lib as ai_behavior;
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use window_lib as window;
pub use cam_lib as cam;
pub use fps_counter_lib as fps_counter;
pub use drag_controller_lib as drag_controller;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    WindowSettings,
};

pub use quack::{
    Action,
    ActOn,
    Get,
    GetFrom,
    Set,
    SetAt,
};
pub use current::{
    Current,
    CurrentGuard,
};

#[cfg(feature = "include_gfx")]
use gfx_graphics::G2D;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceHelper };
use opengl_graphics::Gl;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;
use std::ops::Deref;

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

fn start_window<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut gl = Rc::new(RefCell::new(Gl::new(opengl)));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    let window_guard = CurrentGuard::new(&mut window);
    let gl_guard = CurrentGuard::new(&mut gl);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(gl_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_gfx")]
fn start_gfx<F>(f: F)
    where
        F: FnMut()
{
    let window = current_window();

    let mut device = Rc::new(RefCell::new(gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    })));
    let mut g2d = Rc::new(RefCell::new(G2D::new(device.borrow_mut().deref_mut())));
    let mut renderer = Rc::new(RefCell::new(device.borrow_mut().create_renderer()));
    let event::window::Size([w, h]) = window.get();
    let mut frame = Rc::new(RefCell::new(gfx::Frame::new(w as u16, h as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

/// Initializes window and sets up current objects.
pub fn start<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    start_window(opengl, window_settings, || {
        if cfg!(feature = "include_gfx") {
            start_gfx(|| f());
        } else {
            f();
        }
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<gfx::GlDevice>> {
    unsafe {
        Current::<Rc<RefCell<gfx::GlDevice>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
pub fn current_gl() -> Rc<RefCell<Gl>> {
    unsafe {
        Current::<Rc<RefCell<Gl>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<G2D>> {
    unsafe {
        Current::<Rc<RefCell<G2D>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<gfx::GlCommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_frame() -> Rc<RefCell<gfx::Frame>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Frame>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Rc<RefCell<WindowBackEnd>>, input::Input, event::Event> {
    event::events(current_window())
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> usize {
    current_fps_counter().borrow_mut().tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    current_window().set_mut(window::Title(text));
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use window::ShouldClose;
    let ShouldClose(val) = current_window().get();
    val
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context,
            &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>)
{
    use gfx::Device;

    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = renderer.deref_mut();
    current_g2d().borrow_mut().draw(
        renderer,
        current_frame().borrow_mut().deref_mut(),
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    current_gfx_device().borrow_mut().submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
pub fn render_2d_opengl<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context, &mut opengl_graphics::Gl)
{
    use std::ops::Deref;

    let window::Size([w, h]) = current_window().borrow().deref().get();
    current_gl().borrow_mut().draw([0, 0, w as i32, h as i32], |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<|endoftext|>