<commit_before>use std::env::*;
use std::env;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::ascii::AsciiExt;
use hyper::Client;
use hyper::header::Connection;
use hyper::client::response::Response;

extern crate rustc_serialize;
use self::rustc_serialize::json::*;

extern crate chrono;
use self::chrono::*;

#[derive(Clone, Debug)]
pub struct AWSCredentials {
    key: String,
    secret: String,
    expires_at: DateTime<UTC>
}

impl AWSCredentials {
    pub fn new(key:&str, secret:&str, expires_at:DateTime<UTC>) -> AWSCredentials {
        AWSCredentials {
            key: key.to_string(),
            secret: secret.to_string(),
            expires_at: expires_at,
        }
    }

    pub fn get_aws_access_key_id(&self) -> &str {
    	&self.key
    }

    pub fn get_aws_secret_key(&self) -> &str {
    	&self.secret
    }

    pub fn get_expires_at(&self) -> &DateTime<UTC> {
        &self.expires_at
    }
}

// TODO: refactor get_credentials to return std::result
pub trait AWSCredentialsProvider {
    fn new() -> Self;
	fn get_credentials(&self) -> &AWSCredentials;
	fn refresh(&mut self);
}

pub struct EnvironmentCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for EnvironmentCredentialsProvider {
    fn new() -> EnvironmentCredentialsProvider {
        return EnvironmentCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        let env_key = match var("AWS_ACCESS_KEY_ID") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };
        let env_secret = match var("AWS_SECRET_ACCESS_KEY") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };

        self.credentials = AWSCredentials{key: env_key, secret: env_secret, expires_at: UTC::now() + Duration::seconds(600)};
	}

	fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct FileCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for FileCredentialsProvider {
    fn new() -> FileCredentialsProvider {
        return FileCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // Default credentials file location:
        // ~/.aws/credentials (Linux/Mac)
        // %USERPROFILE%\.aws\credentials  (Windows)
        let mut profile_location = String::new();
        match env::home_dir() {
            Some(ref p) => profile_location = p.display().to_string() + "/.aws/credentials",
            None => {
                println!("Couldn't get your home dir.");
                self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(),
                    expires_at: UTC::now() + Duration::seconds(600) };
                return;
            }
        }
        let credentials = get_credentials_from_file(profile_location);
        self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
            secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
    }

    fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// Finds and uses the first "aws_access_key_id" and "aws_secret_access_key" in the file.
fn get_credentials_from_file(file_with_path: String) -> AWSCredentials {
    println!("Looking for credentials file at {}", file_with_path);
    let path = Path::new(&file_with_path);
    let display = path.display();

    let mut found_file = false;

    match fs::metadata(&path) {
        Err(why) => println!("Couldn't get metadata for file: {}", why),
        Ok(metadata) => found_file = metadata.is_file()
    };

    // bail early.  Should be converted to a return type.
    if !found_file {
        return AWSCredentials{ key: "".to_string(), secret: "".to_string(),
            expires_at: UTC::now() + Duration::seconds(600) };
    }

    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(opened_file) => opened_file,
    };

    let mut access_key = String::new();
    let mut secret_key = String::new();
    let file_lines = BufReader::new(&file);
    for line in file_lines.lines() {
        let unwrapped_line : String = line.unwrap();
        // Skip line if it starts with a comment ('#')
        if unwrapped_line.starts_with('#') {
            continue;
        }

        let lower_case_line = unwrapped_line.to_ascii_lowercase().to_string();

        if lower_case_line.contains("aws_access_key_id") {
            if access_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    access_key = "".to_string();
                } else {
                    access_key = v[1].trim_matches(' ').to_string();
                }
            }
        } else if lower_case_line.contains("aws_secret_access_key") {
            if secret_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    secret_key = "".to_string();
                } else {
                    secret_key = v[1].trim_matches(' ').to_string();
                }
            }
        }
    }

    return AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string(),
        expires_at: UTC::now() + Duration::seconds(600) };
}

// class for IAM role
pub struct IAMRoleCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for IAMRoleCredentialsProvider {
    fn new() -> IAMRoleCredentialsProvider {
        return IAMRoleCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
        secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // call instance metadata to get iam role
        // for "real" use: http://169.254.169.254/latest/meta-data/iam/security-credentials/
        let mut address : String = "http://localhost:8080/latest/meta-data/iam/security-credentials".to_string();
        let client = Client::new();
        let mut response;
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(why) => {
                    println!("boo, request failed: {}", why);
                    return;
                }
                Ok(received_response) => response = received_response
            };

        let mut body = String::new();
        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading response: {}", why),
            Ok(_) => (),
        };

        // use results to make another call:
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/fooprofile

        // sample results:
        // {
        //   "Code" : "Success",
        //   "LastUpdated" : "2015-08-04T00:09:23Z",
        //   "Type" : "AWS-HMAC",
        //   "AccessKeyId" : "AAAAAA",
        //   "SecretAccessKey" : "AAAAA",
        //   "Token" : "AAAAA",
        //   "Expiration" : "2015-08-04T06:32:37Z"
        // }
        //  let format = "%Y-%m-%d %T.%f";

        address.push_str("/");
        address.push_str(&body);
        body = String::new();
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(_) => return,
                Ok(received_response) => response = received_response
            };

        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading iam role response: {}", why),
            Ok(_) => (),
        };

        let json_object : Json;
        match Json::from_str(&body) {
            Err(why) => {
                println!("Error: {}", why);
                return;
            }
            Ok(val) => json_object = val
        };

        let mut access_key = String::new();
        match json_object.find("AccessKeyId") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => access_key = val.to_string()
        };

        let mut secret_key = String::new();
        match json_object.find("SecretAccessKey") {
            None => {
                println!("Error finding SecretAccessKey");
                return;
            }
            Some(val) => secret_key = val.to_string()
        };

        let mut expiration = String::new();
        match json_object.find("Expiration") {
            None => {
                println!("Error finding Expiration");
                return;
            }
            Some(val) => expiration = val.to_string()
        };
        // strptime!  From "Expiration"
        // let mut expiration_time = strptime(&expiration, )

        self.credentials = AWSCredentials{ key: access_key.to_string(),
            secret: secret_key.to_string(), expires_at: UTC::now() + Duration::seconds(600) };
    }

    fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct DefaultAWSCredentialsProviderChain {
    credentials: AWSCredentials
}

// Chain the providers:
impl DefaultAWSCredentialsProviderChain {
    pub fn new() -> DefaultAWSCredentialsProviderChain {
        return DefaultAWSCredentialsProviderChain {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

    pub fn get_credentials(&self) -> &AWSCredentials {
        return &self.credentials;
    }

    // This is getting a bit out of control with nested if/else: should try doing something else for flow control.
    pub fn refresh(&mut self) {
        // fetch creds in order: env, file, IAM
        self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };

        let mut env_provider = EnvironmentCredentialsProvider::new();
        env_provider.refresh();
        let credentials = env_provider.get_credentials();

        if creds_have_values(credentials) {
            println!("using creds from env: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
            self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
            return;
        } else {
            // try the file provider
            let mut file_provider = FileCredentialsProvider::new();
            file_provider.refresh();
            let credentials = file_provider.get_credentials();
            println!("using creds from file: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());

            if creds_have_values(credentials) {
                self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                    secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
            } else {
                let mut iam_provider = IAMRoleCredentialsProvider::new();
                iam_provider.refresh();
                let credentials = iam_provider.get_credentials();
                if creds_have_values(credentials) {
                    println!("using creds from IAM: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
                    self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                        secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
                    return;
                } else {
                    // We're out of options
                    panic!("Couldn't find AWS credentials in environment, default credential file location or IAM role.");
                }
            }
        }
    }
}

fn creds_have_values(creds: &AWSCredentials) -> bool {
    if creds.get_aws_access_key_id().len() > 0 && creds.get_aws_secret_key().len() > 0 {
        return true;
    }
    return false;
}
<commit_msg>Adds basic functionality for expiring creds.<commit_after>use std::env::*;
use std::env;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::ascii::AsciiExt;
use hyper::Client;
use hyper::header::Connection;
use hyper::client::response::Response;

extern crate rustc_serialize;
use self::rustc_serialize::json::*;

extern crate chrono;
use self::chrono::*;

#[derive(Clone, Debug)]
pub struct AWSCredentials {
    key: String,
    secret: String,
    expires_at: DateTime<UTC>
}

impl AWSCredentials {
    pub fn new(key:&str, secret:&str, expires_at:DateTime<UTC>) -> AWSCredentials {
        AWSCredentials {
            key: key.to_string(),
            secret: secret.to_string(),
            expires_at: expires_at,
        }
    }

    pub fn get_aws_access_key_id(&self) -> &str {
    	&self.key
    }

    pub fn get_aws_secret_key(&self) -> &str {
    	&self.secret
    }

    pub fn get_expires_at(&self) -> &DateTime<UTC> {
        &self.expires_at
    }

    fn credentials_are_expired(&self) -> bool {
        println!("Seeing if creds of {:?} are expired compared to {:?}", self.expires_at, UTC::now() + Duration::seconds(20));
        // This is a rough hack to hopefully avoid someone requesting creds then sitting on them
        // before issuing the request:
        if self.expires_at < UTC::now() + Duration::seconds(20) {
            return true;
        }
        return false;
    }
}

// TODO: refactor get_credentials to return std::result
pub trait AWSCredentialsProvider {
    fn new() -> Self;
	fn get_credentials(&mut self) -> &AWSCredentials;
	fn refresh(&mut self);
}

pub struct EnvironmentCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for EnvironmentCredentialsProvider {
    fn new() -> EnvironmentCredentialsProvider {
        return EnvironmentCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        let env_key = match var("AWS_ACCESS_KEY_ID") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };
        let env_secret = match var("AWS_SECRET_ACCESS_KEY") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };

        self.credentials = AWSCredentials{key: env_key, secret: env_secret, expires_at: UTC::now() + Duration::seconds(600)};
	}

	fn get_credentials(&mut self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct FileCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for FileCredentialsProvider {
    fn new() -> FileCredentialsProvider {
        return FileCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // Default credentials file location:
        // ~/.aws/credentials (Linux/Mac)
        // %USERPROFILE%\.aws\credentials  (Windows)
        let mut profile_location = String::new();
        match env::home_dir() {
            Some(ref p) => profile_location = p.display().to_string() + "/.aws/credentials",
            None => {
                println!("Couldn't get your home dir.");
                self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(),
                    expires_at: UTC::now() + Duration::seconds(600) };
                return;
            }
        }
        let credentials = get_credentials_from_file(profile_location);
        self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
            secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
    }

    fn get_credentials(&mut self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// Finds and uses the first "aws_access_key_id" and "aws_secret_access_key" in the file.
fn get_credentials_from_file(file_with_path: String) -> AWSCredentials {
    println!("Looking for credentials file at {}", file_with_path);
    let path = Path::new(&file_with_path);
    let display = path.display();

    let mut found_file = false;

    match fs::metadata(&path) {
        Err(why) => println!("Couldn't get metadata for file: {}", why),
        Ok(metadata) => found_file = metadata.is_file()
    };

    // bail early.  Should be converted to a return type.
    if !found_file {
        return AWSCredentials{ key: "".to_string(), secret: "".to_string(),
            expires_at: UTC::now() + Duration::seconds(600) };
    }

    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(opened_file) => opened_file,
    };

    let mut access_key = String::new();
    let mut secret_key = String::new();
    let file_lines = BufReader::new(&file);
    for line in file_lines.lines() {
        let unwrapped_line : String = line.unwrap();
        // Skip line if it starts with a comment ('#')
        if unwrapped_line.starts_with('#') {
            continue;
        }

        let lower_case_line = unwrapped_line.to_ascii_lowercase().to_string();

        if lower_case_line.contains("aws_access_key_id") {
            if access_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    access_key = "".to_string();
                } else {
                    access_key = v[1].trim_matches(' ').to_string();
                }
            }
        } else if lower_case_line.contains("aws_secret_access_key") {
            if secret_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    secret_key = "".to_string();
                } else {
                    secret_key = v[1].trim_matches(' ').to_string();
                }
            }
        }
    }

