<commit_before>//! which
//!
//! A Rust equivalent of Unix command "which".
//! # Exmaple:
//!
//! To find wihch rustc exectable binary is using.
//!
//! ``` norun
//! use which::which;
//!
//! let result = which::which("rustc").unwrap();
//! assert_eq!(result, PathBuf::from("/usr/bin/rustc"));
//!
//! ```

extern crate libc;
#[cfg(test)]
extern crate tempdir;

use std::path::{Path,PathBuf};
use std::{env, fs};
#[cfg(unix)]
use std::ffi::CString;
use std::ffi::OsStr;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;

fn is_exist(bin_path: &PathBuf) -> bool {

    match fs::metadata(bin_path).map(|metadata|{
        metadata.is_file()
    }) {
        Ok(true) => true,
        _ => false
    }
}

/// Return `true` if `path` is executable.
#[cfg(unix)]
fn is_executable(path: &Path) -> bool {
    CString::new(path.as_os_str().as_bytes())
        .and_then(|c| {
            Ok(unsafe { libc::access(c.as_ptr(), libc::X_OK) == 0 })
        })
        .unwrap_or(false)
}

#[cfg(not(unix))]
fn is_executable(_path: &Path) -> bool { true }

/// Find a exectable binary's path by name.
///
/// # Example
///
/// ``` norun
/// use which::which;
/// use std::path::PathBuf;
///
/// let result = which::which("rustc").unwrap();
/// assert_eq!(result, PathBuf::from("/usr/bin/rustc"));
///
/// ```
pub fn which<T: AsRef<OsStr>>(binary_name: T)
             -> Result<PathBuf, &'static str> {
    which_in(binary_name, env::var_os("PATH"))
}

/// Find `binary_name` in the path list `paths`.
pub fn which_in<T, U>(binary_name: T, paths: Option<U>)
             -> Result<PathBuf, &'static str>
                where T: AsRef<OsStr>,
                U: AsRef<OsStr> {
    let path_buf = paths.and_then(
        |paths| -> Option<PathBuf> {
            for path in env::split_paths(&paths) {
                let bin_path = path.join(binary_name.as_ref());
                if is_exist(&bin_path) && is_executable(&bin_path) {
                    return Some(bin_path);
                }
            }
            return None;

        });

    match path_buf {
        Some(path) => Ok(path),
        None => Err("Can not find binary path")
    }

}

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

    use std::env;
    use std::ffi::OsString;
    use std::fs;
    use std::io;
    use std::path::{Path,PathBuf};
    use tempdir::TempDir;

    struct TestFixture {
        /// Temp directory.
        pub tempdir: TempDir,
        /// $PATH
        pub paths: OsString,
        /// Binaries created in $PATH
        pub bins: Vec<PathBuf>,
    }

    const SUBDIRS: &'static [&'static str] = &["a", "b", "c"];
    const BIN_NAME: &'static str = "bin";

    #[cfg(unix)]
    fn mk_bin(dir: &Path, path: &str) -> io::Result<PathBuf> {
        use libc;
        use std::os::unix::fs::OpenOptionsExt;
        let bin = dir.join(path);
        fs::OpenOptions::new()
            .write(true)
            .create(true)
            .mode(0o666 | (libc::S_IXUSR as u32))
            .open(&bin)
            .and_then(|_f| bin.canonicalize())
    }

    fn touch(dir: &Path, path: &str) -> io::Result<PathBuf> {
        let b = dir.join(path);
        fs::File::create(&b)
            .and_then(|_f| b.canonicalize())
    }

    #[cfg(not(unix))]
    fn mk_bin(dir: &Path, path: &str) -> io::Result<PathBuf> {
        touch(dir, path)
    }

    impl TestFixture {
        pub fn new() -> TestFixture {
            let tempdir = TempDir::new("which_tests").unwrap();
            let mut builder = fs::DirBuilder::new();
            builder.recursive(true);
            let mut paths = vec!();
            let mut bins = vec!();
            for d in SUBDIRS.iter() {
                let p = tempdir.path().join(d);
                builder.create(&p).unwrap();
                bins.push(mk_bin(&p, &BIN_NAME).unwrap());
                paths.push(p);
            }
            TestFixture {
                tempdir: tempdir,
                paths: env::join_paths(paths).unwrap(),
                bins: bins,
            }
        }

        #[allow(dead_code)]
        pub fn touch(&self, path: &str) -> io::Result<PathBuf> {
            touch(self.tempdir.path(), &path)
        }

        pub fn mk_bin(&self, path: &str) -> io::Result<PathBuf> {
            mk_bin(self.tempdir.path(), &path)
        }
    }

    fn _which(f: &TestFixture, path: &str) -> Result<PathBuf, &'static str> {
        which_in(path, Some(f.paths.clone()))
    }

    #[test]
    fn it_works() {
        use std::process::Command;
        let result = which("rustc");
        assert!(result.is_ok());

        let which_result = Command::new("which")
            .arg("rustc")
            .output();

        assert_eq!(String::from(result.unwrap().to_str().unwrap()),
                   String::from_utf8(which_result.unwrap().stdout).unwrap().trim());
    }

    #[test]
    fn test_which() {
        let f = TestFixture::new();
        assert_eq!(_which(&f, &BIN_NAME).unwrap(), f.bins[0])
    }

    #[test]
    fn test_which_not_found() {
        let f = TestFixture::new();
        assert!(_which(&f, "a").is_err());
    }

    #[test]
    fn test_which_second() {
        let f = TestFixture::new();
        let b = f.mk_bin("b/another").unwrap();
        assert_eq!(_which(&f, "another").unwrap(), b);
    }

    #[test]
    #[cfg(unix)]
    fn test_which_non_executable() {
        // Shouldn't return non-executable files.
        let f = TestFixture::new();
        f.touch("b/another").unwrap();
        assert!(_which(&f, "another").is_err());
    }
}
<commit_msg>Support absolute and relative paths passed in<commit_after>//! which
//!
//! A Rust equivalent of Unix command "which".
//! # Exmaple:
//!
//! To find wihch rustc exectable binary is using.
//!
//! ``` norun
//! use which::which;
//!
//! let result = which::which("rustc").unwrap();
//! assert_eq!(result, PathBuf::from("/usr/bin/rustc"));
//!
//! ```

extern crate libc;
#[cfg(test)]
extern crate tempdir;

use std::path::{Path,PathBuf};
use std::{env, fs};
#[cfg(unix)]
use std::ffi::CString;
use std::ffi::OsStr;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;

fn is_exist(bin_path: &Path) -> bool {

    match fs::metadata(bin_path).map(|metadata|{
        metadata.is_file()
    }) {
        Ok(true) => true,
        _ => false
    }
}

/// Return `true` if `path` is executable.
#[cfg(unix)]
fn is_executable(path: &Path) -> bool {
    CString::new(path.as_os_str().as_bytes())
        .and_then(|c| {
            Ok(unsafe { libc::access(c.as_ptr(), libc::X_OK) == 0 })
        })
        .unwrap_or(false)
}

#[cfg(not(unix))]
fn is_executable(_path: &Path) -> bool { true }

/// Find a exectable binary's path by name.
///
/// If given an absolute path, returns it if the file exists and is executable.
///
/// If given a relative path, returns an absolute path to the file if
/// it exists and is executable.
///
/// If given a string without path separators, looks for a file named
/// `binary_name` at each directory in `$PATH` and if it finds an executable
/// file there, returns it.
///
/// # Example
///
/// ``` norun
/// use which::which;
/// use std::path::PathBuf;
///
/// let result = which::which("rustc").unwrap();
/// assert_eq!(result, PathBuf::from("/usr/bin/rustc"));
///
/// ```
pub fn which<T: AsRef<OsStr>>(binary_name: T)
             -> Result<PathBuf, &'static str> {
    env::current_dir()
        .or_else(|_| Err("Couldn't get current directory"))
        .and_then(|cwd| which_in(binary_name, env::var_os("PATH"), &cwd))
}

/// Find `binary_name` in the path list `paths`, using `cwd` to resolve relative paths.
pub fn which_in<T, U, V>(binary_name: T, paths: Option<U>, cwd: V)
             -> Result<PathBuf, &'static str>
                where T: AsRef<OsStr>,
                      U: AsRef<OsStr>,
                      V: AsRef<Path> {
    // Does it have a path separator?
    let path = Path::new(binary_name.as_ref());
    if path.components().count() > 1 {
        if path.is_absolute() {
            if is_exist(path) && is_executable(path) {
                // Already fine.
                Ok(PathBuf::from(path))
            } else {
                // Absolute path but it's not usable.
                Err("Bad absolute path")
            }
        } else {
            // Try to make it absolute.
            let mut new_path = PathBuf::from(cwd.as_ref());
            new_path.push(path);
            if is_exist(&new_path) && is_executable(&new_path) {
                Ok(new_path)
            } else {
                // File doesn't exist or isn't executable.
                Err("Bad relative path")
            }
        }
    } else {
        // No separator, look it up in `paths`.
        paths.and_then(
            |paths|
            env::split_paths(paths.as_ref())
                .map(|p| p.join(binary_name.as_ref()))
                .skip_while(|p| !(is_exist(&p) && is_executable(&p)))
                .next())
            .ok_or("Cannot find binary path")
    }
}

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

    use std::env;
    use std::ffi::{OsStr,OsString};
    use std::fs;
    use std::io;
    use std::path::{Path,PathBuf};
    use tempdir::TempDir;

    struct TestFixture {
        /// Temp directory.
        pub tempdir: TempDir,
        /// $PATH
        pub paths: OsString,
        /// Binaries created in $PATH
        pub bins: Vec<PathBuf>,
    }

    const SUBDIRS: &'static [&'static str] = &["a", "b", "c"];
    const BIN_NAME: &'static str = "bin";

    #[cfg(unix)]
    fn mk_bin(dir: &Path, path: &str) -> io::Result<PathBuf> {
        use libc;
        use std::os::unix::fs::OpenOptionsExt;
        let bin = dir.join(path);
        fs::OpenOptions::new()
            .write(true)
            .create(true)
            .mode(0o666 | (libc::S_IXUSR as u32))
            .open(&bin)
            .and_then(|_f| bin.canonicalize())
    }

    fn touch(dir: &Path, path: &str) -> io::Result<PathBuf> {
        let b = dir.join(path);
        fs::File::create(&b)
            .and_then(|_f| b.canonicalize())
    }

    #[cfg(not(unix))]
    fn mk_bin(dir: &Path, path: &str) -> io::Result<PathBuf> {
        touch(dir, path)
    }

    impl TestFixture {
        pub fn new() -> TestFixture {
            let tempdir = TempDir::new("which_tests").unwrap();
            let mut builder = fs::DirBuilder::new();
            builder.recursive(true);
            let mut paths = vec!();
            let mut bins = vec!();
            for d in SUBDIRS.iter() {
                let p = tempdir.path().join(d);
                builder.create(&p).unwrap();
                bins.push(mk_bin(&p, &BIN_NAME).unwrap());
                paths.push(p);
            }
            TestFixture {
                tempdir: tempdir,
                paths: env::join_paths(paths).unwrap(),
                bins: bins,
            }
        }

        #[allow(dead_code)]
        pub fn touch(&self, path: &str) -> io::Result<PathBuf> {
            touch(self.tempdir.path(), &path)
        }

        pub fn mk_bin(&self, path: &str) -> io::Result<PathBuf> {
            mk_bin(self.tempdir.path(), &path)
        }
    }

    fn _which<T: AsRef<OsStr>>(f: &TestFixture, path: T) -> Result<PathBuf, &'static str> {
        which_in(path, Some(f.paths.clone()), f.tempdir.path())
    }

    #[test]
    fn it_works() {
        use std::process::Command;
        let result = which("rustc");
        assert!(result.is_ok());

        let which_result = Command::new("which")
            .arg("rustc")
            .output();

        assert_eq!(String::from(result.unwrap().to_str().unwrap()),
                   String::from_utf8(which_result.unwrap().stdout).unwrap().trim());
    }

    #[test]
    fn test_which() {
        let f = TestFixture::new();
        assert_eq!(_which(&f, &BIN_NAME).unwrap().canonicalize().unwrap(),
                   f.bins[0])
    }

    #[test]
    fn test_which_not_found() {
        let f = TestFixture::new();
        assert!(_which(&f, "a").is_err());
    }

    #[test]
    fn test_which_second() {
        let f = TestFixture::new();
        let b = f.mk_bin("b/another").unwrap();
        assert_eq!(_which(&f, "another").unwrap().canonicalize().unwrap(), b);
    }

    #[test]
    fn test_which_absolute() {
        let f = TestFixture::new();
        assert_eq!(_which(&f, &f.bins[1]).unwrap().canonicalize().unwrap(),
                   f.bins[1].canonicalize().unwrap());
    }

    #[test]
    fn test_which_relative() {
        let f = TestFixture::new();
        assert_eq!(_which(&f, "b/bin").unwrap().canonicalize().unwrap(),
                   f.bins[1].canonicalize().unwrap());
    }

    #[test]
    fn test_which_relative_leading_dot() {
        let f = TestFixture::new();
        assert_eq!(_which(&f, "./b/bin").unwrap().canonicalize().unwrap(),
                   f.bins[1].canonicalize().unwrap());
    }

    #[test]
    #[cfg(unix)]
    fn test_which_non_executable() {
        // Shouldn't return non-executable files.
        let f = TestFixture::new();
        f.touch("b/another").unwrap();
        assert!(_which(&f, "another").is_err());
    }

    #[test]
    #[cfg(unix)]
    fn test_which_absolute_non_executable() {
        // Shouldn't return non-executable files, even if given an absolute path.
        let f = TestFixture::new();
        let b = f.touch("b/another").unwrap();
        assert!(_which(&f, &b).is_err());
    }

    #[test]
    #[cfg(unix)]
    fn test_which_relative_non_executable() {
        // Shouldn't return non-executable files.
        let f = TestFixture::new();
        f.touch("b/another").unwrap();
        assert!(_which(&f, "b/another").is_err());
    }
}
<|endoftext|>


