<commit_before>use bls::{PublicKey, verify_proof_of_possession};
use types::{BeaconState, Deposit, ValidatorRecord, ValidatorStatus};
use spec::ChainSpec;

/// The size of a validators deposit in GWei.
pub const DEPOSIT_GWEI: u64 = 32_000_000_000;

#[derive(Debug, PartialEq, Clone)]
pub enum ValidatorInductionError {
    InvalidShard,
    InvaidProofOfPossession,
    InvalidWithdrawalCredentials
}

pub fn process_deposit(
    state: &mut BeaconState,
    deposit: &Deposit,
    spec: &ChainSpec)
-> Result<usize, ValidatorInductionError> {
    let deposit_input = &deposit.deposit_data.deposit_input;
    let validator_index = state.validator_registry.iter()
        .position(|validator| validator.pubkey == deposit_input.pubkey);

    match validator_index {
        Some(i) => {
            if state.validator_registry[i].withdrawal_credentials == deposit_input.withdrawal_credentials {
                state.validator_balances[i] += DEPOSIT_GWEI;
                return Ok(i);
            }

            Err(ValidatorInductionError::InvalidWithdrawalCredentials)
        },
        None => {
            let validator = ValidatorRecord {
                pubkey: deposit_input.pubkey.clone(),
                withdrawal_credentials: deposit_input.withdrawal_credentials,
                randao_commitment: deposit_input.randao_commitment,
                randao_layers: 0,
                status: ValidatorStatus::PendingActivation,
                latest_status_change_slot: state.validator_registry_latest_change_slot.clone(),
                exit_count: 0
            };

            match min_empty_validator_index(state, spec) {
                Some(i) => {
                    state.validator_registry[i] = validator;
                    state.validator_balances[i] = DEPOSIT_GWEI;
                    Ok(i)
                },
                None => {
                    state.validator_registry.push(validator);
                    state.validator_balances.push(DEPOSIT_GWEI);
                    Ok(state.validator_registry.len() - 1)
                }
            }
        }
    }
}

fn min_empty_validator_index(
    state: &BeaconState,
    spec: &ChainSpec
) -> Option<usize> {
    for i in 0..state.validator_registry.len() {
        if state.validator_balances[i] == 0
            && state.validator_registry[i].latest_status_change_slot
                + spec.zero_balance_validator_ttl <= state.slot {
            return Some(i);
        }
    }
    None
}

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

    use bls::{Keypair, Signature};
    use hashing::proof_of_possession_hash;
    use types::{Hash256, DepositData, DepositInput};

    fn get_deposit() -> Deposit {
        let kp = Keypair::random();
        let deposit_input = DepositInput {
            pubkey: kp.pk.clone(),
            withdrawal_credentials: Hash256::zero(),
            randao_commitment: Hash256::zero(),
            proof_of_possession: get_proof_of_possession(&kp)
        };
        let deposit_data = DepositData {
            deposit_input: deposit_input,
            value: 0,
            timestamp: 0
        };
        Deposit {
            merkle_branch: Vec::new(),
            merkle_tree_index: 0,
            deposit_data: deposit_data
        }
    }

    fn deposit_equals_record(dep: &Deposit, rec: &ValidatorRecord) -> bool {
        (dep.deposit_data.deposit_input.pubkey == rec.pubkey)
            & (dep.deposit_data.deposit_input.withdrawal_credentials == rec.withdrawal_credentials)
            & (dep.deposit_data.deposit_input.randao_commitment == rec.randao_commitment)
            //& (verify_proof_of_possession(&reg.proof_of_possession, &rec.pubkey))
    }

    /// Generate a proof of possession for some keypair.
    fn get_proof_of_possession(kp: &Keypair) -> Signature {
        let pop_message = proof_of_possession_hash(&kp.pk.as_bytes());
        Signature::new_hashed(&pop_message, &kp.sk)
    }

    #[test]
    fn test_process_deposit_valid_empty_validators() {
        let mut state = BeaconState::default();
        let deposit = get_deposit();
        let spec = ChainSpec::foundation();

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), 0);
        assert!(deposit_equals_record(&deposit, &state.validator_registry[0]));
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposit_empty_validators() {
        let mut state = BeaconState::default();
        let deposit = get_deposit();
        let spec = ChainSpec::foundation();

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), 0);
        assert!(deposit_equals_record(&deposit, &state.validator_registry[0]));
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposits_empty_validators() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        for i in 0..5 {
            let deposit = get_deposit();
            let result = process_deposit(&mut state, &deposit, &spec);
            assert_eq!(result.unwrap(), i);
            assert!(deposit_equals_record(&deposit, &state.validator_registry[i]));
            assert_eq!(state.validator_registry.len(), i + 1);
            assert_eq!(state.validator_balances.len(), i + 1);
        }
    }

    /*
    #[test]
    fn test_validator_inductor_status() {
        let validators = vec![];

        let r = get_registration();

        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let _ = inductor.induct(&r, ValidatorStatus::PendingActivation);
        let _ = inductor.induct(&r, ValidatorStatus::Active);
        let validators = inductor.to_vec();

        assert!(validators[0].status == ValidatorStatus::PendingActivation);
        assert!(validators[1].status == ValidatorStatus::Active);
        assert_eq!(validators.len(), 2);
    }

    #[test]
    fn test_validator_inductor_valid_all_active_validators() {
        let mut validators = vec![];
        for _ in 0..5 {
            let (mut v, _) = ValidatorRecord::zero_with_thread_rand_keypair();
            v.status = ValidatorStatus::Active;
            validators.push(v);
        }

        let r = get_registration();

        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let result = inductor.induct(&r, ValidatorStatus::PendingActivation);
        let validators = inductor.to_vec();

        assert_eq!(result.unwrap(), 5);
        //assert!(registration_equals_record(&r, &validators[5]));
        assert_eq!(validators.len(), 6);
    }

    #[test]
    fn test_validator_inductor_valid_all_second_validator_withdrawn() {
        let mut validators = vec![];
        let (mut v, _) = ValidatorRecord::zero_with_thread_rand_keypair();
        v.status = ValidatorStatus::Active;
        validators.push(v);
        for _ in 0..4 {
            let (mut v, _) = ValidatorRecord::zero_with_thread_rand_keypair();
            v.status = ValidatorStatus::Withdrawn;
            validators.push(v);
        }

        let r = get_registration();

        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let result = inductor.induct(&r, ValidatorStatus::PendingActivation);
        let validators = inductor.to_vec();

        assert_eq!(result.unwrap(), 1);
        //assert!(registration_equals_record(&r, &validators[1]));
        assert_eq!(validators.len(), 5);
    }

    #[test]
    fn test_validator_inductor_valid_all_withdrawn_validators() {
        let mut validators = vec![];
        for _ in 0..5 {
            let (mut v, _) = ValidatorRecord::zero_with_thread_rand_keypair();
            v.status = ValidatorStatus::Withdrawn;
            validators.push(v);
        }

        /*
         * Ensure the first validator gets the 0'th slot
         */
        let r = get_registration();
        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let result = inductor.induct(&r, ValidatorStatus::PendingActivation);
        let validators = inductor.to_vec();
        assert_eq!(result.unwrap(), 0);
        //assert!(registration_equals_record(&r, &validators[0]));

        /*
         * Ensure the second validator gets the 1'st slot
         */
        let r_two = get_registration();
        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let result = inductor.induct(&r_two, ValidatorStatus::PendingActivation);
        let validators = inductor.to_vec();
        assert_eq!(result.unwrap(), 1);
        //assert!(registration_equals_record(&r_two, &validators[1]));
        assert_eq!(validators.len(), 5);
    }

    #[test]
    fn test_validator_inductor_shard_too_high() {
        let validators = vec![];

        let mut r = get_registration();
        r.withdrawal_shard = 1025;

        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let result = inductor.induct(&r, ValidatorStatus::PendingActivation);
        let validators = inductor.to_vec();

        assert_eq!(result, Err(ValidatorInductionError::InvalidShard));
        assert_eq!(validators.len(), 0);
    }

    #[test]
    fn test_validator_inductor_shard_proof_of_possession_failure() {
        let validators = vec![];

        let mut r = get_registration();
        let kp = Keypair::random();
        r.proof_of_possession = get_proof_of_possession(&kp);

        let mut inductor = ValidatorInductor::new(0, 1024, validators);
        let result = inductor.induct(&r, ValidatorStatus::PendingActivation);
        let validators = inductor.to_vec();

        assert_eq!(
            result,
            Err(ValidatorInductionError::InvaidProofOfPossession)
        );
        assert_eq!(validators.len(), 0);
    }
    */
}
<commit_msg>testing around balance increase and zero balance replacement<commit_after>use bls::{PublicKey, verify_proof_of_possession};
use types::{BeaconState, Deposit, ValidatorRecord, ValidatorStatus};
use spec::ChainSpec;

/// The size of a validators deposit in GWei.
pub const DEPOSIT_GWEI: u64 = 32_000_000_000;

#[derive(Debug, PartialEq, Clone)]
pub enum ValidatorInductionError {
    InvalidShard,
    InvaidProofOfPossession,
    InvalidWithdrawalCredentials
}

pub fn process_deposit(
    state: &mut BeaconState,
    deposit: &Deposit,
    spec: &ChainSpec)
