<commit_before>use std::iter::range_step;
use std::collections::Bitv;

pub struct FactorIterator {
    value: uint,
    current: uint,
    max: uint,
}

impl FactorIterator {
    pub fn new(value: uint, limit: uint) -> FactorIterator {
        FactorIterator {
            current: 0u,
            value: value,
            max: limit,
        }
    }
}

impl Iterator<uint> for FactorIterator {
    fn next(&mut self) -> Option<uint> {
        self.current += 1;
        while self.current < self.max {
            if self.value % self.current == 0 {
                return Some(self.current)
            }
            self.current += 1;
        }
        None
    }
}

pub fn is_prime(value: uint) -> bool {
    if value == 1 {
        return false;
    }
    for i in range(2, value) {
        if value % i == 0 {
            return false;
        }
    }
    true
}

/// Calculates the greatest common divisor of `a` and `b`
pub fn gcd(a: uint, b: uint) -> uint {
    let mut i = a;
    let mut j = b;
    while i != j {
        if i > j {
            i = i - j;
        } else {
            j = j - i;
        }
    }
    i
}

/// Calculates the lowest common multiple of `a` and `b`
pub fn lcm(a: uint, b: uint) -> uint {
    if a == 0 && b == 0 {
        0
    } else {
        (a * b) / gcd(a, b)
    }
}

/// Iterator over prime numbers from 2
pub struct PrimeIterator {
    current: uint,
    bitv: Bitv,
}

impl PrimeIterator {
    pub fn new() -> PrimeIterator {
        let mut initial_vector = Bitv::with_capacity(8, false);
        // Preset the initial vector with primes
        for i in vec![2, 3, 5, 7].iter() {
            initial_vector.set(*i, true);
        }
        PrimeIterator {
            current: 0,
            bitv: initial_vector,
        }
    }

    // Double the size of the bitv
    fn grow_table(&mut self) {
        let first_number = self.bitv.len();
        // Default to true, we'll set things to false as we go
        // what's left are primes
        self.bitv.grow(first_number, true);
        let new_length = self.bitv.len();
        for i in range(1, new_length) {
            // If prime, set multiples to false
            if self.bitv.get(i) {
                // Find the first multiple of this prime in the newly created
                // table space
                let first_multiple = if i < first_number {
                    if first_number % i == 0 {
                        first_number
                    } else {
                        (first_number - first_number % i) + i
                    }
                } else {
                    i * 2
                };
                for j in range_step(first_multiple, new_length, i) {
                    self.bitv.set(j, false);
                }
            }
        }
    }
}