<commit_before>use rand::seq::SliceRandom;

/// Convenience function to generate a new petname from default word lists.
#[allow(dead_code)]
pub fn petname(words: u8, separator: &str) -> String {
    Petnames::default().generate_one(words, separator)
}

/// Word lists and the logic to combine them into _petnames_.
///
/// A _petname_ with `n` words will contain, in order:
///
///   * 1 adjective when `n >= 2`, otherwise 0 adjectives.
///   * `n - 2` adverbs when `n >= 2`.
///   * 1 name / noun.
///
pub struct Petnames<'a> {
    pub adjectives: Vec<&'a str>,
    pub adverbs: Vec<&'a str>,
    pub names: Vec<&'a str>,
}

impl<'a> Petnames<'a> {
    /// Constructs a new `Petnames` from the default (small) word lists.
    pub fn default() -> Self {
        Self::small()
    }

    /// Constructs a new `Petnames` from the small word lists.
    pub fn small() -> Self {
        Self::init(
            include_str!("../words/small/adjectives.txt"),
            include_str!("../words/small/adverbs.txt"),
            include_str!("../words/small/names.txt"),
        )
    }

    /// Constructs a new `Petnames` from the medium word lists.
    pub fn medium() -> Self {
        Self::init(
            include_str!("../words/medium/adjectives.txt"),
            include_str!("../words/medium/adverbs.txt"),
            include_str!("../words/medium/names.txt"),
        )
    }

    /// Constructs a new `Petnames` from the large word lists.
    pub fn large() -> Self {
        Self::init(
            include_str!("../words/large/adjectives.txt"),
            include_str!("../words/large/adverbs.txt"),
            include_str!("../words/large/names.txt"),
        )
    }

    pub fn init(adjectives: &'a str, adverbs: &'a str, names: &'a str) -> Self {
        Self {
            adjectives: adjectives.split_whitespace().collect(),
            adverbs: adverbs.split_whitespace().collect(),
            names: names.split_whitespace().collect(),
        }
    }

    /// Keep words matching a predicate.
    ///
    /// # Examples
    ///
    /// ```rust
    /// let mut petnames = petname::Petnames::default();
    /// petnames.retain(|s| s.starts_with("b"));
    /// petnames.generate_one(2, ".");
    /// ```
    ///
    /// This is merely a convenience wrapper that applies the same predicate to
    /// the adjectives, adverbs, and names lists.
    ///
    pub fn retain<F>(&mut self, predicate: F)
    where
        F: Fn(&&str) -> bool,
    {
        self.adjectives.retain(&predicate);
        self.adverbs.retain(&predicate);
        self.names.retain(&predicate);
    }

    /// Generate a new petname.
    ///
    /// # Examples
    ///
    /// ```rust
    /// let mut rng = rand::thread_rng();
    /// petname::Petnames::default().generate(&mut rng, 7, ":");
    /// ```
    ///
    /// # Panics
    ///
    /// If a word list is empty.
    ///
    pub fn generate<RNG>(&self, rng: &mut RNG, words: u8, separator: &str) -> String
    where
        RNG: rand::Rng,
    {
        // Adverbs all the way, finishing with adjective then name.
        let mut parts = Vec::with_capacity(words as usize);
        for num in (0..words).rev() {
            parts.push(*match num {
                0 => self.names.choose(rng).unwrap(),
                1 => self.adjectives.choose(rng).unwrap(),
                _ => self.adverbs.choose(rng).unwrap(),
            });
        }
        parts.join(separator)
    }

    /// Generate a single new petname.
    ///
    /// This is like `generate` but uses `rand::thread_rng` as the random
    /// source. For efficiency use `generate` when creating multiple names, or
    /// when you want to use a custom source of randomness.
    pub fn generate_one(&self, words: u8, separator: &str) -> String {
        self.generate(&mut rand::thread_rng(), words, separator)
    }
}

impl<'a> Default for Petnames<'a> {
    fn default() -> Self {
        Self::default()
    }
}

#[cfg(test)]
mod tests {

    use super::{petname, Petnames};
    use rand;

    #[test]
    fn default_petnames_has_adjectives() {
        let petnames = Petnames::default();
        assert_ne!(petnames.adjectives.len(), 0);
    }

    #[test]
    fn default_petnames_has_adverbs() {
        let petnames = Petnames::default();
        assert_ne!(petnames.adverbs.len(), 0);
    }

    #[test]
    fn default_petnames_has_names() {
        let petnames = Petnames::default();
        assert_ne!(petnames.names.len(), 0);
    }

    #[test]
    fn generate_uses_adverb_adjective_name() {
        let petnames = Petnames {
            adjectives: vec!["adjective"],
            adverbs: vec!["adverb"],
            names: vec!["name"],
        };
        assert_eq!(
            petnames.generate(&mut rand::thread_rng(), 3, "-"),
            "adverb-adjective-name"
        );
    }

    #[test]
    fn petname_renders_desired_number_of_words() {
        assert_eq!(petname(7, "-").split("-").count(), 7);
    }

    #[test]
    fn petname_renders_with_desired_separator() {
        assert_eq!(petname(7, "@").split("@").count(), 7);
    }
}
<commit_msg>Add doc string to Petnames::init.<commit_after>use rand::seq::SliceRandom;

/// Convenience function to generate a new petname from default word lists.
#[allow(dead_code)]
pub fn petname(words: u8, separator: &str) -> String {
    Petnames::default().generate_one(words, separator)
}

/// Word lists and the logic to combine them into _petnames_.
///
/// A _petname_ with `n` words will contain, in order:
///
///   * 1 adjective when `n >= 2`, otherwise 0 adjectives.
///   * `n - 2` adverbs when `n >= 2`.
///   * 1 name / noun.
///
pub struct Petnames<'a> {
    pub adjectives: Vec<&'a str>,
    pub adverbs: Vec<&'a str>,
    pub names: Vec<&'a str>,
}

impl<'a> Petnames<'a> {
    /// Constructs a new `Petnames` from the default (small) word lists.
    pub fn default() -> Self {
        Self::small()
    }

    /// Constructs a new `Petnames` from the small word lists.
    pub fn small() -> Self {
        Self::init(
            include_str!("../words/small/adjectives.txt"),
            include_str!("../words/small/adverbs.txt"),
            include_str!("../words/small/names.txt"),
        )
    }

    /// Constructs a new `Petnames` from the medium word lists.
    pub fn medium() -> Self {
        Self::init(
            include_str!("../words/medium/adjectives.txt"),
            include_str!("../words/medium/adverbs.txt"),
            include_str!("../words/medium/names.txt"),
        )
    }

    /// Constructs a new `Petnames` from the large word lists.
    pub fn large() -> Self {
        Self::init(
            include_str!("../words/large/adjectives.txt"),
            include_str!("../words/large/adverbs.txt"),
            include_str!("../words/large/names.txt"),
        )
    }

    /// Constructs a new `Petnames` from the given word lists.
    ///
    /// The words are extracted from the given strings by splitting on whitespace.
    pub fn init(adjectives: &'a str, adverbs: &'a str, names: &'a str) -> Self {
        Self {
            adjectives: adjectives.split_whitespace().collect(),
            adverbs: adverbs.split_whitespace().collect(),
            names: names.split_whitespace().collect(),
        }
    }

    /// Keep words matching a predicate.
    ///
    /// # Examples
    ///
    /// ```rust
    /// let mut petnames = petname::Petnames::default();
    /// petnames.retain(|s| s.starts_with("b"));
    /// petnames.generate_one(2, ".");
    /// ```
    ///
    /// This is merely a convenience wrapper that applies the same predicate to
    /// the adjectives, adverbs, and names lists.
    ///
    pub fn retain<F>(&mut self, predicate: F)
    where
        F: Fn(&&str) -> bool,
    {
        self.adjectives.retain(&predicate);
        self.adverbs.retain(&predicate);
        self.names.retain(&predicate);
    }

    /// Generate a new petname.
    ///
    /// # Examples
    ///
    /// ```rust
    /// let mut rng = rand::thread_rng();
    /// petname::Petnames::default().generate(&mut rng, 7, ":");
    /// ```
    ///
    /// # Panics
    ///
    /// If a word list is empty.
    ///
    pub fn generate<RNG>(&self, rng: &mut RNG, words: u8, separator: &str) -> String
    where
        RNG: rand::Rng,
    {
        // Adverbs all the way, finishing with adjective then name.
        let mut parts = Vec::with_capacity(words as usize);
        for num in (0..words).rev() {
            parts.push(*match num {
                0 => self.names.choose(rng).unwrap(),
                1 => self.adjectives.choose(rng).unwrap(),
                _ => self.adverbs.choose(rng).unwrap(),
            });
        }
        parts.join(separator)
    }

    /// Generate a single new petname.
    ///
    /// This is like `generate` but uses `rand::thread_rng` as the random
    /// source. For efficiency use `generate` when creating multiple names, or
    /// when you want to use a custom source of randomness.
    pub fn generate_one(&self, words: u8, separator: &str) -> String {
        self.generate(&mut rand::thread_rng(), words, separator)
    }
}

impl<'a> Default for Petnames<'a> {
    fn default() -> Self {
        Self::default()
    }
}

#[cfg(test)]
mod tests {

    use super::{petname, Petnames};
    use rand;

    #[test]
    fn default_petnames_has_adjectives() {
        let petnames = Petnames::default();
        assert_ne!(petnames.adjectives.len(), 0);
    }

    #[test]
    fn default_petnames_has_adverbs() {
        let petnames = Petnames::default();
        assert_ne!(petnames.adverbs.len(), 0);
    }

    #[test]
    fn default_petnames_has_names() {
        let petnames = Petnames::default();
        assert_ne!(petnames.names.len(), 0);
    }

    #[test]
    fn generate_uses_adverb_adjective_name() {
        let petnames = Petnames {
            adjectives: vec!["adjective"],
            adverbs: vec!["adverb"],
            names: vec!["name"],
        };
        assert_eq!(
            petnames.generate(&mut rand::thread_rng(), 3, "-"),
            "adverb-adjective-name"
        );
    }

    #[test]
    fn petname_renders_desired_number_of_words() {
        assert_eq!(petname(7, "-").split("-").count(), 7);
    }

    #[test]
    fn petname_renders_with_desired_separator() {
        assert_eq!(petname(7, "@").split("@").count(), 7);
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(test, deny(warnings))]

extern crate semver;
extern crate conduit;

use std::iter;
use std::io::prelude::*;
use std::net::SocketAddr;
use std::collections::hash_map::{HashMap, Iter};

use conduit::{Method, Scheme, Host, Extensions, Headers, Request};

pub trait RequestDelegator {
    fn request(&self) -> &Request;
    fn mut_request(&mut self) -> &mut Request;