    return AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string(),
        expires_at: UTC::now() + Duration::seconds(600) };
}

// class for IAM role
pub struct IAMRoleCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for IAMRoleCredentialsProvider {
    fn new() -> IAMRoleCredentialsProvider {
        return IAMRoleCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(),
        secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

	fn refresh(&mut self) {
        // call instance metadata to get iam role
        // for "real" use: http://169.254.169.254/latest/meta-data/iam/security-credentials/
        let mut address : String = "http://localhost:8080/latest/meta-data/iam/security-credentials".to_string();
        let client = Client::new();
        let mut response;
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(why) => {
                    println!("boo, request failed: {}", why);
                    return;
                }
                Ok(received_response) => response = received_response
            };

        let mut body = String::new();
        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading response: {}", why),
            Ok(_) => (),
        };

        // use results to make another call:
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/fooprofile

        // sample results:
        // {
        //   "Code" : "Success",
        //   "LastUpdated" : "2015-08-04T00:09:23Z",
        //   "Type" : "AWS-HMAC",
        //   "AccessKeyId" : "AAAAAA",
        //   "SecretAccessKey" : "AAAAA",
        //   "Token" : "AAAAA",
        //   "Expiration" : "2015-08-04T06:32:37Z"
        // }
        //  let format = "%Y-%m-%d %T.%f";

        address.push_str("/");
        address.push_str(&body);
        body = String::new();
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(_) => return,
                Ok(received_response) => response = received_response
            };

        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading iam role response: {}", why),
            Ok(_) => (),
        };

        let json_object : Json;
        match Json::from_str(&body) {
            Err(why) => {
                println!("Error: {}", why);
                return;
            }
            Ok(val) => json_object = val
        };

        let mut access_key = String::new();
        match json_object.find("AccessKeyId") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => access_key = val.to_string().replace("\"", "")
        };

        let mut secret_key = String::new();
        match json_object.find("SecretAccessKey") {
            None => {
                println!("Error finding SecretAccessKey");
                return;
            }
            Some(val) => secret_key = val.to_string().replace("\"", "")
        };

        let mut expiration = String::new();
        match json_object.find("Expiration") {
            None => {
                println!("Error finding Expiration");
                return;
            }
            Some(val) => expiration = val.to_string().replace("\"", "")
        };

        let mut expiration_time;
        match expiration.parse::<DateTime<UTC>>() {
            Err(why) => panic!("Kabloey on parse: {}", why),
            Ok(val) => expiration_time = val
        };

        self.credentials = AWSCredentials{ key: access_key.to_string(),
            secret: secret_key.to_string(), expires_at: expiration_time };
    }

    fn get_credentials(&mut self) -> &AWSCredentials {
        let expired = &self.credentials.credentials_are_expired();
        if *expired {
            println!("Creds are expired, refreshing.");
            &self.refresh();
        }
		return &self.credentials;
	}
}

pub struct DefaultAWSCredentialsProviderChain {
    credentials: AWSCredentials
}

// Chain the providers:
impl DefaultAWSCredentialsProviderChain {
    pub fn new() -> DefaultAWSCredentialsProviderChain {
        return DefaultAWSCredentialsProviderChain {credentials: AWSCredentials{ key: "".to_string(),
            secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) } };
    }

    pub fn get_credentials(&mut self) -> &AWSCredentials {
        return &self.credentials;
    }

    // This is getting a bit out of control with nested if/else: should try doing something else for flow control.
    pub fn refresh(&mut self) {
        // fetch creds in order: env, file, IAM
        self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string(), expires_at: UTC::now() + Duration::seconds(600) };

        let mut env_provider = EnvironmentCredentialsProvider::new();
        env_provider.refresh();
        let credentials = env_provider.get_credentials();

        if creds_have_values(credentials) {
            println!("using creds from env: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
            self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
            return;
        } else {
            // try the file provider
            let mut file_provider = FileCredentialsProvider::new();
            file_provider.refresh();
            let credentials = file_provider.get_credentials();
            println!("using creds from file: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());

            if creds_have_values(credentials) {
                self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                    secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
            } else {
                let mut iam_provider = IAMRoleCredentialsProvider::new();
                iam_provider.refresh();
                let credentials = iam_provider.get_credentials();
                if creds_have_values(credentials) {
                    println!("using creds from IAM: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
                    self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(),
                        secret: credentials.get_aws_secret_key().to_string(), expires_at: UTC::now() + Duration::seconds(600) };
                    return;
                } else {
                    // We're out of options
                    panic!("Couldn't find AWS credentials in environment, default credential file location or IAM role.");
                }
            }
        }
    }
}

fn creds_have_values(creds: &AWSCredentials) -> bool {
    if creds.get_aws_access_key_id().len() > 0 && creds.get_aws_secret_key().len() > 0 {
        return true;
    }
    return false;
}
<|endoftext|>


<commit_before><commit_msg>Add testcase for issue-18088. ref : https://github.com/rust-lang/rust/issues/18088.<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub trait Indexable<T>: std::ops::Index<usize, Output = T> {
    fn index2(&self, i: usize) -> &T {
        &self[i]
    }
}
fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add test for #25439<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Helper<'a, F: 'a>(&'a F);

fn fix<F>(f: F) -> i32 where F: Fn(Helper<F>, i32) -> i32 {
    f(Helper(&f), 8)
}

fn main() {
    fix(|_, x| x);
}
<|endoftext|>


<commit_before>/*
Module: ptr

Unsafe pointer utility functions
*/
#[abi = "rust-intrinsic"]
native mod rusti {
    fn addr_of<T>(val: T) -> *T;
    fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
    fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
    fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
}

/*
Function: addr_of

Get an unsafe pointer to a value
*/
fn addr_of<T>(val: T) -> *T { ret rusti::addr_of(val); }

/*
Function: mut_addr_of

Get an unsafe mutable pointer to a value
*/
fn mut_addr_of<T>(val: T) -> *mutable T unsafe {
    ret unsafe::reinterpret_cast(rusti::addr_of(val));
}

/*
Function: offset

Calculate the offset from a pointer
*/
fn offset<T>(ptr: *T, count: uint) -> *T {
    ret rusti::ptr_offset(ptr, count);
}

/*
Function: mut_offset

Calculate the offset from a mutable pointer
*/
fn mut_offset<T>(ptr: *mutable T, count: uint) -> *mutable T {
    ret rusti::ptr_offset(ptr as *T, count) as *mutable T;
}

/*
Function: null

Create an unsafe null pointer
*/
fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

/*
Function: memcpy

Copies data from one src to dst that is not overlapping each other.
*/
fn memcpy<T>(dst: *T, src: *T, count: uint) unsafe { rusti::memcpy(dst, src, count); }

/*
Function: memmove

Copies data from one src to dst, overlap between the two pointers may occur.
*/
fn memmove<T>(dst: *T, src: *T, count: uint) unsafe { rusti::memcpy(dst, src, count); }