-> Result<usize, ValidatorInductionError> {
    let deposit_input = &deposit.deposit_data.deposit_input;
    let deposit_data = &deposit.deposit_data;

    if !verify_proof_of_possession(&deposit_input.proof_of_possession, &deposit_input.pubkey) {
        return Err(ValidatorInductionError::InvaidProofOfPossession);
    }

    let validator_index = state.validator_registry.iter()
        .position(|validator| validator.pubkey == deposit_input.pubkey);

    match validator_index {
        Some(i) => {
            if state.validator_registry[i].withdrawal_credentials == deposit_input.withdrawal_credentials {
                state.validator_balances[i] += deposit_data.value;
                return Ok(i);
            }

            Err(ValidatorInductionError::InvalidWithdrawalCredentials)
        },
        None => {
            let validator = ValidatorRecord {
                pubkey: deposit_input.pubkey.clone(),
                withdrawal_credentials: deposit_input.withdrawal_credentials,
                randao_commitment: deposit_input.randao_commitment,
                randao_layers: 0,
                status: ValidatorStatus::PendingActivation,
                latest_status_change_slot: state.validator_registry_latest_change_slot.clone(),
                exit_count: 0
            };

            match min_empty_validator_index(state, spec) {
                Some(i) => {
                    state.validator_registry[i] = validator;
                    state.validator_balances[i] = deposit_data.value;
                    Ok(i)
                },
                None => {
                    state.validator_registry.push(validator);
                    state.validator_balances.push(deposit_data.value);
                    Ok(state.validator_registry.len() - 1)
                }
            }
        }
    }
}

fn min_empty_validator_index(
    state: &BeaconState,
    spec: &ChainSpec
) -> Option<usize> {
    for i in 0..state.validator_registry.len() {
        if state.validator_balances[i] == 0
            && state.validator_registry[i].latest_status_change_slot
                + spec.zero_balance_validator_ttl <= state.slot {
            return Some(i);
        }
    }
    None
}

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

    use bls::{Keypair, Signature};
    use hashing::proof_of_possession_hash;
    use types::{Hash256, DepositData, DepositInput};

    fn get_deposit() -> Deposit {
        let kp = Keypair::random();
        let deposit_input = DepositInput {
            pubkey: kp.pk.clone(),
            withdrawal_credentials: Hash256::zero(),
            randao_commitment: Hash256::zero(),
            proof_of_possession: get_proof_of_possession(&kp)
        };
        let deposit_data = DepositData {
            deposit_input: deposit_input,
            value: DEPOSIT_GWEI,
            timestamp: 0
        };
        Deposit {
            merkle_branch: Vec::new(),
            merkle_tree_index: 0,
            deposit_data: deposit_data
        }
    }

    fn deposit_equals_record(dep: &Deposit, rec: &ValidatorRecord) -> bool {
        (dep.deposit_data.deposit_input.pubkey == rec.pubkey)
            & (dep.deposit_data.deposit_input.withdrawal_credentials == rec.withdrawal_credentials)
            & (dep.deposit_data.deposit_input.randao_commitment == rec.randao_commitment)
            //& (verify_proof_of_possession(&reg.proof_of_possession, &rec.pubkey))
    }

    /// Generate a proof of possession for some keypair.
    fn get_proof_of_possession(kp: &Keypair) -> Signature {
        let pop_message = proof_of_possession_hash(&kp.pk.as_bytes());
        Signature::new_hashed(&pop_message, &kp.sk)
    }

    #[test]
    fn test_process_deposit_valid_empty_validators() {
        let mut state = BeaconState::default();
        let deposit = get_deposit();
        let spec = ChainSpec::foundation();

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), 0);
        assert!(deposit_equals_record(&deposit, &state.validator_registry[0]));
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposits_empty_validators() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        for i in 0..5 {
            let deposit = get_deposit();
            let result = process_deposit(&mut state, &deposit, &spec);
            assert_eq!(result.unwrap(), i);
            assert!(deposit_equals_record(&deposit, &state.validator_registry[i]));
            assert_eq!(state.validator_registry.len(), i + 1);
            assert_eq!(state.validator_balances.len(), i + 1);
        }
    }

    #[test]
    fn test_process_deposit_top_out() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        let deposit = get_deposit();
        let (mut validator, _) = ValidatorRecord::zero_with_thread_rand_keypair();
        validator.pubkey = deposit.deposit_data.deposit_input.pubkey.clone();
        validator.withdrawal_credentials = deposit.deposit_data.deposit_input.withdrawal_credentials;
        validator.randao_commitment = deposit.deposit_data.deposit_input.randao_commitment;

        state.validator_registry.push(validator);
        state.validator_balances.push(DEPOSIT_GWEI);

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), 0);
        assert!(deposit_equals_record(&deposit, &state.validator_registry[0]));
        assert_eq!(state.validator_balances[0], DEPOSIT_GWEI * 2);
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposit_replace_validator() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        let (mut validator, _) = ValidatorRecord::zero_with_thread_rand_keypair();
        state.validator_registry.push(validator);
        state.validator_balances.push(0);

        let deposit = get_deposit();
        state.slot = spec.zero_balance_validator_ttl;

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), 0);
        assert!(deposit_equals_record(&deposit, &state.validator_registry[0]));
        assert_eq!(state.validator_balances[0], DEPOSIT_GWEI);
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }
}
<|endoftext|>


<commit_before>use bip_handshake::{HandshakerBuilder, InitiateMessage, Protocol, DiscoveryInfo};
use bip_handshake::transports::TcpTransport;

use bip_util::bt::{self};
use tokio_core::reactor::{Core};
use futures::Future;
use futures::stream::Stream;
use futures::sink::Sink;

#[test]
fn positive_connect() {
    let mut core = Core::new().unwrap();

    let mut handshaker_one_addr = "10.0.0.18:0".parse().unwrap();
    let handshaker_one_pid = [4u8; bt::PEER_ID_LEN].into();

    let handshaker_one = HandshakerBuilder::new()
        .with_bind_addr(handshaker_one_addr)
        .with_peer_id(handshaker_one_pid)
        .build::<TcpTransport>(core.handle()).unwrap();

    handshaker_one_addr.set_port(handshaker_one.port());

    let mut handshaker_two_addr = "10.0.0.18:0".parse().unwrap();
    let handshaker_two_pid = [5u8; bt::PEER_ID_LEN].into();

    let handshaker_two = HandshakerBuilder::new()
        .with_bind_addr(handshaker_two_addr)
        .with_peer_id(handshaker_two_pid)
        .build::<TcpTransport>(core.handle()).unwrap();

    handshaker_two_addr.set_port(handshaker_two.port());

    let (item_one, item_two) = core.run(handshaker_one
        .send(InitiateMessage::new(Protocol::BitTorrent, [55u8; bt::INFO_HASH_LEN].into(), handshaker_two_addr))
        .map_err(|_| ())
        .and_then(|handshaker_one| {
            handshaker_one.into_future()
                .join(handshaker_two.into_future())
                .map_err(|_| ())
        })
        .map(|((opt_item_one, _), (opt_item_two, _))| {
            (opt_item_one.unwrap(), opt_item_two.unwrap())
        })
    ).unwrap();

    assert_eq!(handshaker_one_addr, *item_two.address());
    assert_eq!(handshaker_two_addr, *item_one.address());

    assert_eq!(handshaker_one_pid, *item_two.peer_id());
    assert_eq!(handshaker_two_pid, *item_one.peer_id());
}<commit_msg>Update To Use Loopback Address For Integ Test<commit_after>use bip_handshake::{HandshakerBuilder, InitiateMessage, Protocol, DiscoveryInfo};
use bip_handshake::transports::TcpTransport;

use bip_util::bt::{self};
use tokio_core::reactor::{Core};
use futures::Future;
use futures::stream::Stream;
use futures::sink::Sink;

#[test]
fn positive_connect() {
    let mut core = Core::new().unwrap();

    let mut handshaker_one_addr = "127.0.0.1:0".parse().unwrap();
    let handshaker_one_pid = [4u8; bt::PEER_ID_LEN].into();

    let handshaker_one = HandshakerBuilder::new()
        .with_bind_addr(handshaker_one_addr)
        .with_peer_id(handshaker_one_pid)
        .build::<TcpTransport>(core.handle()).unwrap();

    handshaker_one_addr.set_port(handshaker_one.port());

    let mut handshaker_two_addr = "127.0.0.1:0".parse().unwrap();
    let handshaker_two_pid = [5u8; bt::PEER_ID_LEN].into();

    let handshaker_two = HandshakerBuilder::new()
        .with_bind_addr(handshaker_two_addr)
        .with_peer_id(handshaker_two_pid)
        .build::<TcpTransport>(core.handle()).unwrap();

    handshaker_two_addr.set_port(handshaker_two.port());

    let (item_one, item_two) = core.run(handshaker_one
        .send(InitiateMessage::new(Protocol::BitTorrent, [55u8; bt::INFO_HASH_LEN].into(), handshaker_two_addr))
        .map_err(|_| ())
        .and_then(|handshaker_one| {
            handshaker_one.into_future()
                .join(handshaker_two.into_future())
                .map_err(|_| ())
        })
        .map(|((opt_item_one, _), (opt_item_two, _))| {
            (opt_item_one.unwrap(), opt_item_two.unwrap())
        })
    ).unwrap();

    assert_eq!(handshaker_one_addr, *item_two.address());
    assert_eq!(handshaker_two_addr, *item_one.address());

    assert_eq!(handshaker_one_pid, *item_two.peer_id());
    assert_eq!(handshaker_two_pid, *item_one.peer_id());
}<|endoftext|>


<commit_before>extern crate futures;
extern crate futures_cpupool;
extern crate tokio_timer;
extern crate rand;

use futures::future::select_ok;
use std::time::Duration;
use futures::Future;
use futures_cpupool::CpuPool;
use tokio_timer::Timer;
use std::thread;
use rand::{thread_rng, Rng};

fn player_one() -> &'static str {
    let d = thread_rng().gen_range::<u64>(1, 5);
    thread::sleep(Duration::from_secs(d));
    "player_one"
}

fn player_two() -> &'static str {
    let d = thread_rng().gen_range::<u64>(1, 5);
    thread::sleep(Duration::from_secs(d));
    "player two"
}

