<commit_before>extern crate serde;
extern crate serde_json;
extern crate hyper;

#[macro_use]
extern crate serde_derive;

use std::process::{Command};
use std::io::Read;
use hyper::header::ContentType;
use hyper::client::Client;
use serde_json::Value;

#[derive(Serialize, Deserialize)]
struct RPCRequest {
    jsonrpc: String,
    method: String,
    params: Vec<String>,
    id: usize,
}

#[derive(Serialize, Deserialize)]
struct RPCObjectRequest<T> {
    jsonrpc: String,
    method: String,
    params: T,
    id: usize,
}

#[derive(Serialize, Deserialize)]
struct RPCObjectResponse<T> {
    jsonrpc: String,
    result: T,
    id: usize,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCTransaction {
    pub hash: String,
    pub nonce: String,
    pub blockHash: String,
    pub blockNumber: String,
    pub transactionIndex: String,
    pub from: String,
    pub to: String,
    pub value: String,
    pub gas: String,
    pub gasPrice: String,
    pub input: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCBlock {
    pub number: String,
    pub hash: String,
    pub parentHash: String,
    pub nonce: String,
    pub sha3Uncles: String,
    pub logsBloom: String,
    pub transactionsRoot: String,
    pub stateRoot: String,
    pub miner: String,
    pub difficulty: String,
    pub totalDifficulty: String,
    pub extraData: String,
    pub size: String,
    pub gasLimit: String,
    pub gasUsed: String,
    pub timestamp: String,
    pub transactions: Vec<String>,
    pub uncles: Vec<String>
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum RPCSyncStatus {
    NotSync(bool),
    Sync {
        startingBlock: String,
        currentBlock: String,
        highestBlock: String,
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCTransactionReceipt {
    pub transactionHash: String,
    pub transactionIndex: String,
    pub blockHash: String,
    pub blockNumber: String,
    pub cumulativeGasUsed: String,
    pub gasUsed: String,
    pub contractAddress: String,
    pub logs: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCFilter {
    pub fromBlock: String,
    pub toBlock: String,
    pub address: String,
    pub topics: Vec<String>,
}

pub struct GethRPCClient {
    endpoint: String,
    free_id: usize,
}

impl GethRPCClient {
    pub fn new(endpoint: &str) -> Self {
        GethRPCClient {
            endpoint: endpoint.to_string(),
            free_id: 1,
        }
    }

    fn rpc_request<T: serde::Deserialize>(&mut self, method: &str, params: Vec<String>) -> T {
        self.rpc_object_request::<Vec<String>, T>(method, params)
    }

    fn rpc_object_request<Req: serde::Serialize, Res: serde::Deserialize>(&mut self, method: &str, params: Req) -> Res {
        let request = RPCObjectRequest {
            jsonrpc: "2.0".to_string(),
            method: method.to_string(),
            params: params,
            id: self.free_id,
        };
        self.free_id = self.free_id + 1;

        let client = Client::new();
        let mut response_raw = client.post(&self.endpoint)
            .header(ContentType::json())
            .body(&serde_json::to_string(&request).unwrap())
            .send().unwrap();
        let mut buffer = String::new();
        response_raw.read_to_string(&mut buffer).unwrap();

        let response: RPCObjectResponse<Res> = serde_json::from_str(&buffer).unwrap();
        response.result
    }

    pub fn client_version(&mut self) -> String {
        self.rpc_request::<String>("web3_clientVersion", vec![])
    }

    pub fn net_version(&mut self) -> String {
        self.rpc_request::<String>("net_version", vec![])
    }

    pub fn net_listening(&mut self) -> bool {
        self.rpc_request::<bool>("net_listening", vec![])
    }

    pub fn net_peer_count(&mut self) -> String {
        self.rpc_request::<String>("net_peerCount", vec![])
    }

    pub fn sha3(&mut self, data: &str) -> String {
        self.rpc_request::<String>("web3_sha3", vec![])
    }

    pub fn protocol_version(&mut self) -> String {
        self.rpc_request::<String>("eth_protocolVersion", vec![])
    }

    pub fn syncing(&mut self) -> RPCSyncStatus {
        self.rpc_request::<RPCSyncStatus>("eth_syncing", vec![])
    }

    pub fn coinbase(&mut self) -> String {
        self.rpc_request::<String>("eth_coinbase", vec![])
    }

    pub fn mining(&mut self) -> bool {
        self.rpc_request::<bool>("eth_mining", vec![])
    }

    pub fn hashrate(&mut self) -> String {
        self.rpc_request::<String>("eth_hashrate", vec![])
    }

    pub fn gas_price(&mut self) -> String {
        self.rpc_request::<String>("eth_gasPrice", vec![])
    }

    pub fn accounts(&mut self) -> Vec<String> {
        self.rpc_request::<Vec<String>>("eth_accounts", vec![])
    }

    pub fn block_number(&mut self) -> String {
        self.rpc_request::<String>("eth_blockNumber", vec![])
    }

    pub fn get_balance(&mut self, address: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getBalance",
                                   vec![address.to_string(), number.to_string()])
    }

    pub fn get_storage_at(&mut self, address: &str, index: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getStorageAt",
                                   vec![address.to_string(), index.to_string(), number.to_string()])
    }

    pub fn get_transaction_count(&mut self, address: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getTransactionCount",
                                   vec![address.to_string(), number.to_string()])
    }

    pub fn get_block_transaction_count_by_hash(&mut self, hash: &str) -> String {
        self.rpc_request::<String>("eth_getBlockTransactionCountByHash",
                                   vec![hash.to_string()])
    }

    pub fn get_block_transaction_count_by_number(&mut self, number: &str) -> String {
        self.rpc_request::<String>("eth_getBlockTransactionCountByNumber",
                                   vec![number.to_string()])
    }

    pub fn get_uncle_count_by_block_hash(&mut self, hash: &str) -> String {
        self.rpc_request::<String>("eth_getUncleCountByBlockHash",
                                   vec![hash.to_string()])
    }

    pub fn get_uncle_count_by_block_number(&mut self, number: &str) -> String {
        self.rpc_request::<String>("eth_getUncleCountByBlockNumber",
                                   vec![number.to_string()])
    }

    pub fn get_code(&mut self, address: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getCode", vec![address.to_string(), number.to_string()])
    }

    pub fn sign(&mut self, address: &str, message: &str) -> String {
        self.rpc_request::<String>("eth_sign", vec![address.to_string(), message.to_string()])
    }

    pub fn send_transaction(&mut self, transaction: RPCTransaction) -> String {
        unimplemented!()
    }

    pub fn send_raw_transaction(&mut self, data: &str) -> String {
        self.rpc_request::<String>("eth_sendRawTransaction", vec![data.to_string()])
    }

    pub fn call(&mut self, transaction: RPCTransaction) -> String {
        unimplemented!()
    }

    pub fn estimate_gas(&mut self, transaction: RPCTransaction) -> String {
        unimplemented!()
    }

    pub fn get_block_by_hash(&mut self, hash: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getBlockByHash",
                                     vec![hash.to_string(), "false".to_string()])
    }

    pub fn get_block_by_number(&mut self, number: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getBlockByNumber",
                                     vec![number.to_string(), "false".to_string()])
    }

    pub fn get_transaction_by_hash(&mut self, hash: &str) -> RPCTransaction {
        self.rpc_request::<RPCTransaction>("eth_getTransactionByHash",
                                           vec![hash.to_string()])
    }

    pub fn get_transaction_by_block_hash_and_index(&mut self, hash: &str, index: &str) -> RPCTransaction {
        self.rpc_request::<RPCTransaction>("eth_getTransactionByBlockHashAndIndex",
                                           vec![hash.to_string(), index.to_string()])
    }

    pub fn get_transaction_by_block_number_and_index(&mut self, number: &str, index: &str)
                                                 -> RPCTransaction {
        self.rpc_request::<RPCTransaction>("eth_getTransactionByBlockNumberAndIndex",
                                           vec![number.to_string(), index.to_string()])
    }

    pub fn get_transaction_receipt(&mut self, hash: &str) -> RPCTransactionReceipt {
        self.rpc_request::<RPCTransactionReceipt>("eth_getTransactionReceipt",
                                                 vec![hash.to_string()])
    }

    pub fn get_uncle_by_block_hash_and_index(&mut self, hash: &str, index: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getUncleByBlockHashAndIndex",
                                     vec![hash.to_string(), index.to_string()])
    }

    pub fn get_uncle_by_block_number_and_index(&mut self, number: &str, index: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getUncleByBlockNumberAndIndex",
                                     vec![number.to_string(), index.to_string()])
    }

    pub fn get_compilers(&mut self) -> Vec<String> {
        self.rpc_request::<Vec<String>>("eth_getCompilers", vec![])
    }

    pub fn compile_solidity(&mut self, source: &str) -> String {
        unimplemented!()
    }

    pub fn compile_lll(&mut self, source: &str) -> String {
        self.rpc_request::<String>("eth_compileLLL", vec![source.to_string()])
    }

    pub fn compile_serpent(&mut self, source: &str) -> String {
        self.rpc_request::<String>("eth_compileSerpent", vec![source.to_string()])
    }

    pub fn new_filter(&mut self, filter: RPCFilter) -> String {
        unimplemented!()
    }

    pub fn new_block_filter(&mut self) -> String {
        self.rpc_request::<String>("eth_newBlockFilter", vec![])
    }

    pub fn new_pending_transaction_filter(&mut self) -> String {
        self.rpc_request::<String>("eth_newPendingTransactionFilter", vec![])
    }

    pub fn uninstall_filter(&mut self, id: &str) -> bool {
        self.rpc_request::<bool>("eth_uninstallFilter", vec![id.to_string()])
    }

    pub fn get_filter_changes(&mut self, id: &str) -> String {
        unimplemented!()
    }

    pub fn get_filter_logs(&mut self, id: &str) -> String {
        unimplemented!()
    }

    pub fn get_logs(&mut self, id: &str) -> String {
        unimplemented!()
    }

    pub fn get_work(&mut self) -> Vec<String> {
        self.rpc_request::<Vec<String>>("eth_getWork", vec![])
    }

    pub fn submit_work(&mut self, nonce: &str, pow: &str, mix: &str) -> bool {
        self.rpc_request::<bool>("eth_submitWork",
                                 vec![nonce.to_string(), pow.to_string(), mix.to_string()])
    }

    pub fn submit_hashrate(&mut self, hashrate: &str, id: &str) -> bool {
        self.rpc_request::<bool>("eth_submitHashrate",
                                 vec![hashrate.to_string(), id.to_string()])
    }

    pub fn put_string(&mut self, db: &str, key: &str, value: &str) -> bool {
        self.rpc_request::<bool>("db_putString",
                                 vec![db.to_string(), key.to_string(), value.to_string()])
    }

    pub fn get_string(&mut self, db: &str, key: &str) -> String {
        self.rpc_request::<String>("db_getString",
                                   vec![db.to_string(), key.to_string()])
    }

    pub fn put_hex(&mut self, db: &str, key: &str, value: &str) -> bool {
        self.rpc_request::<bool>("db_putHex",
                                 vec![db.to_string(), key.to_string(), value.to_string()])
    }

    pub fn get_hex(&mut self, db: &str, key: &str) -> String {
        self.rpc_request::<String>("db_getHex",
                                   vec![db.to_string(), key.to_string()])
    }
}