    fn http_version(&self) -> semver::Version {
        self.request().http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        self.request().conduit_version()
    }

    fn method(&self) -> Method {
        self.request().method()
    }

    fn scheme(&self) -> Scheme {
        self.request().scheme()
    }

    fn host(&self) -> Host {
        self.request().host()
    }

    fn virtual_root(&self) -> Option<&str> {
        self.request().virtual_root()
    }

    fn path(&self) -> &str {
        self.request().path()
    }

    fn query_string(&self) -> Option<&str> {
        self.request().query_string()
    }

    fn remote_addr(&self) -> SocketAddr {
        self.request().remote_addr()
    }

    fn content_length(&self) -> Option<u64> {
        self.request().content_length()
    }

    fn headers(&self) -> &Headers {
        self.request().headers()
    }

    fn body(&mut self) -> &mut Read {
        self.mut_request().body()
    }

    fn extensions(&self) -> &Extensions {
        self.request().extensions()
    }

    fn mut_extensions(&mut self) -> &mut Extensions {
        self.mut_request().mut_extensions()
    }
}

impl<'a> Request for &'a mut (RequestDelegator + 'a) {
    fn http_version(&self) -> semver::Version {
        (**self).http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        (**self).conduit_version()
    }

    fn method(&self) -> Method {
        (**self).method()
    }

    fn scheme(&self) -> Scheme {
        (**self).scheme()
    }

    fn host(&self) -> Host {
        (**self).host()
    }

    fn virtual_root(&self) -> Option<&str> {
        (**self).virtual_root()
    }

    fn path(&self) -> &str {
        (**self).path()
    }

    fn query_string(&self) -> Option<&str> {
        (**self).query_string()
    }

    fn remote_addr(&self) -> SocketAddr {
        (**self).remote_addr()
    }

    fn content_length(&self) -> Option<u64> {
        (**self).content_length()
    }

    fn headers(&self) -> &Headers {
        (**self).headers()
    }

    fn body(&mut self) -> &mut Read {
        (**self).body()
    }

    fn extensions(&self) -> &Extensions {
        (**self).extensions()
    }

    fn mut_extensions(&mut self) -> &mut Extensions {
        (**self).mut_extensions()
    }
}

type RawHeaders = HashMap<String, Vec<String>>;
pub type InHeader<'a> = (&'a String, &'a Vec<String>);
pub type OutHeader<'a> = (String, &'a Vec<String>);

#[derive(PartialEq, Clone, Debug)]
pub struct HeaderMap(HashMap<String, Vec<String>>);

impl HeaderMap {
    pub fn normalize(headers: HashMap<String, Vec<String>>) -> HeaderMap {
        let headers = headers.into_iter().map(|(k,v)| (to_lower(&k), v)).collect();
        HeaderMap(headers)
    }

    pub fn iter(&self) -> iter::Map<Iter<String, Vec<String>>,
                                for<'a> fn(InHeader<'a>) -> OutHeader<'a>> {
        fn foo<'a>((k, v): InHeader<'a>) -> OutHeader<'a> { (to_lower(k), v) }
        let f: for<'a> fn(InHeader<'a>) -> OutHeader<'a> = foo;
        self.as_ref().iter().map(f)
    }

    fn as_ref(&self) -> &HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref map) => map
        }
    }

    fn as_mut(&mut self) -> &mut HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref mut map) => map
        }
    }

    pub fn len(&self) -> usize {
        self.as_ref().len()
    }
    pub fn clear(&mut self) {
        self.as_mut().clear()
    }
    pub fn find(&self, key: &str) -> Option<&Vec<String>> {
        self.as_ref().get(&to_lower(key))
    }
    pub fn insert(&mut self, k: &str, v: Vec<String>) -> Option<Vec<String>> {
        self.as_mut().insert(to_lower(&k), v)
    }
    pub fn remove(&mut self, k: &str) -> Option<Vec<String>> {
        self.as_mut().remove(&to_lower(k))
    }

    pub fn find_mut(&mut self, k: &str) -> Option<&mut Vec<String>> {
        self.as_mut().get_mut(&to_lower(k))
    }
}

fn to_lower(string: &str) -> String {
    string.chars().flat_map(|c| c.to_lowercase()).collect()
}

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

    use {RequestDelegator, HeaderMap};

    use std::collections::HashMap;
    use conduit::{Request, Method};

    struct OverrideRequest<'a> {
        request: &'a mut (Request + 'a),
    }

    impl<'a> RequestDelegator for OverrideRequest<'a> {
        fn request(&self) -> &Request {
            let req: &Request = self.request; req
        }

        fn mut_request(&mut self) -> &mut Request {
            let req: &mut Request = self.request; req
        }

        fn method(&self) -> Method {
            Method::Get
        }
    }

    #[test]
    fn test_delegate() {
        let request = &mut test::MockRequest::new(Method::Head, "/hello");
        let new = OverrideRequest { request: request };

        assert_eq!(new.method(), Method::Get);
        assert_eq!(new.path(), "/hello");
    }

    #[test]
    fn test_header_map() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type", vec!("text/html".to_string()));
        map.insert("location", vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())));
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())));
    }

    #[test]
    fn test_header_map_with_static_inserts() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type", vec!("text/html".to_string()));
        map.insert("location", vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())));
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())));
    }

    #[test]
    fn test_normalize() {
        let mut map = HashMap::new();
        map.insert("Content-Type".to_string(), vec!("text/html".to_string()));

        let headers = HeaderMap::normalize(map);
        assert_eq!(headers.find(&"Content-Type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(headers.find(&"Content-Type"), Some(&vec!("text/html".to_string())));
        assert_eq!(headers.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(headers.find(&"content-type"), Some(&vec!("text/html".to_string())));
    }

    #[test]
    fn test_iterate() {
        let mut headers = HeaderMap(HashMap::new());
        headers.insert("Content-Type", vec!("text/html".to_string()));
        headers.insert("location", vec!("http://example.com".to_string()));

        assert!(headers.iter().any(|t| {
            t.0 == "content-type" &&
            &t.1[..] == ["text/html".to_string()]
        }));
        assert!(headers.iter().any(|t| {
            t.0 == "location" &&
            &t.1[..] == ["http://example.com".to_string()]
        }));
        assert!(headers.iter().count() == 2);
    }
}
<commit_msg>Remove unused type alias<commit_after>#![cfg_attr(test, deny(warnings))]

extern crate semver;
extern crate conduit;

use std::iter;
use std::io::prelude::*;
use std::net::SocketAddr;
use std::collections::hash_map::{HashMap, Iter};

use conduit::{Method, Scheme, Host, Extensions, Headers, Request};

pub trait RequestDelegator {
    fn request(&self) -> &Request;
    fn mut_request(&mut self) -> &mut Request;

    fn http_version(&self) -> semver::Version {
        self.request().http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        self.request().conduit_version()
    }

    fn method(&self) -> Method {
        self.request().method()
    }

    fn scheme(&self) -> Scheme {
        self.request().scheme()
    }

    fn host(&self) -> Host {
        self.request().host()
    }

    fn virtual_root(&self) -> Option<&str> {
        self.request().virtual_root()
    }

    fn path(&self) -> &str {
        self.request().path()
    }

    fn query_string(&self) -> Option<&str> {
        self.request().query_string()
    }

    fn remote_addr(&self) -> SocketAddr {
        self.request().remote_addr()
    }

    fn content_length(&self) -> Option<u64> {
        self.request().content_length()
    }

    fn headers(&self) -> &Headers {
        self.request().headers()
    }

    fn body(&mut self) -> &mut Read {
        self.mut_request().body()
    }

    fn extensions(&self) -> &Extensions {
        self.request().extensions()
    }

    fn mut_extensions(&mut self) -> &mut Extensions {
        self.mut_request().mut_extensions()
    }
}

impl<'a> Request for &'a mut (RequestDelegator + 'a) {
    fn http_version(&self) -> semver::Version {
        (**self).http_version()
    }

    fn conduit_version(&self) -> semver::Version {
        (**self).conduit_version()
    }

    fn method(&self) -> Method {
        (**self).method()
    }

    fn scheme(&self) -> Scheme {
        (**self).scheme()
    }

    fn host(&self) -> Host {
        (**self).host()
    }

    fn virtual_root(&self) -> Option<&str> {
        (**self).virtual_root()
    }

    fn path(&self) -> &str {
        (**self).path()
    }

    fn query_string(&self) -> Option<&str> {
        (**self).query_string()
    }

    fn remote_addr(&self) -> SocketAddr {
        (**self).remote_addr()
    }

    fn content_length(&self) -> Option<u64> {
        (**self).content_length()
    }

    fn headers(&self) -> &Headers {
        (**self).headers()
    }

    fn body(&mut self) -> &mut Read {
        (**self).body()
    }

    fn extensions(&self) -> &Extensions {
        (**self).extensions()
    }

    fn mut_extensions(&mut self) -> &mut Extensions {
        (**self).mut_extensions()
    }
}

pub type InHeader<'a> = (&'a String, &'a Vec<String>);
pub type OutHeader<'a> = (String, &'a Vec<String>);

#[derive(PartialEq, Clone, Debug)]
pub struct HeaderMap(HashMap<String, Vec<String>>);

impl HeaderMap {
    pub fn normalize(headers: HashMap<String, Vec<String>>) -> HeaderMap {
        let headers = headers.into_iter().map(|(k,v)| (to_lower(&k), v)).collect();
        HeaderMap(headers)
    }

    pub fn iter(&self) -> iter::Map<Iter<String, Vec<String>>,
                                for<'a> fn(InHeader<'a>) -> OutHeader<'a>> {
        fn foo<'a>((k, v): InHeader<'a>) -> OutHeader<'a> { (to_lower(k), v) }
        let f: for<'a> fn(InHeader<'a>) -> OutHeader<'a> = foo;
        self.as_ref().iter().map(f)
    }

    fn as_ref(&self) -> &HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref map) => map
        }
    }

    fn as_mut(&mut self) -> &mut HashMap<String, Vec<String>> {
        match *self {
            HeaderMap(ref mut map) => map
        }
    }

    pub fn len(&self) -> usize {
        self.as_ref().len()
    }
    pub fn clear(&mut self) {
        self.as_mut().clear()
    }
    pub fn find(&self, key: &str) -> Option<&Vec<String>> {
        self.as_ref().get(&to_lower(key))
    }
    pub fn insert(&mut self, k: &str, v: Vec<String>) -> Option<Vec<String>> {
        self.as_mut().insert(to_lower(&k), v)
    }
    pub fn remove(&mut self, k: &str) -> Option<Vec<String>> {
        self.as_mut().remove(&to_lower(k))
    }

    pub fn find_mut(&mut self, k: &str) -> Option<&mut Vec<String>> {
        self.as_mut().get_mut(&to_lower(k))
    }
}