impl Iterator<uint> for PrimeIterator {
    fn next(&mut self) -> Option<uint> {
        loop {
            // Consider the next number
            self.current += 1;
            // If we've gone over the bounds of our Bitv, grow it
            if self.bitv.len() <= self.current {
                self.grow_table();
            }

            if self.bitv.get(self.current) {
                return Some(self.current);
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::{FactorIterator, is_prime, lcm, gcd, PrimeIterator};

    #[test]
    fn test_factorization() {
        let mut iter = FactorIterator::new(22, 22);
        let result: Vec<uint> = iter.collect();
        assert_eq!(result, vec![1, 2, 11]);
    }

    #[test]
    fn test_primality() {
        assert_eq!(is_prime(1), false);
        assert_eq!(is_prime(2), true);
        assert_eq!(is_prime(3), true);
        assert_eq!(is_prime(4), false);
    }

    #[test]
    fn test_lowest_common_multiple() {
        assert_eq!(lcm(2, 3), 6);
    }

    #[test]
    fn test_greatest_common_divisor() {
        assert_eq!(gcd(5, 5), 5);
        assert_eq!(gcd(54, 24), 6);
    }

    #[test]
    fn test_prime_iterator() {
        let mut iter = PrimeIterator::new();
        let primes = vec![
            2u, 3, 5, 7, 11, 13, 17, 19, 23, 29,
            31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
            73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
            127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
            179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
            233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
            283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
            353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
            419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
            467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
            547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
            607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
            661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
            739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
            811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
            877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
            947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013
        ];
        for i in primes.iter() {
            println!("Looking for {}", *i);
            assert_eq!(iter.next().unwrap(), *i);
        }
    }
}
<commit_msg>Remove unneeded println!()<commit_after>use std::iter::range_step;
use std::collections::Bitv;

pub struct FactorIterator {
    value: uint,
    current: uint,
    max: uint,
}

impl FactorIterator {
    pub fn new(value: uint, limit: uint) -> FactorIterator {
        FactorIterator {
            current: 0u,
            value: value,
            max: limit,
        }
    }
}

impl Iterator<uint> for FactorIterator {
    fn next(&mut self) -> Option<uint> {
        self.current += 1;
        while self.current < self.max {
            if self.value % self.current == 0 {
                return Some(self.current)
            }
            self.current += 1;
        }
        None
    }
}

pub fn is_prime(value: uint) -> bool {
    if value == 1 {
        return false;
    }
    for i in range(2, value) {
        if value % i == 0 {
            return false;
        }
    }
    true
}

/// Calculates the greatest common divisor of `a` and `b`
pub fn gcd(a: uint, b: uint) -> uint {
    let mut i = a;
    let mut j = b;
    while i != j {
        if i > j {
            i = i - j;
        } else {
            j = j - i;
        }
    }
    i
}

/// Calculates the lowest common multiple of `a` and `b`
pub fn lcm(a: uint, b: uint) -> uint {
    if a == 0 && b == 0 {
        0
    } else {
        (a * b) / gcd(a, b)
    }
}

/// Iterator over prime numbers from 2
pub struct PrimeIterator {
    current: uint,
    bitv: Bitv,
}

impl PrimeIterator {
    pub fn new() -> PrimeIterator {
        let mut initial_vector = Bitv::with_capacity(8, false);
        // Preset the initial vector with primes
        for i in vec![2, 3, 5, 7].iter() {
            initial_vector.set(*i, true);
        }
        PrimeIterator {
            current: 0,
            bitv: initial_vector,
        }
    }

    // Double the size of the bitv
    fn grow_table(&mut self) {
        let first_number = self.bitv.len();
        // Default to true, we'll set things to false as we go
        // what's left are primes
        self.bitv.grow(first_number, true);
        let new_length = self.bitv.len();
        for i in range(1, new_length) {
            // If prime, set multiples to false
            if self.bitv.get(i) {
                // Find the first multiple of this prime in the newly created
                // table space
                let first_multiple = if i < first_number {
                    if first_number % i == 0 {
                        first_number
                    } else {
                        (first_number - first_number % i) + i
                    }
                } else {
                    i * 2
                };
                for j in range_step(first_multiple, new_length, i) {
                    self.bitv.set(j, false);
                }
            }
        }
    }
}

impl Iterator<uint> for PrimeIterator {
    fn next(&mut self) -> Option<uint> {
        loop {
            // Consider the next number
            self.current += 1;
            // If we've gone over the bounds of our Bitv, grow it
            if self.bitv.len() <= self.current {
                self.grow_table();
            }

            if self.bitv.get(self.current) {
                return Some(self.current);
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::{FactorIterator, is_prime, lcm, gcd, PrimeIterator};

    #[test]
    fn test_factorization() {
        let mut iter = FactorIterator::new(22, 22);
        let result: Vec<uint> = iter.collect();
        assert_eq!(result, vec![1, 2, 11]);
    }

    #[test]
    fn test_primality() {
        assert_eq!(is_prime(1), false);
        assert_eq!(is_prime(2), true);
        assert_eq!(is_prime(3), true);
        assert_eq!(is_prime(4), false);
    }

    #[test]
    fn test_lowest_common_multiple() {
        assert_eq!(lcm(2, 3), 6);
    }

    #[test]
    fn test_greatest_common_divisor() {
        assert_eq!(gcd(5, 5), 5);
        assert_eq!(gcd(54, 24), 6);
    }

    #[test]
    fn test_prime_iterator() {
        let mut iter = PrimeIterator::new();
        let primes = vec![
            2u, 3, 5, 7, 11, 13, 17, 19, 23, 29,
            31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
            73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
            127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
            179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
            233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
            283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
            353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
            419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
            467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
            547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
            607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
            661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
            739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
            811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
            877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
            947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013
        ];
        for i in primes.iter() {
            assert_eq!(iter.next().unwrap(), *i);
        }
    }
}
<|endoftext|>


<commit_before>#[deriving(Show, PartialEq)]
pub struct Address {
    local: String,
    domain: String,
}

impl Address {
    pub fn new(local: String, domain: String) -> Address {
        Address {
            local: local,
            domain: domain,
        }
    }
}
<commit_msg>implement FromStr<commit_after>use std::from_str::FromStr;
use simple::parse;

#[deriving(Show, PartialEq)]
pub struct Address {
    pub local: String,
    pub domain: String,
}

impl Address {
    pub fn new(local: String, domain: String) -> Address {
        Address {
            local: local,
            domain: domain,
        }
    }
}

impl FromStr for Address {
    fn from_str(string: &str) -> Option<Address> {
        match parse(string.to_string()) {
            Ok(s) => Some(s),
            Err(_) => None,
        }
    }
}

<|endoftext|>


<commit_before>// Copyright 2016 Adam Perry. Dual-licensed MIT and Apache 2.0 (see LICENSE files for details).

use std::collections::BTreeMap;
use std::env;

pub const RFC_BOT_MENTION: &'static str = "@rfcbot";
pub const GH_ORGS: [&'static str; 3] = ["rust-lang", "rust-lang-nursery", "rust-lang-deprecated"];

lazy_static! {
    pub static ref CONFIG: Config = {
        match init() {
            Ok(c) => {
                info!("Configuration parsed from environment variables.");
                c
            },
            Err(missing) => {
                error!("Unable to load environment variables {:?}", missing);
                panic!("Unable to load environment variables {:?}", missing);
            },
        }
    };
}

#[derive(Debug)]
pub struct Config {
    pub server_port: u32,
    pub db_url: String,
    pub db_pool_size: u32,
    pub github_access_token: String,
    pub github_user_agent: String,
    pub github_webhook_secrets: Vec<String>,
    pub github_interval_mins: u64,
    pub post_comments: bool,
}

impl Config {
    pub fn check(&self) -> bool {
        !self.db_url.is_empty() && !self.github_access_token.is_empty() &&
            !self.github_user_agent.is_empty()
    }
}

const SERVER_PORT: &'static str = "SERVER_PORT";
const DB_URL: &'static str = "DATABASE_URL";
const DB_POOL_SIZE: &'static str = "DATABASE_POOL_SIZE";
const GITHUB_TOKEN: &'static str = "GITHUB_ACCESS_TOKEN";
const GITHUB_WEBHOOK_SECRETS: &'static str = "GITHUB_WEBHOOK_SECRETS";
const GITHUB_UA: &'static str = "GITHUB_USER_AGENT";
const GITHUB_INTERVAL: &'static str = "GITHUB_SCRAPE_INTERVAL";
const BUILDBOT_INTERVAL: &'static str = "BUILDBOT_SCRAPE_INTERVAL";
const POST_COMMENTS: &'static str = "POST_COMMENTS";

// this is complex, but we'll shortly need a lot more config items
// so checking them automagically seems like a nice solution
pub fn init() -> Result<Config, Vec<&'static str>> {

    let mut vars: BTreeMap<&'static str, Result<String, _>> = BTreeMap::new();
    let keys = vec![SERVER_PORT,
                    DB_URL,
                    DB_POOL_SIZE,
                    GITHUB_TOKEN,
                    GITHUB_WEBHOOK_SECRETS,
                    GITHUB_UA,
                    GITHUB_INTERVAL,
                    BUILDBOT_INTERVAL,
                    POST_COMMENTS];

    for var in keys {
        vars.insert(var, env::var(var));
    }

    let all_found = vars.iter().all(|(_, v)| v.is_ok());
    if all_found {
        let mut vars = vars.into_iter()
            .map(|(k, v)| (k, v.unwrap()))
            .collect::<BTreeMap<_, _>>();

        let port = vars.remove(SERVER_PORT).unwrap();
        let port = match port.parse::<u32>() {
            Ok(p) => p,
            Err(_) => return Err(vec![SERVER_PORT]),
        };

        let db_url = vars.remove(DB_URL).unwrap();
        let db_pool_size = vars.remove(DB_POOL_SIZE).unwrap();
        let db_pool_size = match db_pool_size.parse::<u32>() {
            Ok(size) => size,
            Err(_) => return Err(vec![DB_POOL_SIZE]),
        };

        let gh_token = vars.remove(GITHUB_TOKEN).unwrap();
        let gh_ua = vars.remove(GITHUB_UA).unwrap();

        let gh_interval = vars.remove(GITHUB_INTERVAL).unwrap();
        let gh_interval = match gh_interval.parse::<u64>() {
            Ok(interval) => interval,
            Err(_) => return Err(vec![GITHUB_INTERVAL]),
        };

        let post_comments = vars.remove(POST_COMMENTS).unwrap();
        let post_comments = match post_comments.parse::<bool>() {
            Ok(pc) => pc,
            Err(_) => return Err(vec![POST_COMMENTS]),
        };

        let webhook_secrets = vars.remove(GITHUB_WEBHOOK_SECRETS).unwrap();
        let webhook_secrets = webhook_secrets.split(',').map(String::from).collect();

        Ok(Config {
            server_port: port,
            db_url: db_url,
            db_pool_size: db_pool_size,
            github_access_token: gh_token,
            github_user_agent: gh_ua,
            github_webhook_secrets: webhook_secrets,
            github_interval_mins: gh_interval,
            post_comments: post_comments,
        })

    } else {

        Err(vars.iter()
            .filter(|&(_, v)| v.is_err())
            .map(|(&k, _)| k)
            .collect())

    }
}
<commit_msg>Remove buildbot interval config.<commit_after>// Copyright 2016 Adam Perry. Dual-licensed MIT and Apache 2.0 (see LICENSE files for details).

use std::collections::BTreeMap;
use std::env;

pub const RFC_BOT_MENTION: &'static str = "@rfcbot";
pub const GH_ORGS: [&'static str; 3] = ["rust-lang", "rust-lang-nursery", "rust-lang-deprecated"];

lazy_static! {
    pub static ref CONFIG: Config = {
        match init() {
            Ok(c) => {
                info!("Configuration parsed from environment variables.");
                c
            },
            Err(missing) => {
                error!("Unable to load environment variables {:?}", missing);
                panic!("Unable to load environment variables {:?}", missing);
            },
        }
    };
}

#[derive(Debug)]
pub struct Config {
    pub server_port: u32,
    pub db_url: String,
    pub db_pool_size: u32,
    pub github_access_token: String,
    pub github_user_agent: String,
    pub github_webhook_secrets: Vec<String>,
    pub github_interval_mins: u64,
    pub post_comments: bool,
}

impl Config {
    pub fn check(&self) -> bool {
        !self.db_url.is_empty() && !self.github_access_token.is_empty() &&
            !self.github_user_agent.is_empty()
    }
}

const SERVER_PORT: &'static str = "SERVER_PORT";
const DB_URL: &'static str = "DATABASE_URL";
const DB_POOL_SIZE: &'static str = "DATABASE_POOL_SIZE";
const GITHUB_TOKEN: &'static str = "GITHUB_ACCESS_TOKEN";
const GITHUB_WEBHOOK_SECRETS: &'static str = "GITHUB_WEBHOOK_SECRETS";
const GITHUB_UA: &'static str = "GITHUB_USER_AGENT";
const GITHUB_INTERVAL: &'static str = "GITHUB_SCRAPE_INTERVAL";
const POST_COMMENTS: &'static str = "POST_COMMENTS";

// this is complex, but we'll shortly need a lot more config items
// so checking them automagically seems like a nice solution
pub fn init() -> Result<Config, Vec<&'static str>> {

    let mut vars: BTreeMap<&'static str, Result<String, _>> = BTreeMap::new();
    let keys = vec![SERVER_PORT,
                    DB_URL,
                    DB_POOL_SIZE,
                    GITHUB_TOKEN,
                    GITHUB_WEBHOOK_SECRETS,
                    GITHUB_UA,
                    GITHUB_INTERVAL,
                    POST_COMMENTS];

    for var in keys {
        vars.insert(var, env::var(var));
    }

    let all_found = vars.iter().all(|(_, v)| v.is_ok());
    if all_found {
        let mut vars = vars.into_iter()
            .map(|(k, v)| (k, v.unwrap()))
            .collect::<BTreeMap<_, _>>();

        let port = vars.remove(SERVER_PORT).unwrap();
        let port = match port.parse::<u32>() {
            Ok(p) => p,
            Err(_) => return Err(vec![SERVER_PORT]),
        };

        let db_url = vars.remove(DB_URL).unwrap();
        let db_pool_size = vars.remove(DB_POOL_SIZE).unwrap();
        let db_pool_size = match db_pool_size.parse::<u32>() {
            Ok(size) => size,
            Err(_) => return Err(vec![DB_POOL_SIZE]),
        };

        let gh_token = vars.remove(GITHUB_TOKEN).unwrap();
        let gh_ua = vars.remove(GITHUB_UA).unwrap();

        let gh_interval = vars.remove(GITHUB_INTERVAL).unwrap();
        let gh_interval = match gh_interval.parse::<u64>() {
            Ok(interval) => interval,
            Err(_) => return Err(vec![GITHUB_INTERVAL]),
        };

        let post_comments = vars.remove(POST_COMMENTS).unwrap();
        let post_comments = match post_comments.parse::<bool>() {
            Ok(pc) => pc,
            Err(_) => return Err(vec![POST_COMMENTS]),
        };

        let webhook_secrets = vars.remove(GITHUB_WEBHOOK_SECRETS).unwrap();
        let webhook_secrets = webhook_secrets.split(',').map(String::from).collect();

        Ok(Config {
            server_port: port,
            db_url: db_url,
            db_pool_size: db_pool_size,
            github_access_token: gh_token,
            github_user_agent: gh_ua,
            github_webhook_secrets: webhook_secrets,
            github_interval_mins: gh_interval,
            post_comments: post_comments,
        })

    } else {

        Err(vars.iter()
            .filter(|&(_, v)| v.is_err())
            .map(|(&k, _)| k)
            .collect())

    }
}
<|endoftext|>


<commit_before>use super::internal::{Bounded, Infinite, SizeLimit};
use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian};
use de::read::BincodeRead;
use error::Result;
use serde;
use std::io::{Read, Write};
use std::marker::PhantomData;
use {DeserializerAcceptor, SerializerAcceptor};

use self::EndianOption::*;
use self::LimitOption::*;

struct DefaultOptions(Infinite);

pub(crate) trait Options {
    type Limit: SizeLimit + 'static;
    type Endian: ByteOrder + 'static;

    fn limit(&mut self) -> &mut Self::Limit;
}

pub(crate) trait OptionsExt: Options + Sized {
    fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> {
        WithOtherLimit::new(self, Infinite)
    }

    fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> {
        WithOtherLimit::new(self, Bounded(limit))
    }

    fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> {
        WithOtherEndian::new(self)
    }

    fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> {
        WithOtherEndian::new(self)
    }

    fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> {
        WithOtherEndian::new(self)
    }
}

impl<'a, O: Options> Options for &'a mut O {
    type Limit = O::Limit;
    type Endian = O::Endian;

    #[inline(always)]
    fn limit(&mut self) -> &mut Self::Limit {
        (*self).limit()
    }
}

impl<T: Options> OptionsExt for T {}

impl DefaultOptions {
    fn new() -> DefaultOptions {
        DefaultOptions(Infinite)
    }
}

impl Options for DefaultOptions {
    type Limit = Infinite;
    type Endian = LittleEndian;

    #[inline(always)]
    fn limit(&mut self) -> &mut Infinite {
        &mut self.0
    }
}

#[derive(Clone, Copy)]
enum LimitOption {
    Unlimited,
    Limited(u64),
}

#[derive(Clone, Copy)]
enum EndianOption {
    Big,
    Little,
    Native,
}

/// A configuration builder whose options Bincode will use
/// while serializing and deserializing.
///
/// ### Options
/// Endianness: The endianness with which multi-byte integers will be read/written.  *default: little endian*
/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited*
///
/// ### Byte Limit Details
/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode
/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long.
///
/// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any
/// serialization that goes over the limit.
pub struct Config {
    limit: LimitOption,
    endian: EndianOption,
}

pub(crate) struct WithOtherLimit<O: Options, L: SizeLimit> {
    _options: O,
    pub(crate) new_limit: L,
}

pub(crate) struct WithOtherEndian<O: Options, E: ByteOrder> {
    options: O,
    _endian: PhantomData<E>,
}

impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> {
    #[inline(always)]
    pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> {
        WithOtherLimit {
            _options: options,
            new_limit: limit,
        }
    }
}

impl<O: Options, E: ByteOrder> WithOtherEndian<O, E> {
    #[inline(always)]
    pub(crate) fn new(options: O) -> WithOtherEndian<O, E> {
        WithOtherEndian {
            options: options,
            _endian: PhantomData,
        }
    }
}

impl<O: Options, E: ByteOrder + 'static> Options for WithOtherEndian<O, E> {
    type Limit = O::Limit;
    type Endian = E;

    #[inline(always)]
    fn limit(&mut self) -> &mut O::Limit {
        self.options.limit()
    }
}

impl<O: Options, L: SizeLimit + 'static> Options for WithOtherLimit<O, L> {
    type Limit = L;
    type Endian = O::Endian;

    fn limit(&mut self) -> &mut L {
        &mut self.new_limit
    }
}

macro_rules! config_map {
    ($self:expr, $opts:ident => $call:expr) => {
        match ($self.limit, $self.endian) {
            (Unlimited, Little) => {
                let $opts = DefaultOptions::new().with_no_limit().with_little_endian();
                $call
            }
            (Unlimited, Big) => {
                let $opts = DefaultOptions::new().with_no_limit().with_big_endian();
                $call
            }
            (Unlimited, Native) => {
                let $opts = DefaultOptions::new().with_no_limit().with_native_endian();
                $call
            }

            (Limited(l), Little) => {
                let $opts = DefaultOptions::new().with_limit(l).with_little_endian();
                $call
            }
            (Limited(l), Big) => {
                let $opts = DefaultOptions::new().with_limit(l).with_big_endian();
                $call
            }
            (Limited(l), Native) => {
                let $opts = DefaultOptions::new().with_limit(l).with_native_endian();
                $call
            }
        }
    };
}

impl Config {
    #[inline(always)]
    pub(crate) fn new() -> Config {
        Config {
            limit: LimitOption::Unlimited,
            endian: EndianOption::Little,
        }
    }

    /// Sets the byte limit to be unlimited.
    /// This is the default.
    #[inline(always)]
    pub fn no_limit(&mut self) -> &mut Self {
        self.limit = LimitOption::Unlimited;
        self
    }

    /// Sets the byte limit to `limit`.
    #[inline(always)]
    pub fn limit(&mut self, limit: u64) -> &mut Self {
        self.limit = LimitOption::Limited(limit);
        self
    }

    /// Sets the endianness to little-endian
    /// This is the default.
    #[inline(always)]
    pub fn little_endian(&mut self) -> &mut Self {
        self.endian = EndianOption::Little;
        self
    }

    /// Sets the endianness to big-endian
    #[inline(always)]
    pub fn big_endian(&mut self) -> &mut Self {
        self.endian = EndianOption::Big;
        self
    }

    /// Sets the endianness to the the machine-native endianness
    #[inline(always)]
    pub fn native_endian(&mut self) -> &mut Self {
        self.endian = EndianOption::Native;
        self
    }

    /// Serializes a serializable object into a `Vec` of bytes using this configuration
    #[inline(always)]
    pub fn serialize<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<Vec<u8>> {
        config_map!(self, opts => ::internal::serialize(t, opts))
    }

    /// Returns the size that an object would be if serialized using Bincode with this configuration
    #[inline(always)]
    pub fn serialized_size<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<u64> {
        config_map!(self, opts => ::internal::serialized_size(t, opts))
    }

    /// Serializes an object directly into a `Writer` using this configuration
    ///
    /// If the serialization would take more bytes than allowed by the size limit, an error
    /// is returned and *no bytes* will be written into the `Writer`
    #[inline(always)]
    pub fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(
        &self,
        w: W,
        t: &T,
    ) -> Result<()> {
        config_map!(self, opts => ::internal::serialize_into(w, t, opts))
    }

    /// Deserializes a slice of bytes into an instance of `T` using this configuration
    #[inline(always)]
    pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T> {
        config_map!(self, opts => ::internal::deserialize(bytes, opts))
    }

    /// TODO: document
    #[doc(hidden)]
    #[inline(always)]
    pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()>
    where
        R: BincodeRead<'a>,
        T: serde::de::Deserialize<'a>,
    {
        config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
    }

    /// Deserializes a slice of bytes with state `seed` using this configuration.
    #[inline(always)]
    pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>(
        &self,
        seed: T,
        bytes: &'a [u8],
    ) -> Result<T::Value> {
        config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts))
    }

    /// Deserializes an object directly from a `Read`er using this configuration
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(
        &self,
        reader: R,
    ) -> Result<T> {
        config_map!(self, opts => ::internal::deserialize_from(reader, opts))
    }

    /// Deserializes an object directly from a `Read`er with state `seed` using this configuration
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>(
        &self,
        seed: T,
        reader: R,
    ) -> Result<T::Value> {
        config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts))
    }

    /// Deserializes an object from a custom `BincodeRead`er using the default configuration.
    /// It is highly recommended to use `deserialize_from` unless you need to implement
    /// `BincodeRead` for performance reasons.
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>(
        &self,
        reader: R,
    ) -> Result<T> {
        config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts))
    }

    /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default
    /// configuration. It is highly recommended to use `deserialize_from` unless you need to
    /// implement `BincodeRead` for performance reasons.
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from_custom_seed<
        'a,
        R: BincodeRead<'a>,
        T: serde::de::DeserializeSeed<'a>,
    >(
        &self,
        seed: T,
        reader: R,
    ) -> Result<T::Value> {
        config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts))
    }

    /// Executes the acceptor with a serde::Deserializer instance.
    /// NOT A PART OF THE STABLE PUBLIC API
    #[doc(hidden)]
    pub fn with_deserializer<'a, A, R>(&self, reader: R, acceptor: A) -> A::Output
    where
        A: DeserializerAcceptor<'a>,
        R: BincodeRead<'a>,
    {
        config_map!(self, opts => {
            let mut deserializer = ::de::Deserializer::new(reader, opts);
            acceptor.accept(&mut deserializer)
        })
    }

    /// Executes the acceptor with a serde::Serializer instance.
    /// NOT A PART OF THE STABLE PUBLIC API
    #[doc(hidden)]
    pub fn with_serializer<A, W>(&self, writer: W, acceptor: A) -> A::Output
    where
        A: SerializerAcceptor,
        W: Write,
    {
        config_map!(self, opts => {
            let mut serializer = ::ser::Serializer::new(writer, opts);
            acceptor.accept(&mut serializer)
        })
    }
}
<commit_msg>Added Clone impl to Config<commit_after>use super::internal::{Bounded, Infinite, SizeLimit};
use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian};
use de::read::BincodeRead;
use error::Result;
use serde;
use std::io::{Read, Write};
use std::marker::PhantomData;
use {DeserializerAcceptor, SerializerAcceptor};