pub fn regression(address: &str) -> bool {
    let mut client = GethRPCClient::new("http://localhost:8545");
    let height = usize::from_str_radix(&client.block_number(), 16).unwrap();
    println!("height: {}", height);

    for blk_no in 49439..height {
        let block = client.get_block_by_number(format!("0x{:x}", blk_no).as_str());
        println!("{:?}", block);
    }
    false
}
<commit_msg>Problem: eth_call was unimpl! due to no support of string params<commit_after>extern crate serde;
extern crate serde_json;
extern crate hyper;

#[macro_use]
extern crate serde_derive;

use std::process::{Command};
use std::io::Read;
use hyper::header::ContentType;
use hyper::client::Client;
use serde_json::Value;

#[derive(Serialize, Deserialize)]
struct RPCRequest {
    jsonrpc: String,
    method: String,
    params: Vec<String>,
    id: usize,
}

#[derive(Serialize, Deserialize)]
struct RPCObjectRequest<T> {
    jsonrpc: String,
    method: String,
    params: T,
    id: usize,
}

#[derive(Serialize, Deserialize)]
struct RPCObjectResponse<T> {
    jsonrpc: String,
    result: T,
    id: usize,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCTransaction {
    pub hash: String,
    pub nonce: String,
    pub blockHash: String,
    pub blockNumber: String,
    pub transactionIndex: String,
    pub from: String,
    pub to: String,
    pub value: String,
    pub gas: String,
    pub gasPrice: String,
    pub input: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCBlock {
    pub number: String,
    pub hash: String,
    pub parentHash: String,
    pub nonce: String,
    pub sha3Uncles: String,
    pub logsBloom: String,
    pub transactionsRoot: String,
    pub stateRoot: String,
    pub miner: String,
    pub difficulty: String,
    pub totalDifficulty: String,
    pub extraData: String,
    pub size: String,
    pub gasLimit: String,
    pub gasUsed: String,
    pub timestamp: String,
    pub transactions: Vec<String>,
    pub uncles: Vec<String>
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum RPCSyncStatus {
    NotSync(bool),
    Sync {
        startingBlock: String,
        currentBlock: String,
        highestBlock: String,
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCTransactionReceipt {
    pub transactionHash: String,
    pub transactionIndex: String,
    pub blockHash: String,
    pub blockNumber: String,
    pub cumulativeGasUsed: String,
    pub gasUsed: String,
    pub contractAddress: String,
    pub logs: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RPCFilter {
    pub fromBlock: String,
    pub toBlock: String,
    pub address: String,
    pub topics: Vec<String>,
}

pub struct GethRPCClient {
    endpoint: String,
    free_id: usize,
}

impl GethRPCClient {
    pub fn new(endpoint: &str) -> Self {
        GethRPCClient {
            endpoint: endpoint.to_string(),
            free_id: 1,
        }
    }

    fn rpc_request<T: serde::Deserialize>(&mut self, method: &str, params: Vec<String>) -> T {
        self.rpc_object_request::<Vec<String>, T>(method, params)
    }

    fn rpc_object_request<Req: serde::Serialize, Res: serde::Deserialize>(&mut self, method: &str, params: Req) -> Res {
        let request = RPCObjectRequest {
            jsonrpc: "2.0".to_string(),
            method: method.to_string(),
            params: params,
            id: self.free_id,
        };
        self.free_id = self.free_id + 1;

        let client = Client::new();
        let mut response_raw = client.post(&self.endpoint)
            .header(ContentType::json())
            .body(&serde_json::to_string(&request).unwrap())
            .send().unwrap();
        let mut buffer = String::new();
        response_raw.read_to_string(&mut buffer).unwrap();

        let response: RPCObjectResponse<Res> = serde_json::from_str(&buffer).unwrap();
        response.result
    }

    pub fn client_version(&mut self) -> String {
        self.rpc_request::<String>("web3_clientVersion", vec![])
    }

    pub fn net_version(&mut self) -> String {
        self.rpc_request::<String>("net_version", vec![])
    }

    pub fn net_listening(&mut self) -> bool {
        self.rpc_request::<bool>("net_listening", vec![])
    }

    pub fn net_peer_count(&mut self) -> String {
        self.rpc_request::<String>("net_peerCount", vec![])
    }

    pub fn sha3(&mut self, data: &str) -> String {
        self.rpc_request::<String>("web3_sha3", vec![])
    }

    pub fn protocol_version(&mut self) -> String {
        self.rpc_request::<String>("eth_protocolVersion", vec![])
    }

    pub fn syncing(&mut self) -> RPCSyncStatus {
        self.rpc_request::<RPCSyncStatus>("eth_syncing", vec![])
    }

    pub fn coinbase(&mut self) -> String {
        self.rpc_request::<String>("eth_coinbase", vec![])
    }

    pub fn mining(&mut self) -> bool {
        self.rpc_request::<bool>("eth_mining", vec![])
    }

    pub fn hashrate(&mut self) -> String {
        self.rpc_request::<String>("eth_hashrate", vec![])
    }

    pub fn gas_price(&mut self) -> String {
        self.rpc_request::<String>("eth_gasPrice", vec![])
    }

    pub fn accounts(&mut self) -> Vec<String> {
        self.rpc_request::<Vec<String>>("eth_accounts", vec![])
    }

    pub fn block_number(&mut self) -> String {
        self.rpc_request::<String>("eth_blockNumber", vec![])
    }

    pub fn get_balance(&mut self, address: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getBalance",
                                   vec![address.to_string(), number.to_string()])
    }

    pub fn get_storage_at(&mut self, address: &str, index: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getStorageAt",
                                   vec![address.to_string(), index.to_string(), number.to_string()])
    }

    pub fn get_transaction_count(&mut self, address: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getTransactionCount",
                                   vec![address.to_string(), number.to_string()])
    }

    pub fn get_block_transaction_count_by_hash(&mut self, hash: &str) -> String {
        self.rpc_request::<String>("eth_getBlockTransactionCountByHash",
                                   vec![hash.to_string()])
    }

    pub fn get_block_transaction_count_by_number(&mut self, number: &str) -> String {
        self.rpc_request::<String>("eth_getBlockTransactionCountByNumber",
                                   vec![number.to_string()])
    }

    pub fn get_uncle_count_by_block_hash(&mut self, hash: &str) -> String {
        self.rpc_request::<String>("eth_getUncleCountByBlockHash",
                                   vec![hash.to_string()])
    }

    pub fn get_uncle_count_by_block_number(&mut self, number: &str) -> String {
        self.rpc_request::<String>("eth_getUncleCountByBlockNumber",
                                   vec![number.to_string()])
    }

    pub fn get_code(&mut self, address: &str, number: &str) -> String {
        self.rpc_request::<String>("eth_getCode", vec![address.to_string(), number.to_string()])
    }

    pub fn sign(&mut self, address: &str, message: &str) -> String {
        self.rpc_request::<String>("eth_sign", vec![address.to_string(), message.to_string()])
    }

    pub fn send_transaction(&mut self, transaction: RPCTransaction) -> String {
        unimplemented!()
    }

    pub fn send_raw_transaction(&mut self, data: &str) -> String {
        self.rpc_request::<String>("eth_sendRawTransaction", vec![data.to_string()])
    }

    pub fn call(&mut self, transaction: RPCTransaction) -> String {
        self.rpc_object_request::<[RPCTransaction; 1], String>("eth_call", [transaction])
    }

    pub fn estimate_gas(&mut self, transaction: RPCTransaction) -> String {
        unimplemented!()
    }

    pub fn get_block_by_hash(&mut self, hash: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getBlockByHash",
                                     vec![hash.to_string(), "false".to_string()])
    }

    pub fn get_block_by_number(&mut self, number: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getBlockByNumber",
                                     vec![number.to_string(), "false".to_string()])
    }

    pub fn get_transaction_by_hash(&mut self, hash: &str) -> RPCTransaction {
        self.rpc_request::<RPCTransaction>("eth_getTransactionByHash",
                                           vec![hash.to_string()])
    }

    pub fn get_transaction_by_block_hash_and_index(&mut self, hash: &str, index: &str) -> RPCTransaction {
        self.rpc_request::<RPCTransaction>("eth_getTransactionByBlockHashAndIndex",
                                           vec![hash.to_string(), index.to_string()])
    }

    pub fn get_transaction_by_block_number_and_index(&mut self, number: &str, index: &str)
                                                 -> RPCTransaction {
        self.rpc_request::<RPCTransaction>("eth_getTransactionByBlockNumberAndIndex",
                                           vec![number.to_string(), index.to_string()])
    }

    pub fn get_transaction_receipt(&mut self, hash: &str) -> RPCTransactionReceipt {
        self.rpc_request::<RPCTransactionReceipt>("eth_getTransactionReceipt",
                                                 vec![hash.to_string()])
    }

    pub fn get_uncle_by_block_hash_and_index(&mut self, hash: &str, index: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getUncleByBlockHashAndIndex",
                                     vec![hash.to_string(), index.to_string()])
    }