fn to_lower(string: &str) -> String {
    string.chars().flat_map(|c| c.to_lowercase()).collect()
}

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

    use {RequestDelegator, HeaderMap};

    use std::collections::HashMap;
    use conduit::{Request, Method};

    struct OverrideRequest<'a> {
        request: &'a mut (Request + 'a),
    }

    impl<'a> RequestDelegator for OverrideRequest<'a> {
        fn request(&self) -> &Request {
            let req: &Request = self.request; req
        }

        fn mut_request(&mut self) -> &mut Request {
            let req: &mut Request = self.request; req
        }

        fn method(&self) -> Method {
            Method::Get
        }
    }

    #[test]
    fn test_delegate() {
        let request = &mut test::MockRequest::new(Method::Head, "/hello");
        let new = OverrideRequest { request: request };

        assert_eq!(new.method(), Method::Get);
        assert_eq!(new.path(), "/hello");
    }

    #[test]
    fn test_header_map() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type", vec!("text/html".to_string()));
        map.insert("location", vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())));
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())));
    }

    #[test]
    fn test_header_map_with_static_inserts() {
        let mut map = HeaderMap(HashMap::new());
        map.insert("Content-Type", vec!("text/html".to_string()));
        map.insert("location", vec!("http://example.com".to_string()));

        assert_eq!(map.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location".to_string()), Some(&vec!("http://example.com".to_string())));
        assert_eq!(map.find(&"content-type"), Some(&vec!("text/html".to_string())));
        assert_eq!(map.find(&"Location"), Some(&vec!("http://example.com".to_string())));
    }

    #[test]
    fn test_normalize() {
        let mut map = HashMap::new();
        map.insert("Content-Type".to_string(), vec!("text/html".to_string()));

        let headers = HeaderMap::normalize(map);
        assert_eq!(headers.find(&"Content-Type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(headers.find(&"Content-Type"), Some(&vec!("text/html".to_string())));
        assert_eq!(headers.find(&"content-type".to_string()), Some(&vec!("text/html".to_string())));
        assert_eq!(headers.find(&"content-type"), Some(&vec!("text/html".to_string())));
    }

    #[test]
    fn test_iterate() {
        let mut headers = HeaderMap(HashMap::new());
        headers.insert("Content-Type", vec!("text/html".to_string()));
        headers.insert("location", vec!("http://example.com".to_string()));

        assert!(headers.iter().any(|t| {
            t.0 == "content-type" &&
            &t.1[..] == ["text/html".to_string()]
        }));
        assert!(headers.iter().any(|t| {
            t.0 == "location" &&
            &t.1[..] == ["http://example.com".to_string()]
        }));
        assert!(headers.iter().count() == 2);
    }
}
<|endoftext|>


<commit_before>#[cfg_attr(target_arch = "riscv32", path = "platform_riscv32.rs")]
#[cfg_attr(target_arch = "arm", path = "platform_arm.rs")]
#[cfg_attr(
    not(any(target_arch = "arm", target_arch = "riscv32")),
    path = "platform_mock.rs"
)]
mod platform;

use crate::callback::CallbackSubscription;
use crate::callback::SubscribableCallback;
use crate::shared_memory::SharedMemory;

pub mod raw {
    use super::platform;

    pub use platform::*;

    /// # Safety
    ///
    /// Yielding in the main function should be safe. Nevertheless, yielding manually is not required as this is already achieved by the `async` runtime.
    ///
    /// When yielding in callbacks, two problems can arise:
    /// - The guarantees of `FnMut` are violated. In this case, make sure your callback has `Fn` behavior.
    /// - Callbacks can get executed in a nested manner and overflow the stack quickly.
    #[export_name = "libtock::syscalls::raw::yieldk"]
    pub unsafe fn yieldk() {
        platform::yieldk()
    }
}

pub fn subscribe<CB: SubscribableCallback>(
    driver_number: usize,
    subscribe_number: usize,
    callback: &mut CB,
) -> Result<CallbackSubscription, isize> {
    extern "C" fn c_callback<CB: SubscribableCallback>(
        arg1: usize,
        arg2: usize,
        arg3: usize,
        data: usize,
    ) {
        let callback = unsafe { &mut *(data as *mut CB) };
        callback.call_rust(arg1, arg2, arg3);
    }

    let return_code = {
        subscribe_fn(
            driver_number,
            subscribe_number,
            c_callback::<CB>,
            callback as *mut CB as usize,
        )
    };

    if return_code == 0 {
        Ok(CallbackSubscription::new(driver_number, subscribe_number))
    } else {
        Err(return_code)
    }
}

pub fn subscribe_fn(
    driver_number: usize,
    subscribe_number: usize,
    callback: extern "C" fn(usize, usize, usize, usize),
    userdata: usize,
) -> isize {
    unsafe {
        raw::subscribe(
            driver_number,
            subscribe_number,
            callback as *const _,
            userdata,
        )
    }
}

pub fn command(driver_number: usize, command_number: usize, arg1: usize, arg2: usize) -> isize {
    unsafe { raw::command(driver_number, command_number, arg1, arg2) }
}

// command1_insecure, is a variant of command() that only sets the first
// argument in the system call interface. It has the benefit of generating
// simpler assembly than command(), but it leaves the second argument's register
// as-is which leaks it to the kernel driver being called. Prefer to use
// command() instead of command1_insecure(), unless the benefit of generating
// simpler assembly outweighs the drawbacks of potentially leaking arbitrary
// information to the driver you are calling.
//
// At the moment, the only suitable use case for command1_insecure is the low
// level debug interface.

pub fn command1_insecure(driver_number: usize, command_number: usize, arg: usize) -> isize {
    unsafe { raw::command1(driver_number, command_number, arg) }
}

pub fn allow(
    driver_number: usize,
    allow_number: usize,
    buffer_to_share: &mut [u8],
) -> Result<SharedMemory, isize> {
    let len = buffer_to_share.len();
    let return_code = unsafe {
        raw::allow(
            driver_number,
            allow_number,
            buffer_to_share.as_mut_ptr(),
            len,
        )
    };
    if return_code == 0 {
        Ok(SharedMemory::new(
            driver_number,
            allow_number,
            buffer_to_share,
        ))
    } else {
        Err(return_code)
    }
}
<commit_msg>Add comment on export_name<commit_after>#[cfg_attr(target_arch = "riscv32", path = "platform_riscv32.rs")]
#[cfg_attr(target_arch = "arm", path = "platform_arm.rs")]
#[cfg_attr(
    not(any(target_arch = "arm", target_arch = "riscv32")),
    path = "platform_mock.rs"
)]
mod platform;

use crate::callback::CallbackSubscription;
use crate::callback::SubscribableCallback;
use crate::shared_memory::SharedMemory;

pub mod raw {
    use super::platform;

    pub use platform::*;

    /// # Safety
    ///
    /// Yielding in the main function should be safe. Nevertheless, yielding manually is not required as this is already achieved by the `async` runtime.
    ///
    /// When yielding in callbacks, two problems can arise:
    /// - The guarantees of `FnMut` are violated. In this case, make sure your callback has `Fn` behavior.
    /// - Callbacks can get executed in a nested manner and overflow the stack quickly.
    ///
    /// This function is exported as `libtock::syscalls::raw::yieldk`. Do not reference this name directly. Its only purpose is to establish a back-channel from `async-support`, a patched version of `core` to `libtock-rs` via linking. This workaround has been chosen to keep the `core` crate free of dependencies on platform-specific syscall implementations and is expected to get removed as soon as possible.
    #[export_name = "libtock::syscalls::raw::yieldk"]
    pub unsafe fn yieldk() {
        platform::yieldk()
    }
}

pub fn subscribe<CB: SubscribableCallback>(
    driver_number: usize,
    subscribe_number: usize,
    callback: &mut CB,
) -> Result<CallbackSubscription, isize> {
    extern "C" fn c_callback<CB: SubscribableCallback>(
        arg1: usize,
        arg2: usize,
        arg3: usize,
        data: usize,
    ) {
        let callback = unsafe { &mut *(data as *mut CB) };
        callback.call_rust(arg1, arg2, arg3);
    }

    let return_code = {
        subscribe_fn(
            driver_number,
            subscribe_number,
            c_callback::<CB>,
            callback as *mut CB as usize,
        )
    };

    if return_code == 0 {
        Ok(CallbackSubscription::new(driver_number, subscribe_number))
    } else {
        Err(return_code)
    }
}

pub fn subscribe_fn(
    driver_number: usize,
    subscribe_number: usize,
    callback: extern "C" fn(usize, usize, usize, usize),
    userdata: usize,
) -> isize {
    unsafe {
        raw::subscribe(
            driver_number,
            subscribe_number,
            callback as *const _,
            userdata,
        )
    }
}

pub fn command(driver_number: usize, command_number: usize, arg1: usize, arg2: usize) -> isize {
    unsafe { raw::command(driver_number, command_number, arg1, arg2) }
}

// command1_insecure, is a variant of command() that only sets the first
// argument in the system call interface. It has the benefit of generating
// simpler assembly than command(), but it leaves the second argument's register
// as-is which leaks it to the kernel driver being called. Prefer to use
// command() instead of command1_insecure(), unless the benefit of generating
// simpler assembly outweighs the drawbacks of potentially leaking arbitrary
// information to the driver you are calling.
//
// At the moment, the only suitable use case for command1_insecure is the low
// level debug interface.

pub fn command1_insecure(driver_number: usize, command_number: usize, arg: usize) -> isize {
    unsafe { raw::command1(driver_number, command_number, arg) }
}

pub fn allow(
    driver_number: usize,
    allow_number: usize,
    buffer_to_share: &mut [u8],
) -> Result<SharedMemory, isize> {
    let len = buffer_to_share.len();
    let return_code = unsafe {
        raw::allow(
            driver_number,
            allow_number,
            buffer_to_share.as_mut_ptr(),
            len,
        )
    };
    if return_code == 0 {
        Ok(SharedMemory::new(
            driver_number,
            allow_number,
            buffer_to_share,
        ))
    } else {
        Err(return_code)
    }
}
<|endoftext|>


<commit_before>use square::*;
use std::ops::{BitAnd, BitOr, BitXor, BitAndAssign, BitOrAssign, BitXorAssign, Mul, Not};
use std::fmt;
use std::sync::{Once, ONCE_INIT};
use rank::Rank;
use file::File;

/// A good old-fashioned bitboard
/// You do *not* have access to the actual value.  You *do* have access to operators
#[derive(PartialEq, PartialOrd, Clone, Copy)]
pub struct BitBoard(u64);

static SETUP: Once = ONCE_INIT;

/// An empty bitboard
pub const EMPTY: BitBoard = BitBoard(0);

impl BitAnd for BitBoard {
    type Output = BitBoard;

    fn bitand(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0 & other.0)
    }
}

impl BitOr for BitBoard {
    type Output = BitBoard;

    fn bitor(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0 | other.0)
    }
}

impl BitXor for BitBoard {
    type Output = BitBoard;

    fn bitxor(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0 ^ other.0)
    }
}

impl BitAndAssign for BitBoard {
    fn bitand_assign(&mut self, other: BitBoard) {
        self.0 &= other.0;
    }
}

impl BitOrAssign for BitBoard {
    fn bitor_assign(&mut self, other: BitBoard) {
        self.0 |= other.0;
    }
}

impl BitXorAssign for BitBoard {
    fn bitxor_assign(&mut self, other: BitBoard) {
        self.0 ^= other.0;
    }
}

impl Mul for BitBoard {
    type Output = BitBoard;

    fn mul(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0.wrapping_mul(other.0))
    }
}

impl Not for BitBoard {
    type Output = BitBoard;

    fn not(self) -> BitBoard {
        BitBoard(!self.0)
    }
}

impl fmt::Display for BitBoard {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut s: String = "".to_owned();
        for x in 0..64 {
            if self.0 & (1u64 << x) == (1u64 << x) {
                s.push_str("X ");
            } else {
                s.push_str(". ");
            }
            if x % 8 == 7 {
                s.push_str("\n");
            }
        }
        write!(f, "{}", s)
    }
}

impl BitBoard {
    /// Construct a new bitboard from a u64
    pub fn new(b: u64) -> BitBoard {
        BitBoard(b)
    }

    /// Construct a new `BitBoard` with a particular `Square` set
    pub fn set(rank: Rank, file: File) -> BitBoard {
        BitBoard::from_square(Square::make_square(rank, file))
    }

    /// Construct a new `BitBoard` with a particular `Square` set
    pub fn from_square(sq: Square) -> BitBoard {
        BitBoard(1u64 << sq.to_int())
    }

    /// Convert an `Option<Square>` to an `Option<BitBoard>`
    pub fn from_maybe_square(sq: Option<Square>) -> Option<BitBoard> {
        sq.map(|s| BitBoard::from_square(s))
    }

    /// Convert a `BitBoard` to a `Square`.  This grabs the least-significant `Square`
    pub fn to_square(&self) -> Square {
        Square::new(self.0.trailing_zeros() as u8)
    }

    /// Count the number of `Squares` set in this `BitBoard`
    pub fn popcnt(&self) -> u32 {
        self.0.count_ones()
    }

    /// Reverse this `BitBoard`.  Look at it from the opponents perspective.
    pub fn reverse_colors(&self) -> BitBoard {
        BitBoard(self.0.swap_bytes())
    }

    /// Convert this `BitBoard` to a `usize` (for table lookups)
    pub fn to_size(&self, rightshift: u8) -> usize {
        (self.0 >> rightshift) as usize
    }
}

/// Get a `BitBoard` that represents all the squares on a particular rank.
pub fn get_rank(rank: Rank) -> BitBoard {
    unsafe {
        *RANKS.get_unchecked(rank.to_index())
    }
}