use self::EndianOption::*;
use self::LimitOption::*;

struct DefaultOptions(Infinite);

pub(crate) trait Options {
    type Limit: SizeLimit + 'static;
    type Endian: ByteOrder + 'static;

    fn limit(&mut self) -> &mut Self::Limit;
}

pub(crate) trait OptionsExt: Options + Sized {
    fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> {
        WithOtherLimit::new(self, Infinite)
    }

    fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> {
        WithOtherLimit::new(self, Bounded(limit))
    }

    fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> {
        WithOtherEndian::new(self)
    }

    fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> {
        WithOtherEndian::new(self)
    }

    fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> {
        WithOtherEndian::new(self)
    }
}

impl<'a, O: Options> Options for &'a mut O {
    type Limit = O::Limit;
    type Endian = O::Endian;

    #[inline(always)]
    fn limit(&mut self) -> &mut Self::Limit {
        (*self).limit()
    }
}

impl<T: Options> OptionsExt for T {}

impl DefaultOptions {
    fn new() -> DefaultOptions {
        DefaultOptions(Infinite)
    }
}

impl Options for DefaultOptions {
    type Limit = Infinite;
    type Endian = LittleEndian;

    #[inline(always)]
    fn limit(&mut self) -> &mut Infinite {
        &mut self.0
    }
}

#[derive(Clone, Copy)]
enum LimitOption {
    Unlimited,
    Limited(u64),
}

#[derive(Clone, Copy)]
enum EndianOption {
    Big,
    Little,
    Native,
}

/// A configuration builder whose options Bincode will use
/// while serializing and deserializing.
///
/// ### Options
/// Endianness: The endianness with which multi-byte integers will be read/written.  *default: little endian*
/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited*
///
/// ### Byte Limit Details
/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode
/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long.
///
/// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any
/// serialization that goes over the limit.
#[derive(Clone)]
pub struct Config {
    limit: LimitOption,
    endian: EndianOption,
}

pub(crate) struct WithOtherLimit<O: Options, L: SizeLimit> {
    _options: O,
    pub(crate) new_limit: L,
}

pub(crate) struct WithOtherEndian<O: Options, E: ByteOrder> {
    options: O,
    _endian: PhantomData<E>,
}

impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> {
    #[inline(always)]
    pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> {
        WithOtherLimit {
            _options: options,
            new_limit: limit,
        }
    }
}

impl<O: Options, E: ByteOrder> WithOtherEndian<O, E> {
    #[inline(always)]
    pub(crate) fn new(options: O) -> WithOtherEndian<O, E> {
        WithOtherEndian {
            options: options,
            _endian: PhantomData,
        }
    }
}

impl<O: Options, E: ByteOrder + 'static> Options for WithOtherEndian<O, E> {
    type Limit = O::Limit;
    type Endian = E;

    #[inline(always)]
    fn limit(&mut self) -> &mut O::Limit {
        self.options.limit()
    }
}

impl<O: Options, L: SizeLimit + 'static> Options for WithOtherLimit<O, L> {
    type Limit = L;
    type Endian = O::Endian;

    fn limit(&mut self) -> &mut L {
        &mut self.new_limit
    }
}

macro_rules! config_map {
    ($self:expr, $opts:ident => $call:expr) => {
        match ($self.limit, $self.endian) {
            (Unlimited, Little) => {
                let $opts = DefaultOptions::new().with_no_limit().with_little_endian();
                $call
            }
            (Unlimited, Big) => {
                let $opts = DefaultOptions::new().with_no_limit().with_big_endian();
                $call
            }
            (Unlimited, Native) => {
                let $opts = DefaultOptions::new().with_no_limit().with_native_endian();
                $call
            }

            (Limited(l), Little) => {
                let $opts = DefaultOptions::new().with_limit(l).with_little_endian();
                $call
            }
            (Limited(l), Big) => {
                let $opts = DefaultOptions::new().with_limit(l).with_big_endian();
                $call
            }
            (Limited(l), Native) => {
                let $opts = DefaultOptions::new().with_limit(l).with_native_endian();
                $call
            }
        }
    };
}

impl Config {
    #[inline(always)]
    pub(crate) fn new() -> Config {
        Config {
            limit: LimitOption::Unlimited,
            endian: EndianOption::Little,
        }
    }

    /// Sets the byte limit to be unlimited.
    /// This is the default.
    #[inline(always)]
    pub fn no_limit(&mut self) -> &mut Self {
        self.limit = LimitOption::Unlimited;
        self
    }

    /// Sets the byte limit to `limit`.
    #[inline(always)]
    pub fn limit(&mut self, limit: u64) -> &mut Self {
        self.limit = LimitOption::Limited(limit);
        self
    }

    /// Sets the endianness to little-endian
    /// This is the default.
    #[inline(always)]
    pub fn little_endian(&mut self) -> &mut Self {
        self.endian = EndianOption::Little;
        self
    }

    /// Sets the endianness to big-endian
    #[inline(always)]
    pub fn big_endian(&mut self) -> &mut Self {
        self.endian = EndianOption::Big;
        self
    }

    /// Sets the endianness to the the machine-native endianness
    #[inline(always)]
    pub fn native_endian(&mut self) -> &mut Self {
        self.endian = EndianOption::Native;
        self
    }