    pub fn get_uncle_by_block_number_and_index(&mut self, number: &str, index: &str) -> RPCBlock {
        self.rpc_request::<RPCBlock>("eth_getUncleByBlockNumberAndIndex",
                                     vec![number.to_string(), index.to_string()])
    }

    pub fn get_compilers(&mut self) -> Vec<String> {
        self.rpc_request::<Vec<String>>("eth_getCompilers", vec![])
    }

    pub fn compile_solidity(&mut self, source: &str) -> String {
        unimplemented!()
    }

    pub fn compile_lll(&mut self, source: &str) -> String {
        self.rpc_request::<String>("eth_compileLLL", vec![source.to_string()])
    }

    pub fn compile_serpent(&mut self, source: &str) -> String {
        self.rpc_request::<String>("eth_compileSerpent", vec![source.to_string()])
    }

    pub fn new_filter(&mut self, filter: RPCFilter) -> String {
        unimplemented!()
    }

    pub fn new_block_filter(&mut self) -> String {
        self.rpc_request::<String>("eth_newBlockFilter", vec![])
    }

    pub fn new_pending_transaction_filter(&mut self) -> String {
        self.rpc_request::<String>("eth_newPendingTransactionFilter", vec![])
    }

    pub fn uninstall_filter(&mut self, id: &str) -> bool {
        self.rpc_request::<bool>("eth_uninstallFilter", vec![id.to_string()])
    }

    pub fn get_filter_changes(&mut self, id: &str) -> String {
        unimplemented!()
    }

    pub fn get_filter_logs(&mut self, id: &str) -> String {
        unimplemented!()
    }

    pub fn get_logs(&mut self, id: &str) -> String {
        unimplemented!()
    }

    pub fn get_work(&mut self) -> Vec<String> {
        self.rpc_request::<Vec<String>>("eth_getWork", vec![])
    }

    pub fn submit_work(&mut self, nonce: &str, pow: &str, mix: &str) -> bool {
        self.rpc_request::<bool>("eth_submitWork",
                                 vec![nonce.to_string(), pow.to_string(), mix.to_string()])
    }

    pub fn submit_hashrate(&mut self, hashrate: &str, id: &str) -> bool {
        self.rpc_request::<bool>("eth_submitHashrate",
                                 vec![hashrate.to_string(), id.to_string()])
    }

    pub fn put_string(&mut self, db: &str, key: &str, value: &str) -> bool {
        self.rpc_request::<bool>("db_putString",
                                 vec![db.to_string(), key.to_string(), value.to_string()])
    }

    pub fn get_string(&mut self, db: &str, key: &str) -> String {
        self.rpc_request::<String>("db_getString",
                                   vec![db.to_string(), key.to_string()])
    }

    pub fn put_hex(&mut self, db: &str, key: &str, value: &str) -> bool {
        self.rpc_request::<bool>("db_putHex",
                                 vec![db.to_string(), key.to_string(), value.to_string()])
    }

    pub fn get_hex(&mut self, db: &str, key: &str) -> String {
        self.rpc_request::<String>("db_getHex",
                                   vec![db.to_string(), key.to_string()])
    }
}

pub fn regression(address: &str) -> bool {
    let mut client = GethRPCClient::new("http://localhost:8545");
    let height = usize::from_str_radix(&client.block_number(), 16).unwrap();
    println!("height: {}", height);

    for blk_no in 49439..height {
        let block = client.get_block_by_number(format!("0x{:x}", blk_no).as_str());
        println!("{:?}", block);
    }
    false
}
<|endoftext|>


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

extern crate smtp;
extern crate getopts;
use std::io::stdin;
use std::io::net::tcp::TcpStream;
use std::string::String;
use std::io::net::ip::Port;
use std::os;
use smtp::client::Client;
use getopts::{optopt,optflag,getopts,OptGroup,usage};

fn sendmail(source_address: String, recipient_addresses: Vec<String>, message: String, server: String, port: Option<Port>, my_hostname: Option<String>) {
    let mut email_client: Client<TcpStream> =
        Client::new(
            server,
            port,
            my_hostname
        );
    let result = email_client.send_mail::<TcpStream>(
            source_address,
            recipient_addresses,
            message
    );
    panic!(result)
}

fn print_usage(description: String, _opts: &[OptGroup]) {
    println!("{}", usage(description.as_slice(), _opts));
}

fn main() {
    let args = os::args();

    let mut args_string = Vec::new();
    for arg in args.iter() {
        args_string.push(arg.clone());
    };

    let program = args[0].clone();
    let description = format!("Usage: {0} [options...] recipients\n\n\
                               This program reads a message on standard input until it reaches EOF,\
                               then tries to send it using the given paramters.\n\n\
                               Example: {0} -r user@example.org user@example.com < message.txt", program);

    let opts = [
        optopt("r", "reverse-path", "set the sender address", "FROM_ADDRESS"),
        optopt("p", "port", "set the port to use, default is 25", "PORT"),
        optopt("s", "server", "set the server to use, default is localhost", "SERVER"),
        optopt("m", "my-hostname", "set the hostname used by the client", "MY_HOSTNAME"),
        optflag("h", "help", "print this help menu"),
        optflag("v", "verbose", "display the transaction details"),
    ];
    let matches = match getopts(args_string.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { panic!("{}", f) }
    };
    if matches.opt_present("h") {
        print_usage(description, opts);
        return;
    }

    let sender = match matches.opt_str("r") {
        Some(sender) => sender,
        None         => {
            println!("The sender option is required");
            print_usage(program, opts);
            return;
        }
    };

    let server = match matches.opt_str("s") {
        Some(server) => server,
        None         => String::from_str("localhost")
    };

    let my_hostname = match matches.opt_str("m") {
        Some(my_hostname) => Some(my_hostname),
        None         => None
    };

    let port = match matches.opt_str("p") {
        Some(port) => from_str::<Port>(port.as_slice()),
        None       => None

    };

    let recipients_str: &str = if !matches.free.is_empty() {
        matches.free[0].as_slice()
    } else {
        print_usage(description, opts);
        return;
    };
    let mut recipients = Vec::new();
    for recipient in recipients_str.split(' ') {
        recipients.push(String::from_str(recipient))
    }

    let mut message = String::new();
    for line in stdin().lines() {
        message.push_str(line.unwrap().as_slice());
    }

    sendmail(sender, recipients, message, server, port, my_hostname);
}
<commit_msg>Add error handling to the example client program<commit_after>// Copyright 2014 Alexis Mousset. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(phase)] #[phase(plugin, link)] extern crate log;

extern crate smtp;
extern crate getopts;
use std::io::stdin;
use std::io::net::tcp::TcpStream;
use std::string::String;
use std::io::net::ip::Port;
use std::os;
use getopts::{optopt,optflag,getopts,OptGroup,usage};

use smtp::client::Client;
use smtp::error::SmtpResult;
use smtp::response::Response;

fn sendmail(source_address: String, recipient_addresses: Vec<String>, message: String,
        server: String, port: Option<Port>, my_hostname: Option<String>) -> SmtpResult<Response> {
    let mut email_client: Client<TcpStream> =
        Client::new(
            server,
            port,
            my_hostname
        );
    email_client.send_mail::<TcpStream>(
            source_address,
            recipient_addresses,
            message
    )
}

fn print_usage(description: String, _opts: &[OptGroup]) {
    println!("{}", usage(description.as_slice(), _opts));
}

fn main() {
    let args = os::args();

    let mut args_string = Vec::new();
    for arg in args.iter() {
        args_string.push(arg.clone());
    };

    let program = args[0].clone();
    let description = format!("Usage: {0} [options...] recipients\n\n\
                               This program reads a message on standard input until it reaches EOF,\
                               then tries to send it using the given paramters.\n\n\
                               Example: {0} -r user@example.org user@example.com < message.txt", program);

    let opts = [
        optopt("r", "reverse-path", "set the sender address", "FROM_ADDRESS"),
        optopt("p", "port", "set the port to use, default is 25", "PORT"),
        optopt("s", "server", "set the server to use, default is localhost", "SERVER"),
        optopt("m", "my-hostname", "set the hostname used by the client", "MY_HOSTNAME"),
        optflag("h", "help", "print this help menu"),
        optflag("v", "verbose", "display the transaction details"),
    ];
    let matches = match getopts(args_string.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { panic!("{}", f) }
    };
    if matches.opt_present("h") {
        print_usage(description, opts);
        return;
    }

    let sender = match matches.opt_str("r") {
        Some(sender) => sender,
        None         => {
            println!("The sender option is required");
            print_usage(program, opts);
            return;
        }
    };

    let server = match matches.opt_str("s") {
        Some(server) => server,
        None         => String::from_str("localhost")
    };

    let my_hostname = match matches.opt_str("m") {
        Some(my_hostname) => Some(my_hostname),
        None         => None
    };

    let port = match matches.opt_str("p") {
        Some(port) => from_str::<Port>(port.as_slice()),
        None       => None

    };

    let recipients_str: &str = if !matches.free.is_empty() {
        matches.free[0].as_slice()
    } else {
        print_usage(description, opts);
        return;
    };
    let mut recipients = Vec::new();
    for recipient in recipients_str.split(' ') {
        recipients.push(String::from_str(recipient))
    }

    let mut message = String::new();
    for line in stdin().lines() {
        message.push_str(line.unwrap().as_slice());
    }

    match sendmail(sender, recipients, message, server, port, my_hostname) {
        Ok(..) => info!("Email sent successfully"),
        Err(error) => error!("{}", error)
    }
}
<|endoftext|>


<commit_before>use crate::codec::FrontendMessage;
use crate::connection::RequestMessages;
#[cfg(feature = "runtime")]
use crate::tls::MakeTlsConnect;
use crate::tls::TlsConnect;
use crate::types::{ToSql, Type};
#[cfg(feature = "runtime")]
use crate::Socket;
use crate::{query, Client, Error, Row, SimpleQueryMessage, Statement};
use bytes::IntoBuf;
use futures::{Stream, TryStream};
use postgres_protocol::message::frontend;
use std::error;
use std::future::Future;
use tokio::io::{AsyncRead, AsyncWrite};