/// Get a `BitBoard` that represents all the squares on a particular file.
pub fn get_file(file: File) -> BitBoard {
    unsafe {
        *FILES.get_unchecked(file.to_index())
    }
}

/// Get a `BitBoard` that represents the squares on the 1 or 2 files next to this file.
pub fn get_adjacent_files(file: File) -> BitBoard {
    unsafe {
        *ADJACENT_FILES.get_unchecked(file.to_index())
    }
}

/// Perform initialization.  Must be called before some functions can be used.
pub fn construct() {
    SETUP.call_once(|| {
        unsafe {
            EDGES = ALL_SQUARES.iter()
                               .filter(|x| x.get_rank() == Rank::First ||
                                           x.get_rank() == Rank::Eighth ||
                                           x.get_file() == File::A ||
                                           x.get_file() == File::H)
                               .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
            for i in 0..8 {
                RANKS[i] = ALL_SQUARES.iter()
                                      .filter(|x| x.get_rank().to_index() == i)
                                      .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
                FILES[i] = ALL_SQUARES.iter()
                                      .filter(|x| x.get_file().to_index() == i)
                                      .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
                ADJACENT_FILES[i] = ALL_SQUARES.iter()
                                               .filter(|y| ((y.get_file().to_index() as i8) == (i as i8) - 1) ||
                                                           ((y.get_file().to_index() as i8) == (i as i8) + 1))
                                               .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
            }
        }
    });
}

static mut EDGES: BitBoard = EMPTY;
static mut RANKS: [BitBoard; 8] = [EMPTY; 8];
static mut FILES: [BitBoard; 8] = [EMPTY; 8];
static mut ADJACENT_FILES: [BitBoard; 8] = [EMPTY; 8];

impl Iterator for BitBoard {
    type Item = Square;

    fn next(&mut self) -> Option<Square> {
        if self.0 == 0 {
            None
        } else {
            let result = self.to_square();
            *self ^= BitBoard::from_square(result);
            Some(result)
        }
    }
}

<commit_msg>More documentation.<commit_after>use square::*;
use std::ops::{BitAnd, BitOr, BitXor, BitAndAssign, BitOrAssign, BitXorAssign, Mul, Not};
use std::fmt;
use std::sync::{Once, ONCE_INIT};
use rank::Rank;
use file::File;

/// A good old-fashioned bitboard
/// You do *not* have access to the actual value.  You *do* have access to operators
#[derive(PartialEq, PartialOrd, Clone, Copy)]
pub struct BitBoard(u64);

static SETUP: Once = ONCE_INIT;

/// An empty bitboard
pub const EMPTY: BitBoard = BitBoard(0);

impl BitAnd for BitBoard {
    type Output = BitBoard;

    fn bitand(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0 & other.0)
    }
}

impl BitOr for BitBoard {
    type Output = BitBoard;

    fn bitor(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0 | other.0)
    }
}

impl BitXor for BitBoard {
    type Output = BitBoard;

    fn bitxor(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0 ^ other.0)
    }
}

impl BitAndAssign for BitBoard {
    fn bitand_assign(&mut self, other: BitBoard) {
        self.0 &= other.0;
    }
}

impl BitOrAssign for BitBoard {
    fn bitor_assign(&mut self, other: BitBoard) {
        self.0 |= other.0;
    }
}

impl BitXorAssign for BitBoard {
    fn bitxor_assign(&mut self, other: BitBoard) {
        self.0 ^= other.0;
    }
}

impl Mul for BitBoard {
    type Output = BitBoard;

    fn mul(self, other: BitBoard) -> BitBoard {
        BitBoard(self.0.wrapping_mul(other.0))
    }
}

impl Not for BitBoard {
    type Output = BitBoard;

    fn not(self) -> BitBoard {
        BitBoard(!self.0)
    }
}

impl fmt::Display for BitBoard {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut s: String = "".to_owned();
        for x in 0..64 {
            if self.0 & (1u64 << x) == (1u64 << x) {
                s.push_str("X ");
            } else {
                s.push_str(". ");
            }
            if x % 8 == 7 {
                s.push_str("\n");
            }
        }
        write!(f, "{}", s)
    }
}

impl BitBoard {
    /// Construct a new bitboard from a u64
    pub fn new(b: u64) -> BitBoard {
        BitBoard(b)
    }

    /// Construct a new `BitBoard` with a particular `Square` set
    pub fn set(rank: Rank, file: File) -> BitBoard {
        BitBoard::from_square(Square::make_square(rank, file))
    }

    /// Construct a new `BitBoard` with a particular `Square` set
    pub fn from_square(sq: Square) -> BitBoard {
        BitBoard(1u64 << sq.to_int())
    }

    /// Convert an `Option<Square>` to an `Option<BitBoard>`
    pub fn from_maybe_square(sq: Option<Square>) -> Option<BitBoard> {
        sq.map(|s| BitBoard::from_square(s))
    }

    /// Convert a `BitBoard` to a `Square`.  This grabs the least-significant `Square`
    pub fn to_square(&self) -> Square {
        Square::new(self.0.trailing_zeros() as u8)
    }

    /// Count the number of `Squares` set in this `BitBoard`
    pub fn popcnt(&self) -> u32 {
        self.0.count_ones()
    }

    /// Reverse this `BitBoard`.  Look at it from the opponents perspective.
    pub fn reverse_colors(&self) -> BitBoard {
        BitBoard(self.0.swap_bytes())
    }

    /// Convert this `BitBoard` to a `usize` (for table lookups)
    pub fn to_size(&self, rightshift: u8) -> usize {
        (self.0 >> rightshift) as usize
    }
}

/// Get a `BitBoard` that represents all the squares on a particular rank.
pub fn get_rank(rank: Rank) -> BitBoard {
    unsafe {
        *RANKS.get_unchecked(rank.to_index())
    }
}

/// Get a `BitBoard` that represents all the squares on a particular file.
pub fn get_file(file: File) -> BitBoard {
    unsafe {
        *FILES.get_unchecked(file.to_index())
    }
}

/// Get a `BitBoard` that represents the squares on the 1 or 2 files next to this file.
pub fn get_adjacent_files(file: File) -> BitBoard {
    unsafe {
        *ADJACENT_FILES.get_unchecked(file.to_index())
    }
}

/// Perform initialization.  Must be called before some functions can be used.
pub fn construct() {
    SETUP.call_once(|| {
        unsafe {
            EDGES = ALL_SQUARES.iter()
                               .filter(|x| x.get_rank() == Rank::First ||
                                           x.get_rank() == Rank::Eighth ||
                                           x.get_file() == File::A ||
                                           x.get_file() == File::H)
                               .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
            for i in 0..8 {
                RANKS[i] = ALL_SQUARES.iter()
                                      .filter(|x| x.get_rank().to_index() == i)
                                      .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
                FILES[i] = ALL_SQUARES.iter()
                                      .filter(|x| x.get_file().to_index() == i)
                                      .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
                ADJACENT_FILES[i] = ALL_SQUARES.iter()
                                               .filter(|y| ((y.get_file().to_index() as i8) == (i as i8) - 1) ||
                                                           ((y.get_file().to_index() as i8) == (i as i8) + 1))
                                               .fold(EMPTY, |v, s| v | BitBoard::from_square(*s));
            }
        }
    });
}

static mut EDGES: BitBoard = EMPTY;
static mut RANKS: [BitBoard; 8] = [EMPTY; 8];
static mut FILES: [BitBoard; 8] = [EMPTY; 8];
static mut ADJACENT_FILES: [BitBoard; 8] = [EMPTY; 8];

/// For the `BitBoard`, iterate over every `Square` set.
impl Iterator for BitBoard {
    type Item = Square;

    fn next(&mut self) -> Option<Square> {
        if self.0 == 0 {
            None
        } else {
            let result = self.to_square();
            *self ^= BitBoard::from_square(result);
            Some(result)
        }
    }
}

<|endoftext|>


<commit_before>//! A fast, low-level IO library for Rust focusing on non-blocking APIs, event
//! notification, and other useful utilities for building high performance IO
//! apps.
//!
//! # Goals
//!
//! * Fast - minimal overhead over the equivalent OS facilities (epoll, kqueue, etc...)
//! * Zero allocations
//! * A scalable readiness-based API, similar to epoll on Linux
//! * Design to allow for stack allocated buffers when possible (avoid double buffering).
//! * Provide utilities such as a timers, a notification channel, buffer abstractions, and a slab.
//!
//! # Usage
//!
//! Using mio starts by creating a [Poll], which reads events from the OS and
//! put them into [`Events`]. You can handle IO events from the OS with it.
//!
//! For more detail, see [`Poll`].
//!
//! [`Poll`]: struct.Poll.html
//! [`Events`]: struct.Events.html
//!
//! # Example
//!
//! ```
//! use mio::*;
//! use mio::tcp::{TcpListener, TcpStream};
//!
//! // Setup some tokens to allow us to identify which event is
//! // for which socket.
//! const SERVER: Token = Token(0);
//! const CLIENT: Token = Token(1);
//!
//! let addr = "127.0.0.1:13265".parse().unwrap();
//!
//! // Setup the server socket
//! let server = TcpListener::bind(&addr).unwrap();
//!
//! // Create a poll instance
//! let poll = Poll::new().unwrap();
//!
//! // Start listening for incoming connections
//! poll.register(&server, SERVER, Ready::readable(),
//!               PollOpt::edge()).unwrap();
//!
//! // Setup the client socket
//! let sock = TcpStream::connect(&addr).unwrap();
//!
//! // Register the socket
//! poll.register(&sock, CLIENT, Ready::readable(),
//!               PollOpt::edge()).unwrap();
//!
//! // Create storage for events
//! let mut events = Events::with_capacity(1024);
//!
//! loop {
//!     poll.poll(&mut events, None).unwrap();
//!
//!     for event in events.iter() {
//!         match event.token() {
//!             SERVER => {
//!                 // Accept and drop the socket immediately, this will close
//!                 // the socket and notify the client of the EOF.
//!                 let _ = server.accept();
//!             }
//!             CLIENT => {
//!                 // The server just shuts down the socket, let's just exit
//!                 // from our event loop.
//!                 return;
//!             }
//!             _ => unreachable!(),
//!         }
//!     }
//! }
//!
//! ```

#![doc(html_root_url = "https://docs.rs/mio/0.6.1")]
#![crate_name = "mio"]

#![deny(warnings, missing_docs, missing_debug_implementations)]

extern crate lazycell;
extern crate net2;
extern crate slab;
extern crate iovec;

#[cfg(unix)]
extern crate libc;

#[cfg(windows)]
extern crate miow;

#[cfg(windows)]
extern crate winapi;

#[cfg(windows)]
extern crate kernel32;

#[macro_use]
extern crate log;

#[cfg(test)]
extern crate env_logger;

mod event_imp;
mod io;
mod poll;
mod sys;
mod token;

pub mod net;

#[deprecated(since = "0.6.5", note = "use mio-more instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod channel;

#[deprecated(since = "0.6.5", note = "use mio-more instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod timer;

#[deprecated(since = "0.6.5", note = "update to use `Poll`")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod deprecated;

#[deprecated(since = "0.6.5", note = "use iovec crate directly")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use iovec::IoVec;

#[deprecated(since = "0.6.6", note = "use net module instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod tcp {
    pub use net::{TcpListener, TcpStream};
    pub use std::net::Shutdown;
}

#[deprecated(since = "0.6.6", note = "use net module instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod udp;

pub use poll::{
    Poll,
    Registration,
    SetReadiness,
};
pub use event_imp::{
    PollOpt,
    Ready,
};
pub use token::Token;

pub mod event {
    //! Readiness event types and utilities.

    pub use super::poll::{Events, Iter};
    pub use super::event_imp::{Event, Evented};
}

pub use event::{
    Events,
};

#[deprecated(since = "0.6.5", note = "use events:: instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use event::{Event, Evented};

#[deprecated(since = "0.6.5", note = "use events::Iter instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use poll::Iter as EventsIter;

#[deprecated(since = "0.6.5", note = "std::io::Error can avoid the allocation now")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use io::deprecated::would_block;

#[cfg(unix)]
pub mod unix {
    //! Unix only extensions
    pub use sys::{
        EventedFd,
    };
    pub use sys::unix::UnixReady;
}