#[test]
fn test() unsafe {
    type pair = {mutable fst: int, mutable snd: int};
    let p = {mutable fst: 10, mutable snd: 20};
    let pptr: *mutable pair = mut_addr_of(p);
    let iptr: *mutable int = unsafe::reinterpret_cast(pptr);
    assert (*iptr == 10);;
    *iptr = 30;
    assert (*iptr == 30);
    assert (p.fst == 30);;

    *pptr = {mutable fst: 50, mutable snd: 60};
    assert (*iptr == 50);
    assert (p.fst == 50);
    assert (p.snd == 60);

    let v0 = [32000u16, 32001u16, 32002u16];
    let v1 = [0u16, 0u16, 0u16];

    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u), ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
    assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(vec::unsafe::to_ptr(v1), ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u), vec::unsafe::to_ptr(v0), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}<commit_msg>added some documentation and made the memcpy and memmove unsafe<commit_after>/*
Module: ptr

Unsafe pointer utility functions
*/
#[abi = "rust-intrinsic"]
native mod rusti {
    fn addr_of<T>(val: T) -> *T;
    fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
    fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
    fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
}

/*
Function: addr_of

Get an unsafe pointer to a value
*/
fn addr_of<T>(val: T) -> *T { ret rusti::addr_of(val); }

/*
Function: mut_addr_of

Get an unsafe mutable pointer to a value
*/
fn mut_addr_of<T>(val: T) -> *mutable T unsafe {
    ret unsafe::reinterpret_cast(rusti::addr_of(val));
}

/*
Function: offset

Calculate the offset from a pointer
*/
fn offset<T>(ptr: *T, count: uint) -> *T {
    ret rusti::ptr_offset(ptr, count);
}

/*
Function: mut_offset

Calculate the offset from a mutable pointer
*/
fn mut_offset<T>(ptr: *mutable T, count: uint) -> *mutable T {
    ret rusti::ptr_offset(ptr as *T, count) as *mutable T;
}

/*
Function: null

Create an unsafe null pointer
*/
fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

/*
Function: memcpy

Copies data from one src to dst that is not overlapping each other.
Count is the number of elements to copy and not the number of bytes.
*/
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) { rusti::memcpy(dst, src, count); }

/*
Function: memmove

Copies data from one src to dst, overlap between the two pointers may occur.
Count is the number of elements to copy and not the number of bytes.
*/
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  { rusti::memcpy(dst, src, count); }

#[test]
fn test() unsafe {
    type pair = {mutable fst: int, mutable snd: int};
    let p = {mutable fst: 10, mutable snd: 20};
    let pptr: *mutable pair = mut_addr_of(p);
    let iptr: *mutable int = unsafe::reinterpret_cast(pptr);
    assert (*iptr == 10);;
    *iptr = 30;
    assert (*iptr == 30);
    assert (p.fst == 30);;

    *pptr = {mutable fst: 50, mutable snd: 60};
    assert (*iptr == 50);
    assert (p.fst == 50);
    assert (p.snd == 60);

    let v0 = [32000u16, 32001u16, 32002u16];
    let v1 = [0u16, 0u16, 0u16];

    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u), ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
    assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(vec::unsafe::to_ptr(v1), ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u), vec::unsafe::to_ptr(v0), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(missing_doc)]
#![experimental]

//! Contains struct definitions for the layout of compiler built-in types.
//!
//! They can be used as targets of transmutes in unsafe code for manipulating
//! the raw representations directly.
//!
//! Their definition should always match the ABI defined in `rustc::back::abi`.

use mem;

/// The representation of a Rust slice
pub struct Slice<T> {
    pub data: *const T,
    pub len: uint,
}

/// The representation of a Rust closure
pub struct Closure {
    pub code: *mut (),
    pub env: *mut (),
}

/// The representation of a Rust procedure (`proc()`)
pub struct Procedure {
    pub code: *mut (),
    pub env: *mut (),
}

/// The representation of a Rust trait object.
///
/// This struct does not have a `Repr` implementation
/// because there is no way to refer to all trait objects generically.
pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}

/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
pub trait Repr<T> {
    /// This function "unwraps" a rust value (without consuming it) into its raw
    /// struct representation. This can be used to read/write different values
    /// for the struct. This is a safe method because by default it does not
    /// enable write-access to the fields of the return value in safe code.
    #[inline]
    fn repr(&self) -> T { unsafe { mem::transmute_copy(self) } }
}

impl<'a, T> Repr<Slice<T>> for &'a [T] {}
impl<'a> Repr<Slice<u8>> for &'a str {}

<commit_msg>rollup merge of #18316 : thestinger/raw<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(missing_doc)]
#![experimental]

//! Contains struct definitions for the layout of compiler built-in types.
//!
//! They can be used as targets of transmutes in unsafe code for manipulating
//! the raw representations directly.
//!
//! Their definition should always match the ABI defined in `rustc::back::abi`.

use mem;

/// The representation of a Rust slice
#[repr(C)]
pub struct Slice<T> {
    pub data: *const T,
    pub len: uint,
}

/// The representation of a Rust closure
#[repr(C)]
pub struct Closure {
    pub code: *mut (),
    pub env: *mut (),
}

/// The representation of a Rust procedure (`proc()`)
#[repr(C)]
pub struct Procedure {
    pub code: *mut (),
    pub env: *mut (),
}

/// The representation of a Rust trait object.
///
/// This struct does not have a `Repr` implementation
/// because there is no way to refer to all trait objects generically.
#[repr(C)]
pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}

/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
pub trait Repr<T> {
    /// This function "unwraps" a rust value (without consuming it) into its raw
    /// struct representation. This can be used to read/write different values
    /// for the struct. This is a safe method because by default it does not
    /// enable write-access to the fields of the return value in safe code.
    #[inline]
    fn repr(&self) -> T { unsafe { mem::transmute_copy(self) } }
}

impl<'a, T> Repr<Slice<T>> for &'a [T] {}
impl<'a> Repr<Slice<u8>> for &'a str {}
<|endoftext|>


<commit_before><commit_msg>Add IndentionHelper for handlebars templating<commit_after><|endoftext|>


<commit_before><commit_msg>Have the num and skip parsing done outside of `tail()`<commit_after><|endoftext|>


<commit_before><commit_msg>Add a single function to get the length of a chunk, based on his index, and a few simple unit tests<commit_after>use std::cmp::min;

use Byte;

/// Represents a range between two Byte types
#[derive(Debug, PartialEq)]
struct RangeBytes(Byte, Byte);

/// Function to get the current chunk length, based on the chunk index.
fn get_chunk_length(chunk_index: Byte,
                    content_length: Byte,
                    global_chunk_length: Byte)
                    -> Option<RangeBytes> {

    // In case of wrong values, do not returns a structure
    if content_length == 0 || global_chunk_length == 0 {
        return None;
    }

    let b_range: Byte = chunk_index * global_chunk_length;

    let e_range: Byte = min(content_length,
                            ((chunk_index + 1) * global_chunk_length) - 1);

    Some(RangeBytes(b_range, e_range))

}

mod test_chunk_length {
    use super::get_chunk_length;
    use super::RangeBytes;

    #[test]
    fn wrong_content_length_parameter_should_return_none() {
        assert_eq!(None, get_chunk_length(0, 15, 0));
    }

    #[test]
    fn wrong_global_chunk_length_parameter_should_return_none() {
        assert_eq!(None, get_chunk_length(0, 0, 15));
    }

    #[test]
    fn wrong_length_parameters_should_return_none() {
        assert_eq!(None, get_chunk_length(0, 0, 0));
    }

}<|endoftext|>


<commit_before><commit_msg>[No-auto] bin/domain/notes: Fix Clippy warnings<commit_after><|endoftext|>


<commit_before><commit_msg>list2.rs<commit_after>//use core::fmt::Display;
use std::fmt;
use List::{Cons, Nil};

enum List<T> {
  Cons(T, Box<List<T>>),
  Nil
}

impl<T> fmt::Display for List<T> where T : fmt::Display {//TがDisplay traitを実装していることを保証したい
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match *self {
      Cons(ref head, ref tail) =>
        {
          write!(f, "{head} :: ", head = head);
          write!(f, "{tail} ", tail = tail)
        }
      Nil => write!(f, "Nil")
    }
  }
}

fn new_list<T>(args: Vec<T>) -> Box<List<T>> where T: Copy {
  let mut vec = args;
  let mut x: Box<List<T>> = Box::new(Nil);
  while vec.len() > 0 {
    match vec.pop() {
      Some(e) => x = Box::new(Cons(e, x)),
      None => {}
    }
  }
  x
}

fn main() {
  let list = new_list(vec!["A", "B", "C"]);
  println!("Hello, {rust}", rust=list);
}
<|endoftext|>


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

//! Configuration options for a single run of the servo application. Created
//! from command line arguments.

use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};

use std::float;
use std::result;
use std::uint;

#[deriving(Clone)]
pub struct Opts {
    urls: ~[~str],
    render_backend: BackendType,
    n_render_threads: uint,
    tile_size: uint,
    profiler_period: Option<float>,
    exit_after_load: bool,
}