/// A representation of a PostgreSQL database transaction.
///
/// Transactions will implicitly roll back when dropped. Use the `commit` method to commit the changes made in the
/// transaction. Transactions can be nested, with inner transactions implemented via safepoints.
pub struct Transaction<'a> {
    client: &'a mut Client,
    done: bool,
}

impl<'a> Drop for Transaction<'a> {
    fn drop(&mut self) {
        if self.done {
            return;
        }

        let mut buf = vec![];
        frontend::query("ROLLBACK", &mut buf).unwrap();
        let _ = self
            .client
            .inner()
            .send(RequestMessages::Single(FrontendMessage::Raw(buf)));
    }
}

impl<'a> Transaction<'a> {
    pub(crate) fn new(client: &'a mut Client) -> Transaction<'a> {
        Transaction {
            client,
            done: false,
        }
    }

    /// Consumes the transaction, committing all changes made within it.
    pub async fn commit(mut self) -> Result<(), Error> {
        self.done = true;
        self.client.batch_execute("COMMIT").await
    }

    /// Rolls the transaction back, discarding all changes made within it.
    ///
    /// This is equivalent to `Transaction`'s `Drop` implementation, but provides any error encountered to the caller.
    pub async fn rollback(mut self) -> Result<(), Error> {
        self.done = true;
        self.client.batch_execute("ROLLBACK").await
    }

    /// Like `Client::prepare`.
    pub fn prepare(&mut self, query: &str) -> impl Future<Output = Result<Statement, Error>> {
        self.client.prepare(query)
    }

    /// Like `Client::prepare_typed`.
    pub fn prepare_typed(
        &mut self,
        query: &str,
        parameter_types: &[Type],
    ) -> impl Future<Output = Result<Statement, Error>> {
        self.client.prepare_typed(query, parameter_types)
    }

    /// Like `Client::query`.
    pub fn query(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
    ) -> impl Stream<Item = Result<Row, Error>> {
        self.client.query(statement, params)
    }

    /// Like `Client::query_iter`.
    pub fn query_iter<'b, I>(
        &mut self,
        statement: &Statement,
        params: I,
    ) -> impl Stream<Item = Result<Row, Error>> + 'static
    where
        I: IntoIterator<Item = &'b dyn ToSql>,
        I::IntoIter: ExactSizeIterator,
    {
        // https://github.com/rust-lang/rust/issues/63032
        let buf = query::encode(statement, params);
        query::query(self.client.inner(), statement.clone(), buf)
    }

    /// Like `Client::execute`.
    pub fn execute(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
    ) -> impl Future<Output = Result<u64, Error>> {
        self.client.execute(statement, params)
    }

    /// Like `Client::execute_iter`.
    pub fn execute_iter<'b, I>(
        &mut self,
        statement: &Statement,
        params: I,
    ) -> impl Future<Output = Result<u64, Error>>
    where
        I: IntoIterator<Item = &'b dyn ToSql>,
        I::IntoIter: ExactSizeIterator,
    {
        // https://github.com/rust-lang/rust/issues/63032
        let buf = query::encode(statement, params);
        query::execute(self.client.inner(), buf)
    }

    /// Like `Client::copy_in`.
    pub fn copy_in<S>(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
        stream: S,
    ) -> impl Future<Output = Result<u64, Error>>
    where
        S: TryStream,
        S::Ok: IntoBuf,
        <S::Ok as IntoBuf>::Buf: 'static + Send,
        S::Error: Into<Box<dyn error::Error + Sync + Send>>,
    {
        self.client.copy_in(statement, params, stream)
    }

    /// Like `Client::simple_query`.
    pub fn simple_query(
        &mut self,
        query: &str,
    ) -> impl Stream<Item = Result<SimpleQueryMessage, Error>> {
        self.client.simple_query(query)
    }

    /// Like `Client::batch_execute`.
    pub fn batch_execute(&mut self, query: &str) -> impl Future<Output = Result<(), Error>> {
        self.client.batch_execute(query)
    }

    /// Like `Client::cancel_query`.
    #[cfg(feature = "runtime")]
    pub fn cancel_query<T>(&mut self, tls: T) -> impl Future<Output = Result<(), Error>>
    where
        T: MakeTlsConnect<Socket>,
    {
        self.client.cancel_query(tls)
    }

    /// Like `Client::cancel_query_raw`.
    pub fn cancel_query_raw<S, T>(
        &mut self,
        stream: S,
        tls: T,
    ) -> impl Future<Output = Result<(), Error>>
    where
        S: AsyncRead + AsyncWrite + Unpin,
        T: TlsConnect<S>,
    {
        self.client.cancel_query_raw(stream, tls)
    }
}
<commit_msg>Transaction::copy_out<commit_after>use crate::codec::FrontendMessage;
use crate::connection::RequestMessages;
#[cfg(feature = "runtime")]
use crate::tls::MakeTlsConnect;
use crate::tls::TlsConnect;
use crate::types::{ToSql, Type};
#[cfg(feature = "runtime")]
use crate::Socket;
use crate::{query, Client, Error, Row, SimpleQueryMessage, Statement};
use bytes::{Bytes, IntoBuf};
use futures::{Stream, TryStream};
use postgres_protocol::message::frontend;
use std::error;
use std::future::Future;
use tokio::io::{AsyncRead, AsyncWrite};

/// A representation of a PostgreSQL database transaction.
///
/// Transactions will implicitly roll back when dropped. Use the `commit` method to commit the changes made in the
/// transaction. Transactions can be nested, with inner transactions implemented via safepoints.
pub struct Transaction<'a> {
    client: &'a mut Client,
    done: bool,
}

impl<'a> Drop for Transaction<'a> {
    fn drop(&mut self) {
        if self.done {
            return;
        }

        let mut buf = vec![];
        frontend::query("ROLLBACK", &mut buf).unwrap();
        let _ = self
            .client
            .inner()
            .send(RequestMessages::Single(FrontendMessage::Raw(buf)));
    }
}

impl<'a> Transaction<'a> {
    pub(crate) fn new(client: &'a mut Client) -> Transaction<'a> {
        Transaction {
            client,
            done: false,
        }
    }

    /// Consumes the transaction, committing all changes made within it.
    pub async fn commit(mut self) -> Result<(), Error> {
        self.done = true;
        self.client.batch_execute("COMMIT").await
    }

    /// Rolls the transaction back, discarding all changes made within it.
    ///
    /// This is equivalent to `Transaction`'s `Drop` implementation, but provides any error encountered to the caller.
    pub async fn rollback(mut self) -> Result<(), Error> {
        self.done = true;
        self.client.batch_execute("ROLLBACK").await
    }

    /// Like `Client::prepare`.
    pub fn prepare(&mut self, query: &str) -> impl Future<Output = Result<Statement, Error>> {
        self.client.prepare(query)
    }

    /// Like `Client::prepare_typed`.
    pub fn prepare_typed(
        &mut self,
        query: &str,
        parameter_types: &[Type],
    ) -> impl Future<Output = Result<Statement, Error>> {
        self.client.prepare_typed(query, parameter_types)
    }

    /// Like `Client::query`.
    pub fn query(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
    ) -> impl Stream<Item = Result<Row, Error>> {
        self.client.query(statement, params)
    }

    /// Like `Client::query_iter`.
    pub fn query_iter<'b, I>(
        &mut self,
        statement: &Statement,
        params: I,
    ) -> impl Stream<Item = Result<Row, Error>> + 'static
    where
        I: IntoIterator<Item = &'b dyn ToSql>,
        I::IntoIter: ExactSizeIterator,
    {
        // https://github.com/rust-lang/rust/issues/63032
        let buf = query::encode(statement, params);
        query::query(self.client.inner(), statement.clone(), buf)
    }

    /// Like `Client::execute`.
    pub fn execute(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
    ) -> impl Future<Output = Result<u64, Error>> {
        self.client.execute(statement, params)
    }

    /// Like `Client::execute_iter`.
    pub fn execute_iter<'b, I>(
        &mut self,
        statement: &Statement,
        params: I,
    ) -> impl Future<Output = Result<u64, Error>>
    where
        I: IntoIterator<Item = &'b dyn ToSql>,
        I::IntoIter: ExactSizeIterator,
    {
        // https://github.com/rust-lang/rust/issues/63032
        let buf = query::encode(statement, params);
        query::execute(self.client.inner(), buf)
    }

    /// Like `Client::copy_in`.
    pub fn copy_in<S>(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
        stream: S,
    ) -> impl Future<Output = Result<u64, Error>>
    where
        S: TryStream,
        S::Ok: IntoBuf,
        <S::Ok as IntoBuf>::Buf: 'static + Send,
        S::Error: Into<Box<dyn error::Error + Sync + Send>>,
    {
        self.client.copy_in(statement, params, stream)
    }

    /// Like `Client::copy_out`.
    pub fn copy_out(
        &mut self,
        statement: &Statement,
        params: &[&dyn ToSql],
    ) -> impl Stream<Item = Result<Bytes, Error>> {
        self.client.copy_out(statement, params)
    }

    /// Like `Client::simple_query`.
    pub fn simple_query(
        &mut self,
        query: &str,
    ) -> impl Stream<Item = Result<SimpleQueryMessage, Error>> {
        self.client.simple_query(query)
    }

    /// Like `Client::batch_execute`.
    pub fn batch_execute(&mut self, query: &str) -> impl Future<Output = Result<(), Error>> {
        self.client.batch_execute(query)
    }

    /// Like `Client::cancel_query`.
    #[cfg(feature = "runtime")]
    pub fn cancel_query<T>(&mut self, tls: T) -> impl Future<Output = Result<(), Error>>
    where
        T: MakeTlsConnect<Socket>,
    {
        self.client.cancel_query(tls)
    }

    /// Like `Client::cancel_query_raw`.
    pub fn cancel_query_raw<S, T>(
        &mut self,
        stream: S,
        tls: T,
    ) -> impl Future<Output = Result<(), Error>>
    where
        S: AsyncRead + AsyncWrite + Unpin,
        T: TlsConnect<S>,
    {
        self.client.cancel_query_raw(stream, tls)
    }
}
<|endoftext|>