    /// Serializes a serializable object into a `Vec` of bytes using this configuration
    #[inline(always)]
    pub fn serialize<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<Vec<u8>> {
        config_map!(self, opts => ::internal::serialize(t, opts))
    }

    /// Returns the size that an object would be if serialized using Bincode with this configuration
    #[inline(always)]
    pub fn serialized_size<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<u64> {
        config_map!(self, opts => ::internal::serialized_size(t, opts))
    }

    /// Serializes an object directly into a `Writer` using this configuration
    ///
    /// If the serialization would take more bytes than allowed by the size limit, an error
    /// is returned and *no bytes* will be written into the `Writer`
    #[inline(always)]
    pub fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(
        &self,
        w: W,
        t: &T,
    ) -> Result<()> {
        config_map!(self, opts => ::internal::serialize_into(w, t, opts))
    }

    /// Deserializes a slice of bytes into an instance of `T` using this configuration
    #[inline(always)]
    pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T> {
        config_map!(self, opts => ::internal::deserialize(bytes, opts))
    }

    /// TODO: document
    #[doc(hidden)]
    #[inline(always)]
    pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()>
    where
        R: BincodeRead<'a>,
        T: serde::de::Deserialize<'a>,
    {
        config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
    }

    /// Deserializes a slice of bytes with state `seed` using this configuration.
    #[inline(always)]
    pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>(
        &self,
        seed: T,
        bytes: &'a [u8],
    ) -> Result<T::Value> {
        config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts))
    }

    /// Deserializes an object directly from a `Read`er using this configuration
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(
        &self,
        reader: R,
    ) -> Result<T> {
        config_map!(self, opts => ::internal::deserialize_from(reader, opts))
    }

    /// Deserializes an object directly from a `Read`er with state `seed` using this configuration
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>(
        &self,
        seed: T,
        reader: R,
    ) -> Result<T::Value> {
        config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts))
    }

    /// Deserializes an object from a custom `BincodeRead`er using the default configuration.
    /// It is highly recommended to use `deserialize_from` unless you need to implement
    /// `BincodeRead` for performance reasons.
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>(
        &self,
        reader: R,
    ) -> Result<T> {
        config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts))
    }

    /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default
    /// configuration. It is highly recommended to use `deserialize_from` unless you need to
    /// implement `BincodeRead` for performance reasons.
    ///
    /// If this returns an `Error`, `reader` may be in an invalid state.
    #[inline(always)]
    pub fn deserialize_from_custom_seed<
        'a,
        R: BincodeRead<'a>,
        T: serde::de::DeserializeSeed<'a>,
    >(
        &self,
        seed: T,
        reader: R,
    ) -> Result<T::Value> {
        config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts))
    }

    /// Executes the acceptor with a serde::Deserializer instance.
    /// NOT A PART OF THE STABLE PUBLIC API
    #[doc(hidden)]
    pub fn with_deserializer<'a, A, R>(&self, reader: R, acceptor: A) -> A::Output
    where
        A: DeserializerAcceptor<'a>,
        R: BincodeRead<'a>,
    {
        config_map!(self, opts => {
            let mut deserializer = ::de::Deserializer::new(reader, opts);
            acceptor.accept(&mut deserializer)
        })
    }

    /// Executes the acceptor with a serde::Serializer instance.
    /// NOT A PART OF THE STABLE PUBLIC API
    #[doc(hidden)]
    pub fn with_serializer<A, W>(&self, writer: W, acceptor: A) -> A::Output
    where
        A: SerializerAcceptor,
        W: Write,
    {
        config_map!(self, opts => {
            let mut serializer = ::ser::Serializer::new(writer, opts);
            acceptor.accept(&mut serializer)
        })
    }
}
<|endoftext|>


<commit_before>use std::io::File;

use collections::treemap::TreeMap;
use serialize::json::ToJson;

use quire::parse;
use J = serialize::json;

use Pid1 = super::linux;
use super::yamlutil::{get_string, get_dict, get_list, get_command, get_bool};

#[deriving(Show)]
pub enum SuperviseMode {
    WaitAll,
    StopOnFailure,
    Restart,
}

pub enum Executor {
    Shell(String),
    Plain(Vec<String>),
    Supervise(SuperviseMode, TreeMap<String, Command>),
}

pub struct Command {
    pub pid1mode: Pid1::Pid1Mode,
    pub execute: Executor,
    pub work_dir: Option<String>,
    pub container: Option<String>,
    pub accepts_arguments: bool,
    pub environ: TreeMap<String, String>,
    pub inherit_environ: Vec<String>,
    pub description: Option<String>,
}

pub struct Variant {
    pub default: Option<String>,
    pub options: Vec<String>,
}

pub struct Container {
    pub default_command: Option<Vec<String>>,
    pub command_wrapper: Option<Vec<String>>,
    pub shell: Vec<String>,
    pub builder: String,
    pub parameters: TreeMap<String, String>,
    pub environ_file: Option<String>,
    pub environ: TreeMap<String, String>,
}

pub struct Config {
    pub commands: TreeMap<String, Command>,
    pub variants: TreeMap<String, Variant>,
    pub containers: TreeMap<String, Container>,
}

fn find_config_path(work_dir: &Path) -> Option<(Path, Path)> {
    let mut dir = work_dir.clone();
    loop {
        let fname = dir.join_many([".vagga", "vagga.yaml"]);
        if fname.exists() {
            return Some((dir, fname));
        }
        let fname = dir.join("vagga.yaml");
        if fname.exists() {
            return Some((dir, fname));
        }
        if !dir.pop() {
            return None;
        }
    }
}