fn main() {
    let pool = CpuPool::new_num_cpus();
    let timer = Timer::default();
    let timeout = timer.sleep(Duration::from_secs(3)).then(|_| Err(()));

    let one = pool.spawn_fn(|| {
        Ok(player_one())
    });
    let two = pool.spawn_fn(|| {
        Ok(player_two())
    });

    let tasks = vec![one, two];
    let winner = select_ok(tasks).select(timeout).map(|(result, _)| result);
    let result  = winner.wait().ok();

    match result {
        Some(("player_one", _)) => println!("Player one won"),
        Some(("player_two", _)) => println!("Player two won"),
        Some((_,_)) | None => println!("Timed out"),
    }
}
<commit_msg>Fixed error printing second player<commit_after>extern crate futures;
extern crate futures_cpupool;
extern crate tokio_timer;
extern crate rand;

use futures::future::select_ok;
use std::time::Duration;
use futures::Future;
use futures_cpupool::CpuPool;
use tokio_timer::Timer;
use std::thread;
use rand::{thread_rng, Rng};

fn player_one() -> &'static str {
    let d = thread_rng().gen_range::<u64>(1, 5);
    thread::sleep(Duration::from_secs(d));
    "player_one"
}

fn player_two() -> &'static str {
    let d = thread_rng().gen_range::<u64>(1, 5);
    thread::sleep(Duration::from_secs(d));
    "player_two"
}

fn main() {
    let pool = CpuPool::new_num_cpus();
    let timer = Timer::default();
    let timeout = timer.sleep(Duration::from_secs(3)).then(|_| Err(()));

    let one = pool.spawn_fn(|| {
        Ok(player_one())
    });
    let two = pool.spawn_fn(|| {
        Ok(player_two())
    });

    let tasks = vec![one, two];
    let winner = select_ok(tasks).select(timeout).map(|(result, _)| result);
    let result  = winner.wait().ok();

    match result {
        Some(("player_one", _)) => println!("Player one won"),
        Some(("player_two", _)) => println!("Player two won"),
        Some((_,_)) | None => println!("Timed out"),
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/MD5/Implementation
/*
 * Ported from C - Simple MD5 implementation
* on Wikipedia https://en.wikipedia.org/wiki/MD5
*/
use std::iter::range_step;
use std::vec::Vec;
use std::fmt::{Show, Formatter, Result};

#[cfg(not(test))]
fn main() {
    let inputs= [bytes!("a"),
                bytes!("abc"),
                bytes!("message digest"),
                bytes!("abcdefghijklmnopqrstuvwxyz"),
                bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
                bytes!("12345678901234567890123456789012345678901234567890123456789012345678901234567890")];

    inputs.iter().map(|&i|md5(i))
        .advance(|x| {println!("{} ", x); true});
}

// Constants are the integer part of the sines of integers (in radians) * 2^32.
static k:[u32,..64] = [
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 ];

// r specifies the per-round shift amounts
static r:[u32,..64] = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
                      5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
                      4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
                      6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21];

// "newtype" for [u8,..16] to specify it's a MD5 hash
struct MD5([u8,..16]);
impl Show for MD5 {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let mut ret = String :: with_capacity(32u);
        let MD5(md5)=*self;
        for b in md5.as_slice().iter() {
            ret=ret.append(format!("{:02x}", *b).as_slice());
        }
        write!(f,"{}", ret)
    }
}

// leftrotate function definition
#[inline]
fn left_rotate(x: u32, c: u32) -> u32 {
    (x << c) | (x >> (32 - c))
}

fn to_bytes(val: u64) -> [u8,..8]
{
    let mut tmp:[u8,..8] = [0u8,..8];
    for i in range (0u, 8) {
        tmp[i] = (val >> (8*i)) as u8;
    }
    tmp
}

fn md5(initial_msg: &[u8]) -> MD5
{
    let initial_len=initial_msg.len() as u64;

    // These vars will contain the hash
    let mut h:[u32,..4]=[0x67452301u32, 0xefcdab89, 0x98badcfe, 0x10325476];

     //Pre-processing:
    //append "1" bit to message
    //append "0" bits until message length in bits ≡ 448 (mod 512)
    //append length mod (2^64) to message
    let mut new_len=initial_len;
    while new_len % (512/8) != 448/8 {
        new_len+=1;
    }

    { // new block (so msg is freed as soon as not needed any longer)
        let mut msg = Vec::<u8>::from_slice(initial_msg);
        msg.push(0x80u8); // append the "1" bit; most significant bit is "first"

        for _ in range (initial_len + 1, new_len) {
            msg.push(0); // append "0" bits
        }

        // append the len in bits at the end of the buffer.
        let msg=msg.append(to_bytes(initial_len << 3));
//                   .append(to_bytes(initial_len >>29));
        // initial_len>>29 == initial_len*8>>32, but avoids overflow.

        assert_eq!(msg.len() % 64, 0);

        let mut w:[u32,..16] = [0u32,..16];
        // Process the message in successive 512-bit chunks:
        //for each 512-bit chunk of message:
        for offset in range_step(0u64, new_len, (512/8)) {
            // break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
            for i in range(0u32, 16) {
                let j = i as uint * 4 + offset as uint;
                w[i as uint] =
                        (*msg.get(j)   as u32)      |
                        (*msg.get(j+1) as u32) <<8  |
                        (*msg.get(j+2) as u32) <<16 |
                         *msg.get(j+3) as u32  <<24;
            }
            //println!("chunk {}", w);
            // Initialize hash value for this chunk:
            let (mut a, mut b, mut c, mut d) = (h[0], h[1], h[2], h[3]);

            // Main loop:
            for ind in range(0u, 64) {
                let (f,g) = match ind {
                    i @ 0..15   => ( (b & c) | ((!b) & d), //f
                                    i ),                   //g
                    i @ 16..31  => ( (d & b) | ((!d) & c),
                                    (5*i + 1) % 16 ),
                    i @ 32..47  => ( b ^ c ^ d,
                                    (3*i + 5) % 16 ),
                    i @ _       => ( c ^ (b | (!d)),
                                    (7*i) % 16 )
                };

                let temp = d;
                d = c;
                c = b;
                b = b + left_rotate((a + f + k[ind] + w[g]), r[ind]);
                a = temp;
            }

            // Add this chunk's hash to result so far:
            h[0] += a;
            h[1] += b;
            h[2] += c;
            h[3] += d;
        }
    } // cleanup (end block, msg is freed)

    //var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
    let mut digest: [u8,..16]=[0u8,..16];
    for (i, s) in h.iter().enumerate() {
        digest[i*4] = (*s ) as u8;
        digest[i*4+1] = (*s >> 8) as u8;
        digest[i*4+2] = (*s >> 16) as u8;
        digest[i*4+3] = (*s >> 24) as u8;
    }
    MD5(digest)
}

#[test]
fn helper_fns() {
    assert_eq!(64, left_rotate(8, 3));

    //let exp:[u8,..4] = [64u8, 226, 1, 0];
    //assert!(to_bytes(123456) == exp);

}

#[test]
fn known_hashes() {
    let in_out=[(bytes!(""),
        "d41d8cd98f00b204e9800998ecf8427e"),
    (bytes!("a"),
        "0cc175b9c0f1b6a831c399e269772661"),
    (bytes!("abc"),
        "900150983cd24fb0d6963f7d28e17f72"),
    (bytes!("message digest"),
        "f96b697d7cb7938d525a2f31aaf161d0"),
    (bytes!("abcdefghijklmnopqrstuvwxyz"),
        "c3fcd3d76192e4007dfb496cca67e13b"),
    (bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
        "d174ab98d277d9f5a5611c2c9f419d9f"),
    (bytes!("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
        "57edf4a22be3c955ac49da2e2107b67a")];

    for &(i,o) in in_out.iter() {
        let m=md5(i);
        assert_eq!(format!("{}", m), o.to_string());
    }
}<commit_msg>cleaned code per @utkarshkukreti's suggestions<commit_after>// Implements http://rosettacode.org/wiki/MD5/Implementation
/*
 * Ported from C - Simple MD5 implementation
* on Wikipedia https://en.wikipedia.org/wiki/MD5
*/
use std::iter::range_step;
use std::vec::Vec;
use std::fmt::{Show, Formatter, Result};

#[cfg(not(test))]
fn main() {
    let inputs= [bytes!("a"),
                bytes!("abc"),
                bytes!("message digest"),
                bytes!("abcdefghijklmnopqrstuvwxyz"),
                bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
                bytes!("12345678901234567890123456789012345678901234567890123456789012345678901234567890")];

    for &input in inputs.iter() {
        println!("{}", md5(input));
    }
}

// Constants are the integer part of the sines of integers (in radians) * 2^32.
static k:[u32,..64] = [
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 ];

// r specifies the per-round shift amounts
static r:[u32,..64] = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
                      5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
                      4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
                      6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21];

// "newtype" for [u8,..16] to specify it's a MD5 hash
struct MD5([u8,..16]);
impl Show for MD5 {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let MD5(md5)=*self;
        for b in md5.iter() {
            try!(write!(f, "{:02x}", *b));
        }
        Ok(())
    }
}

// leftrotate function definition
#[inline]
fn left_rotate(x: u32, c: u32) -> u32 {
    (x << c) | (x >> (32 - c))
}

fn to_bytes(val: u64) -> [u8,..8]
{
    let mut tmp:[u8,..8] = [0u8,..8];
    for i in range (0u, 8) {
        tmp[i] = (val >> (8*i)) as u8;
    }
    tmp
}