/// Windows-only extensions to the mio crate.
///
/// Mio on windows is currently implemented with IOCP for a high-performance
/// implementation of asynchronous I/O. Mio then provides TCP and UDP as sample
/// bindings for the system to connect networking types to asynchronous I/O. On
/// Unix this scheme is then also extensible to all other file descriptors with
/// the `EventedFd` type, but on Windows no such analog is available. The
/// purpose of this module, however, is to similarly provide a mechanism for
/// foreign I/O types to get hooked up into the IOCP event loop.
///
/// This module provides two types for interfacing with a custom IOCP handle:
///
/// * `Binding` - this type is intended to govern binding with mio's `Poll`
///   type. Each I/O object should contain an instance of `Binding` that's
///   interfaced with for the implementation of the `Evented` trait. The
///   `register`, `reregister`, and `deregister` methods for the `Evented` trait
///   all have rough analogs with `Binding`.
///
///   Note that this type **does not handle readiness**. That is, this type does
///   not handle whether sockets are readable/writable/etc. It's intended that
///   IOCP types will internally manage this state with a `SetReadiness` type
///   from the `poll` module. The `SetReadiness` is typically lazily created on
///   the first time that `Evented::register` is called and then stored in the
///   I/O object.
///
///   Also note that for types which represent streams of bytes the mio
///   interface of *readiness* doesn't map directly to the Windows model of
///   *completion*. This means that types will have to perform internal
///   buffering to ensure that a readiness interface can be provided. For a
///   sample implementation see the TCP/UDP modules in mio itself.
///
/// * `Overlapped` - this type is intended to be used as the concreate instances
///   of the `OVERLAPPED` type that most win32 methods expect. It's crucial, for
///   safety, that all asynchronous operations are initiated with an instance of
///   `Overlapped` and not another instantiation of `OVERLAPPED`.
///
///   Mio's `Overlapped` type is created with a function pointer that receives
///   a `OVERLAPPED_ENTRY` type when called. This `OVERLAPPED_ENTRY` type is
///   defined in the `winapi` crate. Whenever a completion is posted to an IOCP
///   object the `OVERLAPPED` that was signaled will be interpreted as
///   `Overlapped` in the mio crate and this function pointer will be invoked.
///   Through this function pointer, and through the `OVERLAPPED` pointer,
///   implementations can handle management of I/O events.
///
/// When put together these two types enable custom Windows handles to be
/// registered with mio's event loops. The `Binding` type is used to associate
/// handles and the `Overlapped` type is used to execute I/O operations. When
/// the I/O operations are completed a custom function pointer is called which
/// typically modifies a `SetReadiness` set by `Evented` methods which will get
/// later hooked into the mio event loop.
#[cfg(windows)]
pub mod windows {

    pub use sys::{Overlapped, Binding};
}

#[cfg(feature = "with-deprecated")]
mod convert {
    use std::time::Duration;

    const NANOS_PER_MILLI: u32 = 1_000_000;
    const MILLIS_PER_SEC: u64 = 1_000;

    /// Convert a `Duration` to milliseconds, rounding up and saturating at
    /// `u64::MAX`.
    ///
    /// The saturating is fine because `u64::MAX` milliseconds are still many
    /// million years.
    pub fn millis(duration: Duration) -> u64 {
        // Round up.
        let millis = (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
        duration.as_secs().saturating_mul(MILLIS_PER_SEC).saturating_add(millis as u64)
    }
}
<commit_msg>fix doc link (#608)<commit_after>//! A fast, low-level IO library for Rust focusing on non-blocking APIs, event
//! notification, and other useful utilities for building high performance IO
//! apps.
//!
//! # Goals
//!
//! * Fast - minimal overhead over the equivalent OS facilities (epoll, kqueue, etc...)
//! * Zero allocations
//! * A scalable readiness-based API, similar to epoll on Linux
//! * Design to allow for stack allocated buffers when possible (avoid double buffering).
//! * Provide utilities such as a timers, a notification channel, buffer abstractions, and a slab.
//!
//! # Usage
//!
//! Using mio starts by creating a [`Poll`], which reads events from the OS and
//! put them into [`Events`]. You can handle IO events from the OS with it.
//!
//! For more detail, see [`Poll`].
//!
//! [`Poll`]: struct.Poll.html
//! [`Events`]: struct.Events.html
//!
//! # Example
//!
//! ```
//! use mio::*;
//! use mio::tcp::{TcpListener, TcpStream};
//!
//! // Setup some tokens to allow us to identify which event is
//! // for which socket.
//! const SERVER: Token = Token(0);
//! const CLIENT: Token = Token(1);
//!
//! let addr = "127.0.0.1:13265".parse().unwrap();
//!
//! // Setup the server socket
//! let server = TcpListener::bind(&addr).unwrap();
//!
//! // Create a poll instance
//! let poll = Poll::new().unwrap();
//!
//! // Start listening for incoming connections
//! poll.register(&server, SERVER, Ready::readable(),
//!               PollOpt::edge()).unwrap();
//!
//! // Setup the client socket
//! let sock = TcpStream::connect(&addr).unwrap();
//!
//! // Register the socket
//! poll.register(&sock, CLIENT, Ready::readable(),
//!               PollOpt::edge()).unwrap();
//!
//! // Create storage for events
//! let mut events = Events::with_capacity(1024);
//!
//! loop {
//!     poll.poll(&mut events, None).unwrap();
//!
//!     for event in events.iter() {
//!         match event.token() {
//!             SERVER => {
//!                 // Accept and drop the socket immediately, this will close
//!                 // the socket and notify the client of the EOF.
//!                 let _ = server.accept();
//!             }
//!             CLIENT => {
//!                 // The server just shuts down the socket, let's just exit
//!                 // from our event loop.
//!                 return;
//!             }
//!             _ => unreachable!(),
//!         }
//!     }
//! }
//!
//! ```

#![doc(html_root_url = "https://docs.rs/mio/0.6.1")]
#![crate_name = "mio"]

#![deny(warnings, missing_docs, missing_debug_implementations)]

extern crate lazycell;
extern crate net2;
extern crate slab;
extern crate iovec;

#[cfg(unix)]
extern crate libc;

#[cfg(windows)]
extern crate miow;

#[cfg(windows)]
extern crate winapi;

#[cfg(windows)]
extern crate kernel32;

#[macro_use]
extern crate log;

#[cfg(test)]
extern crate env_logger;

mod event_imp;
mod io;
mod poll;
mod sys;
mod token;

pub mod net;

#[deprecated(since = "0.6.5", note = "use mio-more instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod channel;

#[deprecated(since = "0.6.5", note = "use mio-more instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod timer;

#[deprecated(since = "0.6.5", note = "update to use `Poll`")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod deprecated;

#[deprecated(since = "0.6.5", note = "use iovec crate directly")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use iovec::IoVec;

#[deprecated(since = "0.6.6", note = "use net module instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod tcp {
    pub use net::{TcpListener, TcpStream};
    pub use std::net::Shutdown;
}

#[deprecated(since = "0.6.6", note = "use net module instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub mod udp;

pub use poll::{
    Poll,
    Registration,
    SetReadiness,
};
pub use event_imp::{
    PollOpt,
    Ready,
};
pub use token::Token;

pub mod event {
    //! Readiness event types and utilities.

    pub use super::poll::{Events, Iter};
    pub use super::event_imp::{Event, Evented};
}

pub use event::{
    Events,
};

#[deprecated(since = "0.6.5", note = "use events:: instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use event::{Event, Evented};

#[deprecated(since = "0.6.5", note = "use events::Iter instead")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use poll::Iter as EventsIter;

#[deprecated(since = "0.6.5", note = "std::io::Error can avoid the allocation now")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
pub use io::deprecated::would_block;

#[cfg(unix)]
pub mod unix {
    //! Unix only extensions
    pub use sys::{
        EventedFd,
    };
    pub use sys::unix::UnixReady;
}

/// Windows-only extensions to the mio crate.
///
/// Mio on windows is currently implemented with IOCP for a high-performance
/// implementation of asynchronous I/O. Mio then provides TCP and UDP as sample
/// bindings for the system to connect networking types to asynchronous I/O. On
/// Unix this scheme is then also extensible to all other file descriptors with
/// the `EventedFd` type, but on Windows no such analog is available. The
/// purpose of this module, however, is to similarly provide a mechanism for
/// foreign I/O types to get hooked up into the IOCP event loop.
///
/// This module provides two types for interfacing with a custom IOCP handle:
///
/// * `Binding` - this type is intended to govern binding with mio's `Poll`
///   type. Each I/O object should contain an instance of `Binding` that's
///   interfaced with for the implementation of the `Evented` trait. The
///   `register`, `reregister`, and `deregister` methods for the `Evented` trait
///   all have rough analogs with `Binding`.
///
///   Note that this type **does not handle readiness**. That is, this type does
///   not handle whether sockets are readable/writable/etc. It's intended that
///   IOCP types will internally manage this state with a `SetReadiness` type
///   from the `poll` module. The `SetReadiness` is typically lazily created on
///   the first time that `Evented::register` is called and then stored in the
///   I/O object.
///
///   Also note that for types which represent streams of bytes the mio
///   interface of *readiness* doesn't map directly to the Windows model of
///   *completion*. This means that types will have to perform internal
///   buffering to ensure that a readiness interface can be provided. For a
///   sample implementation see the TCP/UDP modules in mio itself.
///
/// * `Overlapped` - this type is intended to be used as the concreate instances
///   of the `OVERLAPPED` type that most win32 methods expect. It's crucial, for
///   safety, that all asynchronous operations are initiated with an instance of
///   `Overlapped` and not another instantiation of `OVERLAPPED`.
///
///   Mio's `Overlapped` type is created with a function pointer that receives
///   a `OVERLAPPED_ENTRY` type when called. This `OVERLAPPED_ENTRY` type is
///   defined in the `winapi` crate. Whenever a completion is posted to an IOCP
///   object the `OVERLAPPED` that was signaled will be interpreted as
///   `Overlapped` in the mio crate and this function pointer will be invoked.
///   Through this function pointer, and through the `OVERLAPPED` pointer,
///   implementations can handle management of I/O events.
///
/// When put together these two types enable custom Windows handles to be
/// registered with mio's event loops. The `Binding` type is used to associate
/// handles and the `Overlapped` type is used to execute I/O operations. When
/// the I/O operations are completed a custom function pointer is called which
/// typically modifies a `SetReadiness` set by `Evented` methods which will get
/// later hooked into the mio event loop.
#[cfg(windows)]
pub mod windows {

    pub use sys::{Overlapped, Binding};
}

#[cfg(feature = "with-deprecated")]
mod convert {
    use std::time::Duration;

    const NANOS_PER_MILLI: u32 = 1_000_000;
    const MILLIS_PER_SEC: u64 = 1_000;