#[allow(non_implicitly_copyable_typarams)]
pub fn from_cmdline_args(args: &[~str]) -> Opts {
    use extra::getopts;

    let args = args.tail();

    let opts = ~[
        getopts::optopt("o"),  // output file
        getopts::optopt("r"),  // rendering backend
        getopts::optopt("s"),  // size of tiles
        getopts::optopt("t"),  // threads to render with
        getopts::optflagopt("p"),  // profiler flag and output interval
        getopts::optflag("x"), // exit after load flag
    ];

    let opt_match = match getopts::getopts(args, opts) {
      result::Ok(m) => m,
      result::Err(f) => fail!(getopts::fail_str(copy f)),
    };

    let urls = if opt_match.free.is_empty() {
        fail!(~"servo asks that you provide 1 or more URLs")
    } else {
        copy opt_match.free
    };

    if getopts::opt_present(&opt_match, "o") {
        fail!(~"servo cannot treat 'o' option now.")
    }

    let render_backend = match getopts::opt_maybe_str(&opt_match, "r") {
        Some(backend_str) => {
            if backend_str == ~"direct2d" {
                Direct2DBackend
            } else if backend_str == ~"core-graphics" {
                CoreGraphicsBackend
            } else if backend_str == ~"core-graphics-accelerated" {
                CoreGraphicsAcceleratedBackend
            } else if backend_str == ~"cairo" {
                CairoBackend
            } else if backend_str == ~"skia" {
                SkiaBackend
            } else {
                fail!(~"unknown backend type")
            }
        }
        None => SkiaBackend
    };

    let tile_size: uint = match getopts::opt_maybe_str(&opt_match, "s") {
        Some(tile_size_str) => uint::from_str(tile_size_str).get(),
        None => 512,
    };

    let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, "t") {
        Some(n_render_threads_str) => uint::from_str(n_render_threads_str).get(),
        None => 1,      // FIXME: Number of cores.
    };

    let profiler_period: Option<float> =
        // if only flag is present, default to 5 second period
        match getopts::opt_default(&opt_match, "p", "5") {
        Some(period) => Some(float::from_str(period).get()),
        None => None,
    };

    let exit_after_load = getopts::opt_present(&opt_match, "x");

    Opts {
        urls: urls,
        render_backend: render_backend,
        n_render_threads: n_render_threads,
        tile_size: tile_size,
        profiler_period: profiler_period,
        exit_after_load: exit_after_load,
    }
}
<commit_msg>Enable `-o` option for output_file.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Configuration options for a single run of the servo application. Created
//! from command line arguments.

use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};

use std::float;
use std::result;
use std::uint;

#[deriving(Clone)]
pub struct Opts {
    urls: ~[~str],
    render_backend: BackendType,
    n_render_threads: uint,
    tile_size: uint,
    profiler_period: Option<float>,
    exit_after_load: bool,
    output_file: Option<~str>,
}

#[allow(non_implicitly_copyable_typarams)]
pub fn from_cmdline_args(args: &[~str]) -> Opts {
    use extra::getopts;

    let args = args.tail();

    let opts = ~[
        getopts::optopt("o"),  // output file
        getopts::optopt("r"),  // rendering backend
        getopts::optopt("s"),  // size of tiles
        getopts::optopt("t"),  // threads to render with
        getopts::optflagopt("p"),  // profiler flag and output interval
        getopts::optflag("x"), // exit after load flag
    ];

    let opt_match = match getopts::getopts(args, opts) {
      result::Ok(m) => m,
      result::Err(f) => fail!(getopts::fail_str(copy f)),
    };

    let urls = if opt_match.free.is_empty() {
        fail!(~"servo asks that you provide 1 or more URLs")
    } else {
        copy opt_match.free
    };

    let render_backend = match getopts::opt_maybe_str(&opt_match, "r") {
        Some(backend_str) => {
            if backend_str == ~"direct2d" {
                Direct2DBackend
            } else if backend_str == ~"core-graphics" {
                CoreGraphicsBackend
            } else if backend_str == ~"core-graphics-accelerated" {
                CoreGraphicsAcceleratedBackend
            } else if backend_str == ~"cairo" {
                CairoBackend
            } else if backend_str == ~"skia" {
                SkiaBackend
            } else {
                fail!(~"unknown backend type")
            }
        }
        None => SkiaBackend
    };

    let tile_size: uint = match getopts::opt_maybe_str(&opt_match, "s") {
        Some(tile_size_str) => uint::from_str(tile_size_str).get(),
        None => 512,
    };

    let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, "t") {
        Some(n_render_threads_str) => uint::from_str(n_render_threads_str).get(),
        None => 1,      // FIXME: Number of cores.
    };

    let profiler_period: Option<float> =
        // if only flag is present, default to 5 second period
        match getopts::opt_default(&opt_match, "p", "5") {
        Some(period) => Some(float::from_str(period).get()),
        None => None,
    };

    let exit_after_load = getopts::opt_present(&opt_match, "x");

    let output_file = getopts::opt_maybe_str(&opt_match, "o");

    Opts {
        urls: urls,
        render_backend: render_backend,
        n_render_threads: n_render_threads,
        tile_size: tile_size,
        profiler_period: profiler_period,
        exit_after_load: exit_after_load,
        output_file: output_file,
    }
}
<|endoftext|>


<commit_before>use std::cmp;
use std::collections::{BinaryHeap};
use std::error::Error;

use commands::{Command, CommandExecutor};
use commands::pool::PoolCommand;
use errors::common::CommonError;
use errors::pool::PoolError;
use super::{
    MerkleTree,
    RemoteNode,
};
use super::rust_base58::{FromBase58, ToBase58};
use super::types::*;
use utils::json::JsonEncodable;

pub struct CatchupHandler {
    pub f: usize,
    pub ledger_status_same: usize,
    pub merkle_tree: MerkleTree,
    pub new_mt_size: usize,
    pub new_mt_root: Vec<u8>,
    pub new_mt_vote: usize,
    pub nodes: Vec<RemoteNode>,
    pub initiate_cmd_id: i32,
    pub is_refresh: bool,
    pub pending_catchup: Option<CatchUpProcess>,
    pub pool_id: i32,
}

impl Default for CatchupHandler {
    fn default() -> Self {
        CatchupHandler {
            f: 0,
            ledger_status_same: 0,
            merkle_tree: MerkleTree::from_vec(Vec::new()).unwrap(),
            nodes: Vec::new(),
            new_mt_size: 0,
            new_mt_vote: 0,
            new_mt_root: Vec::new(),
            pending_catchup: None,
            initiate_cmd_id: 0,
            is_refresh: false,
            pool_id: 0,
        }
    }
}

impl CatchupHandler {
    pub fn process_msg(&mut self, msg: Message, raw_msg: &String, src_ind: usize) -> Result<Option<MerkleTree>, PoolError> {
        match msg {
            Message::Pong => {
                //sending ledger status
                //TODO not send ledger status directly as response on ping, wait pongs from all nodes?
                let ls: LedgerStatus = LedgerStatus {
                    txnSeqNo: self.nodes.len(),
                    merkleRoot: self.merkle_tree.root_hash().as_slice().to_base58(),
                    ledgerId: 0,
                    ppSeqNo: None,
                    viewNo: None,
                };
                let resp_msg: Message = Message::LedgerStatus(ls);
                self.nodes[src_ind].send_msg(&resp_msg)?;
            }
            Message::LedgerStatus(ledger_status) => {
                if self.merkle_tree.root_hash().as_slice().to_base58().ne(ledger_status.merkleRoot.as_str()) {
                    return Err(PoolError::CommonError(
                        CommonError::InvalidState(
                            "Ledger merkle tree doesn't acceptable for current tree.".to_string())));
                }
                self.ledger_status_same += 1;
                if self.ledger_status_same == self.f + 1 {
                    return Ok(Some(self.merkle_tree.clone()));
                }
            }
            Message::ConsistencyProof(cons_proof) => {
                trace!("{:?}", cons_proof);
                if cons_proof.seqNoStart == self.merkle_tree.count()
                    && cons_proof.seqNoEnd > self.merkle_tree.count() {
                    self.new_mt_size = cmp::max(cons_proof.seqNoEnd, self.new_mt_size);
                    self.new_mt_vote += 1;
                    self.new_mt_root = cons_proof.newMerkleRoot.from_base58().unwrap();
                    debug!("merkle tree expected size now {}", self.new_mt_size);
                }
                if self.new_mt_vote == self.f + 1 {
                    self.start_catchup()?;
                }
            }
            Message::CatchupRep(catchup) => {
                if let Some(new_mt) = self.process_catchup_rep(catchup)? {
                    return Ok(Some(new_mt));
                }
            }
            _ => {
                warn!("unhandled msg {:?}", msg);
            }
        };
        Ok(None)
    }

    pub fn start_catchup(&mut self) -> Result<(), PoolError> {
        trace!("start_catchup");
        if self.pending_catchup.is_some() {
            return Err(PoolError::CommonError(
                CommonError::InvalidState(
                    "CatchUp already started for the pool".to_string())));
        }
        let node_cnt = self.nodes.len();
        if self.merkle_tree.count() != node_cnt {
            return Err(PoolError::CommonError(
                CommonError::InvalidState(
                    "Merkle tree doesn't equal nodes count".to_string())));
        }
        let cnt_to_catchup = self.new_mt_size - self.merkle_tree.count();
        if cnt_to_catchup <= 0 {
            return Err(PoolError::CommonError(CommonError::InvalidState(
                "Nothing to CatchUp, but started".to_string())));
        }

        self.pending_catchup = Some(CatchUpProcess {
            merkle_tree: self.merkle_tree.clone(),
            pending_reps: BinaryHeap::new(),
        });

        let portion = (cnt_to_catchup + node_cnt - 1) / node_cnt; //TODO check standard round up div
        let mut catchup_req = CatchupReq {
            ledgerId: 0,
            seqNoStart: node_cnt + 1,
            seqNoEnd: node_cnt + 1 + portion - 1,
            catchupTill: self.new_mt_size,
        };
        for node in &self.nodes {
            node.send_msg(&Message::CatchupReq(catchup_req.clone()))?;
            catchup_req.seqNoStart += portion;
            catchup_req.seqNoEnd = cmp::min(catchup_req.seqNoStart + portion - 1,
                                            catchup_req.catchupTill);
        }
        Ok(())
    }