fn md5(initial_msg: &[u8]) -> MD5
{
    let initial_len=initial_msg.len() as u64;

    // These vars will contain the hash
    let mut h:[u32,..4]=[0x67452301u32, 0xefcdab89, 0x98badcfe, 0x10325476];

     //Pre-processing:
    //append "1" bit to message
    //append "0" bits until message length in bits ≡ 448 (mod 512)
    //append length mod (2^64) to message
    let mut new_len=initial_len;
    while new_len % (512/8) != 448/8 {
        new_len+=1;
    }

    { // new block (so msg is freed as soon as not needed any longer)
        let mut msg = Vec::<u8>::from_slice(initial_msg);
        msg.push(0x80u8); // append the "1" bit; most significant bit is "first"

        for _ in range (initial_len + 1, new_len) {
            msg.push(0); // append "0" bits
        }

        // append the len in bits at the end of the buffer.
        let msg=msg.append(to_bytes(initial_len << 3));

        assert_eq!(msg.len() % 64, 0);

        let mut w:[u32,..16] = [0u32,..16];
        // Process the message in successive 512-bit chunks:
        //for each 512-bit chunk of message:
        for offset in range_step(0u64, new_len, (512/8)) {
            // break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
            for i in range(0u32, 16) {
                let j = i as uint * 4 + offset as uint;
                w[i as uint] =
                        (*msg.get(j)   as u32)      |
                        (*msg.get(j+1) as u32) <<8  |
                        (*msg.get(j+2) as u32) <<16 |
                         *msg.get(j+3) as u32  <<24;
            }
            //println!("chunk {}", w);
            // Initialize hash value for this chunk:
            let (mut a, mut b, mut c, mut d) = (h[0], h[1], h[2], h[3]);

            // Main loop:
            for ind in range(0u, 64) {
                let (f,g) = match ind {
                    i @ 0..15   => ( (b & c) | ((!b) & d), //f
                                    i ),                   //g
                    i @ 16..31  => ( (d & b) | ((!d) & c),
                                    (5*i + 1) % 16 ),
                    i @ 32..47  => ( b ^ c ^ d,
                                    (3*i + 5) % 16 ),
                    i @ _       => ( c ^ (b | (!d)),
                                    (7*i) % 16 )
                };

                let temp = d;
                d = c;
                c = b;
                b = b + left_rotate((a + f + k[ind] + w[g]), r[ind]);
                a = temp;
            }

            // Add this chunk's hash to result so far:
            h[0] += a;
            h[1] += b;
            h[2] += c;
            h[3] += d;
        }
    } // cleanup (end block, msg is freed)

    //var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
    let mut digest: [u8,..16]=[0u8,..16];
    for (i, s) in h.iter().enumerate() {
        digest[i*4] = (*s ) as u8;
        digest[i*4+1] = (*s >> 8) as u8;
        digest[i*4+2] = (*s >> 16) as u8;
        digest[i*4+3] = (*s >> 24) as u8;
    }
    MD5(digest)
}

#[test]
fn helper_fns() {
    assert_eq!(64, left_rotate(8, 3));

    let exp:[u8,..8] = [64u8, 226, 1, 0, 0, 0, 0, 0];
    assert!(to_bytes(123456) == exp);
}

#[test]
fn known_hashes() {
    let in_out=[(bytes!(""),
        "d41d8cd98f00b204e9800998ecf8427e"),
    (bytes!("a"),
        "0cc175b9c0f1b6a831c399e269772661"),
    (bytes!("abc"),
        "900150983cd24fb0d6963f7d28e17f72"),
    (bytes!("message digest"),
        "f96b697d7cb7938d525a2f31aaf161d0"),
    (bytes!("abcdefghijklmnopqrstuvwxyz"),
        "c3fcd3d76192e4007dfb496cca67e13b"),
    (bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
        "d174ab98d277d9f5a5611c2c9f419d9f"),
    (bytes!("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
        "57edf4a22be3c955ac49da2e2107b67a")];

    for &(i,o) in in_out.iter() {
        let m=md5(i);
        assert_eq!(format!("{}", m), o.to_string());
    }
}<|endoftext|>


<commit_before>use message::{Message, PatternId};
use MiliSec;
use state::State;

const FIRST_OPENS_DEFAULT: bool = false;
const LAST_CLOSES_DEFAULT: bool = false;

#[derive(Clone, Debug)]
pub struct Conditions {
    pub timeout: MiliSec,
    pub renew_timeout: Option<MiliSec>,
    pub first_opens: Option<bool>,
    pub last_closes: Option<bool>,
    pub max_size: Option<usize>,
    pub patterns: Vec<PatternId>
}

impl Conditions {
    fn new(timeout: MiliSec) -> Conditions {
        Conditions {
            timeout: timeout,
            renew_timeout: None,
            first_opens: None,
            last_closes: None,
            max_size: None,
            patterns: Vec::new()
        }
    }

    pub fn is_opening(&self, message: &Message) -> bool {
        if self.first_opens.unwrap_or(FIRST_OPENS_DEFAULT) {
            self.patterns.first().unwrap() == message.uuid()
        } else {
            true
        }
    }

    pub fn is_closing(&self, state: &State) -> bool {
        self.is_max_size_reached(state) || self.is_closing_message(state) || self.is_any_timer_expired(state)
    }

    fn is_max_size_reached(&self, state: &State) -> bool {
        self.max_size.map_or(false, |max_size| state.messages().len() >= max_size)
    }

    fn is_closing_message(&self, state: &State) -> bool {
        if self.last_closes.unwrap_or(LAST_CLOSES_DEFAULT) {
            self.patterns.last().unwrap() == state.messages().last().unwrap().uuid()
        } else {
            false
        }
    }

    fn is_any_timer_expired(&self, state: &State) -> bool {
        self.is_timeout_expired(state) || self.is_renew_timeout_expired(state)
    }

    fn is_timeout_expired(&self, state: &State) -> bool {
        state.elapsed_time() >= self.timeout
    }

    fn is_renew_timeout_expired(&self, state: &State) -> bool {
        self.renew_timeout.map_or(false, |renew_timeout| {
            state.elapsed_time_since_last_message() >= renew_timeout
        })
    }
}

pub struct Builder {
    conditions: Conditions
}

impl Builder {
    pub fn new(timeout: MiliSec) -> Builder {
        Builder{
            conditions: Conditions::new(timeout)
        }
    }

    pub fn renew_timeout(&mut self, timeout: MiliSec) -> &mut Builder {
        self.conditions.renew_timeout = Some(timeout);
        self
    }

    pub fn first_opens(&mut self, first_opens: bool) -> &mut Builder {
        self.conditions.first_opens = Some(first_opens);
        self
    }

    pub fn last_closes(&mut self, last_closes: bool) -> &mut Builder {
        self.conditions.last_closes = Some(last_closes);
        self
    }
    pub fn max_size(&mut self, max_size: usize) -> &mut Builder {
        self.conditions.max_size = Some(max_size);
        self
    }

    pub fn patterns(&mut self, patterns: Vec<PatternId>) -> &mut Builder {
        self.conditions.patterns = patterns;
        self
    }

    pub fn build(&mut self) -> Conditions {
        self.conditions.clone()
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;

    use message;
    use message::{PatternId};
    use state::State;
    use super::Builder;

    #[test]
    fn test_given_condition_when_an_opening_message_is_received_then_the_state_becomes_opened() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
        ];
        let condition = Builder::new(timeout).patterns(patterns).first_opens(true).build();
        let msg_which_should_not_be_ignored = message::Builder::new(&msg_id1).build();
        let msg_which_should_be_ignored = message::Builder::new(&msg_id2).build();
        assert_false!(condition.is_opening(&msg_which_should_be_ignored));
        assert_true!(condition.is_opening(&msg_which_should_not_be_ignored));
    }

    #[test]
    fn test_given_condition_when_a_closing_message_is_received_then_the_state_becomes_closed() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
            PatternId::Uuid(msg_id2.clone()),
        ];
        let mut state = State::new();
        let condition = Builder::new(timeout).patterns(patterns).last_closes(true).build();
        let msg_1 = message::Builder::new(&msg_id1).build();
        let msg_closing = Rc::new(message::Builder::new(&msg_id2).build());
        assert_true!(condition.is_opening(&msg_1));
        state.open();
        state.add_message(msg_closing);
        assert_true!(condition.is_closing(&mut state));
    }
}

mod deser {

    use super::Conditions;
    use serde;
    use serde::de::Deserialize;

    impl serde::Deserialize for Conditions {
        fn deserialize<D>(deserializer: &mut D) -> Result<Conditions, D::Error>
            where D: serde::de::Deserializer
        {
            deserializer.visit_struct("Conditions", &[], ConditionsVisitor)
        }
    }

    enum Field {
        TIMEOUT,
        RENEW_TIMEOUT,
        FIRST_OPENS,
        LAST_CLOSES,
        MAX_SIZE,
        PATTERNS,
    }

    impl serde::Deserialize for Field {
        fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
            where D: serde::de::Deserializer
        {
            struct FieldVisitor;

            impl serde::de::Visitor for FieldVisitor {
                type Value = Field;

                fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                    where E: serde::de::Error
                {
                    match value {
                        "timeout" => Ok(Field::TIMEOUT),
                        "renew_timeout" => Ok(Field::RENEW_TIMEOUT),
                        "first_opens" => Ok(Field::FIRST_OPENS),
                        "last_closes" => Ok(Field::LAST_CLOSES),
                        "max_size" => Ok(Field::MAX_SIZE),
                        "patterns" => Ok(Field::PATTERNS),
                        name @ _ => Err(serde::de::Error::syntax(&format!("Unexpected field: {}", name))),
                    }
                }
            }

            deserializer.visit(FieldVisitor)
        }
    }

    struct ConditionsVisitor;

    impl serde::de::Visitor for ConditionsVisitor {
        type Value = Conditions;

