<commit_before>use cql_ffi::ssl::Ssl;
use cql_bindgen::CassCluster as _Cluster;
use std::ffi::CString;

use cql_bindgen::cass_cluster_new;
use cql_bindgen::cass_cluster_free;
use cql_bindgen::cass_cluster_set_contact_points;
use cql_bindgen::cass_cluster_set_port;
use cql_bindgen::cass_cluster_set_ssl;
use cql_bindgen::cass_cluster_set_protocol_version;
use cql_bindgen::cass_cluster_set_num_threads_io;
use cql_bindgen::cass_cluster_set_queue_size_io;
use cql_bindgen::cass_cluster_set_queue_size_event;
use cql_bindgen::cass_cluster_set_queue_size_log;
use cql_bindgen::cass_cluster_set_core_connections_per_host;
use cql_bindgen::cass_cluster_set_max_connections_per_host;
use cql_bindgen::cass_cluster_set_reconnect_wait_time;
use cql_bindgen::cass_cluster_set_max_concurrent_creation;
use cql_bindgen::cass_cluster_set_max_concurrent_requests_threshold;
use cql_bindgen::cass_cluster_set_max_requests_per_flush;
use cql_bindgen::cass_cluster_set_write_bytes_high_water_mark;
use cql_bindgen::cass_cluster_set_write_bytes_low_water_mark;
use cql_bindgen::cass_cluster_set_pending_requests_high_water_mark;
use cql_bindgen::cass_cluster_set_pending_requests_low_water_mark;
use cql_bindgen::cass_cluster_set_tcp_keepalive;
use cql_bindgen::cass_cluster_set_tcp_nodelay;
use cql_bindgen::cass_cluster_set_token_aware_routing;
use cql_bindgen::cass_cluster_set_load_balance_dc_aware;
use cql_bindgen::cass_cluster_set_load_balance_round_robin;
use cql_bindgen::cass_cluster_set_credentials;
use cql_bindgen::cass_cluster_set_request_timeout;
use cql_bindgen::cass_cluster_set_connect_timeout;
use cql_bindgen::cass_cluster_set_latency_aware_routing;
use cql_bindgen::cass_cluster_set_latency_aware_routing_settings;

use cql_ffi::error::CassandraError;

use cql_ffi::session::Session;

///
/// The main class to use when interacting with a Cassandra cluster.
/// Typically, one instance of this class will be created for each separate Cassandra cluster that your application interacts with.
///
/// # Examples
/// ```
/// let mut cluster = Cluster::new();
/// cluster.set_contact_points("127.0.0.1").unwrap();
/// let mut session = cluster.connect().unwrap();
/// ```
pub struct Cluster(pub *mut _Cluster);

impl Drop for Cluster {
    fn drop(&mut self) {
        unsafe {
            cass_cluster_free(self.0)
        }
    }
}

impl Cluster {

    pub fn new() -> Cluster {
        unsafe {
            Cluster(cass_cluster_new())
        }
    }

    pub fn set_contact_points<S>(&mut self, contact_points: S) -> Result<&mut Self, CassandraError>
        where S: Into<String>
    {
        unsafe {
            let s = CString::new(contact_points.into()).unwrap();
            let err = CassandraError::build(cass_cluster_set_contact_points(self.0, s.as_ptr()));
            err.wrap(self)
        }
    }

    pub fn set_port(&mut self, port: i32) -> Result<&mut Self, CassandraError> {
        unsafe {
            CassandraError::build(cass_cluster_set_port(self.0,port)).wrap(self)
        }
    }

    pub fn set_ssl(&mut self, ssl: &mut Ssl) -> &Self {
        unsafe {
            cass_cluster_set_ssl(self.0, ssl.0);
            self
        }
    }
    /// Connect to Cassandra cluster
    pub fn connect(&mut self) -> Result<Session, CassandraError> {
        Session::new().connect(&self).wait()
    }

    pub fn set_protocol_version(&mut self, protocol_version: i32) -> Result<&mut Self, CassandraError> {
        unsafe {
            CassandraError::build(cass_cluster_set_protocol_version(self.0,protocol_version)).wrap(self)
        }
    }

    pub fn set_num_threads_io(&mut self, num_threads: u32) -> Result<&Self, CassandraError> {
        unsafe {
            CassandraError::build(cass_cluster_set_num_threads_io(self.0,num_threads)).wrap(self)
        }
    }

    pub unsafe fn set_queue_size_io(&mut self, queue_size: u32) -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_queue_size_io(self.0,queue_size)).wrap(self)
    }

    pub unsafe fn set_queue_size_event(&mut self, queue_size: u32) -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_queue_size_event(self.0,queue_size)).wrap(self)
    }

    pub unsafe fn set_queue_size_log(&mut self, queue_size: u32) -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_queue_size_log(self.0,queue_size)).wrap(self)
    }

    pub unsafe fn set_core_connections_per_host(&mut self,
                                                num_connections: u32)
                                                -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_core_connections_per_host(
                self.0,
                num_connections
            )
        ).wrap(self)
    }

    pub unsafe fn set_max_connections_per_host(&mut self,
                                               num_connections: u32)
                                               -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_max_connections_per_host(
                self.0,
                num_connections
            )
        ).wrap(self)
    }

    pub unsafe fn set_reconnect_wait_time(&mut self, wait_time: u32) -> &Self {
        cass_cluster_set_reconnect_wait_time(self.0, wait_time);
        self
    }

    pub unsafe fn set_max_concurrent_creation(&mut self,
                                              num_connections: u32)
                                              -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_max_concurrent_creation(
                self.0,
                num_connections
            )
        ).wrap(self)
    }

    pub unsafe fn set_max_concurrent_requests_threshold(&mut self,
                                                        num_requests: u32)
                                                        -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_max_concurrent_requests_threshold(
                self.0,
                num_requests
            )
        ).wrap(self)
    }

    pub unsafe fn set_max_requests_per_flush(&mut self,
                                             num_requests: u32)
                                             -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_max_requests_per_flush(self.0,num_requests)).wrap(self)
    }

    pub unsafe fn set_write_bytes_high_water_mark(&mut self,
                                                  num_bytes: u32)
                                                  -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_write_bytes_high_water_mark(self.0,num_bytes)).wrap(self)
    }

    pub unsafe fn set_write_bytes_low_water_mark(&mut self,
                                                 num_bytes: u32)
                                                 -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_write_bytes_low_water_mark(self.0,num_bytes)).wrap(self)
    }

    pub unsafe fn set_pending_requests_high_water_mark(&mut self,
                                                       num_requests: u32)
                                                       -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_pending_requests_high_water_mark(
                self.0,num_requests
            )
        ).wrap(self)
    }

    pub unsafe fn set_pending_requests_low_water_mark(&mut self,
                                                      num_requests: u32)
                                                      -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_pending_requests_low_water_mark(
                self.0,
                num_requests
            )
        ).wrap(self)
    }

    pub unsafe fn set_connect_timeout(&mut self, timeout_ms: u32) -> &Self {
        cass_cluster_set_connect_timeout(self.0, timeout_ms);
        self
    }

    pub unsafe fn set_request_timeout(&mut self, timeout_ms: u32) -> &Self {
        cass_cluster_set_request_timeout(self.0, timeout_ms);
        self
    }

    pub unsafe fn set_credentials(&mut self, username: *const i8, password: *const i8) -> &Self {
        cass_cluster_set_credentials(self.0, username, password);
        self
    }

    pub fn set_load_balance_round_robin(&mut self) -> Result<&Self, CassandraError> {
        unsafe {
            cass_cluster_set_load_balance_round_robin(self.0);
            CassandraError::build(0).wrap(self)
        }
    }

    pub fn set_load_balance_dc_aware<S>(&mut self,
                                        local_dc: S,
                                        used_hosts_per_remote_dc: u32,
                                        allow_remote_dcs_for_local_cl: bool)
                                        -> Result<&Self, CassandraError>
        where S: Into<String>
    {
        unsafe {
            CassandraError::build({
            let local_dc = CString::new(local_dc.into()).unwrap();
            cass_cluster_set_load_balance_dc_aware(
                self.0,local_dc.as_ptr(),
                used_hosts_per_remote_dc,
                if allow_remote_dcs_for_local_cl {1} else {0}
            )
        }).wrap(self)
        }
    }

    pub unsafe fn set_token_aware_routing(&mut self, enabled: bool) -> &Self {
        cass_cluster_set_token_aware_routing(self.0,
                                             if enabled {
                1
            } else {
                0
            });
        self
    }

    pub fn set_tcp_nodelay(&mut self, enable: bool) -> &Self {
        unsafe {
            cass_cluster_set_tcp_nodelay(self.0,
                                         if enable {
                    1
                } else {
                    0
                });
            self
        }
    }

    pub unsafe fn set_tcp_keepalive(&mut self, enable: bool, delay_secs: u32) -> &Self {
        cass_cluster_set_tcp_keepalive(self.0,
                                       if enable {
                1
            } else {
                0
            },
                                       delay_secs);
        self
    }

    pub fn set_latency_aware_routing(&mut self, enabled: bool) -> &Self {
        unsafe {
            cass_cluster_set_latency_aware_routing(self.0,
                                                   if enabled {
                    1
                } else {
                    0
                });
            self
        }
    }

    pub fn cass_cluster_set_latency_aware_routing_settings(&mut self,
                                                           exclusion_threshold: f64,
                                                           scale_ms: u64,
                                                           retry_period_ms: u64,
                                                           update_rate_ms: u64,
                                                           min_measured: u64)
                                                           -> &Self {
        unsafe {
            cass_cluster_set_latency_aware_routing_settings(self.0,
                                                            exclusion_threshold,
                                                            scale_ms,
                                                            retry_period_ms,
                                                            update_rate_ms,
                                                            min_measured);
            self
        }
    }

}
<commit_msg>turns out you can just cast a bool to an int. much cleaner<commit_after>use cql_ffi::ssl::Ssl;
use cql_bindgen::CassCluster as _Cluster;
use std::ffi::CString;

use cql_bindgen::cass_cluster_new;
use cql_bindgen::cass_cluster_free;
use cql_bindgen::cass_cluster_set_contact_points;
use cql_bindgen::cass_cluster_set_port;
use cql_bindgen::cass_cluster_set_ssl;
use cql_bindgen::cass_cluster_set_protocol_version;
use cql_bindgen::cass_cluster_set_num_threads_io;
use cql_bindgen::cass_cluster_set_queue_size_io;
use cql_bindgen::cass_cluster_set_queue_size_event;
use cql_bindgen::cass_cluster_set_queue_size_log;
use cql_bindgen::cass_cluster_set_core_connections_per_host;
use cql_bindgen::cass_cluster_set_max_connections_per_host;
use cql_bindgen::cass_cluster_set_reconnect_wait_time;
use cql_bindgen::cass_cluster_set_max_concurrent_creation;
use cql_bindgen::cass_cluster_set_max_concurrent_requests_threshold;
use cql_bindgen::cass_cluster_set_max_requests_per_flush;
use cql_bindgen::cass_cluster_set_write_bytes_high_water_mark;
use cql_bindgen::cass_cluster_set_write_bytes_low_water_mark;
use cql_bindgen::cass_cluster_set_pending_requests_high_water_mark;
use cql_bindgen::cass_cluster_set_pending_requests_low_water_mark;
use cql_bindgen::cass_cluster_set_tcp_keepalive;
use cql_bindgen::cass_cluster_set_tcp_nodelay;
use cql_bindgen::cass_cluster_set_token_aware_routing;
use cql_bindgen::cass_cluster_set_load_balance_dc_aware;
use cql_bindgen::cass_cluster_set_load_balance_round_robin;
use cql_bindgen::cass_cluster_set_credentials;
use cql_bindgen::cass_cluster_set_request_timeout;
use cql_bindgen::cass_cluster_set_connect_timeout;
use cql_bindgen::cass_cluster_set_latency_aware_routing;
use cql_bindgen::cass_cluster_set_latency_aware_routing_settings;