    pub fn process_catchup_rep(&mut self, catchup: CatchupRep) -> Result<Option<MerkleTree>, PoolError> {
        trace!("append {:?}", catchup);
        let catchup_finished = {
            let mut process = self.pending_catchup.as_mut()
                .ok_or(CommonError::InvalidState("Process non-existing CatchUp".to_string()))?;
            process.pending_reps.push(catchup);
            while !process.pending_reps.is_empty()
                && process.pending_reps.peek().unwrap().min_tx() - 1 == process.merkle_tree.count() {
                let mut first_resp = process.pending_reps.pop().unwrap();
                while !first_resp.txns.is_empty() {
                    let key = first_resp.min_tx().to_string();
                    let new_gen_tx = first_resp.txns
                        .remove(&key)
                        .unwrap()
                        .to_json()
                        .map_err(|err|
                            CommonError::InvalidState(
                                format!("Can't serialize gen-tx json: {}", err.description())))?;
                    trace!("append to tree {}", new_gen_tx);
                    process.merkle_tree.append(
                        new_gen_tx
                    )?;
                    assert!(process.merkle_tree
                        .consistency_proof(&self.new_mt_root, self.new_mt_size,
                                           &first_resp.consProof.iter().map(|x| x.from_base58().unwrap()).collect())
                        .unwrap());
                }
            }
            trace!("updated mt hash {}, tree {:?}", process.merkle_tree.root_hash().as_slice().to_base58(), process.merkle_tree);
            if &process.merkle_tree.count() == &self.new_mt_size {
                if process.merkle_tree.root_hash().ne(&self.new_mt_root) {
                    return Err(PoolError::CommonError(CommonError::InvalidState(
                        "CatchUp failed: all transactions added, proofs checked, but root hash differ with target".to_string())));
                }
                //TODO check also root hash?
                true
            } else {
                false
            }
        };
        if catchup_finished {
            return Ok(Some(self.finish_catchup()?));
        }
        Ok(None)
    }

    pub fn finish_catchup(&mut self) -> Result<MerkleTree, PoolError> {
        Ok(self.pending_catchup.take().
            ok_or(CommonError::InvalidState("Try to finish non-existing CatchUp".to_string()))?
            .merkle_tree)
    }

    pub fn flush_requests(&mut self, status: Result<(), PoolError>) -> Result<(), PoolError> {
        let cmd = if self.is_refresh {
            PoolCommand::RefreshAck(self.initiate_cmd_id, status)
        } else {
            PoolCommand::OpenAck(self.initiate_cmd_id, status.map(|()| self.pool_id))
        };
        CommandExecutor::instance()
            .send(Command::Pool(cmd))
            .map_err(|err|
                PoolError::CommonError(
                    CommonError::InvalidState("Can't send ACK cmd".to_string())))
    }
}
<commit_msg>Fix checking proofs.<commit_after>use std::cmp;
use std::collections::{BinaryHeap};
use std::error::Error;

use commands::{Command, CommandExecutor};
use commands::pool::PoolCommand;
use errors::common::CommonError;
use errors::pool::PoolError;
use super::{
    MerkleTree,
    RemoteNode,
};
use super::rust_base58::{FromBase58, ToBase58};
use super::types::*;
use utils::json::JsonEncodable;

pub struct CatchupHandler {
    pub f: usize,
    pub ledger_status_same: usize,
    pub merkle_tree: MerkleTree,
    pub new_mt_size: usize,
    pub new_mt_root: Vec<u8>,
    pub new_mt_vote: usize,
    pub nodes: Vec<RemoteNode>,
    pub initiate_cmd_id: i32,
    pub is_refresh: bool,
    pub pending_catchup: Option<CatchUpProcess>,
    pub pool_id: i32,
}

impl Default for CatchupHandler {
    fn default() -> Self {
        CatchupHandler {
            f: 0,
            ledger_status_same: 0,
            merkle_tree: MerkleTree::from_vec(Vec::new()).unwrap(),
            nodes: Vec::new(),
            new_mt_size: 0,
            new_mt_vote: 0,
            new_mt_root: Vec::new(),
            pending_catchup: None,
            initiate_cmd_id: 0,
            is_refresh: false,
            pool_id: 0,
        }
    }
}

impl CatchupHandler {
    pub fn process_msg(&mut self, msg: Message, raw_msg: &String, src_ind: usize) -> Result<Option<MerkleTree>, PoolError> {
        match msg {
            Message::Pong => {
                //sending ledger status
                //TODO not send ledger status directly as response on ping, wait pongs from all nodes?
                let ls: LedgerStatus = LedgerStatus {
                    txnSeqNo: self.nodes.len(),
                    merkleRoot: self.merkle_tree.root_hash().as_slice().to_base58(),
                    ledgerId: 0,
                    ppSeqNo: None,
                    viewNo: None,
                };
                let resp_msg: Message = Message::LedgerStatus(ls);
                self.nodes[src_ind].send_msg(&resp_msg)?;
            }
            Message::LedgerStatus(ledger_status) => {
                if self.merkle_tree.root_hash().as_slice().to_base58().ne(ledger_status.merkleRoot.as_str()) {
                    return Err(PoolError::CommonError(
                        CommonError::InvalidState(
                            "Ledger merkle tree doesn't acceptable for current tree.".to_string())));
                }
                self.ledger_status_same += 1;
                if self.ledger_status_same == self.f + 1 {
                    return Ok(Some(self.merkle_tree.clone()));
                }
            }
            Message::ConsistencyProof(cons_proof) => {
                trace!("{:?}", cons_proof);
                if cons_proof.seqNoStart == self.merkle_tree.count()
                    && cons_proof.seqNoEnd > self.merkle_tree.count() {
                    self.new_mt_size = cmp::max(cons_proof.seqNoEnd, self.new_mt_size);
                    self.new_mt_vote += 1;
                    self.new_mt_root = cons_proof.newMerkleRoot.from_base58().unwrap();
                    debug!("merkle tree expected size now {}", self.new_mt_size);
                }
                if self.new_mt_vote == self.f + 1 {
                    self.start_catchup()?;
                }
            }
            Message::CatchupRep(catchup) => {
                if let Some(new_mt) = self.process_catchup_rep(catchup)? {
                    return Ok(Some(new_mt));
                }
            }
            _ => {
                warn!("unhandled msg {:?}", msg);
            }
        };
        Ok(None)
    }

    pub fn start_catchup(&mut self) -> Result<(), PoolError> {
        trace!("start_catchup");
        if self.pending_catchup.is_some() {
            return Err(PoolError::CommonError(
                CommonError::InvalidState(
                    "CatchUp already started for the pool".to_string())));
        }
        let node_cnt = self.nodes.len();
        if self.merkle_tree.count() != node_cnt {
            return Err(PoolError::CommonError(
                CommonError::InvalidState(
                    "Merkle tree doesn't equal nodes count".to_string())));
        }
        let cnt_to_catchup = self.new_mt_size - self.merkle_tree.count();
        if cnt_to_catchup <= 0 {
            return Err(PoolError::CommonError(CommonError::InvalidState(
                "Nothing to CatchUp, but started".to_string())));
        }

        self.pending_catchup = Some(CatchUpProcess {
            merkle_tree: self.merkle_tree.clone(),
            pending_reps: BinaryHeap::new(),
        });

        let portion = (cnt_to_catchup + node_cnt - 1) / node_cnt; //TODO check standard round up div
        let mut catchup_req = CatchupReq {
            ledgerId: 0,
            seqNoStart: node_cnt + 1,
            seqNoEnd: node_cnt + 1 + portion - 1,
            catchupTill: self.new_mt_size,
        };
        for node in &self.nodes {
            node.send_msg(&Message::CatchupReq(catchup_req.clone()))?;
            catchup_req.seqNoStart += portion;
            catchup_req.seqNoEnd = cmp::min(catchup_req.seqNoStart + portion - 1,
                                            catchup_req.catchupTill);
        }
        Ok(())
    }

    pub fn process_catchup_rep(&mut self, catchup: CatchupRep) -> Result<Option<MerkleTree>, PoolError> {
        trace!("append {:?}", catchup);
        let catchup_finished = {
            let mut process = self.pending_catchup.as_mut()
                .ok_or(CommonError::InvalidState("Process non-existing CatchUp".to_string()))?;
            process.pending_reps.push(catchup);
            while !process.pending_reps.is_empty()
                && process.pending_reps.peek().unwrap().min_tx() - 1 == process.merkle_tree.count() {
                let mut first_resp = process.pending_reps.pop().unwrap();
                while !first_resp.txns.is_empty() {
                    let key = first_resp.min_tx().to_string();
                    let new_gen_tx = first_resp.txns
                        .remove(&key)
                        .unwrap()
                        .to_json()
                        .map_err(|err|
                            CommonError::InvalidState(
                                format!("Can't serialize gen-tx json: {}", err.description())))?;
                    trace!("append to tree {}", new_gen_tx);
                    process.merkle_tree.append(
                        new_gen_tx
                    )?;
                }
                assert!(process.merkle_tree
                    .consistency_proof(&self.new_mt_root, self.new_mt_size,
                                       &first_resp.consProof.iter().map(|x| x.from_base58().unwrap()).collect())
                    .unwrap());
            }
            trace!("updated mt hash {}, tree {:?}", process.merkle_tree.root_hash().as_slice().to_base58(), process.merkle_tree);
            if &process.merkle_tree.count() == &self.new_mt_size {
                if process.merkle_tree.root_hash().ne(&self.new_mt_root) {
                    return Err(PoolError::CommonError(CommonError::InvalidState(
                        "CatchUp failed: all transactions added, proofs checked, but root hash differ with target".to_string())));
                }
                //TODO check also root hash?
                true
            } else {
                false
            }
        };
        if catchup_finished {
            return Ok(Some(self.finish_catchup()?));
        }
        Ok(None)
    }

    pub fn finish_catchup(&mut self) -> Result<MerkleTree, PoolError> {
        Ok(self.pending_catchup.take().
            ok_or(CommonError::InvalidState("Try to finish non-existing CatchUp".to_string()))?
            .merkle_tree)
    }