        fn visit_map<V>(&mut self, mut visitor: V) -> Result<Conditions, V::Error>
            where V: serde::de::MapVisitor
        {
            let mut timeout = None;
            let mut renew_timeout = None;
            let mut first_opens = None;
            let mut last_closes = None;
            let mut max_size = None;
            let mut patterns = None;
            let mut values = None;

            loop {
                match try!(visitor.visit_key()) {
                    Some(Field::TIMEOUT) => { timeout = Some(try!(visitor.visit_value())); }
                    Some(Field::RENEW_TIMEOUT) => { renew_timeout = Some(try!(visitor.visit_value())); }
                    Some(Field::FIRST_OPENS) => { first_opens = Some(try!(visitor.visit_value())); }
                    Some(Field::LAST_CLOSES) => { last_closes = Some(try!(visitor.visit_value())); }
                    Some(Field::MAX_SIZE) => { max_size = Some(try!(visitor.visit_value())); }
                    Some(Field::PATTERNS) => { patterns = Some(try!(visitor.visit_value())); }
                    None => { break; }
                }
            }

            let timeout = try!(timeout.ok_or(visitor.missing_field("timeout")));

            try!(visitor.end());

            Ok(
                Conditions {
                    timeout: timeout,
                    renew_timeout: renew_timeout,
                    first_opens: first_opens,
                    last_closes: last_closes,
                    max_size: max_size,
                    patterns: patterns.unwrap_or(Vec::new())
                }
            )
        }
    }
}
<commit_msg>Conditions: remove compiler warnings<commit_after>use message::{Message, PatternId};
use MiliSec;
use state::State;

const FIRST_OPENS_DEFAULT: bool = false;
const LAST_CLOSES_DEFAULT: bool = false;

#[derive(Clone, Debug)]
pub struct Conditions {
    pub timeout: MiliSec,
    pub renew_timeout: Option<MiliSec>,
    pub first_opens: Option<bool>,
    pub last_closes: Option<bool>,
    pub max_size: Option<usize>,
    pub patterns: Vec<PatternId>
}

impl Conditions {
    fn new(timeout: MiliSec) -> Conditions {
        Conditions {
            timeout: timeout,
            renew_timeout: None,
            first_opens: None,
            last_closes: None,
            max_size: None,
            patterns: Vec::new()
        }
    }

    pub fn is_opening(&self, message: &Message) -> bool {
        if self.first_opens.unwrap_or(FIRST_OPENS_DEFAULT) {
            self.patterns.first().unwrap() == message.uuid()
        } else {
            true
        }
    }

    pub fn is_closing(&self, state: &State) -> bool {
        self.is_max_size_reached(state) || self.is_closing_message(state) || self.is_any_timer_expired(state)
    }

    fn is_max_size_reached(&self, state: &State) -> bool {
        self.max_size.map_or(false, |max_size| state.messages().len() >= max_size)
    }

    fn is_closing_message(&self, state: &State) -> bool {
        if self.last_closes.unwrap_or(LAST_CLOSES_DEFAULT) {
            self.patterns.last().unwrap() == state.messages().last().unwrap().uuid()
        } else {
            false
        }
    }

    fn is_any_timer_expired(&self, state: &State) -> bool {
        self.is_timeout_expired(state) || self.is_renew_timeout_expired(state)
    }

    fn is_timeout_expired(&self, state: &State) -> bool {
        state.elapsed_time() >= self.timeout
    }

    fn is_renew_timeout_expired(&self, state: &State) -> bool {
        self.renew_timeout.map_or(false, |renew_timeout| {
            state.elapsed_time_since_last_message() >= renew_timeout
        })
    }
}

pub struct Builder {
    conditions: Conditions
}

impl Builder {
    pub fn new(timeout: MiliSec) -> Builder {
        Builder{
            conditions: Conditions::new(timeout)
        }
    }

    pub fn renew_timeout(&mut self, timeout: MiliSec) -> &mut Builder {
        self.conditions.renew_timeout = Some(timeout);
        self
    }

    pub fn first_opens(&mut self, first_opens: bool) -> &mut Builder {
        self.conditions.first_opens = Some(first_opens);
        self
    }

    pub fn last_closes(&mut self, last_closes: bool) -> &mut Builder {
        self.conditions.last_closes = Some(last_closes);
        self
    }
    pub fn max_size(&mut self, max_size: usize) -> &mut Builder {
        self.conditions.max_size = Some(max_size);
        self
    }

    pub fn patterns(&mut self, patterns: Vec<PatternId>) -> &mut Builder {
        self.conditions.patterns = patterns;
        self
    }

    pub fn build(&mut self) -> Conditions {
        self.conditions.clone()
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;

    use message;
    use message::{PatternId};
    use state::State;
    use super::Builder;

    #[test]
    fn test_given_condition_when_an_opening_message_is_received_then_the_state_becomes_opened() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
        ];
        let condition = Builder::new(timeout).patterns(patterns).first_opens(true).build();
        let msg_which_should_not_be_ignored = message::Builder::new(&msg_id1).build();
        let msg_which_should_be_ignored = message::Builder::new(&msg_id2).build();
        assert_false!(condition.is_opening(&msg_which_should_be_ignored));
        assert_true!(condition.is_opening(&msg_which_should_not_be_ignored));
    }

    #[test]
    fn test_given_condition_when_a_closing_message_is_received_then_the_state_becomes_closed() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
            PatternId::Uuid(msg_id2.clone()),
        ];
        let mut state = State::new();
        let condition = Builder::new(timeout).patterns(patterns).last_closes(true).build();
        let msg_1 = message::Builder::new(&msg_id1).build();
        let msg_closing = Rc::new(message::Builder::new(&msg_id2).build());
        assert_true!(condition.is_opening(&msg_1));
        state.open();
        state.add_message(msg_closing);
        assert_true!(condition.is_closing(&mut state));
    }
}

mod deser {
    use MiliSec;
    use super::Conditions;
    use serde;
    use serde::de::Deserialize;

    impl serde::Deserialize for Conditions {
        fn deserialize<D>(deserializer: &mut D) -> Result<Conditions, D::Error>
            where D: serde::de::Deserializer
        {
            deserializer.visit_struct("Conditions", &[], ConditionsVisitor)
        }
    }

    enum Field {
        Timeout,
        RenewTimeout,
        FirstOpens,
        LastCloses,
        MaxSize,
        Patterns,
    }

    impl serde::Deserialize for Field {
        fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
            where D: serde::de::Deserializer
        {
            struct FieldVisitor;

            impl serde::de::Visitor for FieldVisitor {
                type Value = Field;

                fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                    where E: serde::de::Error
                {
                    match value {
                        "timeout" => Ok(Field::Timeout),
                        "renew_timeout" => Ok(Field::RenewTimeout),
                        "first_opens" => Ok(Field::FirstOpens),
                        "last_closes" => Ok(Field::LastCloses),
                        "max_size" => Ok(Field::MaxSize),
                        "patterns" => Ok(Field::Patterns),
                        name @ _ => Err(serde::de::Error::syntax(&format!("Unexpected field: {}", name))),
                    }
                }
            }

            deserializer.visit(FieldVisitor)
        }
    }

    struct ConditionsVisitor;

    impl serde::de::Visitor for ConditionsVisitor {
        type Value = Conditions;

        fn visit_map<V>(&mut self, mut visitor: V) -> Result<Conditions, V::Error>
            where V: serde::de::MapVisitor
        {
            let mut timeout: Option<MiliSec> = None;
            let mut renew_timeout = None;
            let mut first_opens = None;
            let mut last_closes = None;
            let mut max_size = None;
            let mut patterns = None;

            loop {
                match try!(visitor.visit_key()) {
                    Some(Field::Timeout) => { timeout = Some(try!(visitor.visit_value())); }
                    Some(Field::RenewTimeout) => { renew_timeout = Some(try!(visitor.visit_value())); }
                    Some(Field::FirstOpens) => { first_opens = Some(try!(visitor.visit_value())); }
                    Some(Field::LastCloses) => { last_closes = Some(try!(visitor.visit_value())); }
                    Some(Field::MaxSize) => { max_size = Some(try!(visitor.visit_value())); }
                    Some(Field::Patterns) => { patterns = Some(try!(visitor.visit_value())); }
                    None => { break; }
                }
            }

            let timeout: MiliSec = match timeout {
                Some(timeout) => timeout,
                None => return visitor.missing_field("timeout"),
            };

            try!(visitor.end());

            Ok(
                Conditions {
                    timeout: timeout,
                    renew_timeout: renew_timeout,
                    first_opens: first_opens,
                    last_closes: last_closes,
                    max_size: max_size,
                    patterns: patterns.unwrap_or(Vec::new())
                }
            )
        }
    }
}
<|endoftext|>


<commit_before>use log::{LogRecord, LogLevel, SetLoggerError};
use env_logger::LogBuilder;
use colored::*;

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

use blockchain::GenesisConfig;
use node::NodeConfig;
use crypto::gen_keypair;

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 = vec![gen_keypair(); count as usize];
    let services = vec![gen_keypair(); count as usize];
    let genesis = GenesisConfig::new(validators.iter().map(|x| x.0), services.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()
        .zip(services.into_iter())
        .enumerate()
        .map(|(idx, (validator, service))| {
            NodeConfig {
                listen_address: peers[idx],
                network: Default::default(),
                peers: peers.clone(),
                consensus_public_key: validator.0,
                consensus_secret_key: validator.1,
                service_public_key: service.0,
                service_secret_key: service.1,
                genesis: genesis.clone(),
                whitelist: Default::default(),
                api: Default::default(),
            }
        })
        .collect::<Vec<_>>()
}

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>Testnet keys generation fix<commit_after>use log::{LogRecord, LogLevel, SetLoggerError};
use env_logger::LogBuilder;
use colored::*;

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

use blockchain::GenesisConfig;
use node::NodeConfig;
use crypto::gen_keypair;

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, services): (Vec<_>, Vec<_>) = (0..count as usize)
        .map(|_| (gen_keypair(), gen_keypair())).unzip();
    let genesis = GenesisConfig::new(validators.iter().map(|x| x.0), services.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()
        .zip(services.into_iter())
        .enumerate()
        .map(|(idx, (validator, service))| {
            NodeConfig {
                listen_address: peers[idx],
                network: Default::default(),
                peers: peers.clone(),
                consensus_public_key: validator.0,
                consensus_secret_key: validator.1,
                service_public_key: service.0,
                service_secret_key: service.1,
                genesis: genesis.clone(),
                whitelist: Default::default(),
                api: Default::default(),
            }
        })
        .collect::<Vec<_>>()
}

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>#![crate_id = "chroot#1.0.0"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Vsevolod Velichko <torkvemada@sorokdva.net>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]
extern crate getopts;
extern crate libc;