    /// Convert a `Duration` to milliseconds, rounding up and saturating at
    /// `u64::MAX`.
    ///
    /// The saturating is fine because `u64::MAX` milliseconds are still many
    /// million years.
    pub fn millis(duration: Duration) -> u64 {
        // Round up.
        let millis = (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
        duration.as_secs().saturating_mul(MILLIS_PER_SEC).saturating_add(millis as u64)
    }
}
<|endoftext|>


<commit_before>//! Preferred system exit codes as defined by [sysexits.h](https://www.freebsd.org/cgi/man.cgi?query=sysexits&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html)
//!
//! Exit code constants intended to be passed to
//! `std::env::set_exit_status!()` or `std::process::exit()`
//!
//! # Example:
//! ```
//! use exitcode;
//!
//! ::std::process::exit(exitcode::OK);
//! ```

/// Successful exit
pub const OK: i32 = 0;

/// The command was used incorrectly, e.g., with the
/// wrong number of arguments, a bad flag, a bad syntax
/// in a parameter, etc.
pub const USAGE: i32 = 64;

/// The input data was incorrect in some way.  This
/// should only be used for user's data and not system
/// files.
pub const DATAERR: i32 = 65;

/// An input file (not a system file) did not exist or
/// was not readable.  This could also include errors
/// like "No message" to a mailer (if it cared to
/// catch it).
pub const NOINPUT: i32 = 66;

/// The user specified did not exist.  This might be
/// used for mail addresses or remote logins.
pub const NOUSER: i32 = 67;

/// The host specified did not exist.  This is used in
/// mail addresses or network requests.
pub const NOHOST: i32 = 68;

/// A service is unavailable.  This can occur if a sup
/// port program or file does not exist.  This can also
/// be used as a catchall message when something you
/// wanted to do doesn't work, but you don't know why.
pub const UNAVAILABLE: i32 = 69;

/// An internal software error has been detected.  This
/// should be limited to non-operating system related
/// errors as possible.
pub const SOFTWARE: i32 = 70;

/// An operating system error has been detected.  This
/// is intended to be used for such things as "cannot
/// fork", "cannot create pipe", or the like.  It
/// includes things like getuid returning a user that
/// does not exist in the passwd file.
pub const OSERR: i32 = 71;

/// Some system file (e.g., /etc/passwd, /var/run/utmp,
/// etc.) does not exist, cannot be opened, or has some
/// sort of error (e.g., syntax error).
pub const OSFILE: i32 = 72;

/// A (user specified) output file cannot be created.
pub const CANTCREAT: i32 = 73;

/// An error occurred while doing I/O on some file.
pub const IOERR: i32 = 74;

/// Temporary failure, indicating something that is not
/// really an error.  In sendmail, this means that a
/// mailer (e.g.) could not create a connection, and
/// the request should be reattempted later.
pub const TEMPFAIL: i32 = 75;

/// The remote system returned something that was
/// "not possible" during a protocol exchange.
pub const PROTOCOL: i32 = 76;

/// You did not have sufficient permission to perform
/// the operation.  This is not intended for file system
/// problems, which should use `NOINPUT` or `CANTCREAT`,
/// but rather for higher level permissions.
pub const NOPERM: i32 = 77;

/// Something was found in an unconfigured or misconfigured state.
pub const CONFIG: i32 = 78;

/// Check if exit code given by `code` is successful
///
/// # Example:
/// ```
/// use exitcode;
/// assert!(exitcode::is_success(exitcode::OK));
/// assert!(!exitcode::is_success(exitcode::USAGE));
/// ```
pub fn is_success(code: i32) -> bool {
    code == OK
}

/// Check if exit code given by `code` is an error
///
/// # Example:
/// ```
/// use exitcode;
/// assert!(exitcode::is_error(exitcode::USAGE));
/// assert!(!exitcode::is_error(exitcode::OK));
/// ```
pub fn is_error(code: i32) -> bool {
    !is_success(code)
}
<commit_msg>rustfmt pass<commit_after>//! Preferred system exit codes as defined by sysexits.h
//!
//! Exit code constants intended to be passed to
//! `std::env::set_exit_status!()` or `std::process::exit()`
//!
//! # Example:
//! ```
//! use exitcode;
//!
//! ::std::process::exit(exitcode::OK);
//! ```

/// Successful exit
pub const OK: i32 = 0;

/// The command was used incorrectly, e.g., with the
/// wrong number of arguments, a bad flag, a bad syntax
/// in a parameter, etc.
pub const USAGE: i32 = 64;

/// The input data was incorrect in some way.  This
/// should only be used for user's data and not system
/// files.
pub const DATAERR: i32 = 65;

/// An input file (not a system file) did not exist or
/// was not readable.  This could also include errors
/// like "No message" to a mailer (if it cared to
/// catch it).
pub const NOINPUT: i32 = 66;

/// The user specified did not exist.  This might be
/// used for mail addresses or remote logins.
pub const NOUSER: i32 = 67;

/// The host specified did not exist.  This is used in
/// mail addresses or network requests.
pub const NOHOST: i32 = 68;

/// A service is unavailable.  This can occur if a sup
/// port program or file does not exist.  This can also
/// be used as a catchall message when something you
/// wanted to do doesn't work, but you don't know why.
pub const UNAVAILABLE: i32 = 69;

/// An internal software error has been detected.  This
/// should be limited to non-operating system related
/// errors as possible.
pub const SOFTWARE: i32 = 70;

/// An operating system error has been detected.  This
/// is intended to be used for such things as "cannot
/// fork", "cannot create pipe", or the like.  It
/// includes things like getuid returning a user that
/// does not exist in the passwd file.
pub const OSERR: i32 = 71;

/// Some system file (e.g., /etc/passwd, /var/run/utmp,
/// etc.) does not exist, cannot be opened, or has some
/// sort of error (e.g., syntax error).
pub const OSFILE: i32 = 72;

/// A (user specified) output file cannot be created.
pub const CANTCREAT: i32 = 73;

/// An error occurred while doing I/O on some file.
pub const IOERR: i32 = 74;

/// Temporary failure, indicating something that is not
/// really an error.  In sendmail, this means that a
/// mailer (e.g.) could not create a connection, and
/// the request should be reattempted later.
pub const TEMPFAIL: i32 = 75;

/// The remote system returned something that was
/// "not possible" during a protocol exchange.
pub const PROTOCOL: i32 = 76;

/// You did not have sufficient permission to perform
/// the operation.  This is not intended for file system
/// problems, which should use `NOINPUT` or `CANTCREAT`,
/// but rather for higher level permissions.
pub const NOPERM: i32 = 77;

/// Something was found in an unconfigured or misconfigured state.
pub const CONFIG: i32 = 78;

/// Check if exit code given by `code` is successful
///
/// # Example:
/// ```
/// use exitcode;
/// assert!(exitcode::is_success(exitcode::OK));
/// assert!(!exitcode::is_success(exitcode::USAGE));
/// ```
pub fn is_success(code: i32) -> bool {
    code == OK
}

/// Check if exit code given by `code` is an error
///
/// # Example:
/// ```
/// use exitcode;
/// assert!(exitcode::is_error(exitcode::USAGE));
/// assert!(!exitcode::is_error(exitcode::OK));
/// ```
pub fn is_error(code: i32) -> bool {
    !is_success(code)
}
<|endoftext|>


<commit_before>use std::cmp;

extern crate kana;
use kana::Kana;

pub mod dict;
use dict::{Dict, KanaConversionTable};

pub fn to_hiragana(d: &Dict, s: &String) -> String {
    let s = s.to_lowercase();
    gen_convert(d, &s)
}

pub fn to_katakana(d: &Dict, s: &String) -> String {
    let s = s.to_uppercase();
    gen_convert(d, &s)
}

pub fn to_kana(d: &Dict, s: &String) -> String {
    gen_convert(d, &s)
}

// Converts a String as is
fn gen_convert(d: &Dict, s: &String) -> String {
    let mut ret: String = String::new();

    for w in normalize(s).split_whitespace() {
        let w: String = choose_kana(&w.to_string());
        let ss: Vec<String> = syllables(&d, &w)
            .iter()
            .map(|ref s| convert_syllable(d, &s))
            .collect();
        for syl in ss {
            ret.push_str(syl.as_str());
        }
    }
    ret
}

fn syllables(d: &Dict, original: &String) -> Vec<String> {
    if original.len() == 0 {
        return vec![];
    }

    let mut ret: Vec<String> = vec![];
    let maxlen = cmp::min(original.chars().count(), d.max_len()) + 1;

    for l in (1..maxlen).rev() {
        let tmp: String = original.chars().take(l).collect();

        if is_syllable(d, &tmp) {
            ret.push(tmp);
            let skipped: String = original.chars().skip(l).collect();
            let mut rest = syllables(d, &skipped);

            ret.append(&mut rest);

            return ret;
        }
    }

    // if a match wasn't found, add the first char to ret
    // let mut taken: Vec<String> = vec![original.chars().take(1).collect()];
    // ret.append(&mut taken);

    let taken: String = original.chars().take(1).collect();
    ret.push(taken);

    let skipped: String = original.chars().skip(1).collect();
    let mut rest = syllables(d, &skipped);
    ret.append(&mut rest);

    ret
}

// Given a String (expected to be normalized), returns `true` if it is a syllable and
// `false` otherwise.
fn is_syllable(d: &Dict, k: &String) -> bool {
    d.contains_key(k)
}

// Searches for uppercase characters in a String and, if it finds any, turns the whole String to
// uppercase.
fn choose_kana(s: &String) -> String {
    match s.chars().fold(false, |acc, c| acc || c.is_uppercase()) {
        true => s.to_uppercase(),
        false => s.to_string(),
    }
}

fn normalize(s: &String) -> String {
    let k = Kana::init();
    let mut ret: String = kana::nowidespace(s.as_str());

    ret = kana::nowideyen(ret.as_str());
    ret = kana::wide2ascii(ret.as_str());

    ret = k.combine(ret.as_str());
    ret = k.half2kana(ret.as_str());

    ret
}

// Converts a String (expected to be a syllable) to kana.
pub fn convert_syllable(d: &Dict, ow: &String) -> String {
    // <pingveno> Because String impls Borrow<str>
    // `&ow.to_string()` => `ow`
    match d.get(ow) {
        Some(c) => c.clone(),
        None => ow.clone(),
    }
}
<commit_msg>Remove `pub` from `convert_syllable()`<commit_after>use std::cmp;

extern crate kana;
use kana::Kana;

pub mod dict;
use dict::{Dict, KanaConversionTable};

pub fn to_hiragana(d: &Dict, s: &String) -> String {
    let s = s.to_lowercase();
    gen_convert(d, &s)
}

pub fn to_katakana(d: &Dict, s: &String) -> String {
    let s = s.to_uppercase();
    gen_convert(d, &s)
}

pub fn to_kana(d: &Dict, s: &String) -> String {
    gen_convert(d, &s)
}

// Converts a String as is
fn gen_convert(d: &Dict, s: &String) -> String {
    let mut ret: String = String::new();

    for w in normalize(s).split_whitespace() {
        let w: String = choose_kana(&w.to_string());
        let ss: Vec<String> = syllables(&d, &w)
            .iter()
            .map(|ref s| convert_syllable(d, &s))
            .collect();
        for syl in ss {
            ret.push_str(syl.as_str());
        }
    }
    ret
}

fn syllables(d: &Dict, original: &String) -> Vec<String> {
    if original.len() == 0 {
        return vec![];
    }

    let mut ret: Vec<String> = vec![];
    let maxlen = cmp::min(original.chars().count(), d.max_len()) + 1;

    for l in (1..maxlen).rev() {
        let tmp: String = original.chars().take(l).collect();

        if is_syllable(d, &tmp) {
            ret.push(tmp);
            let skipped: String = original.chars().skip(l).collect();
            let mut rest = syllables(d, &skipped);

            ret.append(&mut rest);

            return ret;
        }
    }

    // if a match wasn't found, add the first char to ret
    // let mut taken: Vec<String> = vec![original.chars().take(1).collect()];
    // ret.append(&mut taken);

    let taken: String = original.chars().take(1).collect();
    ret.push(taken);

    let skipped: String = original.chars().skip(1).collect();
    let mut rest = syllables(d, &skipped);
    ret.append(&mut rest);

    ret
}

// Given a String (expected to be normalized), returns `true` if it is a syllable and
// `false` otherwise.
fn is_syllable(d: &Dict, k: &String) -> bool {
    d.contains_key(k)
}

// Searches for uppercase characters in a String and, if it finds any, turns the whole String to
// uppercase.
fn choose_kana(s: &String) -> String {
    match s.chars().fold(false, |acc, c| acc || c.is_uppercase()) {
        true => s.to_uppercase(),
        false => s.to_string(),
    }
}

fn normalize(s: &String) -> String {
    let k = Kana::init();
    let mut ret: String = kana::nowidespace(s.as_str());

    ret = kana::nowideyen(ret.as_str());
    ret = kana::wide2ascii(ret.as_str());

    ret = k.combine(ret.as_str());
    ret = k.half2kana(ret.as_str());

    ret
}

// Converts a String (expected to be a syllable) to kana.
fn convert_syllable(d: &Dict, ow: &String) -> String {
    // <pingveno> Because String impls Borrow<str>
    // `&ow.to_string()` => `ow`
    match d.get(ow) {
        Some(c) => c.clone(),
        None => ow.clone(),
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#![crate_name = "js"]
#![crate_type = "rlib"]

#![feature(core_intrinsics)]
#![feature(link_args)]
#![feature(str_utf16)]
#![feature(unsafe_no_drop_flag)]
#![feature(const_fn)]

#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, improper_ctypes, raw_pointer_derive)]

extern crate libc;
#[macro_use]
extern crate log;
#[macro_use]
extern crate heapsize;
extern crate rustc_serialize as serialize;
extern crate mozjs_sys;

#[cfg(target_os = "linux")]
#[cfg(target_pointer_width = "64")]
mod jsapi_linux_64;

#[cfg(target_os = "macos")]
#[cfg(target_pointer_width = "64")]
mod jsapi_macos_64;

#[cfg(target_os = "windows")]
#[cfg(target_pointer_width = "64")]
mod jsapi_windows_gcc_64;

#[cfg(not(target_os = "windows"))]
#[cfg(target_pointer_width = "32")]
mod jsapi_linux_32;

pub mod jsapi {
    #[cfg(target_os = "linux")]
    #[cfg(target_pointer_width = "64")]
    pub use jsapi_linux_64::*;

    #[cfg(target_os = "macos")]
    #[cfg(target_pointer_width = "64")]
    pub use jsapi_macos_64::*;

    #[cfg(target_os = "windows")]
    #[cfg(target_pointer_width = "64")]
    pub use jsapi_windows_gcc_64::*;

    #[cfg(not(target_os = "windows"))]
    #[cfg(target_pointer_width = "32")]
    pub use jsapi_linux_32::*;
}

pub mod rust;
pub mod glue;
pub mod jsval;

use jsapi::{JSContext, JSProtoKey, Heap};
use jsval::JSVal;
use rust::GCMethods;

use libc::c_uint;

use heapsize::HeapSizeOf;

pub const default_heapsize: u32 = 32_u32 * 1024_u32 * 1024_u32;
pub const default_stacksize: usize = 8192;

pub const JSID_TYPE_STRING: i64 = 0;
pub const JSID_TYPE_INT: i64 = 1;
pub const JSID_TYPE_VOID: i64 = 2;
pub const JSID_TYPE_OBJECT: i64 = 4;
pub const JSID_TYPE_DEFAULT_XML_NAMESPACE: i64 = 6;
pub const JSID_TYPE_MASK: i64 = 7;

pub const JSFUN_CONSTRUCTOR: u32 = 0x400; /* native that can be called as a ctor */

pub const JSPROP_ENUMERATE: c_uint = 0x01;
pub const JSPROP_READONLY: c_uint  = 0x02;
pub const JSPROP_PERMANENT: c_uint = 0x04;
pub const JSPROP_GETTER: c_uint = 0x10;
pub const JSPROP_SETTER: c_uint = 0x20;
pub const JSPROP_SHARED: c_uint =    0x40;
pub const JSPROP_NATIVE_ACCESSORS: c_uint = 0x08;

pub const JSCLASS_RESERVED_SLOTS_SHIFT: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_WIDTH: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_MASK: c_uint = ((1 << JSCLASS_RESERVED_SLOTS_WIDTH) - 1) as c_uint;

pub const JSCLASS_HIGH_FLAGS_SHIFT: c_uint =
    JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH;
pub const JSCLASS_IS_GLOBAL: c_uint = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 1);
pub const JSCLASS_GLOBAL_APPLICATION_SLOTS: c_uint = 4;
pub const JSCLASS_GLOBAL_SLOT_COUNT: c_uint = JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProtoKey::JSProto_LIMIT as u32 * 3 + 31;

pub const JSCLASS_IS_DOMJSCLASS: u32 = 1 << 4;
pub const JSCLASS_IMPLEMENTS_BARRIERS: u32 = 1 << 5;
pub const JSCLASS_USERBIT1: u32 = 1 << 7;

pub const JSCLASS_IS_PROXY: u32 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT+4);

pub const JSSLOT_PROXY_PRIVATE: u32 = 1;

pub const JS_DEFAULT_ZEAL_FREQ: u32 = 100;

pub const JSITER_ENUMERATE: c_uint   = 0x1;
pub const JSITER_FOREACH: c_uint     = 0x2;
pub const JSITER_KEYVALUE: c_uint    = 0x4;
pub const JSITER_OWNONLY: c_uint     = 0x8;
pub const JSITER_HIDDEN: c_uint      = 0x10;
pub const JSITER_SYMBOLS: c_uint     = 0x20;
pub const JSITER_SYMBOLSONLY: c_uint = 0x40;

#[link(name = "jsglue")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "stdc++")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "gcc")]
extern { }

#[inline(always)]
pub unsafe fn JS_ARGV(_cx: *mut JSContext, vp: *mut JSVal) -> *mut JSVal {
    vp.offset(2)
}

#[inline(always)]
pub unsafe fn JS_CALLEE(_cx: *mut JSContext, vp: *mut JSVal) -> JSVal {
    *vp
}

// This is measured properly by the heap measurement implemented in SpiderMonkey.
impl<T: Copy + GCMethods<T>> HeapSizeOf for Heap<T> {
    fn heap_size_of_children(&self) -> usize {
        0
    }
}
known_heap_size!(0, JSVal);

<commit_msg>Sort crates, mods, uses in lib.rs.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#![crate_name = "js"]
#![crate_type = "rlib"]

#![feature(core_intrinsics)]
#![feature(link_args)]
#![feature(str_utf16)]
#![feature(unsafe_no_drop_flag)]
#![feature(const_fn)]

#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, improper_ctypes, raw_pointer_derive)]

#[macro_use]
extern crate heapsize;
extern crate libc;
#[macro_use]
extern crate log;
extern crate mozjs_sys;
extern crate rustc_serialize as serialize;

#[cfg(target_os = "linux")]
#[cfg(target_pointer_width = "64")]
mod jsapi_linux_64;

#[cfg(target_os = "macos")]
#[cfg(target_pointer_width = "64")]
mod jsapi_macos_64;

#[cfg(target_os = "windows")]
#[cfg(target_pointer_width = "64")]
mod jsapi_windows_gcc_64;

#[cfg(not(target_os = "windows"))]
#[cfg(target_pointer_width = "32")]
mod jsapi_linux_32;

pub mod jsapi {
    #[cfg(target_os = "linux")]
    #[cfg(target_pointer_width = "64")]
    pub use jsapi_linux_64::*;