use cql_ffi::error::CassandraError;

use cql_ffi::session::Session;

///
/// The main class to use when interacting with a Cassandra cluster.
/// Typically, one instance of this class will be created for each separate Cassandra cluster that your application interacts with.
///
/// # Examples
/// ```
/// let mut cluster = Cluster::new();
/// cluster.set_contact_points("127.0.0.1").unwrap();
/// let mut session = cluster.connect().unwrap();
/// ```
pub struct Cluster(pub *mut _Cluster);

impl Drop for Cluster {
    fn drop(&mut self) {
        unsafe {
            cass_cluster_free(self.0)
        }
    }
}

impl Cluster {

    pub fn new() -> Cluster {
        unsafe {
            Cluster(cass_cluster_new())
        }
    }

    pub fn set_contact_points<S>(&mut self, contact_points: S) -> Result<&mut Self, CassandraError>
        where S: Into<String>
    {
        unsafe {
            let s = CString::new(contact_points.into()).unwrap();
            let err = CassandraError::build(cass_cluster_set_contact_points(self.0, s.as_ptr()));
            err.wrap(self)
        }
    }

    pub fn set_port(&mut self, port: i32) -> Result<&mut Self, CassandraError> {
        unsafe {
            CassandraError::build(cass_cluster_set_port(self.0,port)).wrap(self)
        }
    }

    pub fn set_ssl(&mut self, ssl: &mut Ssl) -> &Self {
        unsafe {
            cass_cluster_set_ssl(self.0, ssl.0);
            self
        }
    }
    /// Connect to Cassandra cluster
    pub fn connect(&mut self) -> Result<Session, CassandraError> {
        Session::new().connect(&self).wait()
    }

    pub fn set_protocol_version(&mut self, protocol_version: i32) -> Result<&mut Self, CassandraError> {
        unsafe {
            CassandraError::build(cass_cluster_set_protocol_version(self.0,protocol_version)).wrap(self)
        }
    }

    pub fn set_num_threads_io(&mut self, num_threads: u32) -> Result<&Self, CassandraError> {
        unsafe {
            CassandraError::build(cass_cluster_set_num_threads_io(self.0,num_threads)).wrap(self)
        }
    }

    pub unsafe fn set_queue_size_io(&mut self, queue_size: u32) -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_queue_size_io(self.0,queue_size)).wrap(self)
    }

    pub unsafe fn set_queue_size_event(&mut self, queue_size: u32) -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_queue_size_event(self.0,queue_size)).wrap(self)
    }

    pub unsafe fn set_queue_size_log(&mut self, queue_size: u32) -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_queue_size_log(self.0,queue_size)).wrap(self)
    }

    pub unsafe fn set_core_connections_per_host(&mut self,
                                                num_connections: u32)
                                                -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_core_connections_per_host(
                self.0,
                num_connections
            )
        ).wrap(self)
    }

    pub unsafe fn set_max_connections_per_host(&mut self,
                                               num_connections: u32)
                                               -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_max_connections_per_host(
                self.0,
                num_connections
            )
        ).wrap(self)
    }

    pub unsafe fn set_reconnect_wait_time(&mut self, wait_time: u32) -> &Self {
        cass_cluster_set_reconnect_wait_time(self.0, wait_time);
        self
    }

    pub unsafe fn set_max_concurrent_creation(&mut self,
                                              num_connections: u32)
                                              -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_max_concurrent_creation(
                self.0,
                num_connections
            )
        ).wrap(self)
    }

    pub unsafe fn set_max_concurrent_requests_threshold(&mut self,
                                                        num_requests: u32)
                                                        -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_max_concurrent_requests_threshold(
                self.0,
                num_requests
            )
        ).wrap(self)
    }

    pub unsafe fn set_max_requests_per_flush(&mut self,
                                             num_requests: u32)
                                             -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_max_requests_per_flush(self.0,num_requests)).wrap(self)
    }

    pub unsafe fn set_write_bytes_high_water_mark(&mut self,
                                                  num_bytes: u32)
                                                  -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_write_bytes_high_water_mark(self.0,num_bytes)).wrap(self)
    }

    pub unsafe fn set_write_bytes_low_water_mark(&mut self,
                                                 num_bytes: u32)
                                                 -> Result<&mut Self, CassandraError> {
        CassandraError::build(cass_cluster_set_write_bytes_low_water_mark(self.0,num_bytes)).wrap(self)
    }

    pub unsafe fn set_pending_requests_high_water_mark(&mut self,
                                                       num_requests: u32)
                                                       -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_pending_requests_high_water_mark(
                self.0,num_requests
            )
        ).wrap(self)
    }

    pub unsafe fn set_pending_requests_low_water_mark(&mut self,
                                                      num_requests: u32)
                                                      -> Result<&mut Self, CassandraError> {
        CassandraError::build(
            cass_cluster_set_pending_requests_low_water_mark(
                self.0,
                num_requests
            )
        ).wrap(self)
    }

    pub unsafe fn set_connect_timeout(&mut self, timeout_ms: u32) -> &Self {
        cass_cluster_set_connect_timeout(self.0, timeout_ms);
        self
    }

    pub unsafe fn set_request_timeout(&mut self, timeout_ms: u32) -> &Self {
        cass_cluster_set_request_timeout(self.0, timeout_ms);
        self
    }

    pub unsafe fn set_credentials(&mut self, username: *const i8, password: *const i8) -> &Self {
        cass_cluster_set_credentials(self.0, username, password);
        self
    }

    pub fn set_load_balance_round_robin(&mut self) -> Result<&Self, CassandraError> {
        unsafe {
            cass_cluster_set_load_balance_round_robin(self.0);
            CassandraError::build(0).wrap(self)
        }
    }

    pub fn set_load_balance_dc_aware<S>(&mut self,
                                        local_dc: S,
                                        used_hosts_per_remote_dc: u32,
                                        allow_remote_dcs_for_local_cl: bool)
                                        -> Result<&Self, CassandraError>
        where S: Into<String>
    {
        unsafe {
            CassandraError::build({
            let local_dc = CString::new(local_dc.into()).unwrap();
            cass_cluster_set_load_balance_dc_aware(
                self.0,local_dc.as_ptr(),
                used_hosts_per_remote_dc,
                allow_remote_dcs_for_local_cl as u32
            )
        }).wrap(self)
        }
    }

    pub unsafe fn set_token_aware_routing(&mut self, enabled: bool) -> &Self {
        cass_cluster_set_token_aware_routing(self.0, enabled as u32);
        self
    }

    pub fn set_tcp_nodelay(&mut self, enable: bool) -> &Self {
        unsafe {
            cass_cluster_set_tcp_nodelay(self.0, enable as u32);
            self
        }
    }

    pub unsafe fn set_tcp_keepalive(&mut self, enable: bool, delay_secs: u32) -> &Self {
        cass_cluster_set_tcp_keepalive(self.0, enable as u32, delay_secs);
        self
    }

    pub fn set_latency_aware_routing(&mut self, enabled: bool) -> &Self {
        unsafe {
            cass_cluster_set_latency_aware_routing(self.0,enabled as u32);
            self
        }
    }

    pub fn cass_cluster_set_latency_aware_routing_settings(&mut self,
                                                           exclusion_threshold: f64,
                                                           scale_ms: u64,
                                                           retry_period_ms: u64,
                                                           update_rate_ms: u64,
                                                           min_measured: u64)
                                                           -> &Self {
        unsafe {
            cass_cluster_set_latency_aware_routing_settings(self.0,
                                                            exclusion_threshold,
                                                            scale_ms,
                                                            retry_period_ms,
                                                            update_rate_ms,
                                                            min_measured);
            self
        }
    }

}
<|endoftext|>


<commit_before>use std::thread;
use std::net::SocketAddr;

use log::{LogRecord, LogLevel, SetLoggerError};
use env_logger::LogBuilder;
use colored::*;
use router::Router;
use iron::{Chain, Iron};

use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

use blockchain::{GenesisConfig, ApiContext};
use node::{NodeConfig, Node};
use crypto::gen_keypair;
use explorer::ExplorerApi;
use api::Api;

pub mod clap;

pub fn init_logger() -> Result<(), SetLoggerError> {
    let mut builder = LogBuilder::new();
    builder.format(format_log_record);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init()
}

pub fn generate_testnet_config(count: u8, start_port: u16) -> Vec<NodeConfig> {
    let validators = (0..count as usize)
        .map(|_| gen_keypair())
        .collect::<Vec<_>>();
    let genesis = GenesisConfig::new(validators.iter().map(|x| x.0));
    let peers = (0..validators.len())
        .map(|x| {
                 format!("127.0.0.1:{}", start_port + x as u16)
                     .parse()
                     .unwrap()
             })
        .collect::<Vec<_>>();

    validators
        .into_iter()
        .enumerate()
        .map(|(idx, validator)| {
            NodeConfig {
                listen_address: peers[idx],
                network: Default::default(),
                peers: peers.clone(),
                public_key: validator.0,
                secret_key: validator.1,
                genesis: genesis.clone(),
            }
        })
        .collect::<Vec<_>>()
}

/// Options for the `run_node_with_api` function.
pub struct RunNodeOptions {
    /// Enable api endpoints for the `blockchain_explorer` on public api address.
    pub enable_explorer: bool,
    /// Listen address for public api endpoints
    pub public_api_address: Option<SocketAddr>,
    /// Listen address for private api endpoints
    pub private_api_address: Option<SocketAddr>,
}