use getopts::{optflag, optopt, getopts, usage};
use c_types::{get_pw_from_args, get_group};
use libc::funcs::posix88::unistd::{execvp, setuid, setgid};

#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;

extern {
    fn chroot(path: *libc::c_char) -> libc::c_int;
    fn setgroups(size: libc::c_int, list: *libc::gid_t) -> libc::c_int;
}

static NAME: &'static str = "chroot";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main () { std::os::set_exit_status(uumain(std::os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0);

    let options = [
        optopt("u", "user", "User (ID or name) to switch before running the program", "USER"),
        optopt("g", "group", "Group (ID or name) to switch to", "GROUP"),
        optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2…"),
        optopt("", "userspec", "Colon-separated user and group to switch to. \
                                Same as -u USER -g GROUP. \
                                Userspec has higher preference than -u and/or -g", "USER:GROUP"),
        optflag("h", "help", "Show help"),
        optflag("V", "version", "Show program's version")
    ];

    let opts = match getopts(args.tail(), options) {
        Ok(m) => {m}
        Err(f) => {
            println!("{}", f);
            help_menu(program.as_slice(), options);
            return 1
        }
    };

    if opts.opt_present("V") { version(); return 0 }
    if opts.opt_present("h") { help_menu(program.as_slice(), options); return 0 }

    if opts.free.len() == 0 {
        println!("Missing operand: NEWROOT");
        println!("Try `{:s} --help` for more information.", program.as_slice());
        return 1
    }

    let defaultShell: &'static str = "/bin/sh";
    let defaultOption: &'static str = "-i";
    let userShell = std::os::getenv("SHELL");

    let newroot = Path::new(opts.free.get(0).as_slice());
    if !newroot.is_dir() {
        crash!(1, "cannot change root directory to `{}`: no such directory", newroot.display());
    }

    let command: Vec<&str> = match opts.free.len() {
        1 => {
            let shell: &str = match userShell {
                None => {defaultShell}
                Some(ref s) => {s.as_slice()}
            };
            vec!(shell, defaultOption)
        }
        _ => { opts.free.slice(1, opts.free.len()).iter().map(|x| x.as_slice()).collect() }
    };

    set_context(&newroot, &opts);

    unsafe {
        let executable = command.get(0).as_slice().to_c_str().unwrap();
        let mut commandParts: Vec<*i8> = command.iter().map(|x| x.to_c_str().unwrap()).collect();
        commandParts.push(std::ptr::null());
        execvp(executable as *libc::c_char, commandParts.as_ptr() as **libc::c_char) as int
    }
}

fn set_context(root: &Path, options: &getopts::Matches) {
    let userspecStr = options.opt_str("userspec");
    let userStr = options.opt_str("user").unwrap_or_default();
    let groupStr = options.opt_str("group").unwrap_or_default();
    let groupsStr = options.opt_str("groups").unwrap_or_default();
    let userspec = match userspecStr {
        Some(ref u) => {
            let s: Vec<&str> = u.as_slice().split(':').collect();
            if s.len() != 2 {
                crash!(1, "invalid userspec: `{:s}`", u.as_slice())
            };
            s
        }
        None => { Vec::new() }
    };
    let user = if userspec.is_empty() { userStr.as_slice() } else { userspec.get(0).as_slice() };
    let group = if userspec.is_empty() { groupStr.as_slice() } else { userspec.get(1).as_slice() };

    enter_chroot(root);

    set_groups(groupsStr.as_slice());
    set_main_group(group);
    set_user(user);
}

fn enter_chroot(root: &Path) {
    let rootStr = root.display();
    if !std::os::change_dir(root) {
        crash!(1, "cannot chdir to {}", rootStr)
    };
    let err = unsafe {
        chroot(".".to_c_str().unwrap() as *libc::c_char)
    };
    if err != 0 {
        crash!(1, "cannot chroot to {}: {:s}", rootStr, strerror(err).as_slice())
    };
}

fn set_main_group(group: &str) {
    if !group.is_empty() {
        let group_id = match get_group(group) {
            None => { crash!(1, "no such group: {}", group) }
            Some(g) => g.gr_gid
        };
        let err = unsafe { setgid(group_id) };
        if err != 0 {
            crash!(1, "cannot set gid to {:u}: {:s}", group_id, strerror(err).as_slice())
        }
    }
}

fn set_groups(groups: &str) {
    if !groups.is_empty() {
        let groupsVec: Vec<libc::gid_t> = FromIterator::from_iter(
            groups.split(',').map(
                |x| match get_group(x) {
                    None => { crash!(1, "no such group: {}", x) }
                    Some(g) => { g.gr_gid }
                })
            );
        let err = unsafe {
            setgroups(groupsVec.len() as libc::c_int,
                      groupsVec.as_slice().as_ptr() as *libc::gid_t)
        };
        if err != 0 {
            crash!(1, "cannot set groups: {:s}", strerror(err).as_slice())
        }
    }
}

fn set_user(user: &str) {
    if !user.is_empty() {
        let user_id = get_pw_from_args(&vec!(String::from_str(user))).unwrap().pw_uid;
        let err = unsafe { setuid(user_id as libc::uid_t) };
        if err != 0 {
            crash!(1, "cannot set user to {:s}: {:s}", user, strerror(err).as_slice())
        }
    }
}

fn strerror(errno: i32) -> String {
    unsafe {
        let err = libc::funcs::c95::string::strerror(errno);
        std::str::raw::from_c_str(err)
    }
}

fn version() {
    println!("{} v{}", NAME, VERSION)
}

fn help_menu(program: &str, options: &[getopts::OptGroup]) {
    version();
    println!("Usage:");
    println!("  {:s} [OPTION]… NEWROOT [COMMAND [ARG]…]", program);
    println!("");
    print!("{:s}", usage(
            "Run COMMAND with root directory set to NEWROOT.\n\
             If COMMAND is not specified, it defaults to '${SHELL} -i'. \
             If ${SHELL} is not set, /bin/sh is used.", options))
}
<commit_msg>Remove redundant braces, show_error for getopt parse error<commit_after>#![crate_id = "chroot#1.0.0"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Vsevolod Velichko <torkvemada@sorokdva.net>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]
extern crate getopts;
extern crate libc;

use getopts::{optflag, optopt, getopts, usage};
use c_types::{get_pw_from_args, get_group};
use libc::funcs::posix88::unistd::{execvp, setuid, setgid};

#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;

extern {
    fn chroot(path: *libc::c_char) -> libc::c_int;
    fn setgroups(size: libc::c_int, list: *libc::gid_t) -> libc::c_int;
}

static NAME: &'static str = "chroot";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main () { std::os::set_exit_status(uumain(std::os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0);

    let options = [
        optopt("u", "user", "User (ID or name) to switch before running the program", "USER"),
        optopt("g", "group", "Group (ID or name) to switch to", "GROUP"),
        optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2…"),
        optopt("", "userspec", "Colon-separated user and group to switch to. \
                                Same as -u USER -g GROUP. \
                                Userspec has higher preference than -u and/or -g", "USER:GROUP"),
        optflag("h", "help", "Show help"),
        optflag("V", "version", "Show program's version")
    ];

    let opts = match getopts(args.tail(), options) {
        Ok(m) => m,
        Err(f) => {
            show_error!("{}", f);
            help_menu(program.as_slice(), options);
            return 1
        }
    };

    if opts.opt_present("V") { version(); return 0 }
    if opts.opt_present("h") { help_menu(program.as_slice(), options); return 0 }

    if opts.free.len() == 0 {
        println!("Missing operand: NEWROOT");
        println!("Try `{:s} --help` for more information.", program.as_slice());
        return 1
    }

    let defaultShell: &'static str = "/bin/sh";
    let defaultOption: &'static str = "-i";
    let userShell = std::os::getenv("SHELL");

    let newroot = Path::new(opts.free.get(0).as_slice());
    if !newroot.is_dir() {
        crash!(1, "cannot change root directory to `{}`: no such directory", newroot.display());
    }

    let command: Vec<&str> = match opts.free.len() {
        1 => {
            let shell: &str = match userShell {
                None => {defaultShell}
                Some(ref s) => {s.as_slice()}
            };
            vec!(shell, defaultOption)
        }
        _ => opts.free.slice(1, opts.free.len()).iter().map(|x| x.as_slice()).collect()
    };

    set_context(&newroot, &opts);

    unsafe {
        let executable = command.get(0).as_slice().to_c_str().unwrap();
        let mut commandParts: Vec<*i8> = command.iter().map(|x| x.to_c_str().unwrap()).collect();
        commandParts.push(std::ptr::null());
        execvp(executable as *libc::c_char, commandParts.as_ptr() as **libc::c_char) as int
    }
}

fn set_context(root: &Path, options: &getopts::Matches) {
    let userspecStr = options.opt_str("userspec");
    let userStr = options.opt_str("user").unwrap_or_default();
    let groupStr = options.opt_str("group").unwrap_or_default();
    let groupsStr = options.opt_str("groups").unwrap_or_default();
    let userspec = match userspecStr {
        Some(ref u) => {
            let s: Vec<&str> = u.as_slice().split(':').collect();
            if s.len() != 2 {
                crash!(1, "invalid userspec: `{:s}`", u.as_slice())
            };
            s
        }
        None => Vec::new()
    };
    let user = if userspec.is_empty() { userStr.as_slice() } else { userspec.get(0).as_slice() };
    let group = if userspec.is_empty() { groupStr.as_slice() } else { userspec.get(1).as_slice() };

    enter_chroot(root);

    set_groups(groupsStr.as_slice());
    set_main_group(group);
    set_user(user);
}