pub fn get_supervise(map: &TreeMap<String, J::Json>)
    -> Result<Option<(SuperviseMode, TreeMap<String, Command>)>, String>
{
    let mode = match map.find(&"supervise-mode".to_string()) {
        Some(&J::String(ref val)) => match val.as_slice() {
            "wait-all" => WaitAll,
            "stop-on-failure" => StopOnFailure,
            "restart" => Restart,
            _ => return Err(format!("The `supervise-mode` can be one of
                `wait-all`, `stop-on-failure` (default) or `restart`")),
        },
        None => StopOnFailure,
        _ => return Err(format!("The `supervise-mode` must be string")),
    };
    let mut commands = TreeMap::new();
    let ocommands = match map.find(&"supervise".to_string()) {
        None => return Ok(None),
        Some(&J::Object(ref map)) => map,
        _ => return Err(format!("The `supervise` must be mapping")),
    };
    for (name, jcmd) in ocommands.iter() {
        let cmd = try!(parse_command(name, jcmd));
        commands.insert(name.clone(), cmd);
    }
    return Ok(Some((mode, commands)));
}

fn one<T>(opt: &Option<T>) -> int {
    return if opt.is_some() { 1 } else { 0 };
}

fn parse_command(name: &String, jcmd: &J::Json) -> Result<Command, String> {
    let dcmd = match jcmd {
        &J::Object(ref dict) => dict,
        _ => return Err(format!(
            "Command {} must be mapping", name)),
    };

    let run = get_string(jcmd, "run");
    let command = get_command(jcmd, "command");
    let supervise = try!(get_supervise(*dcmd));
    if one(&run) + one(&command) + one(&supervise) != 1 {
        return Err(format!("Expected exactly one of \
            `command` or `run` or `supervise` for command {}",
            name));
    }
    let mut accepts_arguments = false;
    let executor = if run.is_some() {
        Shell(run.unwrap())
    } else if command.is_some() {
        accepts_arguments = true;
        Plain(command.unwrap())
    } else if supervise.is_some() {
        let (mode, svcs) = supervise.unwrap();
        Supervise(mode, svcs)
    } else {
        unreachable!();
    };
    let accepts_arguments = get_bool(jcmd, "accepts-arguments")
        //  By default accept arguments only by command
        //  because "sh -c" only uses arguments if there is
        //  $1, $2.. used in the expression
        .unwrap_or(accepts_arguments);
    return Ok(Command {
        pid1mode: match get_string(jcmd, "pid1mode") {
            Some(ref s) if s.as_slice() == "wait" => Pid1::Wait,
            Some(ref s) if s.as_slice() == "wait-any" => Pid1::WaitAny,
            Some(ref s) if s.as_slice() == "exec" => Pid1::Exec,
            None => Pid1::Wait,
            _ => return Err(format!("The pid1mode must be one of `wait`, \
                `wait-any` or `exec` for command {}", name)),
            },
        execute: executor,
        container: get_string(jcmd, "container"),
        work_dir: get_string(jcmd, "work-dir"),
        accepts_arguments: accepts_arguments,
        environ: get_dict(jcmd, "environ"),
        inherit_environ: get_list(jcmd, "inherit-environ"),
        description: get_string(jcmd, "description"),
    });
}

pub fn find_config(work_dir: &Path) -> Result<(Config, Path), String>{
    let (cfg_dir, filename) = match find_config_path(work_dir) {
        Some(pair) => pair,
        None => return Err(format!(
            "Config not found in path {}", work_dir.display())),
    };
    let fname = filename.display();
    let data = match File::open(&filename).read_to_str() {
        Ok(data) => data,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };
    let json = match parse(data.as_slice(), |doc| {
        return doc.to_json();
    }) {
        Ok(json) => json,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };

    let mut config = Config {
        commands: TreeMap::new(),
        variants: TreeMap::new(),
        containers: TreeMap::new(),
    };

    let root = match json {
        J::Object(val) => val,
        _ => return Err(format!("{}: root node must be mapping", fname)),
    };

    match root.find(&"commands".to_string()) {
        Some(&J::Object(ref commands)) => {
            for (name, jcmd) in commands.iter() {
                let cmd = try!(parse_command(name, jcmd));
                config.commands.insert(name.clone(), cmd);
            }
        }
        Some(_) => return Err(format!(
            "{}: commands key must be mapping", fname)),
        None => {}
    }

    match root.find(&"containers".to_string()) {
        Some(&J::Object(ref containers)) => {
            for (name, jcont) in containers.iter() {
                let cont = Container {
                    default_command: get_command(jcont, "default-command"),
                    command_wrapper: get_command(jcont, "command-wrapper"),
                    shell: get_command(jcont, "shell").unwrap_or(
                        vec!("/bin/sh".to_string(), "-c".to_string())),
                    builder: get_string(jcont, "builder")
                             .unwrap_or("nix".to_string()),
                    parameters: get_dict(jcont, "parameters"),
                    environ: get_dict(jcont, "environ"),
                    environ_file: get_string(jcont, "environ-file"),
                };
                config.containers.insert(name.clone(), cont);
            }
        }
        Some(_) => return Err(format!(
            "{}: containers key must be mapping", fname)),
        None => {}
    }

    match root.find(&"variants".to_string()) {
        Some(&J::Object(ref variants)) => {
            for (name, jvar) in variants.iter() {
                let var = Variant {
                    default: get_string(jvar, "default"),
                    options: get_list(jvar, "options"),
                };
                config.variants.insert(name.clone(), var);
            }
        }
        Some(_) => return Err(format!(
            "{}: variants key must be mapping", fname)),
        None => {}
    }

    return Ok((config, cfg_dir));
}
<commit_msg>Better error message when container is missing in command<commit_after>use std::io::File;

use collections::treemap::TreeMap;
use serialize::json::ToJson;

use quire::parse;
use J = serialize::json;

use Pid1 = super::linux;
use super::yamlutil::{get_string, get_dict, get_list, get_command, get_bool};

#[deriving(Show)]
pub enum SuperviseMode {
    WaitAll,
    StopOnFailure,
    Restart,
}

pub enum Executor {
    Shell(String),
    Plain(Vec<String>),
    Supervise(SuperviseMode, TreeMap<String, Command>),
}

pub struct Command {
    pub pid1mode: Pid1::Pid1Mode,
    pub execute: Executor,
    pub work_dir: Option<String>,
    pub container: Option<String>,
    pub accepts_arguments: bool,
    pub environ: TreeMap<String, String>,
    pub inherit_environ: Vec<String>,
    pub description: Option<String>,
}

pub struct Variant {
    pub default: Option<String>,
    pub options: Vec<String>,
}

pub struct Container {
    pub default_command: Option<Vec<String>>,
    pub command_wrapper: Option<Vec<String>>,
    pub shell: Vec<String>,
    pub builder: String,
    pub parameters: TreeMap<String, String>,
    pub environ_file: Option<String>,
    pub environ: TreeMap<String, String>,
}

pub struct Config {
    pub commands: TreeMap<String, Command>,
    pub variants: TreeMap<String, Variant>,
    pub containers: TreeMap<String, Container>,
}

fn find_config_path(work_dir: &Path) -> Option<(Path, Path)> {
    let mut dir = work_dir.clone();
    loop {
        let fname = dir.join_many([".vagga", "vagga.yaml"]);
        if fname.exists() {
            return Some((dir, fname));
        }
        let fname = dir.join("vagga.yaml");
        if fname.exists() {
            return Some((dir, fname));
        }
        if !dir.pop() {
            return None;
        }
    }
}

pub fn get_supervise(map: &TreeMap<String, J::Json>)
    -> Result<Option<(SuperviseMode, TreeMap<String, Command>)>, String>
{
    let mode = match map.find(&"supervise-mode".to_string()) {
        Some(&J::String(ref val)) => match val.as_slice() {
            "wait-all" => WaitAll,
            "stop-on-failure" => StopOnFailure,
            "restart" => Restart,
            _ => return Err(format!("The `supervise-mode` can be one of
                `wait-all`, `stop-on-failure` (default) or `restart`")),
        },
        None => StopOnFailure,
        _ => return Err(format!("The `supervise-mode` must be string")),
    };
    let mut commands = TreeMap::new();
    let ocommands = match map.find(&"supervise".to_string()) {
        None => return Ok(None),
        Some(&J::Object(ref map)) => map,
        _ => return Err(format!("The `supervise` must be mapping")),
    };
    for (name, jcmd) in ocommands.iter() {
        let cmd = try!(parse_command(name, jcmd));
        commands.insert(name.clone(), cmd);
    }
    return Ok(Some((mode, commands)));
}

fn one<T>(opt: &Option<T>) -> int {
    return if opt.is_some() { 1 } else { 0 };
}

fn parse_command(name: &String, jcmd: &J::Json) -> Result<Command, String> {
    let dcmd = match jcmd {
        &J::Object(ref dict) => dict,
        _ => return Err(format!(
            "Command {} must be mapping", name)),
    };
    let container = get_string(jcmd, "container");
    if container.is_none() {
        return Err(format!("The `container` is required for command {}",
                           name));
    }

    let run = get_string(jcmd, "run");
    let command = get_command(jcmd, "command");
    let supervise = try!(get_supervise(*dcmd));
    if one(&run) + one(&command) + one(&supervise) != 1 {
        return Err(format!("Expected exactly one of \
            `command` or `run` or `supervise` for command {}",
            name));
    }
    let mut accepts_arguments = false;
    let executor = if run.is_some() {
        Shell(run.unwrap())
    } else if command.is_some() {
        accepts_arguments = true;
        Plain(command.unwrap())
    } else if supervise.is_some() {
        let (mode, svcs) = supervise.unwrap();
        Supervise(mode, svcs)
    } else {
        unreachable!();
    };
    let accepts_arguments = get_bool(jcmd, "accepts-arguments")
        //  By default accept arguments only by command
        //  because "sh -c" only uses arguments if there is
        //  $1, $2.. used in the expression
        .unwrap_or(accepts_arguments);
    return Ok(Command {
        pid1mode: match get_string(jcmd, "pid1mode") {
            Some(ref s) if s.as_slice() == "wait" => Pid1::Wait,
            Some(ref s) if s.as_slice() == "wait-any" => Pid1::WaitAny,
            Some(ref s) if s.as_slice() == "exec" => Pid1::Exec,
            None => Pid1::Wait,
            _ => return Err(format!("The pid1mode must be one of `wait`, \
                `wait-any` or `exec` for command {}", name)),
            },
        execute: executor,
        container: container,
        work_dir: get_string(jcmd, "work-dir"),
        accepts_arguments: accepts_arguments,
        environ: get_dict(jcmd, "environ"),
        inherit_environ: get_list(jcmd, "inherit-environ"),
        description: get_string(jcmd, "description"),
    });
}

pub fn find_config(work_dir: &Path) -> Result<(Config, Path), String>{
    let (cfg_dir, filename) = match find_config_path(work_dir) {
        Some(pair) => pair,
        None => return Err(format!(
            "Config not found in path {}", work_dir.display())),
    };
    let fname = filename.display();
    let data = match File::open(&filename).read_to_str() {
        Ok(data) => data,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };
    let json = match parse(data.as_slice(), |doc| {
        return doc.to_json();
    }) {
        Ok(json) => json,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };

    let mut config = Config {
        commands: TreeMap::new(),
        variants: TreeMap::new(),
        containers: TreeMap::new(),
    };

    let root = match json {
        J::Object(val) => val,
        _ => return Err(format!("{}: root node must be mapping", fname)),
    };

    match root.find(&"commands".to_string()) {
        Some(&J::Object(ref commands)) => {
            for (name, jcmd) in commands.iter() {
                let cmd = try!(parse_command(name, jcmd));
                config.commands.insert(name.clone(), cmd);
            }
        }
        Some(_) => return Err(format!(
            "{}: commands key must be mapping", fname)),
        None => {}
    }

    match root.find(&"containers".to_string()) {
        Some(&J::Object(ref containers)) => {
            for (name, jcont) in containers.iter() {
                let cont = Container {
                    default_command: get_command(jcont, "default-command"),
                    command_wrapper: get_command(jcont, "command-wrapper"),
                    shell: get_command(jcont, "shell").unwrap_or(
                        vec!("/bin/sh".to_string(), "-c".to_string())),
                    builder: get_string(jcont, "builder")
                             .unwrap_or("nix".to_string()),
                    parameters: get_dict(jcont, "parameters"),
                    environ: get_dict(jcont, "environ"),
                    environ_file: get_string(jcont, "environ-file"),
                };
                config.containers.insert(name.clone(), cont);
            }
        }
        Some(_) => return Err(format!(
            "{}: containers key must be mapping", fname)),
        None => {}
    }

    match root.find(&"variants".to_string()) {
        Some(&J::Object(ref variants)) => {
            for (name, jvar) in variants.iter() {
                let var = Variant {
                    default: get_string(jvar, "default"),
                    options: get_list(jvar, "options"),
                };
                config.variants.insert(name.clone(), var);
            }
        }
        Some(_) => return Err(format!(
            "{}: variants key must be mapping", fname)),
        None => {}
    }

    return Ok((config, cfg_dir));
}
<|endoftext|>


<commit_before>use std;
use simd;
use simd::x86::sse2::u64x2;
use simdext::*;

extern "platform-intrinsic" {
    fn x86_mm_testz_si128(x: u64x2, y: u64x2) -> i32;
}

#[inline]
unsafe fn bitcast<T, U>(x: T) -> U {
    debug_assert!(std::mem::size_of::<T>() == std::mem::size_of::<U>());
    std::mem::transmute_copy(&x)
}

#[derive(Clone, Copy)]
pub struct FieldBit {
    m: simd::u16x8,
}

impl FieldBit {
    pub fn new(m: simd::u16x8) -> FieldBit {
        FieldBit {
            m: m,
        }
    }

    pub fn from_values(v1: u16, v2: u16, v3: u16, v4: u16, v5: u16, v6: u16, v7: u16, v8: u16) -> FieldBit {
        FieldBit {
            m: simd::u16x8::new(v1, v2, v3, v4, v5, v6, v7, v8)
        }
    }

    pub fn new_empty() -> FieldBit {
        FieldBit {
            m: simd::u16x8::splat(0)
        }
    }

    pub fn get(&self, x: usize, y: usize) -> bool {
        debug_assert!(FieldBit::check_in_range(x, y));
        unsafe {
            x86_mm_testz_si128(bitcast(FieldBit::onebit(x, y)), bitcast(self.m)) == 0
        }
    }

    pub fn set(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_or_epu16(FieldBit::onebit(x, y), self.m)
    }

    pub fn unset(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_andnot_epu16(FieldBit::onebit(x, y), self.m)
    }

    pub fn masked_field_12(&self) -> FieldBit {
        FieldBit {
            m: self.m & simd::u16x8::new(0, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0)
        }
    }

    pub fn masked_field_13(&self) -> FieldBit {
        FieldBit {
            m: self.m & simd::u16x8::new(0, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0)
        }
    }

    pub fn popcount(&self) -> usize {
        let x: u64x2 = unsafe { bitcast(self.m) };
        let low: u64 = x.extract(0);
        let high: u64 = x.extract(1);
        (low.count_ones() + high.count_ones()) as usize
    }

    pub fn as_u16x8(&self) -> simd::u16x8 {
        self.m
    }

    fn check_in_range(x: usize, y: usize) -> bool {
        x < 8 && y < 16
    }

    fn onebit(x: usize, y: usize) -> simd::u16x8 {
        debug_assert!(FieldBit::check_in_range(x, y));

        let shift = ((x << 4) | y) & 0x3F;
        let hi: u64 = (x as u64) >> 2;
        let lo: u64 = hi ^ 1;
        unsafe { bitcast(u64x2::new(lo << shift, hi << shift)) }
    }
}

impl std::fmt::Display for FieldBit {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "({}, {}, {}, {}, {}, {}, {}, {})",
               self.m.extract(0), self.m.extract(1), self.m.extract(2), self.m.extract(3),
               self.m.extract(4), self.m.extract(5), self.m.extract(6), self.m.extract(7))
    }
}

#[cfg(test)]
mod tests {
    use field;
    use field_bit::FieldBit;

    #[test]
    fn test_empty() {
        let fb = FieldBit::new_empty();
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), false);
            }
        }
    }

    #[test]
    fn test_from_value() {
        let fb = FieldBit::from_values(1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), x == y, "failed at x={}, y={}, fb.get(x, y)={}", x, y, fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_set_get() {
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let mut fb = FieldBit::new_empty();
                assert!(!fb.get(x, y));
                fb.set(x, y);
                assert!(fb.get(x, y));
                fb.unset(x, y);
                assert!(!fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_masked_field() {
        let fb = FieldBit::from_values(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
        let fb12 = fb.masked_field_12();
        let fb13 = fb.masked_field_13();

        for x in 0 .. field::MAP_WIDTH {
            for y in 0 .. field::MAP_HEIGHT {
                assert!(fb.get(x, y), "x={}, y={}", x, y);
                assert_eq!(fb12.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 12, "x={}, y={}", x, y);
                assert_eq!(fb13.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 13, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_popcount() {
        let fb = FieldBit::from_values(1, 2, 3, 4, 5, 6, 7, 8);
        assert_eq!(fb.popcount(), 1 + 1 + 2 + 1 + 2 + 2 + 3 + 1)
    }
}
<commit_msg>Add FieldBit::from_str.<commit_after>use std;
use simd;
use simd::x86::sse2::u64x2;
use simdext::*;

extern "platform-intrinsic" {
    fn x86_mm_testz_si128(x: u64x2, y: u64x2) -> i32;
}

#[inline]
unsafe fn bitcast<T, U>(x: T) -> U {
    debug_assert!(std::mem::size_of::<T>() == std::mem::size_of::<U>());
    std::mem::transmute_copy(&x)
}

#[derive(Clone, Copy)]
pub struct FieldBit {
    m: simd::u16x8,
}

impl FieldBit {
    pub fn new(m: simd::u16x8) -> FieldBit {
        FieldBit {
            m: m,
        }
    }

    pub fn from_values(v1: u16, v2: u16, v3: u16, v4: u16, v5: u16, v6: u16, v7: u16, v8: u16) -> FieldBit {
        FieldBit {
            m: simd::u16x8::new(v1, v2, v3, v4, v5, v6, v7, v8)
        }
    }

    pub fn new_empty() -> FieldBit {
        FieldBit {
            m: simd::u16x8::splat(0)
        }
    }

    pub fn from_str(s: &str) -> FieldBit {
        let mut f = FieldBit::new_empty();

        assert!(s.len() % 6 == 0);

        let mut cnt = 0;
        for b in s.bytes().rev() {
            let x = 6 - (cnt % 6);
            let y = (cnt / 6) + 1;
            if b == b'1' {
                f.set(x, y);
            }
            cnt += 1;
        }

        f
    }

    pub fn get(&self, x: usize, y: usize) -> bool {
        debug_assert!(FieldBit::check_in_range(x, y));
        unsafe {
            x86_mm_testz_si128(bitcast(FieldBit::onebit(x, y)), bitcast(self.m)) == 0
        }
    }

    pub fn set(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_or_epu16(FieldBit::onebit(x, y), self.m)
    }

    pub fn unset(&mut self, x: usize, y: usize) {
        debug_assert!(FieldBit::check_in_range(x, y));
        self.m = mm_andnot_epu16(FieldBit::onebit(x, y), self.m)
    }

    pub fn masked_field_12(&self) -> FieldBit {
        FieldBit {
            m: self.m & simd::u16x8::new(0, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0x1FFE, 0)
        }
    }

    pub fn masked_field_13(&self) -> FieldBit {
        FieldBit {
            m: self.m & simd::u16x8::new(0, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0)
        }
    }

    pub fn popcount(&self) -> usize {
        let x: u64x2 = unsafe { bitcast(self.m) };
        let low: u64 = x.extract(0);
        let high: u64 = x.extract(1);
        (low.count_ones() + high.count_ones()) as usize
    }

    pub fn as_u16x8(&self) -> simd::u16x8 {
        self.m
    }

    fn check_in_range(x: usize, y: usize) -> bool {
        x < 8 && y < 16
    }

    fn onebit(x: usize, y: usize) -> simd::u16x8 {
        debug_assert!(FieldBit::check_in_range(x, y));

        let shift = ((x << 4) | y) & 0x3F;
        let hi: u64 = (x as u64) >> 2;
        let lo: u64 = hi ^ 1;
        unsafe { bitcast(u64x2::new(lo << shift, hi << shift)) }
    }
}

impl std::fmt::Display for FieldBit {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "({}, {}, {}, {}, {}, {}, {}, {})",
               self.m.extract(0), self.m.extract(1), self.m.extract(2), self.m.extract(3),
               self.m.extract(4), self.m.extract(5), self.m.extract(6), self.m.extract(7))
    }
}

#[cfg(test)]
mod tests {
    use field;
    use field_bit::FieldBit;

    #[test]
    fn test_empty() {
        let fb = FieldBit::new_empty();
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), false);
            }
        }
    }

    #[test]
    fn test_from_value() {
        let fb = FieldBit::from_values(1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7);
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                assert_eq!(fb.get(x, y), x == y, "failed at x={}, y={}, fb.get(x, y)={}", x, y, fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_from_str() {
        let fb = FieldBit::from_str(concat!(
            "111...",
            "......",
            "111..."));

        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let b = (y == 1 || y == 3) && (1 <= x && x <= 3);
                assert_eq!(fb.get(x, y), b, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_set_get() {
        for x in 0 .. 8 {
            for y in 0 .. 16 {
                let mut fb = FieldBit::new_empty();
                assert!(!fb.get(x, y));
                fb.set(x, y);
                assert!(fb.get(x, y));
                fb.unset(x, y);
                assert!(!fb.get(x, y));
            }
        }
    }

    #[test]
    fn test_masked_field() {
        let fb = FieldBit::from_values(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
        let fb12 = fb.masked_field_12();
        let fb13 = fb.masked_field_13();

        for x in 0 .. field::MAP_WIDTH {
            for y in 0 .. field::MAP_HEIGHT {
                assert!(fb.get(x, y), "x={}, y={}", x, y);
                assert_eq!(fb12.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 12, "x={}, y={}", x, y);
                assert_eq!(fb13.get(x, y), 1 <= x && x <= 6 && 1 <= y && y <= 13, "x={}, y={}", x, y);
            }
        }
    }

    #[test]
    fn test_popcount() {
        let fb = FieldBit::from_values(1, 2, 3, 4, 5, 6, 7, 8);
        assert_eq!(fb.popcount(), 1 + 1 + 2 + 1 + 2 + 2 + 3 + 1)
    }
}
<|endoftext|>


<commit_before>use proto::metapb;
use super::engine::Mutator;
use super::keys;
use raftserver::{Result, other};

// How do we organize the route meta key to determine the region a key belongs to?
//
// We use 2 hash (meta1, meta2) to route the key.
// Meta1 is always located in region1 and can't be split. Meta2 can be split into
// different regions.
// For a given key, first we find in meta1 to know which meta2 has this key,
// then find in meta2 and know where the really data region is.
//
// The region route meta key for a region is encoded with a meta prefix + region end key.
// E,g, if a data region key range is ["123", "999"), the relevant meta2 key is
//  meta2 prefix + "999"
// Why using the end key but not start key? We use seek in RocksDB to search the key, if we have
// 2 regions ["111", "222"), ["222", "333") and encode the key with start key, the layout may be:
//  \x00\x03"111" -> region 2
//  \x00\x03"222" -> region 3
// If we want to find key "123", using seek we may get `\x00\x03"222"`, but not `\x00\x03"111"`,
// (Rocksdb seeks the key >= given key), so we must move back to get the correct region.
//
// So for a key like "123", the route flow is:
//  1, find meta2 region using key \x00\0x02"123" in meta1.
//  2, find data region using key \x00\x03"123" in meta2.
//  3, find data using key "123".
//
// Client should cache all region route meta so that it can send the commands to the relevant region
// directly and correctly. If the request key is not in the region, clients should re-flesh the cache
// from placement driver first then re-send again.

trait RouteMetaAction <T: Mutator>{
    fn handle(&self, w: &T, key: &[u8], region: &metapb::Region) -> Result<()>;
}

struct PutRouteMetaAction;

impl<T: Mutator> RouteMetaAction<T> for PutRouteMetaAction {
    fn handle(&self, w: &T, key: &[u8], region: &metapb::Region) -> Result<()> {
        try!(w.put_msg(key, region));
        Ok(())
    }
}

struct DeleteRouteMetaAction;

impl<T: Mutator> RouteMetaAction<T> for DeleteRouteMetaAction {
    fn handle(&self, w: &T, key: &[u8], _: &metapb::Region) -> Result<()> {
        try!(w.delete(key));
        Ok(())
    }
}

fn put_route_meta<T: Mutator>(w: &T, key: &[u8], region: &metapb::Region) -> Result<()> {
    try!(w.put_msg(key, region));
    Ok(())
}

fn del_route_meta<T: Mutator>(w: &T, key: &[u8], _: &metapb::Region) -> Result<()> {
    try!(w.delete(key));
    Ok(())
}

pub fn split_region_route<T: Mutator>(w: &T,
                                      left: &metapb::Region,
                                      right: &metapb::Region)
                                      -> Result<()> {
    try!(handle_region_route(w, left, PutRouteMetaAction));
    try!(handle_region_route(w, right, PutRouteMetaAction));
    Ok(())
}

pub fn update_region_route<T: Mutator>(w: &T, region: &metapb::Region) -> Result<()> {
    try!(handle_region_route(w, region, PutRouteMetaAction));
    Ok(())
}

fn handle_region_route<T: Mutator, F: RouteMetaAction<T>>(w: &T,
                                                          region: &metapb::Region,
                                                          action: F)
                                                          -> Result<()> {
    let start_key = region.get_start_key();
    let end_key = region.get_end_key();

    // We can't split meta1.
    if end_key.starts_with(keys::META1_PREFIX_KEY) ||
       start_key.starts_with(keys::META1_PREFIX_KEY) {
        return Err(other("meta1 route can't be split"));
    }

    // If regions end_key ends with a meta2 prefix, updates relevant meta1.
    if end_key.starts_with(keys::META2_PREFIX_KEY) {
        try!(action.handle(w, &keys::region_route_meta_key(end_key), region));
    } else {
        // The regions ends with a normal data key, updates relevant meta2.
        try!(action.handle(w, &vec![keys::META2_PREFIX_KEY, end_key].concat(), region));

        // The regions start_key starts with MIN_KEY or meta2 prefix, updates meta1 KEY_MAX.
        if start_key == keys::MIN_KEY || start_key.starts_with(keys::META2_PREFIX_KEY) {
            try!(action.handle(w,
                               &vec![keys::META1_PREFIX_KEY, keys::MAX_KEY].concat(),
                               region));
        }
    }

    Ok(())
}

// Checks whether the key to split the route is valid or not.
pub fn validate_route_meta_split_key(key: &[u8]) -> bool {
    // TODO: should we consider META2_MAX_KEY as invalid key?
    if key == keys::META2_MAX_KEY {
        return false;
    }

    // Meta1 can't be split.
    if key >= keys::MIN_KEY && key < keys::META2_PREFIX_KEY {
        return false;
    }

    return true;

}
<commit_msg>raftserver: format code.<commit_after>use proto::metapb;
use super::engine::Mutator;
use super::keys;
use raftserver::{Result, other};

// How do we organize the route meta key to determine the region a key belongs to?
//
// We use 2 hash (meta1, meta2) to route the key.
// Meta1 is always located in region1 and can't be split. Meta2 can be split into
// different regions.
// For a given key, first we find in meta1 to know which meta2 has this key,
// then find in meta2 and know where the really data region is.
//
// The region route meta key for a region is encoded with a meta prefix + region end key.
// E,g, if a data region key range is ["123", "999"), the relevant meta2 key is
//  meta2 prefix + "999"
// Why using the end key but not start key? We use seek in RocksDB to search the key, if we have
// 2 regions ["111", "222"), ["222", "333") and encode the key with start key, the layout may be:
//  \x00\x03"111" -> region 2
//  \x00\x03"222" -> region 3
// If we want to find key "123", using seek we may get `\x00\x03"222"`, but not `\x00\x03"111"`,
// (Rocksdb seeks the key >= given key), so we must move back to get the correct region.
//
// So for a key like "123", the route flow is:
//  1, find meta2 region using key \x00\0x02"123" in meta1.
//  2, find data region using key \x00\x03"123" in meta2.
//  3, find data using key "123".
//
// Client should cache all region route meta so that it can send the commands to the relevant region
// directly and correctly. If the request key is not in the region, clients should re-flesh the cache
// from placement driver first then re-send again.

trait RouteMetaAction <T: Mutator>{
    fn handle(&self, w: &T, key: &[u8], region: &metapb::Region) -> Result<()>;
}

struct PutRouteMetaAction;

impl<T: Mutator> RouteMetaAction<T> for PutRouteMetaAction {
    fn handle(&self, w: &T, key: &[u8], region: &metapb::Region) -> Result<()> {
        try!(w.put_msg(key, region));
        Ok(())
    }
}

struct DeleteRouteMetaAction;

impl<T: Mutator> RouteMetaAction<T> for DeleteRouteMetaAction {
    fn handle(&self, w: &T, key: &[u8], _: &metapb::Region) -> Result<()> {
        try!(w.delete(key));
        Ok(())
    }
}

fn put_route_meta<T: Mutator>(w: &T, key: &[u8], region: &metapb::Region) -> Result<()> {
    try!(w.put_msg(key, region));
    Ok(())
}

fn del_route_meta<T: Mutator>(w: &T, key: &[u8], _: &metapb::Region) -> Result<()> {
    try!(w.delete(key));
    Ok(())
}

pub fn split_region_route<T: Mutator>(w: &T,
                                      left: &metapb::Region,
                                      right: &metapb::Region)
                                      -> Result<()> {
    try!(handle_region_route(w, left, PutRouteMetaAction));
    try!(handle_region_route(w, right, PutRouteMetaAction));
    Ok(())
}

pub fn update_region_route<T: Mutator>(w: &T, region: &metapb::Region) -> Result<()> {
    try!(handle_region_route(w, region, PutRouteMetaAction));
    Ok(())
}

fn handle_region_route<T: Mutator, F: RouteMetaAction<T>>(w: &T,
                                                          region: &metapb::Region,
                                                          action: F)
                                                          -> Result<()> {
    let start_key = region.get_start_key();
    let end_key = region.get_end_key();

    // We can't split meta1.
    if end_key.starts_with(keys::META1_PREFIX_KEY) ||
       start_key.starts_with(keys::META1_PREFIX_KEY) {
        return Err(other("meta1 route can't be split"));
    }

    // If regions end_key ends with a meta2 prefix, updates relevant meta1.
    if end_key.starts_with(keys::META2_PREFIX_KEY) {
        try!(action.handle(w, &keys::region_route_meta_key(end_key), region));
    } else {
        // The regions ends with a normal data key, updates relevant meta2.
        try!(action.handle(w, &vec![keys::META2_PREFIX_KEY, end_key].concat(), region));

        // The regions start_key starts with MIN_KEY or meta2 prefix, updates meta1 KEY_MAX.
        if start_key == keys::MIN_KEY || start_key.starts_with(keys::META2_PREFIX_KEY) {
            try!(action.handle(w,
                               &vec![keys::META1_PREFIX_KEY, keys::MAX_KEY].concat(),
                               region));
        }
    }

    Ok(())
}

// Checks whether the key to split the route is valid or not.
pub fn validate_route_meta_split_key(key: &[u8]) -> bool {
    // TODO: should we consider META2_MAX_KEY as invalid key?
    if key == keys::META2_MAX_KEY {
        return false;
    }

    // Meta1 can't be split.
    if key >= keys::MIN_KEY && key < keys::META2_PREFIX_KEY {
        return false;
    }

    return true;

}
<|endoftext|>


<commit_before>import syntax::ast::*;
import syntax::visit;
import driver::session::session;

type ctx = {in_loop: bool, can_ret: bool};

fn check_crate(tcx: ty::ctxt, crate: @crate) {
    visit::visit_crate(*crate, {in_loop: false,can_ret: true}, visit::mk_vt(@{
        visit_item: |i, _cx, v| {
            visit::visit_item(i, {in_loop: false, can_ret: true}, v);
        },
        visit_expr: |e: @expr, cx: ctx, v: visit::vt<ctx>| {
            alt e.node {
              expr_while(e, b) {
                v.visit_expr(e, cx, v);
                v.visit_block(b, {in_loop: true with cx}, v);
              }
              expr_loop(b) {
                v.visit_block(b, {in_loop: true with cx}, v);
              }
              expr_fn(_, _, _, _) {
                visit::visit_expr(e, {in_loop: false, can_ret: true}, v);
              }
              expr_fn_block(_, b, _) {
                v.visit_block(b, {in_loop: false, can_ret: false}, v);
              }
              expr_loop_body(@{node: expr_fn_block(_, b, _), _}) {
                let blk = is_blockish(ty::ty_fn_proto(ty::expr_ty(tcx, e)));
                v.visit_block(b, {in_loop: true, can_ret: blk}, v);
              }
              expr_break {
                if !cx.in_loop {
                    tcx.sess.span_err(e.span, "`break` outside of loop");
                }
              }
              expr_again {
                if !cx.in_loop {
                    tcx.sess.span_err(e.span, "`cont` outside of loop");
                }
              }
              expr_ret(oe) {
                if !cx.can_ret {
                    tcx.sess.span_err(e.span, "`ret` in block function");
                }
                visit::visit_expr_opt(oe, cx, v);
              }
              _ { visit::visit_expr(e, cx, v); }
            }
        }
        with *visit::default_visitor()
    }));
}<commit_msg>Change cont out of loop error to again out of loop<commit_after>import syntax::ast::*;
import syntax::visit;
import driver::session::session;

type ctx = {in_loop: bool, can_ret: bool};

fn check_crate(tcx: ty::ctxt, crate: @crate) {
    visit::visit_crate(*crate, {in_loop: false,can_ret: true}, visit::mk_vt(@{
        visit_item: |i, _cx, v| {
            visit::visit_item(i, {in_loop: false, can_ret: true}, v);
        },
        visit_expr: |e: @expr, cx: ctx, v: visit::vt<ctx>| {
            alt e.node {
              expr_while(e, b) {
                v.visit_expr(e, cx, v);
                v.visit_block(b, {in_loop: true with cx}, v);
              }
              expr_loop(b) {
                v.visit_block(b, {in_loop: true with cx}, v);
              }
              expr_fn(_, _, _, _) {
                visit::visit_expr(e, {in_loop: false, can_ret: true}, v);
              }
              expr_fn_block(_, b, _) {
                v.visit_block(b, {in_loop: false, can_ret: false}, v);
              }
              expr_loop_body(@{node: expr_fn_block(_, b, _), _}) {
                let blk = is_blockish(ty::ty_fn_proto(ty::expr_ty(tcx, e)));
                v.visit_block(b, {in_loop: true, can_ret: blk}, v);
              }
              expr_break {
                if !cx.in_loop {
                    tcx.sess.span_err(e.span, "`break` outside of loop");
                }
              }
              expr_again {
                if !cx.in_loop {
                    tcx.sess.span_err(e.span, "`again` outside of loop");
                }
              }
              expr_ret(oe) {
                if !cx.can_ret {
                    tcx.sess.span_err(e.span, "`ret` in block function");
                }
                visit::visit_expr_opt(oe, cx, v);
              }
              _ { visit::visit_expr(e, cx, v); }
            }
        }
        with *visit::default_visitor()
    }));
}
<|endoftext|>


<commit_before>use screen::*;
use piston_window;
use conrod::{self, Widget, Frameable, Positionable};
use conrod::color::Colorable;

pub struct MainMenuScreen {
    ui: conrod::Ui<piston_window::Glyphs>,
}

impl MainMenuScreen {
    pub fn new(window: &piston_window::PistonWindow, context: &mut Context) -> MainMenuScreen {
        MainMenuScreen { ui: create_ui(&window, &context.assets_path) }
    }
}

impl Screen for MainMenuScreen {
    fn on_input(&mut self,
                input: &piston_window::Input,
                window: &piston_window::PistonWindow,
                context: &mut Context)
                -> InputResults {
        use piston_window::{Input, Button, MouseButton};

        let mut result = Vec::new();

        match input {
            &Input::Press(Button::Mouse(MouseButton::Left)) => {
                result.push(InputResult::PopScreen);
                result.push(InputResult::PushScreen(Box::new(BattleScreen::new(&window, context))));
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
        self.ui.handle_event(window);
        window.draw_2d(|context, graphics| self.ui.draw_if_changed(context, graphics));
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {
        self.ui.set_widgets(|ui| {
            conrod::Canvas::new()
                .frame(200.)
                .pad(30.0)
                .color(conrod::color::rgb(0.2, 0.35, 0.45))
                .scroll_kids()
                .set(CANVAS, ui);

            conrod::Text::new("Widget Demonstration")
                .top_left_with_margins_on(CANVAS, 0.0, 350.0)
                .font_size(32)
                .color(conrod::color::rgb(0.2, 0.35, 0.45).plain_contrast())
                .set(TITLE, ui);
        });
    }
}

widget_ids! {
    CANVAS,
    TITLE,
}

fn create_ui(window: &piston_window::PistonWindow,
             assets_path: &::std::path::Path)
             -> conrod::Ui<piston_window::Glyphs> {
    let font_path = assets_path.join("NotoSans-Regular.ttf");
    let theme = conrod::Theme::default();
    let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.borrow().clone());
    conrod::Ui::new(glyph_cache.unwrap(), theme)
}
<commit_msg>TODO note<commit_after>use screen::*;
use piston_window;
use conrod::{self, Widget, Frameable, Positionable};
use conrod::color::Colorable;

pub struct MainMenuScreen {
    ui: conrod::Ui<piston_window::Glyphs>,
}

impl MainMenuScreen {
    pub fn new(window: &piston_window::PistonWindow, context: &mut Context) -> MainMenuScreen {
        MainMenuScreen { ui: create_ui(&window, &context.assets_path) }
    }
}

impl Screen for MainMenuScreen {
    fn on_input(&mut self,
                input: &piston_window::Input,
                window: &piston_window::PistonWindow,
                context: &mut Context)
                -> InputResults {
        use piston_window::{Input, Button, MouseButton};

        let mut result = Vec::new();

        match input {
            &Input::Press(Button::Mouse(MouseButton::Left)) => {
                result.push(InputResult::PopScreen);
                result.push(InputResult::PushScreen(Box::new(BattleScreen::new(&window, context))));
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
        self.ui.handle_event(window);
        window.draw_2d(|context, graphics| self.ui.draw_if_changed(context, graphics));
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {
        self.ui.set_widgets(|ui| {
            conrod::Canvas::new()
                .frame(200.)
                .pad(30.0)
                .color(conrod::color::rgb(0.2, 0.35, 0.45))
                .scroll_kids()
                .set(CANVAS, ui);

            conrod::Text::new("Widget Demonstration")
                .top_left_with_margins_on(CANVAS, 0.0, 350.0)
                .font_size(32)
                .color(conrod::color::rgb(0.2, 0.35, 0.45).plain_contrast())
                .set(TITLE, ui);

            // TODO: Button.
        });
    }
}

widget_ids! {
    CANVAS,
    TITLE,
}

fn create_ui(window: &piston_window::PistonWindow,
             assets_path: &::std::path::Path)
             -> conrod::Ui<piston_window::Glyphs> {
    let font_path = assets_path.join("NotoSans-Regular.ttf");
    let theme = conrod::Theme::default();
    let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.borrow().clone());
    conrod::Ui::new(glyph_cache.unwrap(), theme)
}
<|endoftext|>


<commit_before>//! Naive LR(1) generation algorithm.

use grammar::repr::*;
use self::tls::Lr1Tls;

pub mod ascent;

mod build;
mod build_lalr;
mod core;
mod error;
mod example;
mod first;
mod lane_table;
mod lookahead;
mod state_graph;
mod tls;
mod trace;

#[cfg(test)] mod interpret;

use self::core::LR1State;

pub use self::core::{LR1Result, LR1TableConstructionError};
pub use self::error::report_error;

pub fn build_states<'grammar>(grammar: &'grammar Grammar,
                              start: NonterminalString)
                              -> LR1Result<'grammar> {
    let _lr1_tls = Lr1Tls::install(grammar.terminals.clone());

    match grammar.algorithm {
        Algorithm::LR1 => build::build_lr1_states(grammar, start),
        Algorithm::LALR1 => build_lalr::build_lalr_states(grammar, start),
    }
}

<commit_msg>remove dead import<commit_after>//! Naive LR(1) generation algorithm.

use grammar::repr::*;
use self::tls::Lr1Tls;

pub mod ascent;

mod build;
mod build_lalr;
mod core;
mod error;
mod example;
mod first;
mod lane_table;
mod lookahead;
mod state_graph;
mod tls;
mod trace;

#[cfg(test)] mod interpret;

pub use self::core::{LR1Result, LR1TableConstructionError};
pub use self::error::report_error;

pub fn build_states<'grammar>(grammar: &'grammar Grammar,
                              start: NonterminalString)
                              -> LR1Result<'grammar> {
    let _lr1_tls = Lr1Tls::install(grammar.terminals.clone());

    match grammar.algorithm {
        Algorithm::LR1 => build::build_lr1_states(grammar, start),
        Algorithm::LALR1 => build_lalr::build_lalr_states(grammar, start),
    }
}

<|endoftext|>


<commit_before>//! Makes direct use of the renderer module for testing purposes.

extern crate amethyst;

use amethyst::renderer::{Backend, Frontend, Light, Object, Frame};
use amethyst::renderer::types::Buffer;

extern crate amethyst_opengl;

use amethyst_opengl::BackendGl;

fn main() {
    let mut frontend = Frontend::new(BackendGl);

    let mut frame = Frame::new();
    frame.objects = vec![Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite,
                         Object::Mesh { vertices: Buffer::Vertex(0) },
                         Object::Sprite];
    frame.lights = vec![Light::Directional {
                            color: [0.0, 0.0, 0.0, 0.0],
                            direction: [0.0, 0.0, 0.0],
                            intensity: 3.0,
                        }];

    frontend.draw(frame);
}
<commit_msg>move example to amethyst_opengl<commit_after><|endoftext|>


<commit_before>//! An example that determines the time stamp counter frequency (RDTSC, RDTSCP) .
extern crate raw_cpuid;

use std::time;

const MHZ_TO_HZ: u64 = 1000000;
const KHZ_TO_HZ: u64 = 1000;

#[cfg(target_arch = "x86_64")]
#[rustversion::nightly]
use core::arch::x86_64::_rdtsc as rdtsc;

#[cfg(target_arch = "x86")]
#[rustversion::nightly]
use core::arch::x86::_rdtsc as rdtsc;

#[rustversion::stable]
unsafe fn rdtsc() -> u64 {
    0
}

fn main() {
    let cpuid = raw_cpuid::CpuId::new();
    let has_tsc = cpuid
        .get_feature_info()
        .map_or(false, |finfo| finfo.has_tsc());

    let has_invariant_tsc = cpuid
        .get_extended_function_info()
        .map_or(false, |efinfo| efinfo.has_invariant_tsc());

    let tsc_frequency_hz = cpuid.get_tsc_info().map(|tinfo| {
        if tinfo.nominal_frequency() != 0 {
            tinfo.tsc_frequency()
        } else if tinfo.numerator() != 0 && tinfo.denominator() != 0 {
            // Skylake and Kabylake don't report the crystal clock, approximate with base frequency:
            cpuid
                .get_processor_frequency_info()
                .map(|pinfo| pinfo.processor_base_frequency() as u64 * MHZ_TO_HZ)
                .map(|cpu_base_freq_hz| {
                    let crystal_hz =
                        cpu_base_freq_hz * tinfo.denominator() as u64 / tinfo.numerator() as u64;
                    crystal_hz * tinfo.numerator() as u64 / tinfo.denominator() as u64
                })
        } else {
            None
        }
    });

    if has_tsc {
        // Try to figure out TSC frequency with CPUID
        println!(
            "TSC Frequency is: {} ({})",
            match tsc_frequency_hz {
                Some(x) => format!("{} Hz", x.unwrap_or(0)),
                None => String::from("unknown"),
            },
            if has_invariant_tsc {
                "invariant"
            } else {
                "TSC frequency varies with speed-stepping"
            }
        );

        // Check if we run in a VM and the hypervisor can give us the TSC frequency
        cpuid.get_hypervisor_info().map(|hv| {
            hv.tsc_frequency().map(|tsc_khz| {
                let virtual_tsc_frequency_hz = tsc_khz as u64 * KHZ_TO_HZ;
                println!(
                    "Hypervisor reports TSC Frequency at: {} Hz",
                    virtual_tsc_frequency_hz
                );
            })
        });

        // Determine TSC frequency by measuring it (loop for a second, record ticks)
        let one_second = time::Duration::from_secs(1);
        let now = time::Instant::now();
        let start = unsafe { rdtsc() };
        if start > 0 {
            loop {
                if now.elapsed() >= one_second {
                    break;
                }
            }
            let end = unsafe { rdtsc() };
            println!(
                "Empirical measurement of TSC frequency was: {} Hz",
                (end - start)
            );
        } else {
            // Don't have rdtsc on stable!
        }
    } else {
        println!("System does not have a TSC.")
    }
}
<commit_msg>Update tsc_frequency (fixes #35)<commit_after>//! An example that determines the time stamp counter frequency (RDTSC, RDTSCP) .
extern crate raw_cpuid;

use std::time;

const MHZ_TO_HZ: u64 = 1000000;
const KHZ_TO_HZ: u64 = 1000;

#[cfg(target_arch = "x86_64")]
#[rustversion::nightly]
use core::arch::x86_64::_rdtsc as rdtsc;

#[cfg(target_arch = "x86")]
#[rustversion::nightly]
use core::arch::x86::_rdtsc as rdtsc;

#[rustversion::not(nightly)]
unsafe fn rdtsc() -> u64 {
    0
}

fn main() {
    let cpuid = raw_cpuid::CpuId::new();
    let has_tsc = cpuid
        .get_feature_info()
        .map_or(false, |finfo| finfo.has_tsc());

    let has_invariant_tsc = cpuid
        .get_extended_function_info()
        .map_or(false, |efinfo| efinfo.has_invariant_tsc());

    let tsc_frequency_hz = cpuid.get_tsc_info().map(|tinfo| {
        if tinfo.nominal_frequency() != 0 {
            tinfo.tsc_frequency()
        } else if tinfo.numerator() != 0 && tinfo.denominator() != 0 {
            // Skylake and Kabylake don't report the crystal clock, approximate with base frequency:
            cpuid
                .get_processor_frequency_info()
                .map(|pinfo| pinfo.processor_base_frequency() as u64 * MHZ_TO_HZ)
                .map(|cpu_base_freq_hz| {
                    let crystal_hz =
                        cpu_base_freq_hz * tinfo.denominator() as u64 / tinfo.numerator() as u64;
                    crystal_hz * tinfo.numerator() as u64 / tinfo.denominator() as u64
                })
        } else {
            None
        }
    });

    if has_tsc {
        // Try to figure out TSC frequency with CPUID
        println!(
            "TSC Frequency is: {} ({})",
            match tsc_frequency_hz {
                Some(x) => format!("{} Hz", x.unwrap_or(0)),
                None => String::from("unknown"),
            },
            if has_invariant_tsc {
                "invariant"
            } else {
                "TSC frequency varies with speed-stepping"
            }
        );

        // Check if we run in a VM and the hypervisor can give us the TSC frequency
        cpuid.get_hypervisor_info().map(|hv| {
            hv.tsc_frequency().map(|tsc_khz| {
                let virtual_tsc_frequency_hz = tsc_khz as u64 * KHZ_TO_HZ;
                println!(
                    "Hypervisor reports TSC Frequency at: {} Hz",
                    virtual_tsc_frequency_hz
                );
            })
        });

        // Determine TSC frequency by measuring it (loop for a second, record ticks)
        let one_second = time::Duration::from_secs(1);
        let now = time::Instant::now();
        let start = unsafe { rdtsc() };
        if start > 0 {
            loop {
                if now.elapsed() >= one_second {
                    break;
                }
            }
            let end = unsafe { rdtsc() };
            println!(
                "Empirical measurement of TSC frequency was: {} Hz",
                (end - start)
            );
        } else {
            // Don't have rdtsc on stable!
        }
    } else {
        println!("System does not have a TSC.")
    }
}
<|endoftext|>