<commit_before>//! The CXX code generator for constructing and compiling C++ code.
//!
//! This is intended to be used from Cargo build scripts to execute CXX's
//! C++ code generator, set up any additional compiler flags depending on
//! the use case, and make the C++ compiler invocation.
//!
//!

//!
//! # Example
//!
//! Example of a canonical Cargo build script that builds a CXX bridge:
//!
//! ```no_run
//! // build.rs
//!
//! fn main() {
//!     cxx_build::bridge("src/main.rs")
//!         .file("../demo-cxx/demo.cc")
//!         .flag_if_supported("-std=c++11")
//!         .compile("cxxbridge-demo");
//!
//!     println!("cargo:rerun-if-changed=src/main.rs");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.h");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.cc");
//! }
//! ```
//!
//! A runnable working setup with this build script is shown in the
//! *demo-rs* and *demo-cxx* directories of [https://github.com/dtolnay/cxx].
//!
//! [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx
//!
//!

//!
//! # Alternatives
//!
//! For use in non-Cargo builds like Bazel or Buck, CXX provides an
//! alternate way of invoking the C++ code generator as a standalone command
//! line tool. The tool is packaged as the `cxxbridge-cmd` crate.
//!
//! ```bash
//! $ cargo install cxxbridge-cmd  # or build it from the repo
//!
//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
//! $ cxxbridge src/main.rs > path/to/mybridge.cc
//! ```

#![allow(
    clippy::inherent_to_string,
    clippy::needless_doctest_main,
    clippy::new_without_default,
    clippy::toplevel_ref_arg
)]

mod error;
mod gen;
mod paths;
mod syntax;

use crate::error::Result;
use crate::gen::error::report;
use crate::gen::{fs, Opt};
use cc::Build;
use std::io::{self, Write};
use std::iter;
use std::path::Path;
use std::process;

/// This returns a [`cc::Build`] on which you should continue to set up any
/// additional source files or compiler flags, and lastly call its [`compile`]
/// method to execute the C++ build.
///
/// [`compile`]: https://docs.rs/cc/1.0.49/cc/struct.Build.html#method.compile
#[must_use]
pub fn bridge(rust_source_file: impl AsRef<Path>) -> Build {
    bridges(iter::once(rust_source_file))
}

/// `cxx_build::bridge` but for when more than one file contains a
/// #\[cxx::bridge\] module.
///
/// ```no_run
/// let source_files = vec!["src/main.rs", "src/path/to/other.rs"];
/// cxx_build::bridges(source_files)
///     .file("../demo-cxx/demo.cc")
///     .flag_if_supported("-std=c++11")
///     .compile("cxxbridge-demo");
/// ```
pub fn bridges(rust_source_files: impl IntoIterator<Item = impl AsRef<Path>>) -> Build {
    let ref mut rust_source_files = rust_source_files.into_iter();
    build(rust_source_files).unwrap_or_else(|err| {
        let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {}\n\n", report(err));
        process::exit(1);
    })
}

fn build(rust_source_files: &mut dyn Iterator<Item = impl AsRef<Path>>) -> Result<Build> {
    let mut build = paths::cc_build();
    build.cpp(true);
    build.cpp_link_stdlib(None); // linked via link-cplusplus crate

    for path in rust_source_files {
        try_generate_bridge(&mut build, path.as_ref())?;
    }

    Ok(build)
}

fn try_generate_bridge(build: &mut Build, rust_source_file: &Path) -> Result<()> {
    let opt = Opt::default();
    let generated = gen::generate_from_path(rust_source_file, &opt);

    let header_path = paths::out_with_extension(rust_source_file, ".h")?;
    fs::create_dir_all(header_path.parent().unwrap())?;
    fs::write(&header_path, generated.header)?;
    paths::symlink_header(&header_path, rust_source_file);

    let implementation_path = paths::out_with_extension(rust_source_file, ".cc")?;
    fs::write(&implementation_path, generated.implementation)?;
    build.file(&implementation_path);

    let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
    let _ = fs::create_dir_all(cxx_h.parent().unwrap());
    let _ = fs::remove_file(cxx_h);
    let _ = fs::write(cxx_h, gen::include::HEADER);

    Ok(())
}
<commit_msg>Write rust/cxx.h header only once<commit_after>//! The CXX code generator for constructing and compiling C++ code.
//!
//! This is intended to be used from Cargo build scripts to execute CXX's
//! C++ code generator, set up any additional compiler flags depending on
//! the use case, and make the C++ compiler invocation.
//!
//!

//!
//! # Example
//!
//! Example of a canonical Cargo build script that builds a CXX bridge:
//!
//! ```no_run
//! // build.rs
//!
//! fn main() {
//!     cxx_build::bridge("src/main.rs")
//!         .file("../demo-cxx/demo.cc")
//!         .flag_if_supported("-std=c++11")
//!         .compile("cxxbridge-demo");
//!
//!     println!("cargo:rerun-if-changed=src/main.rs");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.h");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.cc");
//! }
//! ```
//!
//! A runnable working setup with this build script is shown in the
//! *demo-rs* and *demo-cxx* directories of [https://github.com/dtolnay/cxx].
//!
//! [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx
//!
//!

//!
//! # Alternatives
//!
//! For use in non-Cargo builds like Bazel or Buck, CXX provides an
//! alternate way of invoking the C++ code generator as a standalone command
//! line tool. The tool is packaged as the `cxxbridge-cmd` crate.
//!
//! ```bash
//! $ cargo install cxxbridge-cmd  # or build it from the repo
//!
//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
//! $ cxxbridge src/main.rs > path/to/mybridge.cc
//! ```

#![allow(
    clippy::inherent_to_string,
    clippy::needless_doctest_main,
    clippy::new_without_default,
    clippy::toplevel_ref_arg
)]

mod error;
mod gen;
mod paths;
mod syntax;

use crate::error::Result;
use crate::gen::error::report;
use crate::gen::{fs, Opt};
use cc::Build;
use std::io::{self, Write};
use std::iter;
use std::path::Path;
use std::process;

/// This returns a [`cc::Build`] on which you should continue to set up any
/// additional source files or compiler flags, and lastly call its [`compile`]
/// method to execute the C++ build.
///
/// [`compile`]: https://docs.rs/cc/1.0.49/cc/struct.Build.html#method.compile
#[must_use]
pub fn bridge(rust_source_file: impl AsRef<Path>) -> Build {
    bridges(iter::once(rust_source_file))
}

/// `cxx_build::bridge` but for when more than one file contains a
/// #\[cxx::bridge\] module.
///
/// ```no_run
/// let source_files = vec!["src/main.rs", "src/path/to/other.rs"];
/// cxx_build::bridges(source_files)
///     .file("../demo-cxx/demo.cc")
///     .flag_if_supported("-std=c++11")
///     .compile("cxxbridge-demo");
/// ```
pub fn bridges(rust_source_files: impl IntoIterator<Item = impl AsRef<Path>>) -> Build {
    let ref mut rust_source_files = rust_source_files.into_iter();
    build(rust_source_files).unwrap_or_else(|err| {
        let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {}\n\n", report(err));
        process::exit(1);
    })
}

fn build(rust_source_files: &mut dyn Iterator<Item = impl AsRef<Path>>) -> Result<Build> {
    let mut build = paths::cc_build();
    build.cpp(true);
    build.cpp_link_stdlib(None); // linked via link-cplusplus crate
    write_header()?;

    for path in rust_source_files {
        generate_bridge(&mut build, path.as_ref())?;
    }

    Ok(build)
}

fn write_header() -> Result<()> {
    let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
    let _ = fs::create_dir_all(cxx_h.parent().unwrap());
    let _ = fs::remove_file(cxx_h);
    let _ = fs::write(cxx_h, gen::include::HEADER);
    Ok(())
}

fn generate_bridge(build: &mut Build, rust_source_file: &Path) -> Result<()> {
    let opt = Opt::default();
    let generated = gen::generate_from_path(rust_source_file, &opt);

    let header_path = paths::out_with_extension(rust_source_file, ".h")?;
    fs::create_dir_all(header_path.parent().unwrap())?;
    fs::write(&header_path, generated.header)?;
    paths::symlink_header(&header_path, rust_source_file);

    let implementation_path = paths::out_with_extension(rust_source_file, ".cc")?;
    fs::write(&implementation_path, generated.implementation)?;
    build.file(&implementation_path);
    Ok(())
}
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate hyper;
extern crate hubcaps;
extern crate tokio_core;
#[macro_use(quick_main)]
extern crate error_chain;

use std::env;

use tokio_core::reactor::Core;

use hubcaps::{Credentials, Github, Result};

quick_main!(run);

fn run() -> Result<()> {
    drop(env_logger::init());
    match env::var("GITHUB_TOKEN").ok() {
        Some(token) => {
            let mut core = Core::new()?;
            let github = Github::new(
                concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")),
                Credentials::Token(token),
                &core.handle(),
            );
            for issue in core.run(github.repo("softprops", "hubcat").issues().list(
                &Default::default(),
            ))?
            {
                println!("{:#?}", issue)
            }
        }
        _ => Err("example missing GITHUB_TOKEN".into()),
    }
}
<commit_msg>fix example<commit_after>extern crate env_logger;
extern crate hyper;
extern crate hubcaps;
extern crate tokio_core;
#[macro_use(quick_main)]
extern crate error_chain;

use std::env;

use tokio_core::reactor::Core;

use hubcaps::{Credentials, Github, Result};

quick_main!(run);