fn enter_chroot(root: &Path) {
    let rootStr = root.display();
    if !std::os::change_dir(root) {
        crash!(1, "cannot chdir to {}", rootStr)
    };
    let err = unsafe {
        chroot(".".to_c_str().unwrap() as *libc::c_char)
    };
    if err != 0 {
        crash!(1, "cannot chroot to {}: {:s}", rootStr, strerror(err).as_slice())
    };
}

fn set_main_group(group: &str) {
    if !group.is_empty() {
        let group_id = match get_group(group) {
            None => crash!(1, "no such group: {}", group),
            Some(g) => g.gr_gid
        };
        let err = unsafe { setgid(group_id) };
        if err != 0 {
            crash!(1, "cannot set gid to {:u}: {:s}", group_id, strerror(err).as_slice())
        }
    }
}

fn set_groups(groups: &str) {
    if !groups.is_empty() {
        let groupsVec: Vec<libc::gid_t> = FromIterator::from_iter(
            groups.split(',').map(
                |x| match get_group(x) {
                    None => crash!(1, "no such group: {}", x),
                    Some(g) => g.gr_gid
                })
            );
        let err = unsafe {
            setgroups(groupsVec.len() as libc::c_int,
                      groupsVec.as_slice().as_ptr() as *libc::gid_t)
        };
        if err != 0 {
            crash!(1, "cannot set groups: {:s}", strerror(err).as_slice())
        }
    }
}

fn set_user(user: &str) {
    if !user.is_empty() {
        let user_id = get_pw_from_args(&vec!(String::from_str(user))).unwrap().pw_uid;
        let err = unsafe { setuid(user_id as libc::uid_t) };
        if err != 0 {
            crash!(1, "cannot set user to {:s}: {:s}", user, strerror(err).as_slice())
        }
    }
}

fn strerror(errno: i32) -> String {
    unsafe {
        let err = libc::funcs::c95::string::strerror(errno);
        std::str::raw::from_c_str(err)
    }
}

fn version() {
    println!("{} v{}", NAME, VERSION)
}

fn help_menu(program: &str, options: &[getopts::OptGroup]) {
    version();
    println!("Usage:");
    println!("  {:s} [OPTION]… NEWROOT [COMMAND [ARG]…]", program);
    println!("");
    print!("{:s}", usage(
            "Run COMMAND with root directory set to NEWROOT.\n\
             If COMMAND is not specified, it defaults to '${SHELL} -i'. \
             If ${SHELL} is not set, /bin/sh is used.", options))
}
<|endoftext|>


<commit_before>use std::{
    collections::BTreeMap,
    convert::{TryFrom, TryInto},
    fmt,
};

use js_int::Int;
use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize};
use serde_json::{to_string as to_json_string, Value as JsonValue};

use super::Error;

/// The inner type of `CanonicalJsonValue::Object`.
pub type Object = BTreeMap<String, CanonicalJsonValue>;

#[derive(Clone, Eq, PartialEq)]
pub enum CanonicalJsonValue {
    /// Represents a JSON null value.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(null).try_into().unwrap();
    /// ```
    Null,

    /// Represents a JSON boolean.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(true).try_into().unwrap();
    /// ```
    Bool(bool),

    /// Represents a JSON integer.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(12).try_into().unwrap();
    /// ```
    Integer(Int),

    /// Represents a JSON string.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!("a string").try_into().unwrap();
    /// ```
    String(String),

    /// Represents a JSON array.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(["an", "array"]).try_into().unwrap();
    /// ```
    Array(Vec<CanonicalJsonValue>),

    /// Represents a JSON object.
    ///
    /// The map is backed by a BTreeMap to guarantee the sorting of keys.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!({ "an": "object" }).try_into().unwrap();
    /// ```
    Object(Object),
}

impl Default for CanonicalJsonValue {
    fn default() -> Self {
        Self::Null
    }
}

impl fmt::Debug for CanonicalJsonValue {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Self::Null => formatter.debug_tuple("Null").finish(),
            Self::Bool(v) => formatter.debug_tuple("Bool").field(&v).finish(),
            Self::Integer(ref v) => fmt::Debug::fmt(v, formatter),
            Self::String(ref v) => formatter.debug_tuple("String").field(v).finish(),
            Self::Array(ref v) => {
                formatter.write_str("Array(")?;
                fmt::Debug::fmt(v, formatter)?;
                formatter.write_str(")")
            }
            Self::Object(ref v) => {
                formatter.write_str("Object(")?;
                fmt::Debug::fmt(v, formatter)?;
                formatter.write_str(")")
            }
        }
    }
}

impl fmt::Display for CanonicalJsonValue {
    /// Display this value as a string.
    ///
    /// This `Display` implementation is intentionally unaffected by any formatting parameters,
    /// because adding extra whitespace or otherwise pretty-printing it would make it not the
    /// canonical form anymore.
    ///
    /// If you want to pretty-print a `CanonicalJsonValue` for debugging purposes, use
    /// one of `serde_json::{to_string_pretty, to_vec_pretty, to_writer_pretty}`.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", to_json_string(&self).map_err(|_| fmt::Error)?)
    }
}

impl TryFrom<JsonValue> for CanonicalJsonValue {
    type Error = Error;

    fn try_from(val: JsonValue) -> Result<Self, Self::Error> {
        Ok(match val {
            JsonValue::Bool(b) => Self::Bool(b),
            JsonValue::Number(num) => Self::Integer(
                Int::try_from(num.as_i64().ok_or(Error::IntConvert)?)
                    .map_err(|_| Error::IntConvert)?,
            ),
            JsonValue::Array(vec) => {
                Self::Array(vec.into_iter().map(TryInto::try_into).collect::<Result<Vec<_>, _>>()?)
            }
            JsonValue::String(string) => Self::String(string),
            JsonValue::Object(obj) => Self::Object(
                obj.into_iter()
                    .map(|(k, v)| Ok((k, v.try_into()?)))
                    .collect::<Result<Object, _>>()?,
            ),
            JsonValue::Null => Self::Null,
        })
    }
}

impl From<CanonicalJsonValue> for JsonValue {
    fn from(val: CanonicalJsonValue) -> Self {
        match val {
            CanonicalJsonValue::Bool(b) => Self::Bool(b),
            CanonicalJsonValue::Integer(int) => Self::Number(i64::from(int).into()),
            CanonicalJsonValue::String(string) => Self::String(string),
            CanonicalJsonValue::Array(vec) => {
                Self::Array(vec.into_iter().map(Into::into).collect())
            }
            CanonicalJsonValue::Object(obj) => {
                Self::Object(obj.into_iter().map(|(k, v)| (k, v.into())).collect())
            }
            CanonicalJsonValue::Null => Self::Null,
        }
    }
}

impl Serialize for CanonicalJsonValue {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Self::Null => serializer.serialize_unit(),
            Self::Bool(b) => serializer.serialize_bool(*b),
            Self::Integer(n) => n.serialize(serializer),
            Self::String(s) => serializer.serialize_str(s),
            Self::Array(v) => v.serialize(serializer),
            Self::Object(m) => {
                use serde::ser::SerializeMap;
                let mut map = serializer.serialize_map(Some(m.len()))?;
                for (k, v) in m {
                    map.serialize_entry(k, v)?;
                }
                map.end()
            }
        }
    }
}

impl<'de> Deserialize<'de> for CanonicalJsonValue {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<CanonicalJsonValue, D::Error>
    where
        D: Deserializer<'de>,
    {
        let val = JsonValue::deserialize(deserializer)?;
        val.try_into().map_err(serde::de::Error::custom)
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryInto;

    use serde_json::json;

    use super::CanonicalJsonValue;

    #[test]
    fn to_string() {
        const CANONICAL_STR: &str = r#"{"city":"London","street":"10 Downing Street"}"#;

        let json: CanonicalJsonValue =
            json!({ "city": "London", "street": "10 Downing Street" }).try_into().unwrap();

        assert_eq!(format!("{}", json), CANONICAL_STR);
        assert_eq!(format!("{:#}", json), CANONICAL_STR);
    }
}
<commit_msg>serde: Add &self accessor methods to CanonicalJsonValue<commit_after>use std::{
    collections::BTreeMap,
    convert::{TryFrom, TryInto},
    fmt,
};

use js_int::Int;
use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize};
use serde_json::{to_string as to_json_string, Value as JsonValue};

use super::Error;

/// The inner type of `CanonicalJsonValue::Object`.
pub type Object = BTreeMap<String, CanonicalJsonValue>;

#[derive(Clone, Eq, PartialEq)]
pub enum CanonicalJsonValue {
    /// Represents a JSON null value.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(null).try_into().unwrap();
    /// ```
    Null,

    /// Represents a JSON boolean.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(true).try_into().unwrap();
    /// ```
    Bool(bool),

    /// Represents a JSON integer.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(12).try_into().unwrap();
    /// ```
    Integer(Int),

    /// Represents a JSON string.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!("a string").try_into().unwrap();
    /// ```
    String(String),

    /// Represents a JSON array.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!(["an", "array"]).try_into().unwrap();
    /// ```
    Array(Vec<CanonicalJsonValue>),

    /// Represents a JSON object.
    ///
    /// The map is backed by a BTreeMap to guarantee the sorting of keys.
    ///
    /// ```
    /// # use serde_json::json;
    /// # use std::convert::TryInto;
    /// # use ruma_serde::CanonicalJsonValue;
    /// let v: CanonicalJsonValue = json!({ "an": "object" }).try_into().unwrap();
    /// ```
    Object(Object),
}

impl CanonicalJsonValue {
    /// If the `CanonicalJsonValue` is a `Bool`, return the inner value.
    pub fn as_bool(&self) -> Option<bool> {
        match self {
            Self::Bool(b) => Some(*b),
            _ => None,
        }
    }