    #[cfg(target_os = "macos")]
    #[cfg(target_pointer_width = "64")]
    pub use jsapi_macos_64::*;

    #[cfg(target_os = "windows")]
    #[cfg(target_pointer_width = "64")]
    pub use jsapi_windows_gcc_64::*;

    #[cfg(not(target_os = "windows"))]
    #[cfg(target_pointer_width = "32")]
    pub use jsapi_linux_32::*;
}

pub mod glue;
pub mod jsval;
pub mod rust;

use heapsize::HeapSizeOf;
use jsapi::{JSContext, JSProtoKey, Heap};
use jsval::JSVal;
use libc::c_uint;
use rust::GCMethods;

pub const default_heapsize: u32 = 32_u32 * 1024_u32 * 1024_u32;
pub const default_stacksize: usize = 8192;

pub const JSID_TYPE_STRING: i64 = 0;
pub const JSID_TYPE_INT: i64 = 1;
pub const JSID_TYPE_VOID: i64 = 2;
pub const JSID_TYPE_OBJECT: i64 = 4;
pub const JSID_TYPE_DEFAULT_XML_NAMESPACE: i64 = 6;
pub const JSID_TYPE_MASK: i64 = 7;

pub const JSFUN_CONSTRUCTOR: u32 = 0x400; /* native that can be called as a ctor */

pub const JSPROP_ENUMERATE: c_uint = 0x01;
pub const JSPROP_READONLY: c_uint  = 0x02;
pub const JSPROP_PERMANENT: c_uint = 0x04;
pub const JSPROP_GETTER: c_uint = 0x10;
pub const JSPROP_SETTER: c_uint = 0x20;
pub const JSPROP_SHARED: c_uint =    0x40;
pub const JSPROP_NATIVE_ACCESSORS: c_uint = 0x08;

pub const JSCLASS_RESERVED_SLOTS_SHIFT: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_WIDTH: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_MASK: c_uint = ((1 << JSCLASS_RESERVED_SLOTS_WIDTH) - 1) as c_uint;

pub const JSCLASS_HIGH_FLAGS_SHIFT: c_uint =
    JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH;
pub const JSCLASS_IS_GLOBAL: c_uint = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 1);
pub const JSCLASS_GLOBAL_APPLICATION_SLOTS: c_uint = 4;
pub const JSCLASS_GLOBAL_SLOT_COUNT: c_uint = JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProtoKey::JSProto_LIMIT as u32 * 3 + 31;

pub const JSCLASS_IS_DOMJSCLASS: u32 = 1 << 4;
pub const JSCLASS_IMPLEMENTS_BARRIERS: u32 = 1 << 5;
pub const JSCLASS_USERBIT1: u32 = 1 << 7;

pub const JSCLASS_IS_PROXY: u32 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT+4);

pub const JSSLOT_PROXY_PRIVATE: u32 = 1;

pub const JS_DEFAULT_ZEAL_FREQ: u32 = 100;

pub const JSITER_ENUMERATE: c_uint   = 0x1;
pub const JSITER_FOREACH: c_uint     = 0x2;
pub const JSITER_KEYVALUE: c_uint    = 0x4;
pub const JSITER_OWNONLY: c_uint     = 0x8;
pub const JSITER_HIDDEN: c_uint      = 0x10;
pub const JSITER_SYMBOLS: c_uint     = 0x20;
pub const JSITER_SYMBOLSONLY: c_uint = 0x40;

#[link(name = "jsglue")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "stdc++")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "gcc")]
extern { }

#[inline(always)]
pub unsafe fn JS_ARGV(_cx: *mut JSContext, vp: *mut JSVal) -> *mut JSVal {
    vp.offset(2)
}

#[inline(always)]
pub unsafe fn JS_CALLEE(_cx: *mut JSContext, vp: *mut JSVal) -> JSVal {
    *vp
}

// This is measured properly by the heap measurement implemented in SpiderMonkey.
impl<T: Copy + GCMethods<T>> HeapSizeOf for Heap<T> {
    fn heap_size_of_children(&self) -> usize {
        0
    }
}
known_heap_size!(0, JSVal);

<|endoftext|>


<commit_before>#![warn(missing_docs)]
#![cfg_attr(feature = "serde_derive", feature(proc_macro))]

//! Crate for communicating with the hue API

#[cfg(feature = "serde_derive")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "ssdp")]
extern crate ssdp;

extern crate serde;
extern crate serde_json;
extern crate hyper;
extern crate regex;
#[macro_use]
extern crate lazy_static;

mod clean{
    use regex::Regex;
    lazy_static!{
        static ref REMOVE_NULL: Regex = Regex::new(r#""\w*":null,?"#).unwrap();
        static ref TRAILING_COMMA: Regex = Regex::new(r",\}").unwrap();
    }
    /// Removes null values from the JSON-formatted String
    pub fn clean_json(s: String) -> String{
        let cleaned = REMOVE_NULL.replace_all(&s, "");
        TRAILING_COMMA.replace_all(&cleaned, "}")
    }
}

/// Errors that can occur in the crate
pub mod errors;
/// Handles all the communication with the bridge
pub mod bridge;
/// Structs mapping the different JSON-objects used with Hue API
pub mod hue;
<commit_msg>Re-export common types and functions<commit_after>#![warn(missing_docs)]
#![cfg_attr(feature = "serde_derive", feature(proc_macro))]

//! Crate for communicating with the hue API

#[cfg(feature = "serde_derive")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "ssdp")]
extern crate ssdp;

extern crate serde;
extern crate serde_json;
extern crate hyper;
extern crate regex;
#[macro_use]
extern crate lazy_static;

pub use bridge::{discover, Bridge};
pub use hue::LightCommand;

mod clean{
    use regex::Regex;
    lazy_static!{
        static ref REMOVE_NULL: Regex = Regex::new(r#""\w*":null,?"#).unwrap();
        static ref TRAILING_COMMA: Regex = Regex::new(r",\}").unwrap();
    }
    /// Removes null values from the JSON-formatted String
    pub fn clean_json(s: String) -> String{
        let cleaned = REMOVE_NULL.replace_all(&s, "");
        TRAILING_COMMA.replace_all(&cleaned, "}")
    }
}

/// Errors that can occur in the crate
pub mod errors;
/// Handles all the communication with the bridge
pub mod bridge;
/// Structs mapping the different JSON-objects used with Hue API
pub mod hue;
<|endoftext|>