    pub fn flush_requests(&mut self, status: Result<(), PoolError>) -> Result<(), PoolError> {
        let cmd = if self.is_refresh {
            PoolCommand::RefreshAck(self.initiate_cmd_id, status)
        } else {
            PoolCommand::OpenAck(self.initiate_cmd_id, status.map(|()| self.pool_id))
        };
        CommandExecutor::instance()
            .send(Command::Pool(cmd))
            .map_err(|err|
                PoolError::CommonError(
                    CommonError::InvalidState("Can't send ACK cmd".to_string())))
    }
}
<|endoftext|>


<commit_before><commit_msg>Strip back the Vulkan renderer to the simplest synchronisation to get it working (fix issue #15)<commit_after><|endoftext|>


<commit_before><commit_msg>[No-auto] bin/core/category: Fix Clippy warnings<commit_after><|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use core::cell::Cell;
use core::os;
use core::result::Result;
use core::result;
use core::run::ProcessOutput;
use core::run;
use core::vec;
use extra::getopts;

/// The type of document to output
#[deriving(Eq)]
pub enum OutputFormat {
    /// Markdown
    pub Markdown,
    /// HTML, via markdown and pandoc
    pub PandocHtml
}

/// How to organize the output
#[deriving(Eq)]
pub enum OutputStyle {
    /// All in a single document
    pub DocPerCrate,
    /// Each module in its own document
    pub DocPerMod
}

/// The configuration for a rustdoc session
pub struct Config {
    input_crate: Path,
    output_dir: Path,
    output_format: OutputFormat,
    output_style: OutputStyle,
    pandoc_cmd: Option<~str>
}

impl Clone for Config {
    fn clone(&self) -> Config { copy *self }
}

fn opt_output_dir() -> ~str { ~"output-dir" }
fn opt_output_format() -> ~str { ~"output-format" }
fn opt_output_style() -> ~str { ~"output-style" }
fn opt_pandoc_cmd() -> ~str { ~"pandoc-cmd" }
fn opt_help() -> ~str { ~"h" }

fn opts() -> ~[(getopts::Opt, ~str)] {
    ~[
        (getopts::optopt(opt_output_dir()),
         ~"--output-dir <val>     put documents here"),
        (getopts::optopt(opt_output_format()),
         ~"--output-format <val>  either 'markdown' or 'html'"),
        (getopts::optopt(opt_output_style()),
         ~"--output-style <val>   either 'doc-per-crate' or 'doc-per-mod'"),
        (getopts::optopt(opt_pandoc_cmd()),
         ~"--pandoc-cmd <val>     the command for running pandoc"),
        (getopts::optflag(opt_help()),
         ~"-h                     print help")
    ]
}

pub fn usage() {
    use core::io::println;

    println("Usage: rustdoc [options] <cratefile>\n");
    println("Options:\n");
    for opts().each |opt| {
        println(fmt!("    %s", opt.second()));
    }
    println("");
}

pub fn default_config(input_crate: &Path) -> Config {
    Config {
        input_crate: copy *input_crate,
        output_dir: Path("."),
        output_format: PandocHtml,
        output_style: DocPerMod,
        pandoc_cmd: None
    }
}

type Process = ~fn((&str), (&[~str])) -> ProcessOutput;

pub fn mock_process_output(_prog: &str, _args: &[~str]) -> ProcessOutput {
    ProcessOutput {
        status: 0,
        output: ~[],
        error: ~[]
    }
}

pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
    run::process_output(prog, args)
}

pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
    parse_config_(args, process_output)
}

pub fn parse_config_(
    args: &[~str],
    process_output: Process
) -> Result<Config, ~str> {
    let args = args.tail();
    let opts = vec::unzip(opts()).first();
    match getopts::getopts(args, opts) {
        Ok(matches) => {
            if matches.free.len() == 1 {
                let input_crate = Path(*matches.free.head());
                config_from_opts(&input_crate, &matches, process_output)
            } else if matches.free.is_empty() {
                Err(~"no crates specified")
            } else {
                Err(~"multiple crates specified")
            }
        }
        Err(f) => {
            Err(getopts::fail_str(f))
        }
    }
}

fn config_from_opts(
    input_crate: &Path,
    matches: &getopts::Matches,
    process_output: Process
) -> Result<Config, ~str> {

    let config = default_config(input_crate);
    let result = result::Ok(config);
    let result = do result::chain(result) |config| {
        let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
        let output_dir = output_dir.map(|s| Path(*s));
        result::Ok(Config {
            output_dir: output_dir.get_or_default(copy config.output_dir),
            .. config
        })
    };
    let result = do result::chain(result) |config| {
        let output_format = getopts::opt_maybe_str(
            matches, opt_output_format());
        do output_format.map_default(result::Ok(copy config))
            |output_format| {
            do result::chain(parse_output_format(*output_format))
                |output_format| {

                result::Ok(Config {
                    output_format: output_format,
                    .. copy config
                })
            }
        }
    };
    let result = do result::chain(result) |config| {
        let output_style =
            getopts::opt_maybe_str(matches, opt_output_style());
        do output_style.map_default(result::Ok(copy config))
            |output_style| {
            do result::chain(parse_output_style(*output_style))
                |output_style| {
                result::Ok(Config {
                    output_style: output_style,
                    .. copy config
                })
            }
        }
    };
    let process_output = Cell::new(process_output);
    let result = do result::chain(result) |config| {
        let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
        let pandoc_cmd = maybe_find_pandoc(
            &config, pandoc_cmd, process_output.take());
        do result::chain(pandoc_cmd) |pandoc_cmd| {
            result::Ok(Config {
                pandoc_cmd: pandoc_cmd,
                .. copy config
            })
        }
    };
    return result;
}

fn parse_output_format(output_format: &str) -> Result<OutputFormat, ~str> {
    match output_format.to_str() {
      ~"markdown" => result::Ok(Markdown),
      ~"html" => result::Ok(PandocHtml),
      _ => result::Err(fmt!("unknown output format '%s'", output_format))
    }
}

fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
    match output_style.to_str() {
      ~"doc-per-crate" => result::Ok(DocPerCrate),
      ~"doc-per-mod" => result::Ok(DocPerMod),
      _ => result::Err(fmt!("unknown output style '%s'", output_style))
    }
}

pub fn maybe_find_pandoc(
    config: &Config,
    maybe_pandoc_cmd: Option<~str>,
    process_output: Process
) -> Result<Option<~str>, ~str> {
    if config.output_format != PandocHtml {
        return result::Ok(maybe_pandoc_cmd);
    }

    let possible_pandocs = match maybe_pandoc_cmd {
      Some(pandoc_cmd) => ~[pandoc_cmd],
      None => {
        ~[~"pandoc"] + match os::homedir() {
          Some(dir) => {
            ~[dir.push_rel(&Path(".cabal/bin/pandoc")).to_str()]
          }
          None => ~[]
        }
      }
    };

    let pandoc = do vec::find(possible_pandocs) |pandoc| {
        let output = process_output(*pandoc, [~"--version"]);
        debug!("testing pandoc cmd %s: %?", *pandoc, output);
        output.status == 0
    };

    if pandoc.is_some() {
        result::Ok(pandoc)
    } else {
        result::Err(~"couldn't find pandoc")
    }
}

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

    use config::*;
    use core::result;
    use core::run::ProcessOutput;

    fn parse_config(args: &[~str]) -> Result<Config, ~str> {
        parse_config_(args, mock_process_output)
    }

    #[test]
    fn should_find_pandoc() {
        let config = Config {
            output_format: PandocHtml,
            .. default_config(&Path("test"))
        };
        let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
            ProcessOutput { status: 0, output: "pandoc 1.8.2.1".as_bytes().to_owned(), error: ~[] }
        };
        let result = maybe_find_pandoc(&config, None, mock_process_output);
        assert!(result == result::Ok(Some(~"pandoc")));
    }

    #[test]
    fn should_error_with_no_pandoc() {
        let config = Config {
            output_format: PandocHtml,
            .. default_config(&Path("test"))
        };
        let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
            ProcessOutput { status: 1, output: ~[], error: ~[] }
        };
        let result = maybe_find_pandoc(&config, None, mock_process_output);
        assert!(result == result::Err(~"couldn't find pandoc"));
    }

    #[test]
    fn should_error_with_no_crates() {
        let config = parse_config([~"rustdoc"]);
        assert!(config.get_err() == ~"no crates specified");
    }

    #[test]
    fn should_error_with_multiple_crates() {
        let config =
            parse_config([~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
        assert!(config.get_err() == ~"multiple crates specified");
    }

    #[test]
    fn should_set_output_dir_to_cwd_if_not_provided() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().output_dir == Path("."));
    }

    #[test]
    fn should_set_output_dir_if_provided() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
        ]);
        assert!(config.get().output_dir == Path("snuggles"));
    }

    #[test]
    fn should_set_output_format_to_pandoc_html_if_not_provided() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().output_format == PandocHtml);
    }

    #[test]
    fn should_set_output_format_to_markdown_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
        ]);
        assert!(config.get().output_format == Markdown);
    }

    #[test]
    fn should_set_output_format_to_pandoc_html_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
        ]);
        assert!(config.get().output_format == PandocHtml);
    }

    #[test]
    fn should_error_on_bogus_format() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
        ]);
        assert!(config.get_err() == ~"unknown output format 'bogus'");
    }

    #[test]
    fn should_set_output_style_to_doc_per_mod_by_default() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().output_style == DocPerMod);
    }

    #[test]
    fn should_set_output_style_to_one_doc_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
        ]);
        assert!(config.get().output_style == DocPerCrate);
    }

    #[test]
    fn should_set_output_style_to_doc_per_mod_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
        ]);
        assert!(config.get().output_style == DocPerMod);
    }

    #[test]
    fn should_error_on_bogus_output_style() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
        ]);
        assert!(config.get_err() == ~"unknown output style 'bogus'");
    }

    #[test]
    fn should_set_pandoc_command_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
        ]);
        assert!(config.get().pandoc_cmd == Some(~"panda-bear-doc"));
    }

    #[test]
    fn should_set_pandoc_command_when_using_pandoc() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().pandoc_cmd == Some(~"pandoc"));
    }
}
<commit_msg>Show defaults in rustdoc usage message<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use core::cell::Cell;
use core::os;
use core::result::Result;
use core::result;
use core::run::ProcessOutput;
use core::run;
use core::vec;
use extra::getopts;