    /// If the `CanonicalJsonValue` is an `Integer`, return the inner value.
    pub fn as_integer(&self) -> Option<Int> {
        match self {
            Self::Integer(i) => Some(*i),
            _ => None,
        }
    }

    /// If the `CanonicalJsonValue` is a `String`, return a reference to the inner value.
    pub fn as_str(&self) -> Option<&str> {
        match self {
            Self::String(s) => Some(s),
            _ => None,
        }
    }

    /// If the `CanonicalJsonValue` is an `Array`, return a reference to the inner value.
    pub fn as_array(&self) -> Option<&[CanonicalJsonValue]> {
        match self {
            Self::Array(a) => Some(a),
            _ => None,
        }
    }

    /// If the `CanonicalJsonValue` is an `Object`, return a reference to the inner value.
    pub fn as_object(&self) -> Option<&Object> {
        match self {
            Self::Object(o) => Some(o),
            _ => None,
        }
    }
}

impl Default for CanonicalJsonValue {
    fn default() -> Self {
        Self::Null
    }
}

impl fmt::Debug for CanonicalJsonValue {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Self::Null => formatter.debug_tuple("Null").finish(),
            Self::Bool(v) => formatter.debug_tuple("Bool").field(&v).finish(),
            Self::Integer(ref v) => fmt::Debug::fmt(v, formatter),
            Self::String(ref v) => formatter.debug_tuple("String").field(v).finish(),
            Self::Array(ref v) => {
                formatter.write_str("Array(")?;
                fmt::Debug::fmt(v, formatter)?;
                formatter.write_str(")")
            }
            Self::Object(ref v) => {
                formatter.write_str("Object(")?;
                fmt::Debug::fmt(v, formatter)?;
                formatter.write_str(")")
            }
        }
    }
}

impl fmt::Display for CanonicalJsonValue {
    /// Display this value as a string.
    ///
    /// This `Display` implementation is intentionally unaffected by any formatting parameters,
    /// because adding extra whitespace or otherwise pretty-printing it would make it not the
    /// canonical form anymore.
    ///
    /// If you want to pretty-print a `CanonicalJsonValue` for debugging purposes, use
    /// one of `serde_json::{to_string_pretty, to_vec_pretty, to_writer_pretty}`.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", to_json_string(&self).map_err(|_| fmt::Error)?)
    }
}

impl TryFrom<JsonValue> for CanonicalJsonValue {
    type Error = Error;

    fn try_from(val: JsonValue) -> Result<Self, Self::Error> {
        Ok(match val {
            JsonValue::Bool(b) => Self::Bool(b),
            JsonValue::Number(num) => Self::Integer(
                Int::try_from(num.as_i64().ok_or(Error::IntConvert)?)
                    .map_err(|_| Error::IntConvert)?,
            ),
            JsonValue::Array(vec) => {
                Self::Array(vec.into_iter().map(TryInto::try_into).collect::<Result<Vec<_>, _>>()?)
            }
            JsonValue::String(string) => Self::String(string),
            JsonValue::Object(obj) => Self::Object(
                obj.into_iter()
                    .map(|(k, v)| Ok((k, v.try_into()?)))
                    .collect::<Result<Object, _>>()?,
            ),
            JsonValue::Null => Self::Null,
        })
    }
}

impl From<CanonicalJsonValue> for JsonValue {
    fn from(val: CanonicalJsonValue) -> Self {
        match val {
            CanonicalJsonValue::Bool(b) => Self::Bool(b),
            CanonicalJsonValue::Integer(int) => Self::Number(i64::from(int).into()),
            CanonicalJsonValue::String(string) => Self::String(string),
            CanonicalJsonValue::Array(vec) => {
                Self::Array(vec.into_iter().map(Into::into).collect())
            }
            CanonicalJsonValue::Object(obj) => {
                Self::Object(obj.into_iter().map(|(k, v)| (k, v.into())).collect())
            }
            CanonicalJsonValue::Null => Self::Null,
        }
    }
}

impl Serialize for CanonicalJsonValue {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Self::Null => serializer.serialize_unit(),
            Self::Bool(b) => serializer.serialize_bool(*b),
            Self::Integer(n) => n.serialize(serializer),
            Self::String(s) => serializer.serialize_str(s),
            Self::Array(v) => v.serialize(serializer),
            Self::Object(m) => {
                use serde::ser::SerializeMap;
                let mut map = serializer.serialize_map(Some(m.len()))?;
                for (k, v) in m {
                    map.serialize_entry(k, v)?;
                }
                map.end()
            }
        }
    }
}

impl<'de> Deserialize<'de> for CanonicalJsonValue {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<CanonicalJsonValue, D::Error>
    where
        D: Deserializer<'de>,
    {
        let val = JsonValue::deserialize(deserializer)?;
        val.try_into().map_err(serde::de::Error::custom)
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryInto;

    use serde_json::json;

    use super::CanonicalJsonValue;

    #[test]
    fn to_string() {
        const CANONICAL_STR: &str = r#"{"city":"London","street":"10 Downing Street"}"#;

        let json: CanonicalJsonValue =
            json!({ "city": "London", "street": "10 Downing Street" }).try_into().unwrap();

        assert_eq!(format!("{}", json), CANONICAL_STR);
        assert_eq!(format!("{:#}", json), CANONICAL_STR);
    }
}
<|endoftext|>


<commit_before>extern crate zip;

use std::io::prelude::*;
use zip::write::FileOptions;
use std::io::Cursor;

// This test asserts that after creating a zip file, then reading its contents back out,
// the extracted data will *always* be exactly the same as the original data.
#[test]
fn main() {
    // TODO: The buffer length is tied to the LOREM_IPSUM length currently
    let buf: &mut [u8] = &mut [0u8; 760];
    let mut file = Cursor::new(buf);

    write_to_zip_file(&mut file).expect("file written");

    let file_contents: String = read_zip_file(file).unwrap();

    assert!(file_contents.as_bytes() == LOREM_IPSUM);
}

fn write_to_zip_file(file: &mut Cursor<&mut [u8]>) -> zip::result::ZipResult<()> {
    let mut zip = zip::ZipWriter::new(file);

    zip.add_directory("test/", FileOptions::default())?;

    let options = FileOptions::default()
        .compression_method(zip::CompressionMethod::Stored)
        .unix_permissions(0o755);
    zip.start_file("test/☃.txt", options)?;
    zip.write_all(b"Hello, World!\n")?;

    zip.start_file("test/lorem_ipsum.txt", FileOptions::default())?;
    zip.write_all(LOREM_IPSUM)?;

    zip.finish()?;
    Ok(())
}

fn read_zip_file(zip_file: Cursor<&mut [u8]>) -> zip::result::ZipResult<String> {
    let mut archive = zip::ZipArchive::new(zip_file).unwrap();

    let mut file = archive.by_name("test/lorem_ipsum.txt")?;

    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    Ok(contents)
}

const LOREM_IPSUM : &'static [u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tellus elit, tristique vitae mattis egestas, ultricies vitae risus. Quisque sit amet quam ut urna aliquet
molestie. Proin blandit ornare dui, a tempor nisl accumsan in. Praesent a consequat felis. Morbi metus diam, auctor in auctor vel, feugiat id odio. Curabitur ex ex,
dictum quis auctor quis, suscipit id lorem. Aliquam vestibulum dolor nec enim vehicula, porta tristique augue tincidunt. Vivamus ut gravida est. Sed pellentesque, dolor
vitae tristique consectetur, neque lectus pulvinar dui, sed feugiat purus diam id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Maecenas feugiat velit in ex ultrices scelerisque id id neque.
";
<commit_msg>Revert to Vec<u8> owned by cursor<commit_after>extern crate zip;

use std::io::prelude::*;
use zip::write::FileOptions;
use std::io::Cursor;

// This test asserts that after creating a zip file, then reading its contents back out,
// the extracted data will *always* be exactly the same as the original data.
#[test]
fn main() {
    let file = &mut Cursor::new(Vec::new());

    write_to_zip_file(file).expect("file written");

    let file_contents: String = read_zip_file(file).unwrap();

    assert!(file_contents.as_bytes() == LOREM_IPSUM);
}

fn write_to_zip_file(file: &mut Cursor<Vec<u8>>) -> zip::result::ZipResult<()> {
    let mut zip = zip::ZipWriter::new(file);

    zip.add_directory("test/", FileOptions::default())?;

    let options = FileOptions::default()
        .compression_method(zip::CompressionMethod::Stored)
        .unix_permissions(0o755);
    zip.start_file("test/☃.txt", options)?;
    zip.write_all(b"Hello, World!\n")?;

    zip.start_file("test/lorem_ipsum.txt", FileOptions::default())?;
    zip.write_all(LOREM_IPSUM)?;

    zip.finish()?;
    Ok(())
}

fn read_zip_file(zip_file: &mut Cursor<Vec<u8>>) -> zip::result::ZipResult<String> {
    let mut archive = zip::ZipArchive::new(zip_file).unwrap();

    let mut file = archive.by_name("test/lorem_ipsum.txt")?;

    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    Ok(contents)
}

const LOREM_IPSUM : &'static [u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tellus elit, tristique vitae mattis egestas, ultricies vitae risus. Quisque sit amet quam ut urna aliquet
molestie. Proin blandit ornare dui, a tempor nisl accumsan in. Praesent a consequat felis. Morbi metus diam, auctor in auctor vel, feugiat id odio. Curabitur ex ex,
dictum quis auctor quis, suscipit id lorem. Aliquam vestibulum dolor nec enim vehicula, porta tristique augue tincidunt. Vivamus ut gravida est. Sed pellentesque, dolor
vitae tristique consectetur, neque lectus pulvinar dui, sed feugiat purus diam id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Maecenas feugiat velit in ex ultrices scelerisque id id neque.
";
<|endoftext|>