/// A generic implementation that launches `Node` and optionally creates threads
/// for public and private api handlers.
pub fn run_node_with_api(mut node: Node, options: RunNodeOptions) {
    let blockchain = node.handler().blockchain.clone();
    let private_config_api_thread = match options.private_api_address {
        Some(listen_address) => {
            let blockchain_clone = blockchain.clone();
            let api_context = ApiContext::new(&node);
            let thread = thread::spawn(move || {
                info!("Private exonum api started on {}", listen_address);

                let mut router = Router::new();
                blockchain_clone.wire_private_api(&api_context, &mut router);
                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    let public_config_api_thread = match options.public_api_address {
        Some(listen_address) => {
            let blockchain_clone = blockchain.clone();
            let api_context = ApiContext::new(&node);
            let thread = thread::spawn(move || {
                info!("Public exonum api started on {}", listen_address);

                let mut router = Router::new();
                blockchain_clone.wire_public_api(&api_context, &mut router);
                if options.enable_explorer {
                    let explorer_api = ExplorerApi {
                        blockchain: blockchain_clone
                    };
                    explorer_api.wire(&mut router);
                }
                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    node.run().unwrap();
    if let Some(private_config_api_thread) = private_config_api_thread {
        private_config_api_thread.join().unwrap();
    }
    if let Some(public_config_api_thread) = public_config_api_thread {
        public_config_api_thread.join().unwrap();
    }
}

fn has_colors() -> bool {
    use term::terminfo::TerminfoTerminal;
    use term::Terminal;
    use std::io;

    let out = io::stderr();
    if let Some(term) = TerminfoTerminal::new(out) {
        term.supports_color()
    } else {
        false
    }
}

fn format_log_record(record: &LogRecord) -> String {
    let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    let secs = ts.as_secs().to_string();
    let millis = (ts.subsec_nanos() as u64 / 1000000).to_string();

    let module = record.location().module_path();
    let file = record.location().file();
    let line = record.location().line();

    let source_path;
    let verbose_src_path = match env::var("RUST_VERBOSE_PATH") {
        Ok(val) => val.parse::<bool>().unwrap_or(false),
        Err(_) => false,
    };
    if verbose_src_path {
        source_path = format!("{}:{}:{}", module, file, line);
    } else {
        source_path = module.to_string();
    }

    if has_colors() {
        let level = match record.level() {
            LogLevel::Error => "ERROR".red(),
            LogLevel::Warn => "WARN".yellow(),
            LogLevel::Info => "INFO".green(),
            LogLevel::Debug => "DEBUG".cyan(),
            LogLevel::Trace => "TRACE".white(),
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs.bold(),
                millis.bold(),
                level,
                &source_path,
                record.args())
    } else {
        let level = match record.level() {
            LogLevel::Error => "ERROR",
            LogLevel::Warn => "WARN",
            LogLevel::Info => "INFO",
            LogLevel::Debug => "DEBUG",
            LogLevel::Trace => "TRACE",
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs,
                millis,
                level,
                &source_path,
                record.args())
    }
}<commit_msg>Rename RunNodeOptions<commit_after>use std::thread;
use std::net::SocketAddr;

use log::{LogRecord, LogLevel, SetLoggerError};
use env_logger::LogBuilder;
use colored::*;
use router::Router;
use iron::{Chain, Iron};

use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

use blockchain::{GenesisConfig, ApiContext};
use node::{NodeConfig, Node};
use crypto::gen_keypair;
use explorer::ExplorerApi;
use api::Api;

pub mod clap;

pub fn init_logger() -> Result<(), SetLoggerError> {
    let mut builder = LogBuilder::new();
    builder.format(format_log_record);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init()
}

pub fn generate_testnet_config(count: u8, start_port: u16) -> Vec<NodeConfig> {
    let validators = (0..count as usize)
        .map(|_| gen_keypair())
        .collect::<Vec<_>>();
    let genesis = GenesisConfig::new(validators.iter().map(|x| x.0));
    let peers = (0..validators.len())
        .map(|x| {
                 format!("127.0.0.1:{}", start_port + x as u16)
                     .parse()
                     .unwrap()
             })
        .collect::<Vec<_>>();

    validators
        .into_iter()
        .enumerate()
        .map(|(idx, validator)| {
            NodeConfig {
                listen_address: peers[idx],
                network: Default::default(),
                peers: peers.clone(),
                public_key: validator.0,
                secret_key: validator.1,
                genesis: genesis.clone(),
            }
        })
        .collect::<Vec<_>>()
}

/// Options for the `run_node_with_api` function.
pub struct NodeRunOptions {
    /// Enable api endpoints for the `blockchain_explorer` on public api address.
    pub enable_explorer: bool,
    /// Listen address for public api endpoints
    pub public_api_address: Option<SocketAddr>,
    /// Listen address for private api endpoints
    pub private_api_address: Option<SocketAddr>,
}

/// A generic implementation that launches `Node` and optionally creates threads
/// for public and private api handlers.
pub fn run_node_with_api(mut node: Node, options: NodeRunOptions) {
    let blockchain = node.handler().blockchain.clone();
    let private_config_api_thread = match options.private_api_address {
        Some(listen_address) => {
            let blockchain_clone = blockchain.clone();
            let api_context = ApiContext::new(&node);
            let thread = thread::spawn(move || {
                info!("Private exonum api started on {}", listen_address);

                let mut router = Router::new();
                blockchain_clone.wire_private_api(&api_context, &mut router);
                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    let public_config_api_thread = match options.public_api_address {
        Some(listen_address) => {
            let blockchain_clone = blockchain.clone();
            let api_context = ApiContext::new(&node);
            let thread = thread::spawn(move || {
                info!("Public exonum api started on {}", listen_address);

                let mut router = Router::new();
                blockchain_clone.wire_public_api(&api_context, &mut router);
                if options.enable_explorer {
                    let explorer_api = ExplorerApi {
                        blockchain: blockchain_clone
                    };
                    explorer_api.wire(&mut router);
                }
                let chain = Chain::new(router);
                Iron::new(chain).http(listen_address).unwrap();
            });
            Some(thread)
        }
        None => None,
    };

    node.run().unwrap();
    if let Some(private_config_api_thread) = private_config_api_thread {
        private_config_api_thread.join().unwrap();
    }
    if let Some(public_config_api_thread) = public_config_api_thread {
        public_config_api_thread.join().unwrap();
    }
}

fn has_colors() -> bool {
    use term::terminfo::TerminfoTerminal;
    use term::Terminal;
    use std::io;

    let out = io::stderr();
    if let Some(term) = TerminfoTerminal::new(out) {
        term.supports_color()
    } else {
        false
    }
}

fn format_log_record(record: &LogRecord) -> String {
    let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    let secs = ts.as_secs().to_string();
    let millis = (ts.subsec_nanos() as u64 / 1000000).to_string();

    let module = record.location().module_path();
    let file = record.location().file();
    let line = record.location().line();

    let source_path;
    let verbose_src_path = match env::var("RUST_VERBOSE_PATH") {
        Ok(val) => val.parse::<bool>().unwrap_or(false),
        Err(_) => false,
    };
    if verbose_src_path {
        source_path = format!("{}:{}:{}", module, file, line);
    } else {
        source_path = module.to_string();
    }

    if has_colors() {
        let level = match record.level() {
            LogLevel::Error => "ERROR".red(),
            LogLevel::Warn => "WARN".yellow(),
            LogLevel::Info => "INFO".green(),
            LogLevel::Debug => "DEBUG".cyan(),
            LogLevel::Trace => "TRACE".white(),
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs.bold(),
                millis.bold(),
                level,
                &source_path,
                record.args())
    } else {
        let level = match record.level() {
            LogLevel::Error => "ERROR",
            LogLevel::Warn => "WARN",
            LogLevel::Info => "INFO",
            LogLevel::Debug => "DEBUG",
            LogLevel::Trace => "TRACE",
        };
        format!("[{} : {}] - [ {} ] - {} - {}",
                secs,
                millis,
                level,
                &source_path,
                record.args())
    }
}<|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/. */

//! The bulk of the HTML parser integration is in `script::parse::html`.
//! This module is mostly about its interaction with DOM memory management.

use document_loader::LoadType;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::ServoHTMLParserBinding;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::Document;
use dom::node::Node;
use dom::text::Text;
use dom::window::Window;
use encoding::all::UTF_8;
use encoding::types::{DecoderTrap, Encoding};
use html5ever::tokenizer;
use html5ever::tree_builder;
use html5ever::tree_builder::{NodeOrText, TreeBuilder, TreeBuilderOpts};
use hyper::header::ContentType;
use hyper::mime::{Mime, SubLevel, TopLevel};
use js::jsapi::JSTracer;
use msg::constellation_msg::{PipelineId, SubpageId};
use net_traits::{AsyncResponseListener, Metadata};
use network_listener::PreInvoke;
use parse::Parser;
use script_task::{ScriptChan, ScriptTask};
use std::cell::Cell;
use std::default::Default;
use url::Url;

#[must_root]
#[derive(JSTraceable, HeapSizeOf)]
pub struct Sink {
    pub base_url: Option<Url>,
    pub document: JS<Document>,
}

impl Sink {
    #[allow(unrooted_must_root)] // method is only run at parse time
    pub fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Root<Node> {
        match child {
            NodeOrText::AppendNode(n) => n.root(),
            NodeOrText::AppendText(t) => {
                let text = Text::new(t.into(), &self.document);
                Root::upcast(text)
            }
        }
    }
}

/// FragmentContext is used only to pass this group of related values
/// into functions.
#[derive(Copy, Clone)]
pub struct FragmentContext<'a> {
    pub context_elem: &'a Node,
    pub form_elem: Option<&'a Node>,
}

pub type Tokenizer = tokenizer::Tokenizer<TreeBuilder<JS<Node>, Sink>>;

/// The context required for asynchronously fetching a document and parsing it progressively.
pub struct ParserContext {
    /// The parser that initiated the request.
    parser: Option<Trusted<ServoHTMLParser>>,
    /// Is this document a synthesized document for a single image?
    is_image_document: bool,
    /// The pipeline associated with this document.
    id: PipelineId,
    /// The subpage associated with this document.
    subpage: Option<SubpageId>,
    /// The target event loop for the response notifications.
    script_chan: Box


<commit_before>// TODO:
//
// - Better error reporting

extern crate libc;

use std::collections::HashMap;
use std::collections::HashSet;
use std::ops::BitOr;

pub struct EvLoop<Ctx> {
    fds: HashMap<libc::c_int, Handler<Ctx>>,
}

enum Handler<Ctx> {
    Timer { cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx, u64) -> ()> },
    Signal { cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()> },
    Fd { evs: FdEv, cb: Box<FnMut(FdEv, &mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()> },
}

/// File descriptor events. Use bitwise or to combine.
pub struct FdEv(libc::c_short);

pub const READ_EV: FdEv = FdEv(libc::POLLIN);
pub const WRITE_EV: FdEv = FdEv(libc::POLLOUT);
pub const ERR_EV: FdEv = FdEv(libc::POLLERR);
pub const HUP_EV: FdEv = FdEv(libc::POLLHUP);

impl BitOr for FdEv {
    type Output = FdEv;

    fn bitor(self, rhs: FdEv) -> FdEv {
        FdEv(self.0 | rhs.0)
    }
}

pub struct TimerRef(libc::c_int);
pub struct SignalRef(libc::c_int);

extern "C" {
    fn timerfd_create(
        clockid: libc::c_int,
        flags: libc::c_int
        ) -> libc::c_int;

    fn timerfd_settime(
        fd: libc::c_int,
        flags: libc::c_int,
        new_value: *const itimerspec,
        old_value: *mut itimerspec
        ) -> libc::c_int;

    // fn timerfd_gettime(
    //     fd: libc::c_int,
    //     curr_value: *mut libc::itimerspec
    //     ) -> libc::c_int;
}

// Can't find itimerspec in libc
#[repr(C)]
pub struct itimerspec {
    it_interval: libc::timespec,
    it_value: libc::timespec,
}

pub struct EvLoopCtrl<'a, Ctx: 'a> {
    stop_ref: &'a mut bool,
    remove_self: &'a mut bool,
    new_fds: HashMap<libc::c_int, Handler<Ctx>>,
    removed_fds: HashSet<libc::c_int>,
}

impl<'a, Ctx> EvLoopCtrl<'a, Ctx> {
    pub fn stop(&mut self) {
        *self.stop_ref = true;
    }

    pub fn remove_self(&mut self) {
        *self.remove_self = true;
    }

    pub fn add_fd(&mut self, fd: libc::c_int, evs: FdEv, cb: Box<FnMut(FdEv, &mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()>) {
        self.new_fds.insert(fd, Handler::Fd { evs: evs, cb: cb });
        self.removed_fds.remove(&fd);
    }

    pub fn remove_fd(&mut self, fd: libc::c_int) {
        self.removed_fds.insert(fd);
        self.new_fds.remove(&fd);
    }
}

fn mk_timespec(millis: i64) -> libc::timespec {
    let secs: i64 = millis / 1000;
    let nanos: i64 = (millis % 1000) * 1000000;
    libc::timespec { tv_sec: secs, tv_nsec: nanos }
}

impl<Ctx> EvLoop<Ctx> {
    pub fn new() -> EvLoop<Ctx> {
        EvLoop { fds: HashMap::new() }
    }

    /// Register a non-blocking socket. Use the same fd for unregister.
    pub fn add_fd(&mut self, fd: libc::c_int, evs: FdEv, cb: Box<FnMut(FdEv, &mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()>) {
        self.fds.insert(fd, Handler::Fd { evs: evs, cb: cb });
    }

    pub fn remove_fd(&mut self, fd: libc::c_int) {
        self.fds.remove(&fd);
    }

    /// `timeout` and `period` in milliseconds. `timeout` must be non-zero for this to work. If
    /// `period` is non-zero, timer expires repeatedly after the initial timeout.
    pub fn add_timer(&mut self, timeout: i64, period: i64, cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx, u64) -> ()>) -> TimerRef {
        let fd = unsafe { timerfd_create(libc::CLOCK_MONOTONIC, libc::EFD_NONBLOCK) };
        assert!(fd != -1);

        let timeout_spec = mk_timespec(timeout);
        let period_spec = mk_timespec(period);
        let timerspec = itimerspec { it_interval: period_spec, it_value: timeout_spec };

        assert!(unsafe { timerfd_settime(fd, 0, &timerspec, std::ptr::null_mut()) } != -1);
        self.fds.insert(fd, Handler::Timer { cb: cb });
        TimerRef(fd)
    }

    pub fn remove_timer(&mut self, timer_ref: TimerRef) {
        assert!(unsafe { libc::close(timer_ref.0) } != -1);
        self.fds.remove(&timer_ref.0);
    }

    pub fn add_signal(&mut self, sigs: &libc::sigset_t, cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()>) -> SignalRef {
        // Block the signals we handle using signalfd() so they don't cause signal handlers to run
        assert!(unsafe { libc::sigprocmask(libc::SIG_BLOCK, sigs as *const libc::sigset_t, std::ptr::null_mut()) } != -1);
        let fd = unsafe { libc::signalfd(-1, sigs, libc::EFD_NONBLOCK) };
        assert!(fd != -1);
        self.fds.insert(fd, Handler::Signal { cb: cb });
        SignalRef(fd)
    }

    pub fn remove_signal(&mut self, signal_ref: SignalRef) {
        self.fds.remove(&signal_ref.0);
    }

    pub fn run(&mut self, mut ctx: Ctx) -> Ctx {
        let mut stop = false;
        while !stop {
            let mut fds: Vec<libc::pollfd> = Vec::with_capacity(self.fds.len());

            for (fd, handler) in self.fds.iter() {
                match handler {
                    &Handler::Timer{ .. } | &Handler::Signal{ .. } => {
                        fds.push(libc::pollfd { fd: *fd, events: libc::POLLIN, revents: 0 });
                    }
                    &Handler::Fd{ ref evs, .. } => {
                        fds.push(libc::pollfd { fd: *fd, events: evs.0, revents: 0 });
                    }
                }
            }

            assert!(unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as u64, -1) } != -1);

            for pollfd in fds {
                if pollfd.revents != 0 {

                    let mut remove_fd = false;
                    {
                        let mut controller = EvLoopCtrl {
                            stop_ref: &mut stop,
                            remove_self: &mut remove_fd,
                            new_fds: HashMap::with_capacity(0),
                            removed_fds: HashSet::with_capacity(0),
                        };

                        match self.fds.get_mut(&pollfd.fd).unwrap() {
                            &mut Handler::Timer{ ref mut cb } => {
                                let mut ret: u64 = 0;
                                assert!(unsafe { libc::read(pollfd.fd, &mut ret as *mut u64 as *mut libc::c_void, 8) } != -1);
                                cb(&mut controller, &mut ctx, ret);
                            }
                            &mut Handler::Signal{ ref mut cb } => {
                                let mut siginfo: libc::signalfd_siginfo = unsafe { std::mem::zeroed() };
                                assert!(unsafe {
                                    libc::read(
                                        pollfd.fd,
                                        &mut siginfo as *mut libc::signalfd_siginfo as *mut libc::c_void,
                                        std::mem::size_of::<libc::signalfd_siginfo>())
                                } != -1);
                                cb(&mut controller, &mut ctx);
                            }
                            &mut Handler::Fd{ ref mut cb, .. } => {
                                cb(FdEv(pollfd.revents), &mut controller, &mut ctx);
                            }
                        }

                        for (fd, h) in controller.new_fds.into_iter() {
                            self.fds.insert(fd, h);
                        }

                        for fd in controller.removed_fds.into_iter() {
                            self.fds.remove(&fd);
                        }
                    }

                    if remove_fd {
                        self.fds.remove(&pollfd.fd);
                    }
                }
            }
        }
        ctx
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::cell::RefCell;
    use std::rc::Rc;

    #[test]
    fn it_works() {
        let it_worked: Rc<RefCell<bool>> = Rc::new(RefCell::new(false));

        let mut ev_loop = EvLoop::new();
        {
            let it_worked_clone = it_worked.clone();
            ev_loop.add_timer(100, 100, Box::new(move |ctrl, _, _| {
                *it_worked_clone.borrow_mut() = true;
                ctrl.stop();
            }));
        }
        ev_loop.run(());

        assert!(*(*it_worked).borrow());
    }

    #[test]
    fn it_works_2() {
        struct Ctx {
            cb1: u64,
            cb2: u64,
            cb3: bool,
        }

        let mut ev_loop: EvLoop<Ctx> = EvLoop::new();

        ev_loop.add_timer(100, 100, Box::new(move |ctrl, ctx, amt| {
            assert!(ctx.cb1 == 0);
            ctx.cb1 = amt;
            ctrl.remove_self();
        }));

        ev_loop.add_timer(100, 100, Box::new(move |ctrl, ctx, amt| {
            assert!(ctx.cb2 == 0);
            ctx.cb2 = amt;
            ctrl.remove_self();
        }));

        {
            let fd = unsafe { timerfd_create(libc::CLOCK_MONOTONIC, libc::EFD_NONBLOCK) };
            assert!(fd != -1);

            let timeout_spec = mk_timespec(300);
            let period_spec = mk_timespec(300);
            let timerspec = itimerspec { it_interval: period_spec, it_value: timeout_spec };

            assert!(unsafe { timerfd_settime(fd, 0, &timerspec, std::ptr::null_mut()) } != -1);
            ev_loop.add_fd(fd, READ_EV, Box::new(move |_, ctrl, ctx| {
                assert!(ctx.cb3 == false);
                ctx.cb3 = true;
                ctrl.remove_self();
                ctrl.stop();
            }));
        }

        let ctx = ev_loop.run(Ctx { cb1: 0, cb2: 0, cb3: false });

        assert_eq!(ctx.cb1, 1);
        assert_eq!(ctx.cb2, 1);
        assert!(ctx.cb3);
    }
}
<commit_msg>ev_loop: Slightly improve the timer test<commit_after>// TODO:
//
// - Better error reporting

extern crate libc;

use std::collections::HashMap;
use std::collections::HashSet;
use std::ops::BitOr;

pub struct EvLoop<Ctx> {
    fds: HashMap<libc::c_int, Handler<Ctx>>,
}

enum Handler<Ctx> {
    Timer { cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx, u64) -> ()> },
    Signal { cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()> },
    Fd { evs: FdEv, cb: Box<FnMut(FdEv, &mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()> },
}

/// File descriptor events. Use bitwise or to combine.
pub struct FdEv(libc::c_short);

pub const READ_EV: FdEv = FdEv(libc::POLLIN);
pub const WRITE_EV: FdEv = FdEv(libc::POLLOUT);
pub const ERR_EV: FdEv = FdEv(libc::POLLERR);
pub const HUP_EV: FdEv = FdEv(libc::POLLHUP);

impl BitOr for FdEv {
    type Output = FdEv;

    fn bitor(self, rhs: FdEv) -> FdEv {
        FdEv(self.0 | rhs.0)
    }
}

pub struct TimerRef(libc::c_int);
pub struct SignalRef(libc::c_int);

extern "C" {
    fn timerfd_create(
        clockid: libc::c_int,
        flags: libc::c_int
        ) -> libc::c_int;

    fn timerfd_settime(
        fd: libc::c_int,
        flags: libc::c_int,
        new_value: *const itimerspec,
        old_value: *mut itimerspec
        ) -> libc::c_int;

    // fn timerfd_gettime(
    //     fd: libc::c_int,
    //     curr_value: *mut libc::itimerspec
    //     ) -> libc::c_int;
}

// Can't find itimerspec in libc
#[repr(C)]
pub struct itimerspec {
    it_interval: libc::timespec,
    it_value: libc::timespec,
}

pub struct EvLoopCtrl<'a, Ctx: 'a> {
    stop_ref: &'a mut bool,
    remove_self: &'a mut bool,
    new_fds: HashMap<libc::c_int, Handler<Ctx>>,
    removed_fds: HashSet<libc::c_int>,
}

impl<'a, Ctx> EvLoopCtrl<'a, Ctx> {
    pub fn stop(&mut self) {
        *self.stop_ref = true;
    }

    pub fn remove_self(&mut self) {
        *self.remove_self = true;
    }

    pub fn add_fd(&mut self, fd: libc::c_int, evs: FdEv, cb: Box<FnMut(FdEv, &mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()>) {
        self.new_fds.insert(fd, Handler::Fd { evs: evs, cb: cb });
        self.removed_fds.remove(&fd);
    }

    pub fn remove_fd(&mut self, fd: libc::c_int) {
        self.removed_fds.insert(fd);
        self.new_fds.remove(&fd);
    }
}

fn mk_timespec(millis: i64) -> libc::timespec {
    let secs: i64 = millis / 1000;
    let nanos: i64 = (millis % 1000) * 1000000;
    libc::timespec { tv_sec: secs, tv_nsec: nanos }
}

impl<Ctx> EvLoop<Ctx> {
    pub fn new() -> EvLoop<Ctx> {
        EvLoop { fds: HashMap::new() }
    }

    /// Register a non-blocking socket. Use the same fd for unregister.
    pub fn add_fd(&mut self, fd: libc::c_int, evs: FdEv, cb: Box<FnMut(FdEv, &mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()>) {
        self.fds.insert(fd, Handler::Fd { evs: evs, cb: cb });
    }

    pub fn remove_fd(&mut self, fd: libc::c_int) {
        self.fds.remove(&fd);
    }

    /// `timeout` and `period` in milliseconds. `timeout` must be non-zero for this to work. If
    /// `period` is non-zero, timer expires repeatedly after the initial timeout.
    pub fn add_timer(&mut self, timeout: i64, period: i64, cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx, u64) -> ()>) -> TimerRef {
        let fd = unsafe { timerfd_create(libc::CLOCK_MONOTONIC, libc::EFD_NONBLOCK) };
        assert!(fd != -1);

        let timeout_spec = mk_timespec(timeout);
        let period_spec = mk_timespec(period);
        let timerspec = itimerspec { it_interval: period_spec, it_value: timeout_spec };

        assert!(unsafe { timerfd_settime(fd, 0, &timerspec, std::ptr::null_mut()) } != -1);
        self.fds.insert(fd, Handler::Timer { cb: cb });
        TimerRef(fd)
    }

    pub fn remove_timer(&mut self, timer_ref: TimerRef) {
        assert!(unsafe { libc::close(timer_ref.0) } != -1);
        self.fds.remove(&timer_ref.0);
    }

    pub fn add_signal(&mut self, sigs: &libc::sigset_t, cb: Box<FnMut(&mut EvLoopCtrl<Ctx>, &mut Ctx) -> ()>) -> SignalRef {
        // Block the signals we handle using signalfd() so they don't cause signal handlers to run
        assert!(unsafe { libc::sigprocmask(libc::SIG_BLOCK, sigs as *const libc::sigset_t, std::ptr::null_mut()) } != -1);
        let fd = unsafe { libc::signalfd(-1, sigs, libc::EFD_NONBLOCK) };
        assert!(fd != -1);
        self.fds.insert(fd, Handler::Signal { cb: cb });
        SignalRef(fd)
    }

    pub fn remove_signal(&mut self, signal_ref: SignalRef) {
        self.fds.remove(&signal_ref.0);
    }

    pub fn run(&mut self, mut ctx: Ctx) -> Ctx {
        let mut stop = false;
        while !stop {
            let mut fds: Vec<libc::pollfd> = Vec::with_capacity(self.fds.len());

            for (fd, handler) in self.fds.iter() {
                match handler {
                    &Handler::Timer{ .. } | &Handler::Signal{ .. } => {
                        fds.push(libc::pollfd { fd: *fd, events: libc::POLLIN, revents: 0 });
                    }
                    &Handler::Fd{ ref evs, .. } => {
                        fds.push(libc::pollfd { fd: *fd, events: evs.0, revents: 0 });
                    }
                }
            }

            assert!(unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as u64, -1) } != -1);

            for pollfd in fds {
                if pollfd.revents != 0 {

                    let mut remove_fd = false;
                    {
                        let mut controller = EvLoopCtrl {
                            stop_ref: &mut stop,
                            remove_self: &mut remove_fd,
                            new_fds: HashMap::with_capacity(0),
                            removed_fds: HashSet::with_capacity(0),
                        };

                        match self.fds.get_mut(&pollfd.fd).unwrap() {
                            &mut Handler::Timer{ ref mut cb } => {
                                let mut ret: u64 = 0;
                                assert!(unsafe { libc::read(pollfd.fd, &mut ret as *mut u64 as *mut libc::c_void, 8) } != -1);
                                cb(&mut controller, &mut ctx, ret);
                            }
                            &mut Handler::Signal{ ref mut cb } => {
                                let mut siginfo: libc::signalfd_siginfo = unsafe { std::mem::zeroed() };
                                assert!(unsafe {
                                    libc::read(
                                        pollfd.fd,
                                        &mut siginfo as *mut libc::signalfd_siginfo as *mut libc::c_void,
                                        std::mem::size_of::<libc::signalfd_siginfo>())
                                } != -1);
                                cb(&mut controller, &mut ctx);
                            }
                            &mut Handler::Fd{ ref mut cb, .. } => {
                                cb(FdEv(pollfd.revents), &mut controller, &mut ctx);
                            }
                        }

                        for (fd, h) in controller.new_fds.into_iter() {
                            self.fds.insert(fd, h);
                        }

                        for fd in controller.removed_fds.into_iter() {
                            self.fds.remove(&fd);
                        }
                    }

                    if remove_fd {
                        self.fds.remove(&pollfd.fd);
                    }
                }
            }
        }
        ctx
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::cell::RefCell;
    use std::rc::Rc;

    #[test]
    fn it_works() {
        let count: Rc<RefCell<i32>> = Rc::new(RefCell::new(0));

        let mut ev_loop = EvLoop::new();
        {
            let count_clone = count.clone();
            ev_loop.add_timer(100, 100, Box::new(move |ctrl, _, _| {
                *count_clone.borrow_mut() += 1;
                println!("bump");
                if *(*count_clone).borrow() == 10 {
                    ctrl.stop();
                }
            }));
        }
        ev_loop.run(());

        assert_eq!(*(*count).borrow(), 10);
    }

    #[test]
    fn it_works_2() {
        struct Ctx {
            cb1: u64,
            cb2: u64,
            cb3: bool,
        }

        let mut ev_loop: EvLoop<Ctx> = EvLoop::new();

        ev_loop.add_timer(100, 100, Box::new(move |ctrl, ctx, amt| {
            assert!(ctx.cb1 == 0);
            ctx.cb1 = amt;
            ctrl.remove_self();
        }));

        ev_loop.add_timer(100, 100, Box::new(move |ctrl, ctx, amt| {
            assert!(ctx.cb2 == 0);
            ctx.cb2 = amt;
            ctrl.remove_self();
        }));

        {
            let fd = unsafe { timerfd_create(libc::CLOCK_MONOTONIC, libc::EFD_NONBLOCK) };
            assert!(fd != -1);

            let timeout_spec = mk_timespec(300);
            let period_spec = mk_timespec(300);
            let timerspec = itimerspec { it_interval: period_spec, it_value: timeout_spec };

            assert!(unsafe { timerfd_settime(fd, 0, &timerspec, std::ptr::null_mut()) } != -1);
            ev_loop.add_fd(fd, READ_EV, Box::new(move |_, ctrl, ctx| {
                assert!(ctx.cb3 == false);
                ctx.cb3 = true;
                ctrl.remove_self();
                ctrl.stop();
            }));
        }

        let ctx = ev_loop.run(Ctx { cb1: 0, cb2: 0, cb3: false });

        assert_eq!(ctx.cb1, 1);
        assert_eq!(ctx.cb2, 1);
        assert!(ctx.cb3);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashMap;

use hcore::service::ServiceGroup;

use census::{CensusGroup, CensusMember, CensusRing, ElectionStatus};
use manager::Sys;
use manager::service::{Cfg, Pkg, ServiceBind};

#[derive(Clone, Debug, Serialize)]
pub struct Binds<'a>(HashMap<String, BindGroup<'a>>);

impl<'a> Binds<'a> {
    fn new(bindings: &[ServiceBind], census: &'a CensusRing) -> Self {
        let mut map = HashMap::default();
        for bind in bindings {
            if let Some(group) = census.census_group_for(&bind.service_group) {
                map.insert(bind.name.to_string(), BindGroup::new(group));
            }
        }
        Binds(map)
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct BindGroup<'a> {
    members: Vec<SvcMember<'a>>,
}

impl<'a> BindGroup<'a> {
    fn new(group: &'a CensusGroup) -> Self {
        BindGroup { members: group.members().iter().map(|m| SvcMember(m)).collect() }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct RenderContext<'a> {
    pub sys: &'a Sys,
    pub pkg: &'a Pkg,
    pub cfg: &'a Cfg,
    pub svc: Svc<'a>,
    pub bind: Binds<'a>,
}

impl<'a> RenderContext<'a> {
    pub fn new(service_group: &ServiceGroup,
               sys: &'a Sys,
               pkg: &'a Pkg,
               cfg: &'a Cfg,
               census: &'a CensusRing,
               bindings: &[ServiceBind])
               -> RenderContext<'a> {
        let census_group = census
            .census_group_for(&service_group)
            .expect("Census Group missing from list!");
        RenderContext {
            sys: sys,
            pkg: pkg,
            cfg: cfg,
            svc: Svc::new(census_group),
            bind: Binds::new(bindings, census),
        }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct Svc<'a> {
    pub group: &'a ServiceGroup,
    pub election_running: bool,
    pub election_no_quorum: bool,
    pub election_finished: bool,
    pub update_election_running: bool,
    pub update_election_no_quorum: bool,
    pub update_election_finished: bool,
    pub me: SvcMember<'a>,
    pub members: Vec<SvcMember<'a>>,
    pub leader: Option<SvcMember<'a>>,
    pub update_leader: Option<SvcMember<'a>>,
}

impl<'a> Svc<'a> {
    fn new(census_group: &'a CensusGroup) -> Self {
        Svc {
            group: &census_group.service_group,
            election_running: census_group.election_status == ElectionStatus::ElectionInProgress,
            election_no_quorum: census_group.election_status == ElectionStatus::ElectionNoQuorum,
            election_finished: census_group.election_status == ElectionStatus::ElectionFinished,
            update_election_running: census_group.election_status ==
                                     ElectionStatus::ElectionInProgress,
            update_election_no_quorum: census_group.election_status ==
                                       ElectionStatus::ElectionNoQuorum,
            update_election_finished: census_group.election_status ==
                                      ElectionStatus::ElectionFinished,
            me: SvcMember(census_group.me().expect("Missing 'me'")),
            members: census_group
                .members()
                .iter()
                .map(|m| SvcMember(m))
                .collect(),
            leader: census_group.leader().map(|m| SvcMember(m)),
            update_leader: census_group.update_leader().map(|m| SvcMember(m)),
        }
    }
}

/// A friendly representation of a `CensusMember` to the templating system.
#[derive(Clone, Debug, Serialize)]
pub struct SvcMember<'a>(&'a CensusMember);
<commit_msg>Update Svc election boolean fields in RenderingContext<commit_after>// Copyright (c) 2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashMap;

use hcore::service::ServiceGroup;

use census::{CensusGroup, CensusMember, CensusRing, ElectionStatus};
use manager::Sys;
use manager::service::{Cfg, Pkg, ServiceBind};

#[derive(Clone, Debug, Serialize)]
pub struct Binds<'a>(HashMap<String, BindGroup<'a>>);

impl<'a> Binds<'a> {
    fn new(bindings: &[ServiceBind], census: &'a CensusRing) -> Self {
        let mut map = HashMap::default();
        for bind in bindings {
            if let Some(group) = census.census_group_for(&bind.service_group) {
                map.insert(bind.name.to_string(), BindGroup::new(group));
            }
        }
        Binds(map)
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct BindGroup<'a> {
    members: Vec<SvcMember<'a>>,
}

impl<'a> BindGroup<'a> {
    fn new(group: &'a CensusGroup) -> Self {
        BindGroup { members: group.members().iter().map(|m| SvcMember(m)).collect() }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct RenderContext<'a> {
    pub sys: &'a Sys,
    pub pkg: &'a Pkg,
    pub cfg: &'a Cfg,
    pub svc: Svc<'a>,
    pub bind: Binds<'a>,
}

impl<'a> RenderContext<'a> {
    pub fn new(service_group: &ServiceGroup,
               sys: &'a Sys,
               pkg: &'a Pkg,
               cfg: &'a Cfg,
               census: &'a CensusRing,
               bindings: &[ServiceBind])
               -> RenderContext<'a> {
        let census_group = census
            .census_group_for(&service_group)
            .expect("Census Group missing from list!");
        RenderContext {
            sys: sys,
            pkg: pkg,
            cfg: cfg,
            svc: Svc::new(census_group),
            bind: Binds::new(bindings, census),
        }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct Svc<'a> {
    pub group: &'a ServiceGroup,
    pub election_is_running: bool,
    pub election_is_no_quorum: bool,
    pub election_is_finished: bool,
    pub update_election_is_running: bool,
    pub update_election_is_no_quorum: bool,
    pub update_election_is_finished: bool,
    pub me: SvcMember<'a>,
    pub members: Vec<SvcMember<'a>>,
    pub leader: Option<SvcMember<'a>>,
    pub update_leader: Option<SvcMember<'a>>,
}

impl<'a> Svc<'a> {
    fn new(census_group: &'a CensusGroup) -> Self {
        Svc {
            group: &census_group.service_group,
            election_is_running: census_group.election_status == ElectionStatus::ElectionInProgress,
            election_is_no_quorum: census_group.election_status == ElectionStatus::ElectionNoQuorum,
            election_is_finished: census_group.election_status == ElectionStatus::ElectionFinished,
            update_election_is_running: census_group.election_status ==
                                        ElectionStatus::ElectionInProgress,
            update_election_is_no_quorum: census_group.election_status ==
                                          ElectionStatus::ElectionNoQuorum,
            update_election_is_finished: census_group.election_status ==
                                         ElectionStatus::ElectionFinished,
            me: SvcMember(census_group.me().expect("Missing 'me'")),
            members: census_group
                .members()
                .iter()
                .map(|m| SvcMember(m))
                .collect(),
            leader: census_group.leader().map(|m| SvcMember(m)),
            update_leader: census_group.update_leader().map(|m| SvcMember(m)),
        }
    }
}

/// A friendly representation of a `CensusMember` to the templating system.
#[derive(Clone, Debug, Serialize)]
pub struct SvcMember<'a>(&'a CensusMember);
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Averages/Mean_angle

use std::num::Float;

fn mean_angle(angles: &[f64]) -> f64 {
    let mean_cos = angles.iter().map(|&x| (x * Float::pi() / 180.).cos())
                                .fold(0., |a, b| a + b) / (angles.len() as f64);
    let mean_sin = angles.iter().map(|&x| (x * Float::pi() / 180.).sin())
                                .fold(0., |a, b| a + b) / (angles.len() as f64);

    mean_sin.atan2(&mean_cos) * 180. / Float::pi()
}

fn main() {
    let set1 = [350., 10.];
    let set2 = [90., 180., 270., 360.];
    let set3 = [10., 20., 30.];

    println!("Mean angle of first set is {} degrees", mean_angle(set1));
    println!("Mean angle of second set is {} degrees", mean_angle(set2));
    println!("Mean angle of third set is {} degrees", mean_angle(set3));
}
<commit_msg>Fixed averages_mean_angle.rs<commit_after>// http://rosettacode.org/wiki/Averages/Mean_angle

use std::num::Float;

fn mean_angle(angles: &[f64]) -> f64 {
    let mean_cos = angles.iter().map(|&x| (x * Float::pi() / 180.).cos())
                                .fold(0., |a, b| a + b) / (angles.len() as f64);
    let mean_sin = angles.iter().map(|&x| (x * Float::pi() / 180.).sin())
                                .fold(0., |a, b| a + b) / (angles.len() as f64);

    mean_sin.atan2(mean_cos) * 180. / Float::pi()
}

fn main() {
    let set1 = [350., 10.];
    let set2 = [90., 180., 270., 360.];
    let set3 = [10., 20., 30.];

    println!("Mean angle of first set is {} degrees", mean_angle(set1));
    println!("Mean angle of second set is {} degrees", mean_angle(set2));
    println!("Mean angle of third set is {} degrees", mean_angle(set3));
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate nom;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::Stream;

use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    Stream::from_file(input_file).map_err(hound::Error::IoError)
  };
  let info       = stream.info();
  let frames_len = stream.frames.len();

  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  for _ in 0..frames_len {
    if let Some(buffer) = stream.next_frame() {
      let buffer_size = buffer.len();
      let block_size  = buffer_size / 2;
      let left        = &buffer[0..block_size];
      let right       = &buffer[block_size..buffer_size];

      for i in 0..block_size {
        try!(output.write_sample(left[i]));
        try!(output.write_sample(right[i]));
      }
    } else {
      break;
    }
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<commit_msg>Convert sample loop to a single iterator loop<commit_after>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate nom;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::Stream;

use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    Stream::from_file(input_file).map_err(hound::Error::IoError)
  };
  let info       = stream.info();
  let frames_len = stream.frames.len();

  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  for sample in stream.iter() {
    try!(output.write_sample(sample));
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate nadezhda;

use nadezhda::grammar::Program;
use nadezhda::environment::Environment;
use nadezhda::population::Population;
use nadezhda::evaluate::Evaluator;
use nadezhda::darwin::evolve::succesion;

fn main() {
    let mut rng = rand::thread_rng();
    let environment: Environment = Environment::new(5);
    let mut last_population: Population = Population::new(5);

    let mut generation_count = 0;
    while generation_count < 100 {
        let next_population = succesion(&mut rng, environment.clone(), last_population.clone());
        let Population(generation) = next_population.clone();
        let survivors: Vec<Program> = generation
            .iter()
            .map(|program| (program.clone(), program.evaluate_on(environment.clone())))
            .filter(|&(_, ref env)| env.cockroach_location - env.food_location == 0)
            .map(|(program, _)| program)
            .collect();

        if survivors.len() > 0 { break; }

        last_population = next_population;
        generation_count += 1;
    }
    println!("{} {:?}", generation_count, last_population);

}
<commit_msg>Show survivor if there is one<commit_after>extern crate rand;
extern crate nadezhda;

use nadezhda::grammar::Program;
use nadezhda::environment::Environment;
use nadezhda::population::Population;
use nadezhda::evaluate::Evaluator;
use nadezhda::darwin::evolve::succesion;

fn survivors(population: Population, environment: Environment) -> Vec<Program> {
    let Population(generation) = population;
    let survivors: Vec<Program> = generation
        .iter()
        .map(|program| (program.clone(), program.evaluate_on(environment.clone())))
        .filter(|&(_, ref env)| env.cockroach_location - env.food_location == 0)
        .map(|(program, _)| program)
        .collect();

    survivors
}

fn main() {
    let mut rng = rand::thread_rng();
    let environment: Environment = Environment::new(5);
    let mut last_population: Population = Population::new(5);

    let mut generation_count = 0;
    while generation_count < 100 {
        let next_population = succesion(&mut rng, environment.clone(), last_population.clone());

        let survivors: Vec<Program> = survivors(next_population.clone(), environment.clone());
        last_population = next_population;

        if survivors.len() > 0 { break; }
        generation_count += 1;
    }

    let survivors: Vec<Program> = survivors(last_population.clone(), environment.clone());
    if survivors.len() > 0 {
        println!("{} {} {:?}", generation_count, survivors.len(), survivors[0]);
    } else {
        println!("{} {:?}", generation_count, last_population);
    }
}
<|endoftext|>


<commit_before>#[allow(unused_imports)]
use segmentation::SegmentSelector;
use segmentation::{
    BuildDescriptor, Descriptor, DescriptorBuilder, DescriptorType, GateDescriptorBuilder,
    LdtDescriptorBuilder, SystemDescriptorTypes64,
};

/// Entry for IDT, GDT or LDT.
///
/// See Intel 3a, Section 3.4.5 "Segment Descriptors", and Section 3.5.2
/// "Segment Descriptor Tables in IA-32e Mode", especially Figure 3-8.
#[derive(Copy, Clone, Debug, Default)]
#[repr(C, packed)]
pub struct Descriptor64 {
    desc32: Descriptor,
    lower: u32,
    upper: u32,
}

impl Descriptor64 {
    pub const NULL: Descriptor64 = Descriptor64 {
        desc32: Descriptor::NULL,
        lower: 0,
        upper: 0,
    };

    pub(crate) fn apply_builder_settings(&mut self, builder: &DescriptorBuilder) {
        self.desc32.apply_builder_settings(builder);
        builder
            .base_limit
            .map(|(base, limit)| self.set_base_limit(base, limit));
        builder
            .selector_offset
            .map(|(selector, offset)| self.set_selector_offset(selector, offset));
    }

    /// Create a new segment, TSS or LDT descriptor
    /// by setting the three base and two limit fields.
    pub fn set_base_limit(&mut self, base: u64, limit: u64) {
        self.desc32.set_base_limit(base as u32, limit as u32);
        self.lower = (base >> 32) as u32;
    }

    /// Creates a new descriptor with selector and offset (for IDT Gate descriptors,
    /// e.g. Trap, Interrupts and Task gates)
    pub fn set_selector_offset(&mut self, selector: SegmentSelector, offset: u64) {
        self.desc32.set_selector_offset(selector, offset as u32);
        self.lower = (offset >> 32) as u32;
    }

    /// Sets the interrupt stack table index.
    /// The 3-bit IST index field that provides an offset into the IST section of the TSS.
    /// Using the IST mechanism, the processor loads the value pointed by an IST pointer into the RSP.
    pub fn set_ist(&mut self, index: u8) {
        assert!(index <= 0b111);
        self.desc32.upper |= index as u32;
    }
}

impl GateDescriptorBuilder<u64> for DescriptorBuilder {
    fn tss_descriptor(base: u64, limit: u64, available: bool) -> DescriptorBuilder {
        let typ = match available {
            true => DescriptorType::System64(SystemDescriptorTypes64::TssAvailable),
            false => DescriptorType::System64(SystemDescriptorTypes64::TssBusy),
        };

        DescriptorBuilder::with_base_limit(base, limit).set_type(typ)
    }

    fn call_gate_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_selector_offset(selector, offset)
            .set_type(DescriptorType::System64(SystemDescriptorTypes64::CallGate))
    }

    fn interrupt_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_selector_offset(selector, offset).set_type(
            DescriptorType::System64(SystemDescriptorTypes64::InterruptGate),
        )
    }

    fn trap_gate_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_selector_offset(selector, offset)
            .set_type(DescriptorType::System64(SystemDescriptorTypes64::TrapGate))
    }
}

impl LdtDescriptorBuilder<u64> for DescriptorBuilder {
    fn ldt_descriptor(base: u64, limit: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_base_limit(base, limit)
            .set_type(DescriptorType::System64(SystemDescriptorTypes64::LDT))
    }
}

impl BuildDescriptor<Descriptor64> for DescriptorBuilder {
    fn finish(&self) -> Descriptor64 {
        let mut desc: Descriptor64 = Default::default();
        desc.apply_builder_settings(self);

        let typ = match self.typ {
            Some(DescriptorType::System64(typ)) => {
                assert!(!self.l);
                if typ == SystemDescriptorTypes64::LDT
                    || typ == SystemDescriptorTypes64::TssAvailable
                    || typ == SystemDescriptorTypes64::TssBusy
                {
                    assert!(!self.db);
                }
                typ as u8
            }
            Some(DescriptorType::System32(_typ)) => {
                panic!("Can't build a 64-bit version of this type.")
            }
            Some(DescriptorType::Data(_typ)) => {
                panic!("Can't build a 64-bit version of this type.")
            }
            Some(DescriptorType::Code(_typ)) => {
                panic!("Can't build a 64-bit version of this type.")
            }
            None => unreachable!("Type not set, this is a library bug in x86."),
        };

        desc.desc32.set_type(typ);
        desc
    }
}

/// Reload code segment register.
/// Note this is special since we can not directly move
/// to %cs. Instead we push the new segment selector
/// and return value on the stack and use lretq
/// to reload cs and continue at 1:.
#[cfg(target_arch = "x86_64")]
pub unsafe fn load_cs(sel: SegmentSelector) {
    asm!("pushq $0; \
          leaq  1f(%rip), %rax; \
          pushq %rax; \
          lretq; \
          1:" :: "ri" (sel.bits() as usize) : "rax" "memory");
}
<commit_msg>Add fs/gs read/write functions.<commit_after>#[allow(unused_imports)]
use segmentation::SegmentSelector;
use segmentation::{
    BuildDescriptor, Descriptor, DescriptorBuilder, DescriptorType, GateDescriptorBuilder,
    LdtDescriptorBuilder, SystemDescriptorTypes64,
};

/// Entry for IDT, GDT or LDT.
///
/// See Intel 3a, Section 3.4.5 "Segment Descriptors", and Section 3.5.2
/// "Segment Descriptor Tables in IA-32e Mode", especially Figure 3-8.
#[derive(Copy, Clone, Debug, Default)]
#[repr(C, packed)]
pub struct Descriptor64 {
    desc32: Descriptor,
    lower: u32,
    upper: u32,
}

impl Descriptor64 {
    pub const NULL: Descriptor64 = Descriptor64 {
        desc32: Descriptor::NULL,
        lower: 0,
        upper: 0,
    };

    pub(crate) fn apply_builder_settings(&mut self, builder: &DescriptorBuilder) {
        self.desc32.apply_builder_settings(builder);
        builder
            .base_limit
            .map(|(base, limit)| self.set_base_limit(base, limit));
        builder
            .selector_offset
            .map(|(selector, offset)| self.set_selector_offset(selector, offset));
    }

    /// Create a new segment, TSS or LDT descriptor
    /// by setting the three base and two limit fields.
    pub fn set_base_limit(&mut self, base: u64, limit: u64) {
        self.desc32.set_base_limit(base as u32, limit as u32);
        self.lower = (base >> 32) as u32;
    }

    /// Creates a new descriptor with selector and offset (for IDT Gate descriptors,
    /// e.g. Trap, Interrupts and Task gates)
    pub fn set_selector_offset(&mut self, selector: SegmentSelector, offset: u64) {
        self.desc32.set_selector_offset(selector, offset as u32);
        self.lower = (offset >> 32) as u32;
    }

    /// Sets the interrupt stack table index.
    /// The 3-bit IST index field that provides an offset into the IST section of the TSS.
    /// Using the IST mechanism, the processor loads the value pointed by an IST pointer into the RSP.
    pub fn set_ist(&mut self, index: u8) {
        assert!(index <= 0b111);
        self.desc32.upper |= index as u32;
    }
}

impl GateDescriptorBuilder<u64> for DescriptorBuilder {
    fn tss_descriptor(base: u64, limit: u64, available: bool) -> DescriptorBuilder {
        let typ = match available {
            true => DescriptorType::System64(SystemDescriptorTypes64::TssAvailable),
            false => DescriptorType::System64(SystemDescriptorTypes64::TssBusy),
        };

        DescriptorBuilder::with_base_limit(base, limit).set_type(typ)
    }

    fn call_gate_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_selector_offset(selector, offset)
            .set_type(DescriptorType::System64(SystemDescriptorTypes64::CallGate))
    }

    fn interrupt_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_selector_offset(selector, offset).set_type(
            DescriptorType::System64(SystemDescriptorTypes64::InterruptGate),
        )
    }

    fn trap_gate_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_selector_offset(selector, offset)
            .set_type(DescriptorType::System64(SystemDescriptorTypes64::TrapGate))
    }
}

impl LdtDescriptorBuilder<u64> for DescriptorBuilder {
    fn ldt_descriptor(base: u64, limit: u64) -> DescriptorBuilder {
        DescriptorBuilder::with_base_limit(base, limit)
            .set_type(DescriptorType::System64(SystemDescriptorTypes64::LDT))
    }
}

impl BuildDescriptor<Descriptor64> for DescriptorBuilder {
    fn finish(&self) -> Descriptor64 {
        let mut desc: Descriptor64 = Default::default();
        desc.apply_builder_settings(self);

        let typ = match self.typ {
            Some(DescriptorType::System64(typ)) => {
                assert!(!self.l);
                if typ == SystemDescriptorTypes64::LDT
                    || typ == SystemDescriptorTypes64::TssAvailable
                    || typ == SystemDescriptorTypes64::TssBusy
                {
                    assert!(!self.db);
                }
                typ as u8
            }
            Some(DescriptorType::System32(_typ)) => {
                panic!("Can't build a 64-bit version of this type.")
            }
            Some(DescriptorType::Data(_typ)) => {
                panic!("Can't build a 64-bit version of this type.")
            }
            Some(DescriptorType::Code(_typ)) => {
                panic!("Can't build a 64-bit version of this type.")
            }
            None => unreachable!("Type not set, this is a library bug in x86."),
        };

        desc.desc32.set_type(typ);
        desc
    }
}

/// Reload code segment register.
/// Note this is special since we can not directly move
/// to %cs. Instead we push the new segment selector
/// and return value on the stack and use lretq
/// to reload cs and continue at 1:.
#[cfg(target_arch = "x86_64")]
pub unsafe fn load_cs(sel: SegmentSelector) {
    asm!("pushq $0; \
          leaq  1f(%rip), %rax; \
          pushq %rax; \
          lretq; \
          1:" :: "ri" (sel.bits() as usize) : "rax" "memory");
}

/// Write GS Segment Base
/// Needs FSGSBASE-Enable Bit (bit 16 of CR4) set.
pub unsafe fn wrgsbase(base: u64) {
    asm!("wrgsbase $0" :: "r" (base) : "memory");
}

/// Write FS Segment Base
/// Needs FSGSBASE-Enable Bit (bit 16 of CR4) set.
pub unsafe fn wrfsbase(base: u64) {
    asm!("wrfsbase $0" :: "r" (base) : "memory");
}

/// Read GS Segment Base
/// Needs FSGSBASE-Enable Bit (bit 16 of CR4) set.
pub unsafe fn rdgsbase() -> u64 {
    let gs_base: u64;
    asm!("rdgsbase $0" : "=r" (gs_base) );
    gs_base
}

/// Read FS Segment Base
/// Needs FSGSBASE-Enable Bit (bit 16 of CR4) set.
pub unsafe fn rdfsbase() -> u64 {
    let fs_base: u64;
    asm!("rdfsbase $0" : "=r" (fs_base) );
    fs_base
}
<|endoftext|>


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

fn main() {
    let mut input_string = String::new();
    let mut file = File::open("input.txt").unwrap();
    let _ = file.read_to_string(&mut input_string);

    let num_abba = input_string.lines()
        .filter(|test_ip| valid_abba(test_ip))
        .count();

    println!("Part 1: num valid = {}", num_abba);
    assert!(num_abba == 118);
}

fn valid_abba(input: &str) -> bool {

    let bytes = input.as_bytes();
    const OPEN:u8 = '[' as u8;
    const CLOSE:u8 = ']' as u8;

    // Run a "convolution" kernel abba over the string, checking that
    // a==a and b==b and a!=b.
    let mut has_abba = false;

    // Also keep track of bracket [...] start stop points, to discard abba
    // patterns inside brackets
    let mut inside_brackets = false;

    // We use a 4-wide window, so stop early to avoid running off the end.
    for i in 0..(bytes.len() - 3) {
        let is_abba = bytes[i] == bytes[i + 3] && bytes[i + 1] == bytes[i + 2] &&
                      bytes[i] != bytes[i + 1];

        let has_start = bytes[i] == OPEN || bytes[i + 1] == OPEN || bytes[i + 2] == OPEN ||
            bytes[i + 3] == OPEN;

        let has_end = bytes[i] == CLOSE || bytes[i + 1] == CLOSE || bytes[i + 2] == CLOSE ||
            bytes[i + 3] == CLOSE;

        assert!(!(has_start && has_end));

        inside_brackets = (inside_brackets || has_start) && !(inside_brackets && has_end);

        if is_abba && inside_brackets {
            return false;
        }

        if is_abba {
            has_abba = has_abba || is_abba;
        }
    }
    has_abba
}

#[test]
fn test1() {
    assert!(valid_abba("abba[mnop]qrst") == true);
}

#[test]
fn test2() {
    assert!(valid_abba("abcd[bddb]xyyx") == false);
}

#[test]
fn test3() {
    assert!(valid_abba("aaaa[qwer]tyui") == false);
}

#[test]
fn test4() {
    assert!(valid_abba("ioxxoj[asdfgh]zxcvbn") == true);
}<commit_msg>Day 7, part 2<commit_after>
use std::fs::File;
use std::io::Read;

use std::collections::hash_set::HashSet;

fn main() {
    let mut input_string = String::new();
    let mut file = File::open("input.txt").unwrap();
    let _ = file.read_to_string(&mut input_string);

    let num_abba = input_string.lines()
        .filter(|test_ip| valid_abba(test_ip))
        .count();

    println!("Part 1: num valid = {}", num_abba);
    assert!(num_abba == 118);

    let num_ssl = input_string.lines()
        .filter(|test_ip| valid_ssl(test_ip))
        .count();

    println!("Part 2: num valid SSL = {}", num_ssl);
    assert!(num_ssl == 260);
}

fn valid_abba(input: &str) -> bool {

    let bytes = input.as_bytes();
    const OPEN:u8 = '[' as u8;
    const CLOSE:u8 = ']' as u8;

    // Run a "convolution" kernel abba over the string, checking that
    // a==a and b==b and a!=b.
    let mut has_abba = false;

    // Also keep track of bracket [...] start stop points, to discard abba
    // patterns inside brackets
    let mut inside_brackets = false;

    // We use a 4-wide window, so stop early to avoid running off the end.
    for i in 0..(bytes.len() - 3) {
        let is_abba = bytes[i] == bytes[i + 3] && bytes[i + 1] == bytes[i + 2] &&
                      bytes[i] != bytes[i + 1];

        let has_start = bytes[i] == OPEN || bytes[i + 1] == OPEN || bytes[i + 2] == OPEN ||
            bytes[i + 3] == OPEN;

        let has_end = bytes[i] == CLOSE || bytes[i + 1] == CLOSE || bytes[i + 2] == CLOSE ||
            bytes[i + 3] == CLOSE;

        assert!(!(has_start && has_end));

        inside_brackets = (inside_brackets || has_start) && !(inside_brackets && has_end);

        if is_abba && inside_brackets {
            return false;
        }

        if is_abba {
            has_abba = has_abba || is_abba;
        }
    }
    has_abba
}

// Valid if aba outside brackets, and bab inside brackets
fn valid_ssl(input: &str) -> bool {
    let bytes = input.as_bytes();
    const OPEN:u8 = '[' as u8;
    const CLOSE:u8 = ']' as u8;

    // Run a "convolution" kernel abba over the string, checking that
    // for the strings aba (a==a and a != b) and bab (the inverse)
    // Keep track of bracket [...] start and stop points.
    let mut inside_brackets = false;

    let mut aba_set = HashSet::new();
    let mut bab_set = HashSet::new();

    // We use a 3-wide window, so stop early to avoid running off the end.
    for i in 0..(bytes.len() - 2) {
        let has_start = bytes[i] == OPEN || bytes[i + 1] == OPEN || bytes[i + 2] == OPEN;
        let has_end = bytes[i] == CLOSE || bytes[i + 1] == CLOSE || bytes[i + 2] == CLOSE;
        inside_brackets = (inside_brackets || has_start) && !(inside_brackets && has_end);

        // Check for the 'xyx' pattern
        if bytes[i] == bytes[i + 2] && bytes[i] != bytes[i + 1] {

            // Generate the inverse pattern for table query.
            let xyx = [bytes[i + 1], bytes[i], bytes[i + 1]];

            if inside_brackets {
                // As 'bab'
                if aba_set.contains(xyx.as_ref()) {
                    return true;
                }
                bab_set.insert(&bytes[i..i + 3]);
            } else {
                // As 'aba'
                if bab_set.contains(xyx.as_ref()) {
                    return true;
                }
                aba_set.insert(&bytes[i..i + 3]);
            }
        }
    }
    false
}

#[test]
fn test1() {
    assert!(valid_abba("abba[mnop]qrst") == true);
}

#[test]
fn test2() {
    assert!(valid_abba("abcd[bddb]xyyx") == false);
}

#[test]
fn test3() {
    assert!(valid_abba("aaaa[qwer]tyui") == false);
}

#[test]
fn test4() {
    assert!(valid_abba("ioxxoj[asdfgh]zxcvbn") == true);
}

#[test]
fn ssl_test1() {
    assert!(valid_ssl("aba[bab]xyz") == true);
}

#[test]
fn ssl_test2() {
    assert!(valid_ssl("xyx[xyx]xyx") == false);
}

#[test]
fn ssl_test3() {
    assert!(valid_ssl("aaa[kek]eke") == true);
}

#[test]
fn ssl_test4() {
    assert!(valid_ssl("zazbz[bzb]cdb") == true);
}<|endoftext|>


<commit_before>#![feature(decl_macro, proc_macro_hygiene)]
#[macro_use]
extern crate rocket;

use rocket::http::{ContentType, Status};
use rocket::response;
use rust_embed::RustEmbed;

use std::ffi::OsStr;
use std::io::Cursor;
use std::path::PathBuf;

#[derive(RustEmbed)]
#[folder = "examples/public/"]
struct Asset;

#[get("/")]
fn index<'r>() -> response::Result<'r> {
  Asset::get("index.html").map_or_else(
    || Err(Status::NotFound),
    |d| response::Response::build().header(ContentType::HTML).sized_body(Cursor::new(d)).ok(),
  )
}

#[get("/dist/<file..>")]
fn dist<'r>(file: PathBuf) -> response::Result<'r> {
  let filename = file.display().to_string();
  Asset::get(&filename).map_or_else(
    || Err(Status::NotFound),
    |d| {
      let ext = file
        .as_path()
        .extension()
        .and_then(OsStr::to_str)
        .ok_or_else(|| Status::new(400, "Could not get file extension"))?;
      let content_type = ContentType::from_extension(ext).ok_or_else(|| Status::new(400, "Could not get file content type"))?;
      response::Response::build().header(content_type).sized_body(Cursor::new(d.data)).ok()
    },
  )
}

fn main() {
  rocket::ignite().mount("/", routes![index, dist]).launch();
}
<commit_msg>Fix rocket example index page<commit_after>#![feature(decl_macro, proc_macro_hygiene)]
#[macro_use]
extern crate rocket;

use rocket::http::{ContentType, Status};
use rocket::response;
use rust_embed::RustEmbed;

use std::ffi::OsStr;
use std::io::Cursor;
use std::path::PathBuf;

#[derive(RustEmbed)]
#[folder = "examples/public/"]
struct Asset;

#[get("/")]
fn index<'r>() -> response::Result<'r> {
  Asset::get("index.html").map_or_else(
    || Err(Status::NotFound),
    |d| response::Response::build().header(ContentType::HTML).sized_body(Cursor::new(d.data)).ok(),
  )
}

#[get("/dist/<file..>")]
fn dist<'r>(file: PathBuf) -> response::Result<'r> {
  let filename = file.display().to_string();
  Asset::get(&filename).map_or_else(
    || Err(Status::NotFound),
    |d| {
      let ext = file
        .as_path()
        .extension()
        .and_then(OsStr::to_str)
        .ok_or_else(|| Status::new(400, "Could not get file extension"))?;
      let content_type = ContentType::from_extension(ext).ok_or_else(|| Status::new(400, "Could not get file content type"))?;
      response::Response::build().header(content_type).sized_body(Cursor::new(d.data)).ok()
    },
  )
}

fn main() {
  rocket::ignite().mount("/", routes![index, dist]).launch();
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate mount;
extern crate logger;
extern crate rustc_serialize;
#[macro_use] extern crate juniper;

use mount::Mount;
use logger::Logger;
use iron::prelude::*;
use juniper::FieldResult;
use juniper::iron_handlers::{GraphQLHandler, GraphiQLHandler};

fn context_factory(_: &mut Request) -> () {
    ()
}

fn main() {
    let mut mount = Mount::new();

    let graphql_endpoint = GraphQLHandler::new(context_factory, Query { }, Mutation { });
    let graphiql_endpoint = GraphiQLHandler::new("/graphql");

    mount.mount("/graphiql", graphiql_endpoint);
    mount.mount("/graphql", graphql_endpoint);

    let (logger_before, logger_after) = Logger::new(None);

    let mut chain = Chain::new(mount);
    chain.link_before(logger_before);
    chain.link_after(logger_after);

    let host = "localhost:8080";
    println!("GraphQL server started on {}", host);
    Iron::new(chain).http(host).unwrap();
}

struct Query {}
struct Mutation {}

graphql_object!(Query: () as "Query" |&self| {
    field dummy() -> FieldResult<&str> {
        Ok("Dummy field")
    }

    field error() -> FieldResult<&str> {
        Err("Can't do it".to_owned())
    }
});

graphql_object!(<CtxT> Mutation: CtxT as "Mutation" |&self| {
    field print(value: String) -> FieldResult<String> {
        println!("Printing text according to mutation");
        println!("{}", value);
        Ok(value)
    }
});
<commit_msg>Read environment variable in example server<commit_after>extern crate iron;
extern crate mount;
extern crate logger;
extern crate rustc_serialize;
#[macro_use] extern crate juniper;

use std::env;

use mount::Mount;
use logger::Logger;
use iron::prelude::*;
use juniper::FieldResult;
use juniper::iron_handlers::{GraphQLHandler, GraphiQLHandler};

fn context_factory(_: &mut Request) -> () {
    ()
}

fn main() {
    let mut mount = Mount::new();

    let graphql_endpoint = GraphQLHandler::new(context_factory, Query { }, Mutation { });
    let graphiql_endpoint = GraphiQLHandler::new("/graphql");

    mount.mount("/graphiql", graphiql_endpoint);
    mount.mount("/graphql", graphql_endpoint);

    let (logger_before, logger_after) = Logger::new(None);

    let mut chain = Chain::new(mount);
    chain.link_before(logger_before);
    chain.link_after(logger_after);

    let host = env::var("LISTEN").unwrap_or("0.0.0.0:8080".to_owned());
    println!("GraphQL server started on {}", host);
    Iron::new(chain).http(host.as_str()).unwrap();
}

struct Query {}
struct Mutation {}

graphql_object!(Query: () as "Query" |&self| {
    field dummy() -> FieldResult<&str> {
        Ok("Dummy field")
    }

    field error() -> FieldResult<&str> {
        Err("Can't do it".to_owned())
    }
});

graphql_object!(<CtxT> Mutation: CtxT as "Mutation" |&self| {
    field print(value: String) -> FieldResult<String> {
        println!("Printing text according to mutation");
        println!("{}", value);
        Ok(value)
    }
});
<|endoftext|>


<commit_before>// test1.rs
// This is a test for the following sections:
// - Variables
// - Functions

// Mary is buying apples. One apple usually costs 2 dollars, but if you buy
// more than 40 at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the order amount. No hints this time!

// Put your function here!
// fn ..... {

// Don't modify this function!
#[test]
fn verify_test() {
    let price1 = calculateprice(55);
    let price2 = calculateprice(40);

    assert_eq!(price1, 55);
    assert_eq!(price2, 80);
}
<commit_msg>fix(test1): renamed function name to snake case closes #180<commit_after>// test1.rs
// This is a test for the following sections:
// - Variables
// - Functions

// Mary is buying apples. One apple usually costs 2 dollars, but if you buy
// more than 40 at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the order amount. No hints this time!

// Put your function here!
// fn ..... {

// Don't modify this function!
#[test]
fn verify_test() {
    let price1 = calculate_price(55);
    let price2 = calculate_price(40);

    assert_eq!(price1, 55);
    assert_eq!(price2, 80);
}
<|endoftext|>