/// The type of document to output
#[deriving(Eq)]
pub enum OutputFormat {
    /// Markdown
    pub Markdown,
    /// HTML, via markdown and pandoc
    pub PandocHtml
}

/// How to organize the output
#[deriving(Eq)]
pub enum OutputStyle {
    /// All in a single document
    pub DocPerCrate,
    /// Each module in its own document
    pub DocPerMod
}

/// The configuration for a rustdoc session
pub struct Config {
    input_crate: Path,
    output_dir: Path,
    output_format: OutputFormat,
    output_style: OutputStyle,
    pandoc_cmd: Option<~str>
}

impl Clone for Config {
    fn clone(&self) -> Config { copy *self }
}

fn opt_output_dir() -> ~str { ~"output-dir" }
fn opt_output_format() -> ~str { ~"output-format" }
fn opt_output_style() -> ~str { ~"output-style" }
fn opt_pandoc_cmd() -> ~str { ~"pandoc-cmd" }
fn opt_help() -> ~str { ~"h" }

fn opts() -> ~[(getopts::Opt, ~str)] {
    ~[
        (getopts::optopt(opt_output_dir()),
         ~"--output-dir <val>     Put documents here (default: .)"),
        (getopts::optopt(opt_output_format()),
         ~"--output-format <val>  'markdown' or 'html' (default)"),
        (getopts::optopt(opt_output_style()),
         ~"--output-style <val>   'doc-per-crate' or 'doc-per-mod' (default)"),
        (getopts::optopt(opt_pandoc_cmd()),
         ~"--pandoc-cmd <val>     Command for running pandoc"),
        (getopts::optflag(opt_help()),
         ~"-h, --help             Print help")
    ]
}

pub fn usage() {
    use core::io::println;

    println("Usage: rustdoc [options] <cratefile>\n");
    println("Options:\n");
    for opts().each |opt| {
        println(fmt!("    %s", opt.second()));
    }
    println("");
}

pub fn default_config(input_crate: &Path) -> Config {
    Config {
        input_crate: copy *input_crate,
        output_dir: Path("."),
        output_format: PandocHtml,
        output_style: DocPerMod,
        pandoc_cmd: None
    }
}

type Process = ~fn((&str), (&[~str])) -> ProcessOutput;

pub fn mock_process_output(_prog: &str, _args: &[~str]) -> ProcessOutput {
    ProcessOutput {
        status: 0,
        output: ~[],
        error: ~[]
    }
}

pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
    run::process_output(prog, args)
}

pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
    parse_config_(args, process_output)
}

pub fn parse_config_(
    args: &[~str],
    process_output: Process
) -> Result<Config, ~str> {
    let args = args.tail();
    let opts = vec::unzip(opts()).first();
    match getopts::getopts(args, opts) {
        Ok(matches) => {
            if matches.free.len() == 1 {
                let input_crate = Path(*matches.free.head());
                config_from_opts(&input_crate, &matches, process_output)
            } else if matches.free.is_empty() {
                Err(~"no crates specified")
            } else {
                Err(~"multiple crates specified")
            }
        }
        Err(f) => {
            Err(getopts::fail_str(f))
        }
    }
}

fn config_from_opts(
    input_crate: &Path,
    matches: &getopts::Matches,
    process_output: Process
) -> Result<Config, ~str> {

    let config = default_config(input_crate);
    let result = result::Ok(config);
    let result = do result::chain(result) |config| {
        let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
        let output_dir = output_dir.map(|s| Path(*s));
        result::Ok(Config {
            output_dir: output_dir.get_or_default(copy config.output_dir),
            .. config
        })
    };
    let result = do result::chain(result) |config| {
        let output_format = getopts::opt_maybe_str(
            matches, opt_output_format());
        do output_format.map_default(result::Ok(copy config))
            |output_format| {
            do result::chain(parse_output_format(*output_format))
                |output_format| {

                result::Ok(Config {
                    output_format: output_format,
                    .. copy config
                })
            }
        }
    };
    let result = do result::chain(result) |config| {
        let output_style =
            getopts::opt_maybe_str(matches, opt_output_style());
        do output_style.map_default(result::Ok(copy config))
            |output_style| {
            do result::chain(parse_output_style(*output_style))
                |output_style| {
                result::Ok(Config {
                    output_style: output_style,
                    .. copy config
                })
            }
        }
    };
    let process_output = Cell::new(process_output);
    let result = do result::chain(result) |config| {
        let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
        let pandoc_cmd = maybe_find_pandoc(
            &config, pandoc_cmd, process_output.take());
        do result::chain(pandoc_cmd) |pandoc_cmd| {
            result::Ok(Config {
                pandoc_cmd: pandoc_cmd,
                .. copy config
            })
        }
    };
    return result;
}

fn parse_output_format(output_format: &str) -> Result<OutputFormat, ~str> {
    match output_format.to_str() {
      ~"markdown" => result::Ok(Markdown),
      ~"html" => result::Ok(PandocHtml),
      _ => result::Err(fmt!("unknown output format '%s'", output_format))
    }
}

fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
    match output_style.to_str() {
      ~"doc-per-crate" => result::Ok(DocPerCrate),
      ~"doc-per-mod" => result::Ok(DocPerMod),
      _ => result::Err(fmt!("unknown output style '%s'", output_style))
    }
}

pub fn maybe_find_pandoc(
    config: &Config,
    maybe_pandoc_cmd: Option<~str>,
    process_output: Process
) -> Result<Option<~str>, ~str> {
    if config.output_format != PandocHtml {
        return result::Ok(maybe_pandoc_cmd);
    }

    let possible_pandocs = match maybe_pandoc_cmd {
      Some(pandoc_cmd) => ~[pandoc_cmd],
      None => {
        ~[~"pandoc"] + match os::homedir() {
          Some(dir) => {
            ~[dir.push_rel(&Path(".cabal/bin/pandoc")).to_str()]
          }
          None => ~[]
        }
      }
    };

    let pandoc = do vec::find(possible_pandocs) |pandoc| {
        let output = process_output(*pandoc, [~"--version"]);
        debug!("testing pandoc cmd %s: %?", *pandoc, output);
        output.status == 0
    };

    if pandoc.is_some() {
        result::Ok(pandoc)
    } else {
        result::Err(~"couldn't find pandoc")
    }
}

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

    use config::*;
    use core::result;
    use core::run::ProcessOutput;

    fn parse_config(args: &[~str]) -> Result<Config, ~str> {
        parse_config_(args, mock_process_output)
    }

    #[test]
    fn should_find_pandoc() {
        let config = Config {
            output_format: PandocHtml,
            .. default_config(&Path("test"))
        };
        let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
            ProcessOutput { status: 0, output: "pandoc 1.8.2.1".as_bytes().to_owned(), error: ~[] }
        };
        let result = maybe_find_pandoc(&config, None, mock_process_output);
        assert!(result == result::Ok(Some(~"pandoc")));
    }

    #[test]
    fn should_error_with_no_pandoc() {
        let config = Config {
            output_format: PandocHtml,
            .. default_config(&Path("test"))
        };
        let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
            ProcessOutput { status: 1, output: ~[], error: ~[] }
        };
        let result = maybe_find_pandoc(&config, None, mock_process_output);
        assert!(result == result::Err(~"couldn't find pandoc"));
    }

    #[test]
    fn should_error_with_no_crates() {
        let config = parse_config([~"rustdoc"]);
        assert!(config.get_err() == ~"no crates specified");
    }

    #[test]
    fn should_error_with_multiple_crates() {
        let config =
            parse_config([~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
        assert!(config.get_err() == ~"multiple crates specified");
    }

    #[test]
    fn should_set_output_dir_to_cwd_if_not_provided() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().output_dir == Path("."));
    }

    #[test]
    fn should_set_output_dir_if_provided() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
        ]);
        assert!(config.get().output_dir == Path("snuggles"));
    }

    #[test]
    fn should_set_output_format_to_pandoc_html_if_not_provided() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().output_format == PandocHtml);
    }

    #[test]
    fn should_set_output_format_to_markdown_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
        ]);
        assert!(config.get().output_format == Markdown);
    }

    #[test]
    fn should_set_output_format_to_pandoc_html_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
        ]);
        assert!(config.get().output_format == PandocHtml);
    }

    #[test]
    fn should_error_on_bogus_format() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
        ]);
        assert!(config.get_err() == ~"unknown output format 'bogus'");
    }

    #[test]
    fn should_set_output_style_to_doc_per_mod_by_default() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().output_style == DocPerMod);
    }

    #[test]
    fn should_set_output_style_to_one_doc_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
        ]);
        assert!(config.get().output_style == DocPerCrate);
    }

    #[test]
    fn should_set_output_style_to_doc_per_mod_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
        ]);
        assert!(config.get().output_style == DocPerMod);
    }

    #[test]
    fn should_error_on_bogus_output_style() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
        ]);
        assert!(config.get_err() == ~"unknown output style 'bogus'");
    }

    #[test]
    fn should_set_pandoc_command_if_requested() {
        let config = parse_config([
            ~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
        ]);
        assert!(config.get().pandoc_cmd == Some(~"panda-bear-doc"));
    }

    #[test]
    fn should_set_pandoc_command_when_using_pandoc() {
        let config = parse_config([~"rustdoc", ~"crate.rc"]);
        assert!(config.get().pandoc_cmd == Some(~"pandoc"));
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*
 * The compiler code necessary to support the env! extension.  Eventually this
 * should all get sucked into either the compiler syntax extension plugin
 * interface.
 */

use ast;
use codemap::Span;
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
use parse::token;

use std::env;
use std::os;

pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                              -> Box<base::MacResult+'cx> {
    let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
        None => return DummyResult::expr(sp),
        Some(v) => v
    };

    let e = match env::var_string(&var[]) {
      Err(..) => {
          cx.expr_path(cx.path_all(sp,
                                   true,
                                   vec!(cx.ident_of("std"),
                                        cx.ident_of("option"),
                                        cx.ident_of("Option"),
                                        cx.ident_of("None")),
                                   Vec::new(),
                                   vec!(cx.ty_rptr(sp,
                                                   cx.ty_ident(sp,
                                                        cx.ident_of("str")),
                                                   Some(cx.lifetime(sp,
                                                        cx.ident_of(
                                                            "'static").name)),
                                                   ast::MutImmutable)),
                                   Vec::new()))
      }
      Ok(s) => {
          cx.expr_call_global(sp,
                              vec!(cx.ident_of("std"),
                                   cx.ident_of("option"),
                                   cx.ident_of("Option"),
                                   cx.ident_of("Some")),
                              vec!(cx.expr_str(sp,
                                               token::intern_and_get_ident(
                                          &s[]))))
      }
    };
    MacExpr::new(e)
}

pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                       -> Box<base::MacResult+'cx> {
    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
        Some(ref exprs) if exprs.len() == 0 => {
            cx.span_err(sp, "env! takes 1 or 2 arguments");
            return DummyResult::expr(sp);
        }
        None => return DummyResult::expr(sp),
        Some(exprs) => exprs.into_iter()
    };

    let var = match expr_to_string(cx,
                                exprs.next().unwrap(),
                                "expected string literal") {
        None => return DummyResult::expr(sp),
        Some((v, _style)) => v
    };
    let msg = match exprs.next() {
        None => {
            token::intern_and_get_ident(&format!("environment variable `{}` \
                                                 not defined",
                                                var)[])
        }
        Some(second) => {
            match expr_to_string(cx, second, "expected string literal") {
                None => return DummyResult::expr(sp),
                Some((s, _style)) => s
            }
        }
    };

    match exprs.next() {
        None => {}
        Some(_) => {
            cx.span_err(sp, "env! takes 1 or 2 arguments");
            return DummyResult::expr(sp);
        }
    }

    let e = match os::getenv(&var) {
        None => {
            cx.span_err(sp, &msg);
            cx.expr_usize(sp, 0)
        }
        Some(s) => cx.expr_str(sp, token::intern_and_get_ident(&s))
    };
    MacExpr::new(e)
}
<commit_msg>Remove getenv warning<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*
 * The compiler code necessary to support the env! extension.  Eventually this
 * should all get sucked into either the compiler syntax extension plugin
 * interface.
 */

use ast;
use codemap::Span;
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
use parse::token;

use std::env;

pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                              -> Box<base::MacResult+'cx> {
    let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
        None => return DummyResult::expr(sp),
        Some(v) => v
    };

    let e = match env::var_string(&var[]) {
      Err(..) => {
          cx.expr_path(cx.path_all(sp,
                                   true,
                                   vec!(cx.ident_of("std"),
                                        cx.ident_of("option"),
                                        cx.ident_of("Option"),
                                        cx.ident_of("None")),
                                   Vec::new(),
                                   vec!(cx.ty_rptr(sp,
                                                   cx.ty_ident(sp,
                                                        cx.ident_of("str")),
                                                   Some(cx.lifetime(sp,
                                                        cx.ident_of(
                                                            "'static").name)),
                                                   ast::MutImmutable)),
                                   Vec::new()))
      }
      Ok(s) => {
          cx.expr_call_global(sp,
                              vec!(cx.ident_of("std"),
                                   cx.ident_of("option"),
                                   cx.ident_of("Option"),
                                   cx.ident_of("Some")),
                              vec!(cx.expr_str(sp,
                                               token::intern_and_get_ident(
                                          &s[]))))
      }
    };
    MacExpr::new(e)
}

pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                       -> Box<base::MacResult+'cx> {
    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
        Some(ref exprs) if exprs.len() == 0 => {
            cx.span_err(sp, "env! takes 1 or 2 arguments");
            return DummyResult::expr(sp);
        }
        None => return DummyResult::expr(sp),
        Some(exprs) => exprs.into_iter()
    };

    let var = match expr_to_string(cx,
                                exprs.next().unwrap(),
                                "expected string literal") {
        None => return DummyResult::expr(sp),
        Some((v, _style)) => v
    };
    let msg = match exprs.next() {
        None => {
            token::intern_and_get_ident(&format!("environment variable `{}` \
                                                 not defined",
                                                var)[])
        }
        Some(second) => {
            match expr_to_string(cx, second, "expected string literal") {
                None => return DummyResult::expr(sp),
                Some((s, _style)) => s
            }
        }
    };

    match exprs.next() {
        None => {}
        Some(_) => {
            cx.span_err(sp, "env! takes 1 or 2 arguments");
            return DummyResult::expr(sp);
        }
    }

    let e = match env::var_string(&var[]) {
        Err(_) => {
            cx.span_err(sp, &msg);
            cx.expr_usize(sp, 0)
        }
        Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s))
    };
    MacExpr::new(e)
}
<|endoftext|>


<commit_before><commit_msg>map boundaries set<commit_after><|endoftext|>


<commit_before>extern crate rustie;

use rustie::cli::Runner;

fn main() {
    Runner::run();
}
<commit_msg>basic binary implementation - run with cli argument or use "." as default path<commit_after>extern crate rustie;

use rustie::cli::Runner;
use std::os;

fn main() {
    let args        = os::args();
    let use_default = args.len() == 1u;

    if use_default {
        Runner::run(".");
    } else {
        Runner::run(args[1].as_slice());
    }
}
<|endoftext|>


<commit_before><commit_msg>Setting things back to basics<commit_after><|endoftext|>


<commit_before><commit_msg>day 8 part 2<commit_after><|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate piston_window;
extern crate time;
extern crate rand;
extern crate ai_behavior;
extern crate cgmath;
extern crate opengl_graphics;

mod app;
mod camera;
mod entity;
mod player;
mod config;

use piston_window::{ PistonWindow, WindowSettings };
use piston::input::*;
use piston::event_loop::*;
use opengl_graphics::*;
use graphics::{ Image, clear, default_draw_state };
use graphics::rectangle::square;
use std::path::Path;

use cgmath::rad;
use cgmath::{ Vector2, Vector4 };
use cgmath::{ Rotation2, Basis2 };

fn main() {
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow = WindowSettings::new("GGJ2016", [800, 600])
        .exit_on_esc(true)
        .opengl(opengl)
        .build()
        .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
    window.set_ups(60);
    let mut gl = GlGraphics::new(opengl);

    let mut app = app::App::new();

    // Add player to entities (player instanciated in app)
    //app.add_entity(Box::new(player::Player::new()));

    let image = Image::new().rect(square(0.0, 0.0, 200.0));
    let texture = Texture::from_path(Path::new("assets/img/emoji/60.png")).unwrap();

    for e in window {
        if let Some(args) = e.press_args() {
            app.key_press(args);
        }

        if let Some(args) = e.update_args() {
            app.update(args);
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, gl| {
                clear([0.5, 0.2, 0.9, 1.0], gl);
                image.draw(&texture, default_draw_state(), c.transform, gl);
            });
            app.render(args);
        }
    }
}
<commit_msg>Added ground rendering<commit_after>extern crate piston;
extern crate graphics;
extern crate piston_window;
extern crate time;
extern crate rand;
extern crate ai_behavior;
extern crate cgmath;
extern crate opengl_graphics;

mod app;
mod camera;
mod entity;
mod player;
mod config;

use piston_window::{ PistonWindow, WindowSettings };
use piston::input::*;
use piston::event_loop::*;
use opengl_graphics::*;
use graphics::{ Image, clear, default_draw_state };
use graphics::rectangle::square;
use std::path::Path;

use cgmath::rad;
use cgmath::{ Vector2, Vector4 };
use cgmath::{ Rotation2, Basis2 };

fn draw_background(x: u32, y: u32, context: graphics::context::Context, gl_graphics: &mut GlGraphics, txt: &Texture) {
    let (width, height) = txt.get_size();
    for i in 0..x + 1 {
        for j in 0..y + 1 {
            let image = Image::new().rect(square((i * width) as f64, (j * height) as f64, width as f64));
            image.draw(txt, default_draw_state(), context.transform, gl_graphics);
        }
    }
}

fn main() {
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow = WindowSettings::new("GGJ2016", [800, 600])
        .exit_on_esc(true)
        .opengl(opengl)
        .build()
        .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
    window.set_ups(60);
    let mut gl = GlGraphics::new(opengl);

    let mut app = app::App::new();
    let size_image = 160;
    // Add player to entities (player instanciated in app)
    //app.add_entity(Box::new(player::Player::new()));

    let texture = Texture::from_path(Path::new("assets/img/ground/placeholder_01.jpg")).unwrap();

    for e in window {
        if let Some(args) = e.press_args() {
            app.key_press(args);
        }

        if let Some(args) = e.update_args() {
            app.update(args);
        }

        if let Some(args) = e.render_args() {
            let grid_width = args.width / size_image;
            let grid_height = args.height / size_image;
            gl.draw(args.viewport(), |c, gl| {
                clear([0.5, 0.2, 0.9, 1.0], gl);
                draw_background(grid_width, grid_height, c, gl, &texture);
            });
            app.render(args);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Move metrics handler to top level.<commit_after><|endoftext|>


<commit_before><commit_msg>Add test: check whether imag-init creates store path<commit_after><|endoftext|>