fn run() -> Result<()> {
    drop(env_logger::init());
    match env::var("GITHUB_TOKEN").ok() {
        Some(token) => {
            let mut core = Core::new()?;
            let github = Github::new(
                concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")),
                Credentials::Token(token),
                &core.handle(),
            );
            for issue in core.run(github.repo("softprops", "hubcat").issues().list(
                &Default::default(),
            ))?
            {
                println!("{:#?}", issue)
            }
            Ok(())
        }
        _ => Err("example missing GITHUB_TOKEN".into()),
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using perlin noise

extern mod noise;

use std::uint::range;
use noise::perlin::*;

static WIDTH: uint = 100;
static HEIGHT: uint = 100;

static GRADIENT: [&'static str, ..6] = [" ", "░", "▒", "▓", "█", "█"];

fn main() {
    let ctx = PerlinContext::new::<f32>();

    for range(0, HEIGHT) |y| {
        for range(0, WIDTH) |x| {
            let val = [x as f32 * 0.1f32,
                       y as f32 * 0.1f32].perlin(&ctx) * 0.5f32 + 0.5f32;
            print(GRADIENT[val / 0.2f32 as int]);
        }
        println("");
    }
}
<commit_msg>Update to use new for loop protocol, and fix for new `as` binding rules<commit_after>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using perlin noise

extern mod noise;

use noise::perlin::*;

static WIDTH: uint = 100;
static HEIGHT: uint = 100;

static GRADIENT: [&'static str, ..6] = [" ", "░", "▒", "▓", "█", "█"];

fn main() {
    let ctx = PerlinContext::new::<f32>();

    for y in range(0, HEIGHT) {
        for x in range(0, WIDTH) {
            let val = [x as f32 * 0.1f32,
                       y as f32 * 0.1f32].perlin(&ctx) * 0.5f32 + 0.5f32;
            print(GRADIENT[(val / 0.2f32) as int]);
        }
        println("");
    }
}
<|endoftext|>


<commit_before>extern crate event;
extern crate netutils;
extern crate syscall;

use event::EventQueue;
use netutils::{getcfg, n16, Ipv4Addr, MacAddr, Ipv4, EthernetII, EthernetIIHeader, Arp, Tcp};
use std::cell::RefCell;
use std::collections::{BTreeMap, VecDeque};
use std::fs::File;
use std::io::{self, Read, Write};
use std::os::unix::io::FromRawFd;
use std::rc::Rc;
use std::{slice, str};
use syscall::data::Packet;
use syscall::error::{Error, Result, EACCES, EADDRNOTAVAIL, EBADF, EIO, EINVAL, ENOENT, EWOULDBLOCK};
use syscall::flag::{EVENT_READ, O_NONBLOCK};
use syscall::scheme::SchemeMut;

struct Interface {
    mac: MacAddr,
    ip: Ipv4Addr,
    router: Ipv4Addr,
    subnet: Ipv4Addr,
    arp_file: File,
    ip_file: File,
    arp: BTreeMap<Ipv4Addr, MacAddr>,
    rarp: BTreeMap<MacAddr, Ipv4Addr>,
}

impl Interface {
    fn new(arp_fd: usize, ip_fd: usize) -> Self {
        Interface {
            mac: MacAddr::from_str(&getcfg("mac").unwrap()),
            ip: Ipv4Addr::from_str(&getcfg("ip").unwrap()),
            router: Ipv4Addr::from_str(&getcfg("ip_router").unwrap()),
            subnet: Ipv4Addr::from_str(&getcfg("ip_subnet").unwrap()),
            arp_file: unsafe { File::from_raw_fd(arp_fd) },
            ip_file: unsafe { File::from_raw_fd(ip_fd) },
            arp: BTreeMap::new(),
            rarp: BTreeMap::new(),
        }
    }
}

struct Handle {
    proto: u8,
    flags: usize,
    events: usize,
    data: VecDeque<Vec<u8>>,
    todo: VecDeque<Packet>,
}

struct Ipd {
    scheme_file: File,
    interfaces: Vec<Interface>,
    next_id: usize,
    handles: BTreeMap<usize, Handle>,
}

impl Ipd {
    fn new(scheme_file: File) -> Self {
        Ipd {
            scheme_file: scheme_file,
            interfaces: Vec::new(),
            next_id: 1,
            handles: BTreeMap::new(),
        }
    }

    fn scheme_event(&mut self) -> io::Result<()> {
        loop {
            let mut packet = Packet::default();
            if self.scheme_file.read(&mut packet)? == 0 {
                break;
            }

            let a = packet.a;
            self.handle(&mut packet);
            if packet.a == (-EWOULDBLOCK) as usize {
                packet.a = a;
                if let Some(mut handle) = self.handles.get_mut(&packet.b) {
                    handle.todo.push_back(packet);
                }
            } else {
                self.scheme_file.write(&packet)?;
            }
        }

        Ok(())
    }

    fn arp_event(&mut self, if_id: usize) -> io::Result<()> {
        if let Some(mut interface) = self.interfaces.get_mut(if_id) {
            loop {
                let mut bytes = [0; 65536];
                let count = interface.arp_file.read(&mut bytes)?;
                if count == 0 {
                    break;
                }
                if let Some(frame) = EthernetII::from_bytes(&bytes[.. count]) {
                    if let Some(packet) = Arp::from_bytes(&frame.data) {
                        if packet.header.oper.get() == 1 {
                            if packet.header.dst_ip == interface.ip {
                                let mut response = Arp {
                                    header: packet.header,
                                    data: packet.data.clone(),
                                };
                                response.header.oper.set(2);
                                response.header.dst_mac = packet.header.src_mac;
                                response.header.dst_ip = packet.header.src_ip;
                                response.header.src_mac = interface.mac;
                                response.header.src_ip = interface.ip;

                                let mut response_frame = EthernetII {
                                    header: frame.header,
                                    data: response.to_bytes()
                                };

                                response_frame.header.dst = response_frame.header.src;
                                response_frame.header.src = interface.mac;

                                interface.arp_file.write(&response_frame.to_bytes())?;
                            }
                        }
                    }
                }
            }
        }

        Ok(())
    }

    fn ip_event(&mut self, if_id: usize) -> io::Result<()> {
        if let Some(mut interface) = self.interfaces.get_mut(if_id) {
            loop {
                let mut bytes = [0; 65536];
                let count = interface.ip_file.read(&mut bytes)?;
                if count == 0 {
                    break;
                }
                if let Some(frame) = EthernetII::from_bytes(&bytes[.. count]) {
                    if let Some(ip) = Ipv4::from_bytes(&frame.data) {
                        if ip.header.dst == interface.ip || ip.header.dst == Ipv4Addr::BROADCAST {
                            //TODO: Handle ping here
                            for (id, handle) in self.handles.iter_mut() {
                                if ip.header.proto == handle.proto {
                                    handle.data.push_back(frame.data.clone());

                                    while ! handle.todo.is_empty() && ! handle.data.is_empty() {
                                        let mut packet = handle.todo.pop_front().unwrap();
                                        let buf = unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) };
                                        let data = handle.data.pop_front().unwrap();

                                        let mut i = 0;
                                        while i < buf.len() && i < data.len() {
                                            buf[i] = data[i];
                                            i += 1;
                                        }
                                        packet.a = i;

                                        self.scheme_file.write(&packet)?;
                                    }

                                    if handle.events & EVENT_READ == EVENT_READ {
                                        if let Some(data) = handle.data.get(0) {
                                            self.scheme_file.write(&Packet {
                                                id: 0,
                                                pid: 0,
                                                uid: 0,
                                                gid: 0,
                                                a: syscall::number::SYS_FEVENT,
                                                b: *id,
                                                c: EVENT_READ,
                                                d: data.len()
                                            })?;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        Ok(())
    }
}

impl SchemeMut for Ipd {
    fn open(&mut self, url: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
        if uid == 0 {
            let path = str::from_utf8(url).or(Err(Error::new(EINVAL)))?;

            let proto = u8::from_str_radix(path, 16).or(Err(Error::new(ENOENT)))?;

            let id = self.next_id;
            self.next_id += 1;

            self.handles.insert(id, Handle {
                proto: proto,
                flags: flags,
                events: 0,
                data: VecDeque::new(),
                todo: VecDeque::new(),
            });

            Ok(id)
        } else {
            Err(Error::new(EACCES))
        }
    }

    fn dup(&mut self, file: usize, _buf: &[u8]) -> Result<usize> {
        let handle = {
            let handle = self.handles.get(&file).ok_or(Error::new(EBADF))?;
            Handle {
                proto: handle.proto,
                flags: handle.flags,
                events: 0,
                data: handle.data.clone(),
                todo: VecDeque::new(),
            }
        };

        let id = self.next_id;
        self.next_id += 1;

        self.handles.insert(id, handle);

        Ok(id)
    }

    fn read(&mut self, file: usize, buf: &mut [u8]) -> Result<usize> {
        let mut handle = self.handles.get_mut(&file).ok_or(Error::new(EBADF))?;

        if let Some(data) = handle.data.pop_front() {
            let mut i = 0;
            while i < buf.len() && i < data.len() {
                buf[i] = data[i];
                i += 1;
            }

            Ok(i)
        } else if handle.flags & O_NONBLOCK == O_NONBLOCK {
            Ok(0)
        } else {
            Err(Error::new(EWOULDBLOCK))
        }
    }

    fn write(&mut self, file: usize, buf: &[u8]) -> Result<usize> {
        let handle = self.handles.get(&file).ok_or(Error::new(EBADF))?;

        if let Some(mut ip) = Ipv4::from_bytes(buf) {
            for mut interface in self.interfaces.iter_mut() {
                if ip.header.src == interface.ip || ip.header.src == Ipv4Addr::NULL {
                    ip.header.src = interface.ip;
                    ip.header.proto = handle.proto;

                    if let Some(mut tcp) = Tcp::from_bytes(&ip.data) {
                        tcp.checksum(&ip.header.src, &ip.header.dst);
                        ip.data = tcp.to_bytes();
                    }

                    ip.checksum();

                    let frame = EthernetII {
                        header: EthernetIIHeader {
                            //TODO: Get real dst
                            dst: MacAddr::BROADCAST,
                            src: interface.mac,
                            ethertype: n16::new(0x800),
                        },
                        data: ip.to_bytes()
                    };

                    interface.ip_file.write(&frame.to_bytes()).map_err(|err| Error::new(err.raw_os_error().unwrap_or(EIO)))?;

                    return Ok(buf.len());
                }
            }

            Err(Error::new(EADDRNOTAVAIL))
        } else {
            Err(Error::new(EINVAL))
        }
    }

    fn fevent(&mut self, file: usize, flags: usize) -> Result<usize> {
        let mut handle = self.handles.get_mut(&file).ok_or(Error::new(EBADF))?;

        handle.events = flags;

        Ok(file)
    }

    fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
        let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;

        let path_string = format!("ip:{:X}", handle.proto);
        let path = path_string.as_bytes();

        let mut i = 0;
        while i < buf.len() && i < path.len() {
            buf[i] = path[i];
            i += 1;
        }

        Ok(i)
    }

    fn fsync(&mut self, file: usize) -> Result<usize> {
        let _handle = self.handles.get(&file).ok_or(Error::new(EBADF))?;

        Ok(0)
    }

    fn close(&mut self, file: usize) -> Result<usize> {
        let handle = self.handles.remove(&file).ok_or(Error::new(EBADF))?;

        drop(handle);

        Ok(0)
    }
}

fn main() {
    // Daemonize
    if unsafe { syscall::clone(0).unwrap() } == 0 {
        let scheme_fd = syscall::open(":ip", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ipd: failed to create :ip");
        let scheme_file = unsafe { File::from_raw_fd(scheme_fd) };

        let ipd = Rc::new(RefCell::new(Ipd::new(scheme_file)));

        let mut event_queue = EventQueue::<()>::new().expect("ipd: failed to create event queue");

        //TODO: Multiple interfaces
        {
            let arp_fd = syscall::open("ethernet:806", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ipd: failed to open ethernet:806");
            let ip_fd = syscall::open("ethernet:800", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ipd: failed to open ethernet:800");
            let if_id = {
                let mut ipd = ipd.borrow_mut();
                let if_id = ipd.interfaces.len();
                ipd.interfaces.push(Interface::new(arp_fd, ip_fd));
                if_id
            };

            let arp_ipd = ipd.clone();
            event_queue.add(arp_fd, move |_count: usize| -> io::Result<Option<()>> {
                arp_ipd.borrow_mut().arp_event(if_id)?;
                Ok(None)
            }).expect("ipd: failed to listen to events on ethernet:806");

            let ip_ipd = ipd.clone();
            event_queue.add(ip_fd, move |_count: usize| -> io::Result<Option<()>> {
                ip_ipd.borrow_mut().ip_event(if_id)?;
                Ok(None)
            }).expect("ipd: failed to listen to events on ethernet:800");
        }

        event_queue.add(scheme_fd, move |_count: usize| -> io::Result<Option<()>> {
            ipd.borrow_mut().scheme_event()?;
            Ok(None)
        }).expect("ipd: failed to listen to events on :ip");

        // Make sure that all descriptors are at EOF
        event_queue.trigger_all(0).expect("ipd: failed to trigger event queue");

        event_queue.run().expect("ipd: failed to run event queue");
    }
}
<commit_msg>ipd: Add router usage, fill arp when possible<commit_after>extern crate event;
extern crate netutils;
extern crate syscall;

use event::EventQueue;
use netutils::{getcfg, n16, Ipv4Addr, MacAddr, Ipv4, EthernetII, EthernetIIHeader, Arp, Tcp};
use std::cell::RefCell;
use std::collections::{BTreeMap, VecDeque};
use std::fs::File;
use std::io::{self, Read, Write};
use std::os::unix::io::FromRawFd;
use std::rc::Rc;
use std::{slice, str};
use syscall::data::Packet;
use syscall::error::{Error, Result, EACCES, EADDRNOTAVAIL, EBADF, EIO, EINVAL, ENOENT, EWOULDBLOCK};
use syscall::flag::{EVENT_READ, O_NONBLOCK};
use syscall::scheme::SchemeMut;

struct Interface {
    mac: MacAddr,
    ip: Ipv4Addr,
    router: Ipv4Addr,
    subnet: Ipv4Addr,
    arp_file: File,
    ip_file: File,
    arp: BTreeMap<Ipv4Addr, MacAddr>,
    rarp: BTreeMap<MacAddr, Ipv4Addr>,
}

impl Interface {
    fn new(arp_fd: usize, ip_fd: usize) -> Self {
        Interface {
            mac: MacAddr::from_str(&getcfg("mac").unwrap()),
            ip: Ipv4Addr::from_str(&getcfg("ip").unwrap()),
            router: Ipv4Addr::from_str(&getcfg("ip_router").unwrap()),
            subnet: Ipv4Addr::from_str(&getcfg("ip_subnet").unwrap()),
            arp_file: unsafe { File::from_raw_fd(arp_fd) },
            ip_file: unsafe { File::from_raw_fd(ip_fd) },
            arp: BTreeMap::new(),
            rarp: BTreeMap::new(),
        }
    }
}

struct Handle {
    proto: u8,
    flags: usize,
    events: usize,
    data: VecDeque<Vec<u8>>,
    todo: VecDeque<Packet>,
}

struct Ipd {
    scheme_file: File,
    interfaces: Vec<Interface>,
    next_id: usize,
    handles: BTreeMap<usize, Handle>,
}

impl Ipd {
    fn new(scheme_file: File) -> Self {
        Ipd {
            scheme_file: scheme_file,
            interfaces: Vec::new(),
            next_id: 1,
            handles: BTreeMap::new(),
        }
    }

    fn scheme_event(&mut self) -> io::Result<()> {
        loop {
            let mut packet = Packet::default();
            if self.scheme_file.read(&mut packet)? == 0 {
                break;
            }

            let a = packet.a;
            self.handle(&mut packet);
            if packet.a == (-EWOULDBLOCK) as usize {
                packet.a = a;
                if let Some(mut handle) = self.handles.get_mut(&packet.b) {
                    handle.todo.push_back(packet);
                }
            } else {
                self.scheme_file.write(&packet)?;
            }
        }

        Ok(())
    }

    fn arp_event(&mut self, if_id: usize) -> io::Result<()> {
        if let Some(mut interface) = self.interfaces.get_mut(if_id) {
            loop {
                let mut bytes = [0; 65536];
                let count = interface.arp_file.read(&mut bytes)?;
                if count == 0 {
                    break;
                }
                if let Some(frame) = EthernetII::from_bytes(&bytes[.. count]) {
                    if let Some(packet) = Arp::from_bytes(&frame.data) {
                        if packet.header.oper.get() == 1 {
                            if packet.header.dst_ip == interface.ip {
                                if packet.header.src_ip != Ipv4Addr::BROADCAST && frame.header.src != MacAddr::BROADCAST {
                                    interface.arp.insert(packet.header.src_ip, frame.header.src);
                                    interface.rarp.insert(frame.header.src, packet.header.src_ip);
                                }

                                let mut response = Arp {
                                    header: packet.header,
                                    data: packet.data.clone(),
                                };
                                response.header.oper.set(2);
                                response.header.dst_mac = packet.header.src_mac;
                                response.header.dst_ip = packet.header.src_ip;
                                response.header.src_mac = interface.mac;
                                response.header.src_ip = interface.ip;

                                let mut response_frame = EthernetII {
                                    header: frame.header,
                                    data: response.to_bytes()
                                };

                                response_frame.header.dst = response_frame.header.src;
                                response_frame.header.src = interface.mac;

                                interface.arp_file.write(&response_frame.to_bytes())?;
                            }
                        }
                    }
                }
            }
        }

        Ok(())
    }

    fn ip_event(&mut self, if_id: usize) -> io::Result<()> {
        if let Some(mut interface) = self.interfaces.get_mut(if_id) {
            loop {
                let mut bytes = [0; 65536];
                let count = interface.ip_file.read(&mut bytes)?;
                if count == 0 {
                    break;
                }
                if let Some(frame) = EthernetII::from_bytes(&bytes[.. count]) {
                    if let Some(ip) = Ipv4::from_bytes(&frame.data) {
                        if ip.header.dst == interface.ip || ip.header.dst == Ipv4Addr::BROADCAST {
                            if ip.header.src != Ipv4Addr::BROADCAST && frame.header.src != MacAddr::BROADCAST {
                                interface.arp.insert(ip.header.src, frame.header.src);
                                interface.rarp.insert(frame.header.src, ip.header.src);
                            }

                            //TODO: Handle ping here
                            for (id, handle) in self.handles.iter_mut() {
                                if ip.header.proto == handle.proto {
                                    handle.data.push_back(frame.data.clone());

                                    while ! handle.todo.is_empty() && ! handle.data.is_empty() {
                                        let mut packet = handle.todo.pop_front().unwrap();
                                        let buf = unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) };
                                        let data = handle.data.pop_front().unwrap();

                                        let mut i = 0;
                                        while i < buf.len() && i < data.len() {
                                            buf[i] = data[i];
                                            i += 1;
                                        }
                                        packet.a = i;

                                        self.scheme_file.write(&packet)?;
                                    }

                                    if handle.events & EVENT_READ == EVENT_READ {
                                        if let Some(data) = handle.data.get(0) {
                                            self.scheme_file.write(&Packet {
                                                id: 0,
                                                pid: 0,
                                                uid: 0,
                                                gid: 0,
                                                a: syscall::number::SYS_FEVENT,
                                                b: *id,
                                                c: EVENT_READ,
                                                d: data.len()
                                            })?;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        Ok(())
    }
}

impl SchemeMut for Ipd {
    fn open(&mut self, url: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
        if uid == 0 {
            let path = str::from_utf8(url).or(Err(Error::new(EINVAL)))?;

            let proto = u8::from_str_radix(path, 16).or(Err(Error::new(ENOENT)))?;

            let id = self.next_id;
            self.next_id += 1;

            self.handles.insert(id, Handle {
                proto: proto,
                flags: flags,
                events: 0,
                data: VecDeque::new(),
                todo: VecDeque::new(),
            });

            Ok(id)
        } else {
            Err(Error::new(EACCES))
        }
    }

    fn dup(&mut self, file: usize, _buf: &[u8]) -> Result<usize> {
        let handle = {
            let handle = self.handles.get(&file).ok_or(Error::new(EBADF))?;
            Handle {
                proto: handle.proto,
                flags: handle.flags,
                events: 0,
                data: handle.data.clone(),
                todo: VecDeque::new(),
            }
        };

        let id = self.next_id;
        self.next_id += 1;

        self.handles.insert(id, handle);

        Ok(id)
    }

    fn read(&mut self, file: usize, buf: &mut [u8]) -> Result<usize> {
        let mut handle = self.handles.get_mut(&file).ok_or(Error::new(EBADF))?;

        if let Some(data) = handle.data.pop_front() {
            let mut i = 0;
            while i < buf.len() && i < data.len() {
                buf[i] = data[i];
                i += 1;
            }

            Ok(i)
        } else if handle.flags & O_NONBLOCK == O_NONBLOCK {
            Ok(0)
        } else {
            Err(Error::new(EWOULDBLOCK))
        }
    }

    fn write(&mut self, file: usize, buf: &[u8]) -> Result<usize> {
        let handle = self.handles.get(&file).ok_or(Error::new(EBADF))?;

        if let Some(mut ip) = Ipv4::from_bytes(buf) {
            for mut interface in self.interfaces.iter_mut() {
                if ip.header.src == interface.ip || ip.header.src == Ipv4Addr::NULL {
                    ip.header.src = interface.ip;
                    ip.header.proto = handle.proto;

                    if let Some(mut tcp) = Tcp::from_bytes(&ip.data) {
                        tcp.checksum(&ip.header.src, &ip.header.dst);
                        ip.data = tcp.to_bytes();
                    }

                    ip.checksum();

                    let mut dst = MacAddr::BROADCAST;
                    if ip.header.dst != Ipv4Addr::BROADCAST {
                        let mut needs_routing = false;

                        for octet in 0..4 {
                            let me = interface.ip.bytes[octet];
                            let mask = interface.subnet.bytes[octet];
                            let them = ip.header.dst.bytes[octet];
                            if me & mask != them & mask {
                                needs_routing = true;
                                break;
                            }
                        }

                        let route_addr = if needs_routing {
                            interface.router
                        } else {
                            ip.header.dst
                        };

                        if let Some(mac) = interface.arp.get(&route_addr) {
                            dst = *mac;
                        } else {
                            println!("ipd: need to arp {}", route_addr.to_string());
                        }
                    }

                    let frame = EthernetII {
                        header: EthernetIIHeader {
                            dst: dst,
                            src: interface.mac,
                            ethertype: n16::new(0x800),
                        },
                        data: ip.to_bytes()
                    };

                    interface.ip_file.write(&frame.to_bytes()).map_err(|err| Error::new(err.raw_os_error().unwrap_or(EIO)))?;

                    return Ok(buf.len());
                }
            }

            Err(Error::new(EADDRNOTAVAIL))
        } else {
            Err(Error::new(EINVAL))
        }
    }

    fn fevent(&mut self, file: usize, flags: usize) -> Result<usize> {
        let mut handle = self.handles.get_mut(&file).ok_or(Error::new(EBADF))?;

        handle.events = flags;

        Ok(file)
    }

    fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
        let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;

        let path_string = format!("ip:{:X}", handle.proto);
        let path = path_string.as_bytes();

        let mut i = 0;
        while i < buf.len() && i < path.len() {
            buf[i] = path[i];
            i += 1;
        }

        Ok(i)
    }

    fn fsync(&mut self, file: usize) -> Result<usize> {
        let _handle = self.handles.get(&file).ok_or(Error::new(EBADF))?;

        Ok(0)
    }

    fn close(&mut self, file: usize) -> Result<usize> {
        let handle = self.handles.remove(&file).ok_or(Error::new(EBADF))?;

        drop(handle);

        Ok(0)
    }
}

fn main() {
    // Daemonize
    if unsafe { syscall::clone(0).unwrap() } == 0 {
        let scheme_fd = syscall::open(":ip", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ipd: failed to create :ip");
        let scheme_file = unsafe { File::from_raw_fd(scheme_fd) };

        let ipd = Rc::new(RefCell::new(Ipd::new(scheme_file)));

        let mut event_queue = EventQueue::<()>::new().expect("ipd: failed to create event queue");

        //TODO: Multiple interfaces
        {
            let arp_fd = syscall::open("ethernet:806", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ipd: failed to open ethernet:806");
            let ip_fd = syscall::open("ethernet:800", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ipd: failed to open ethernet:800");
            let if_id = {
                let mut ipd = ipd.borrow_mut();
                let if_id = ipd.interfaces.len();
                ipd.interfaces.push(Interface::new(arp_fd, ip_fd));
                if_id
            };

            let arp_ipd = ipd.clone();
            event_queue.add(arp_fd, move |_count: usize| -> io::Result<Option<()>> {
                arp_ipd.borrow_mut().arp_event(if_id)?;
                Ok(None)
            }).expect("ipd: failed to listen to events on ethernet:806");

            let ip_ipd = ipd.clone();
            event_queue.add(ip_fd, move |_count: usize| -> io::Result<Option<()>> {
                ip_ipd.borrow_mut().ip_event(if_id)?;
                Ok(None)
            }).expect("ipd: failed to listen to events on ethernet:800");
        }

        event_queue.add(scheme_fd, move |_count: usize| -> io::Result<Option<()>> {
            ipd.borrow_mut().scheme_event()?;
            Ok(None)
        }).expect("ipd: failed to listen to events on :ip");

        // Make sure that all descriptors are at EOF
        event_queue.trigger_all(0).expect("ipd: failed to trigger event queue");

        event_queue.run().expect("ipd: failed to run event queue");
    }
}
<|endoftext|>


<commit_before><commit_msg>[chore]: remove emacs temp file<commit_after><|endoftext|>


<commit_before>use conduit::{Request, Response};
use diesel::prelude::*;
use time::Timespec;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, users, crates, crate_owners};
use user::RequestUser;
use util::errors::{CargoResult, human};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
    pub created_at: Timespec,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
}

impl CrateOwnerInvitation {
    pub fn invited_by_username(&self, conn: &PgConnection) -> String {
        users::table
            .find(self.invited_by_user_id)
            .select(users::gh_login)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown username)"))
    }

    pub fn crate_name(&self, conn: &PgConnection) -> String {
        crates::table
            .find(self.crate_id)
            .select(crates::name)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown crate name)"))
    }

    pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
        EncodableCrateOwnerInvitation {
            invited_by_username: self.invited_by_username(conn),
            crate_name: self.crate_name(conn),
            crate_id: self.crate_id,
            created_at: ::encode_time(self.created_at),
        }
    }
}

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
    pub invited_by_username: String,
    pub crate_name: String,
    pub crate_id: i32,
    pub created_at: String,
}

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R { crate_owner_invitations }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
    pub crate_id: i32,
    pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {

    let conn = &*req.db_conn()?;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(|_| {
        human("invalid json request")
    })?;

    let crate_invite = crate_invite.crate_owner_invite;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite)
    } else {
        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    }
}

fn accept_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    let user_id = req.user()?.id;
    use diesel::{insert, delete};
    let pending_crate_owner = crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let owner = CrateOwner {
        crate_id: crate_invite.crate_id,
        owner_id: user_id,
        created_by: pending_crate_owner.invited_by_user_id,
        owner_kind: OwnerKind::User as i32,
    };

    conn.transaction(|| {
        insert(&owner).into(crate_owners::table).execute(conn)?;
        delete(
            crate_owner_invitations::table
                .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
                .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
        ).execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    })
}

/// Handles the `PUT /me/decline_owner_invite` route.
pub fn decline_invite(req: &mut Request) -> CargoResult<Response> {
    use diesel::delete;
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    #[derive(Deserialize)]
    struct OwnerInvitation {
        crate_owner_invitation: EncodableCrateOwnerInvitation,
    }

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(
        |_| human("invalid json request"),
    )?;

    let crate_invite = crate_invite.crate_owner_invitation;

    delete(crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id)))
        .execute(conn)?;

    #[derive(Serialize)]
    struct R {
        ok: bool,
    }

    Ok(req.json(&R { ok: true }))
}
<commit_msg>add decline function for /me/crate_invitations/:crate_id route<commit_after>use conduit::{Request, Response};
use diesel::prelude::*;
use time::Timespec;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, users, crates, crate_owners};
use user::RequestUser;
use util::errors::{CargoResult, human};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
    pub created_at: Timespec,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
}

impl CrateOwnerInvitation {
    pub fn invited_by_username(&self, conn: &PgConnection) -> String {
        users::table
            .find(self.invited_by_user_id)
            .select(users::gh_login)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown username)"))
    }

    pub fn crate_name(&self, conn: &PgConnection) -> String {
        crates::table
            .find(self.crate_id)
            .select(crates::name)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown crate name)"))
    }

    pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
        EncodableCrateOwnerInvitation {
            invited_by_username: self.invited_by_username(conn),
            crate_name: self.crate_name(conn),
            crate_id: self.crate_id,
            created_at: ::encode_time(self.created_at),
        }
    }
}

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
    pub invited_by_username: String,
    pub crate_name: String,
    pub crate_id: i32,
    pub created_at: String,
}

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R { crate_owner_invitations }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
    pub crate_id: i32,
    pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {

    let conn = &*req.db_conn()?;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(|_| {
        human("invalid json request")
    })?;

    let crate_invite = crate_invite.crate_owner_invite;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite)
    } else {
        decline_invite(req, conn, crate_invite)
    }
}

fn accept_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    let user_id = req.user()?.id;
    use diesel::{insert, delete};
    let pending_crate_owner = crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let owner = CrateOwner {
        crate_id: crate_invite.crate_id,
        owner_id: user_id,
        created_by: pending_crate_owner.invited_by_user_id,
        owner_kind: OwnerKind::User as i32,
    };

    conn.transaction(|| {
        insert(&owner).into(crate_owners::table).execute(conn)?;
        delete(
            crate_owner_invitations::table
                .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
                .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
        ).execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    })
}

fn decline_invite(req: &mut Request, conn: &PgConnection, crate_invite: InvitationResponse) -> CargoResult<Response> {
    use diesel::delete;
    let user_id = req.user()?.id;

    delete(crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id)))
        .execute(conn)?;

    #[derive(Serialize)]
    struct R {
        crate_owner_invitation: InvitationResponse,
    }

    Ok(req.json(&R { crate_owner_invitation: crate_invite }))
}
<|endoftext|>