<commit_before>// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! Receipt
#![rustfmt_skip]

use BlockNumber;
use log_entry::{LocalizedLogEntry, LogBloom, LogEntry};
use rlp::*;
use util::{Address, H256, U256, Bytes};
use util::HeapSizeOf;
use std::str::FromStr;
use libproto::executor::{Receipt as ProtoReceipt, ReceiptError as ProtoReceiptError, ReceiptErrorWithOption, StateRoot};

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy, Eq)]
pub enum ReceiptError {
    //ExecutionError
    NoTransactionPermission,
    NoContractPermission,
    NotEnoughBaseGas,
    BlockGasLimitReached,
    AccountGasLimitReached,
    //EVM error(chain/core/src/evm/evm.rs)
    OutOfGas,
    BadJumpDestination,
    BadInstruction,
    StackUnderflow,
    OutOfStack,
    Internal,
}

impl ReceiptError {
    /// Returns human-readable description
    pub fn description(&self) -> String {
        let desc = match *self {
            ReceiptError::NoTransactionPermission => "No transaction permission.",
            ReceiptError::NoContractPermission => "No contract permission.",
            ReceiptError::NotEnoughBaseGas => "Not enough base gas.",
            ReceiptError::BlockGasLimitReached => "Block gas limit reached.",
            ReceiptError::AccountGasLimitReached => "Account gas limit reached.",
            ReceiptError::OutOfGas => "Out of gas.",
            ReceiptError::BadJumpDestination => "Jump position wasn't marked with JUMPDEST instruction.",
            ReceiptError::BadInstruction => "Instruction is not supported.",
            ReceiptError::StackUnderflow => "Not enough stack elements to execute instruction.",
            ReceiptError::OutOfStack => "Execution would exceed defined Stack Limit.",
            ReceiptError::Internal => "EVM internal error.",
        };
        desc.to_string()
    }

    pub fn protobuf(&self) -> ProtoReceiptError {
        match *self {
            ReceiptError::NoTransactionPermission => ProtoReceiptError::NoTransactionPermission,
            ReceiptError::NoContractPermission => ProtoReceiptError::NoContractPermission,
            ReceiptError::NotEnoughBaseGas => ProtoReceiptError::NotEnoughBaseGas,
            ReceiptError::BlockGasLimitReached => ProtoReceiptError::BlockGasLimitReached,
            ReceiptError::AccountGasLimitReached => ProtoReceiptError::AccountGasLimitReached,
            ReceiptError::OutOfGas => ProtoReceiptError::OutOfGas,
            ReceiptError::BadJumpDestination => ProtoReceiptError::BadJumpDestination,
            ReceiptError::BadInstruction => ProtoReceiptError::BadInstruction,
            ReceiptError::StackUnderflow => ProtoReceiptError::StackUnderflow,
            ReceiptError::OutOfStack => ProtoReceiptError::OutOfStack,
            ReceiptError::Internal => ProtoReceiptError::Internal,
        }
    }

    fn from_proto(receipt_error: ProtoReceiptError) -> Self {
        match receipt_error {
            ProtoReceiptError::NoTransactionPermission => ReceiptError::NoTransactionPermission,
            ProtoReceiptError::NoContractPermission => ReceiptError::NoContractPermission,
            ProtoReceiptError::NotEnoughBaseGas => ReceiptError::NotEnoughBaseGas,
            ProtoReceiptError::BlockGasLimitReached => ReceiptError::BlockGasLimitReached,
            ProtoReceiptError::AccountGasLimitReached => ReceiptError::AccountGasLimitReached,
            ProtoReceiptError::OutOfGas => ReceiptError::OutOfGas,
            ProtoReceiptError::BadJumpDestination => ReceiptError::BadJumpDestination,
            ProtoReceiptError::BadInstruction => ReceiptError::BadInstruction,
            ProtoReceiptError::StackUnderflow => ReceiptError::StackUnderflow,
            ProtoReceiptError::OutOfStack => ReceiptError::OutOfStack,
            ProtoReceiptError::Internal => ReceiptError::Internal,
        }
    }

}

impl Decodable for ReceiptError {
    fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
        match rlp.as_val::<u8>()? {
            0 => Ok(ReceiptError::NoTransactionPermission),
            1 => Ok(ReceiptError::NoContractPermission),
            2 => Ok(ReceiptError::NotEnoughBaseGas),
            3 => Ok(ReceiptError::BlockGasLimitReached),
            4 => Ok(ReceiptError::AccountGasLimitReached),
            5 => Ok(ReceiptError::BadJumpDestination),
            6 => Ok(ReceiptError::BadInstruction),
            7 => Ok(ReceiptError::StackUnderflow),
            8 => Ok(ReceiptError::OutOfStack),
            9 => Ok(ReceiptError::Internal),
            _ => Err(DecoderError::Custom("Unknown Receipt error.")),
        }
    }
}

impl Encodable for ReceiptError {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.append(&(*self as u8));
    }
}

/// Information describing execution of a transaction.
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)]
pub struct Receipt {
    /// The state root after executing the transaction. Optional since EIP98
    pub state_root: Option<H256>,
    /// The total gas used in the block following execution of the transaction.
    pub gas_used: U256,
    /// The OR-wide combination of all logs' blooms for this transaction.
    pub log_bloom: LogBloom,
    /// The logs stemming from this transaction.
    pub logs: Vec<LogEntry>,
    /// Transaction transact error
    pub error: Option<ReceiptError>,
    pub account_nonce: U256,
}

impl Receipt {
    /// Create a new receipt.
    pub fn new(state_root: Option<H256>, gas_used: U256, logs: Vec<LogEntry>, error: Option<ReceiptError>, account_nonce: U256) -> Receipt {
        Receipt {
            state_root: state_root,
            gas_used: gas_used,
            log_bloom: logs.iter().fold(LogBloom::default(), |mut b, l| {
                b = &b | &l.bloom();
                b
            }), //TODO: use |= operator
            logs: logs,
            error: error,
            account_nonce: account_nonce
        }
    }

    pub fn protobuf(&self) -> ProtoReceipt {
        let mut receipt_proto = ProtoReceipt::new();
        let mut state_root_option = StateRoot::new();
        let mut receipt_error_with_option = ReceiptErrorWithOption::new();

        if let Some(state_root) = self.state_root {
            state_root_option.set_state_root(state_root.to_vec());
            receipt_proto.set_state_root(state_root_option);
        }

        if let Some(error) = self.error {
            receipt_error_with_option.set_error(error.protobuf());
            receipt_proto.set_error(receipt_error_with_option);
        }

        receipt_proto.set_gas_used(self.gas_used.to_hex());
        receipt_proto.set_log_bloom(self.log_bloom.to_vec());
        receipt_proto.logs = self.logs
            .clone()
            .into_iter()
            .map(|log_entry| log_entry.protobuf())
            .collect();
        receipt_proto.set_account_nonce(self.gas_used.as_u64());
        receipt_proto
    }
}

impl From<ProtoReceipt> for Receipt {
    fn from(receipt: ProtoReceipt) -> Self {
        let mut state_root = None;
        if receipt.state_root.is_some() {
            state_root = Some(H256::from_slice(
                receipt.clone().take_state_root().get_state_root(),
            ));
        }

        let gas_used: U256 = U256::from_str(receipt.get_gas_used()).unwrap();
        let account_nonce: U256 = U256::from(receipt.get_account_nonce());
        let mut error = None;

        let logs = receipt.get_logs().into_iter().map(|log_entry|{
            let address: Address = Address::from_slice(log_entry.get_address());
            let topics: Vec<H256> = log_entry.get_topics().into_iter().map(|topic|{H256::from_slice(topic)}).collect();
            let data: Bytes = Bytes::from(log_entry.get_data());
            LogEntry {
                address: address,
                topics: topics,
                data: data,
            }
        }).collect();

        if receipt.error.is_some() {
            error = Some(ReceiptError::from_proto(receipt.clone().take_error().get_error()));
        }

        Receipt::new(state_root, gas_used, logs, error, account_nonce)
    }
}

impl Encodable for Receipt {
    fn rlp_append(&self, s: &mut RlpStream) {
        if let Some(ref root) = self.state_root {
            s.begin_list(6);
            s.append(root);
        } else {
            s.begin_list(5);
        }
        s.append(&self.gas_used);
        s.append(&self.log_bloom);
        s.append_list(&self.logs);
        s.append(&self.error);
        s.append(&self.account_nonce);
    }
}

impl Decodable for Receipt {
    fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
        if rlp.item_count()? == 5 {
            Ok(Receipt {
                   state_root: None,
                   gas_used: rlp.val_at(0)?,
                   log_bloom: rlp.val_at(1)?,
                   logs: rlp.list_at(2)?,
                   error: rlp.val_at(3)?,
                   account_nonce: rlp.val_at(4)?,
               })
        } else {
            Ok(Receipt {
                   state_root: Some(rlp.val_at(0)?),
                   gas_used: rlp.val_at(1)?,
                   log_bloom: rlp.val_at(2)?,
                   logs: rlp.list_at(3)?,
                   error: rlp.val_at(4)?,
                   account_nonce: rlp.val_at(5)?,
               })
        }
    }
}

impl HeapSizeOf for Receipt {
    fn heap_size_of_children(&self) -> usize {
        self.logs.heap_size_of_children()
    }
}

/// Receipt with additional info.
#[derive(Debug, Clone, PartialEq)]
pub struct RichReceipt {
    /// Transaction hash.
    pub transaction_hash: H256,
    /// Transaction index.
    pub transaction_index: usize,
    /// The total gas used in the block following execution of the transaction.
    pub cumulative_gas_used: U256,
    /// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`.
    pub gas_used: U256,
    /// Contract address.
    pub contract_address: Option<Address>,
    /// Logs
    pub logs: Vec<LogEntry>,
    /// Logs bloom
    pub log_bloom: LogBloom,
    /// State root
    pub state_root: Option<H256>,
    /// Receipt error
    pub error: Option<ReceiptError>,
}

/// Receipt with additional info.
#[derive(Debug, Clone, PartialEq)]
pub struct LocalizedReceipt {
    /// Transaction hash.
    pub transaction_hash: H256,
    /// Transaction index.
    pub transaction_index: usize,
    /// Block hash.
    pub block_hash: H256,
    /// Block number.
    pub block_number: BlockNumber,
    /// The total gas used in the block following execution of the transaction.
    pub cumulative_gas_used: U256,
    /// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`.
    pub gas_used: U256,
    /// Contract address.
    pub contract_address: Option<Address>,
    /// Logs
    pub logs: Vec<LocalizedLogEntry>,
    /// Logs bloom
    pub log_bloom: LogBloom,
    /// State root
    pub state_root: Option<H256>,
    /// Receipt error
    pub error: Option<ReceiptError>,
}

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

    #[test]
    fn test_no_state_root() {
        let r = Receipt::new(
            None,
            0x40cae.into(),
            vec![
                LogEntry {
                    address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
                    topics: vec![],
                    data: vec![0u8; 32],
                },
            ],
            None,
            1.into(),
        );
        let encoded = ::rlp::encode(&r);
        println!("encode ok");
        let decoded: Receipt = ::rlp::decode(&encoded);
        println!("decoded: {:?}", decoded);
        assert_eq!(decoded, r);

    }

    #[test]
    fn test_basic() {
        let r = Receipt::new(
            Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()),
            0x40cae.into(),
            vec![
                LogEntry {
                    address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
                    topics: vec![],
                    data: vec![0u8; 32],
                },
            ],
            None,
            1.into(),
        );
        let encoded = ::rlp::encode(&r);
        let decoded: Receipt = ::rlp::decode(&encoded);
        println!("decoded: {:?}", decoded);
        assert_eq!(decoded, r);
    }

    #[test]
    fn test_with_error() {
        let r = Receipt::new(
            Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()),
            0x40cae.into(),
            vec![
                LogEntry {
                    address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
                    topics: vec![],
                    data: vec![0u8; 32],
                },
            ],
            Some(ReceiptError::NoTransactionPermission),
            1.into(),
        );
        let encoded = ::rlp::encode(&r);
        let decoded: Receipt = ::rlp::decode(&encoded);
        println!("decoded: {:?}", decoded);
        assert_eq!(decoded, r);
    }
}
<commit_msg>Fix contract address<commit_after>// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! Receipt
#![rustfmt_skip]

use BlockNumber;
use log_entry::{LocalizedLogEntry, LogBloom, LogEntry};
use rlp::*;
use util::{Address, H256, U256, Bytes};
use util::HeapSizeOf;
use std::str::FromStr;
use libproto::executor::{Receipt as ProtoReceipt, ReceiptError as ProtoReceiptError, ReceiptErrorWithOption, StateRoot};

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy, Eq)]
pub enum ReceiptError {
    //ExecutionError
    NoTransactionPermission,
    NoContractPermission,
    NotEnoughBaseGas,
    BlockGasLimitReached,
    AccountGasLimitReached,
    //EVM error(chain/core/src/evm/evm.rs)
    OutOfGas,
    BadJumpDestination,
    BadInstruction,
    StackUnderflow,
    OutOfStack,
    Internal,
}

impl ReceiptError {
    /// Returns human-readable description
    pub fn description(&self) -> String {
        let desc = match *self {
            ReceiptError::NoTransactionPermission => "No transaction permission.",
            ReceiptError::NoContractPermission => "No contract permission.",
            ReceiptError::NotEnoughBaseGas => "Not enough base gas.",
            ReceiptError::BlockGasLimitReached => "Block gas limit reached.",
            ReceiptError::AccountGasLimitReached => "Account gas limit reached.",
            ReceiptError::OutOfGas => "Out of gas.",
            ReceiptError::BadJumpDestination => "Jump position wasn't marked with JUMPDEST instruction.",
            ReceiptError::BadInstruction => "Instruction is not supported.",
            ReceiptError::StackUnderflow => "Not enough stack elements to execute instruction.",
            ReceiptError::OutOfStack => "Execution would exceed defined Stack Limit.",
            ReceiptError::Internal => "EVM internal error.",
        };
        desc.to_string()
    }

    pub fn protobuf(&self) -> ProtoReceiptError {
        match *self {
            ReceiptError::NoTransactionPermission => ProtoReceiptError::NoTransactionPermission,
            ReceiptError::NoContractPermission => ProtoReceiptError::NoContractPermission,
            ReceiptError::NotEnoughBaseGas => ProtoReceiptError::NotEnoughBaseGas,
            ReceiptError::BlockGasLimitReached => ProtoReceiptError::BlockGasLimitReached,
            ReceiptError::AccountGasLimitReached => ProtoReceiptError::AccountGasLimitReached,
            ReceiptError::OutOfGas => ProtoReceiptError::OutOfGas,
            ReceiptError::BadJumpDestination => ProtoReceiptError::BadJumpDestination,
            ReceiptError::BadInstruction => ProtoReceiptError::BadInstruction,
            ReceiptError::StackUnderflow => ProtoReceiptError::StackUnderflow,
            ReceiptError::OutOfStack => ProtoReceiptError::OutOfStack,
            ReceiptError::Internal => ProtoReceiptError::Internal,
        }
    }

    fn from_proto(receipt_error: ProtoReceiptError) -> Self {
        match receipt_error {
            ProtoReceiptError::NoTransactionPermission => ReceiptError::NoTransactionPermission,
            ProtoReceiptError::NoContractPermission => ReceiptError::NoContractPermission,
            ProtoReceiptError::NotEnoughBaseGas => ReceiptError::NotEnoughBaseGas,
            ProtoReceiptError::BlockGasLimitReached => ReceiptError::BlockGasLimitReached,
            ProtoReceiptError::AccountGasLimitReached => ReceiptError::AccountGasLimitReached,
            ProtoReceiptError::OutOfGas => ReceiptError::OutOfGas,
            ProtoReceiptError::BadJumpDestination => ReceiptError::BadJumpDestination,
            ProtoReceiptError::BadInstruction => ReceiptError::BadInstruction,
            ProtoReceiptError::StackUnderflow => ReceiptError::StackUnderflow,
            ProtoReceiptError::OutOfStack => ReceiptError::OutOfStack,
            ProtoReceiptError::Internal => ReceiptError::Internal,
        }
    }

}

impl Decodable for ReceiptError {
    fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
        match rlp.as_val::<u8>()? {
            0 => Ok(ReceiptError::NoTransactionPermission),
            1 => Ok(ReceiptError::NoContractPermission),
            2 => Ok(ReceiptError::NotEnoughBaseGas),
            3 => Ok(ReceiptError::BlockGasLimitReached),
            4 => Ok(ReceiptError::AccountGasLimitReached),
            5 => Ok(ReceiptError::BadJumpDestination),
            6 => Ok(ReceiptError::BadInstruction),
            7 => Ok(ReceiptError::StackUnderflow),
            8 => Ok(ReceiptError::OutOfStack),
            9 => Ok(ReceiptError::Internal),
            _ => Err(DecoderError::Custom("Unknown Receipt error.")),
        }
    }
}

impl Encodable for ReceiptError {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.append(&(*self as u8));
    }
}

/// Information describing execution of a transaction.
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)]
pub struct Receipt {
    /// The state root after executing the transaction. Optional since EIP98
    pub state_root: Option<H256>,
    /// The total gas used in the block following execution of the transaction.
    pub gas_used: U256,
    /// The OR-wide combination of all logs' blooms for this transaction.
    pub log_bloom: LogBloom,
    /// The logs stemming from this transaction.
    pub logs: Vec<LogEntry>,
    /// Transaction transact error
    pub error: Option<ReceiptError>,
    pub account_nonce: U256,
}

impl Receipt {
    /// Create a new receipt.
    pub fn new(state_root: Option<H256>, gas_used: U256, logs: Vec<LogEntry>, error: Option<ReceiptError>, account_nonce: U256) -> Receipt {
        Receipt {
            state_root: state_root,
            gas_used: gas_used,
            log_bloom: logs.iter().fold(LogBloom::default(), |mut b, l| {
                b = &b | &l.bloom();
                b
            }), //TODO: use |= operator
            logs: logs,
            error: error,
            account_nonce: account_nonce
        }
    }

    pub fn protobuf(&self) -> ProtoReceipt {
        let mut receipt_proto = ProtoReceipt::new();
        let mut state_root_option = StateRoot::new();
        let mut receipt_error_with_option = ReceiptErrorWithOption::new();

        if let Some(state_root) = self.state_root {
            state_root_option.set_state_root(state_root.to_vec());
            receipt_proto.set_state_root(state_root_option);
        }

        if let Some(error) = self.error {
            receipt_error_with_option.set_error(error.protobuf());
            receipt_proto.set_error(receipt_error_with_option);
        }

        receipt_proto.set_gas_used(self.gas_used.to_hex());
        receipt_proto.set_log_bloom(self.log_bloom.to_vec());
        receipt_proto.logs = self.logs
            .clone()
            .into_iter()
            .map(|log_entry| log_entry.protobuf())
            .collect();
        receipt_proto.set_account_nonce(self.account_nonce.as_u64());
        receipt_proto
    }
}

impl From<ProtoReceipt> for Receipt {
    fn from(receipt: ProtoReceipt) -> Self {
        let mut state_root = None;
        if receipt.state_root.is_some() {
            state_root = Some(H256::from_slice(
                receipt.clone().take_state_root().get_state_root(),
            ));
        }

        let gas_used: U256 = U256::from_str(receipt.get_gas_used()).unwrap();
        let account_nonce: U256 = U256::from(receipt.get_account_nonce());
        let mut error = None;

        let logs = receipt.get_logs().into_iter().map(|log_entry|{
            let address: Address = Address::from_slice(log_entry.get_address());
            let topics: Vec<H256> = log_entry.get_topics().into_iter().map(|topic|{H256::from_slice(topic)}).collect();
            let data: Bytes = Bytes::from(log_entry.get_data());
            LogEntry {
                address: address,
                topics: topics,
                data: data,
            }
        }).collect();

        if receipt.error.is_some() {
            error = Some(ReceiptError::from_proto(receipt.clone().take_error().get_error()));
        }

        Receipt::new(state_root, gas_used, logs, error, account_nonce)
    }
}

impl Encodable for Receipt {
    fn rlp_append(&self, s: &mut RlpStream) {
        if let Some(ref root) = self.state_root {
            s.begin_list(6);
            s.append(root);
        } else {
            s.begin_list(5);
        }
        s.append(&self.gas_used);
        s.append(&self.log_bloom);
        s.append_list(&self.logs);
        s.append(&self.error);
        s.append(&self.account_nonce);
    }
}

impl Decodable for Receipt {
    fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
        if rlp.item_count()? == 5 {
            Ok(Receipt {
                   state_root: None,
                   gas_used: rlp.val_at(0)?,
                   log_bloom: rlp.val_at(1)?,
                   logs: rlp.list_at(2)?,
                   error: rlp.val_at(3)?,
                   account_nonce: rlp.val_at(4)?,
               })
        } else {
            Ok(Receipt {
                   state_root: Some(rlp.val_at(0)?),
                   gas_used: rlp.val_at(1)?,
                   log_bloom: rlp.val_at(2)?,
                   logs: rlp.list_at(3)?,
                   error: rlp.val_at(4)?,
                   account_nonce: rlp.val_at(5)?,
               })
        }
    }
}

impl HeapSizeOf for Receipt {
    fn heap_size_of_children(&self) -> usize {
        self.logs.heap_size_of_children()
    }
}

/// Receipt with additional info.
#[derive(Debug, Clone, PartialEq)]
pub struct RichReceipt {
    /// Transaction hash.
    pub transaction_hash: H256,
    /// Transaction index.
    pub transaction_index: usize,
    /// The total gas used in the block following execution of the transaction.
    pub cumulative_gas_used: U256,
    /// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`.
    pub gas_used: U256,
    /// Contract address.
    pub contract_address: Option<Address>,
    /// Logs
    pub logs: Vec<LogEntry>,
    /// Logs bloom
    pub log_bloom: LogBloom,
    /// State root
    pub state_root: Option<H256>,
    /// Receipt error
    pub error: Option<ReceiptError>,
}

/// Receipt with additional info.
#[derive(Debug, Clone, PartialEq)]
pub struct LocalizedReceipt {
    /// Transaction hash.
    pub transaction_hash: H256,
    /// Transaction index.
    pub transaction_index: usize,
    /// Block hash.
    pub block_hash: H256,
    /// Block number.
    pub block_number: BlockNumber,
    /// The total gas used in the block following execution of the transaction.
    pub cumulative_gas_used: U256,
    /// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`.
    pub gas_used: U256,
    /// Contract address.
    pub contract_address: Option<Address>,
    /// Logs
    pub logs: Vec<LocalizedLogEntry>,
    /// Logs bloom
    pub log_bloom: LogBloom,
    /// State root
    pub state_root: Option<H256>,
    /// Receipt error
    pub error: Option<ReceiptError>,
}

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

    #[test]
    fn test_no_state_root() {
        let r = Receipt::new(
            None,
            0x40cae.into(),
            vec![
                LogEntry {
                    address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
                    topics: vec![],
                    data: vec![0u8; 32],
                },
            ],
            None,
            1.into(),
        );
        let encoded = ::rlp::encode(&r);
        println!("encode ok");
        let decoded: Receipt = ::rlp::decode(&encoded);
        println!("decoded: {:?}", decoded);
        assert_eq!(decoded, r);

    }

    #[test]
    fn test_basic() {
        let r = Receipt::new(
            Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()),
            0x40cae.into(),
            vec![
                LogEntry {
                    address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
                    topics: vec![],
                    data: vec![0u8; 32],
                },
            ],
            None,
            1.into(),
        );
        let encoded = ::rlp::encode(&r);
        let decoded: Receipt = ::rlp::decode(&encoded);
        println!("decoded: {:?}", decoded);
        assert_eq!(decoded, r);
    }

    #[test]
    fn test_with_error() {
        let r = Receipt::new(
            Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()),
            0x40cae.into(),
            vec![
                LogEntry {
                    address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
                    topics: vec![],
                    data: vec![0u8; 32],
                },
            ],
            Some(ReceiptError::NoTransactionPermission),
            1.into(),
        );
        let encoded = ::rlp::encode(&r);
        let decoded: Receipt = ::rlp::decode(&encoded);
        println!("decoded: {:?}", decoded);
        assert_eq!(decoded, r);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. 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 mod std;
extern mod extra;

use std::io;
use std::io::{File, Reader};
use std::io::process::ExitStatus;
use std::os;
use std::run::{Process, ProcessOptions};
use std::str;
use extra::test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use extra::test::run_tests_console;

fn main() {
    let args = os::args();
    if args.len() < 2 {
        println("error: at least one reftest list must be given");
        os::set_exit_status(1);
        return;
    }

    let tests = parse_lists(args.tail());
    let test_opts = TestOpts {
        filter: None,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        ratchet_noise_percent: None,
        ratchet_metrics: None,
        save_metrics: None,
        test_shard: None,
    };

    if !run_tests_console(&test_opts, tests) {
        os::set_exit_status(1);
    }
}

enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: ~str,
    kind: ReftestKind,
    left: ~str,
    right: ~str,
    id: uint,
}

fn parse_lists(filenames: &[~str]) -> ~[TestDescAndFn] {
    let mut tests: ~[TestDescAndFn] = ~[];
    let mut next_id = 0;
    for file in filenames.iter() {
        let file_path = Path::new(file.clone());
        let contents = match File::open_mode(&file_path, io::Open, io::Read) {
            Some(mut f) => str::from_utf8_owned(f.read_to_end()),
            None => fail!("Could not open file")
        };

        for line in contents.lines() {
            let parts: ~[&str] = line.split(' ').filter(|p| !p.is_empty()).collect();

            if parts.len() != 3 {
                fail!("reftest line: '{:s}' doesn't match 'KIND LEFT RIGHT'", line);
            }

            let kind = match parts[0] {
                "==" => Same,
                "!=" => Different,
                _ => fail!("reftest line: '{:s}' has invalid kind '{:s}'",
                           line, parts[0])
            };
            let src_path = file_path.dir_path();
            let src_dir = src_path.display().to_str();
            let file_left =  src_dir + "/" + parts[1];
            let file_right = src_dir + "/" + parts[2];

            let reftest = Reftest {
                name: parts[1] + " / " + parts[2],
                kind: kind,
                left: file_left,
                right: file_right,
                id: next_id,
            };

            next_id += 1;

            tests.push(make_test(reftest));
        }
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: false,
        },
        testfn: DynTestFn(proc() {
            check_reftest(reftest);
        }),
    }
}

fn check_reftest(reftest: Reftest) {
    let left_filename = format!("/tmp/servo-reftest-{:06u}-left.png", reftest.id);
    let right_filename = format!("/tmp/servo-reftest-{:06u}-right.png", reftest.id);

    let args = ~[~"-o", left_filename.clone(), reftest.left.clone()];
    let mut process = Process::new("./servo", args, ProcessOptions::new()).unwrap();
    let _retval = process.finish();
    // assert!(retval == 0);

    let args = ~[~"-o", right_filename.clone(), reftest.right.clone()];
    let mut process = Process::new("./servo", args, ProcessOptions::new()).unwrap();
    let _retval = process.finish();
    // assert!(retval == 0);

    // check the pngs are bit equal
    let args = ~[left_filename.clone(), right_filename.clone()];
    let mut process = Process::new("cmp", args, ProcessOptions::new()).unwrap();
    let retval = process.finish();

    match reftest.kind {
        Same => assert!(retval == ExitStatus(0)),
        Different => assert!(retval != ExitStatus(0)),
    }
}
<commit_msg>auto merge of #1484 : metajack/servo/check-reftest-status, r=larsbergstrom<commit_after>// Copyright 2013 The Servo Project Developers. 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 mod std;
extern mod extra;

use std::io;
use std::io::{File, Reader};
use std::io::process::ExitStatus;
use std::os;
use std::run::{Process, ProcessOptions};
use std::str;
use extra::test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use extra::test::run_tests_console;

fn main() {
    let args = os::args();
    if args.len() < 2 {
        println("error: at least one reftest list must be given");
        os::set_exit_status(1);
        return;
    }

    let tests = parse_lists(args.tail());
    let test_opts = TestOpts {
        filter: None,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        ratchet_noise_percent: None,
        ratchet_metrics: None,
        save_metrics: None,
        test_shard: None,
    };

    if !run_tests_console(&test_opts, tests) {
        os::set_exit_status(1);
    }
}

enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: ~str,
    kind: ReftestKind,
    left: ~str,
    right: ~str,
    id: uint,
}

fn parse_lists(filenames: &[~str]) -> ~[TestDescAndFn] {
    let mut tests: ~[TestDescAndFn] = ~[];
    let mut next_id = 0;
    for file in filenames.iter() {
        let file_path = Path::new(file.clone());
        let contents = match File::open_mode(&file_path, io::Open, io::Read) {
            Some(mut f) => str::from_utf8_owned(f.read_to_end()),
            None => fail!("Could not open file")
        };

        for line in contents.lines() {
            let parts: ~[&str] = line.split(' ').filter(|p| !p.is_empty()).collect();

            if parts.len() != 3 {
                fail!("reftest line: '{:s}' doesn't match 'KIND LEFT RIGHT'", line);
            }

            let kind = match parts[0] {
                "==" => Same,
                "!=" => Different,
                _ => fail!("reftest line: '{:s}' has invalid kind '{:s}'",
                           line, parts[0])
            };
            let src_path = file_path.dir_path();
            let src_dir = src_path.display().to_str();
            let file_left =  src_dir + "/" + parts[1];
            let file_right = src_dir + "/" + parts[2];

            let reftest = Reftest {
                name: parts[1] + " / " + parts[2],
                kind: kind,
                left: file_left,
                right: file_right,
                id: next_id,
            };

            next_id += 1;

            tests.push(make_test(reftest));
        }
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: false,
        },
        testfn: DynTestFn(proc() {
            check_reftest(reftest);
        }),
    }
}

fn check_reftest(reftest: Reftest) {
    let left_filename = format!("/tmp/servo-reftest-{:06u}-left.png", reftest.id);
    let right_filename = format!("/tmp/servo-reftest-{:06u}-right.png", reftest.id);

    let args = ~[~"-o", left_filename.clone(), reftest.left.clone()];
    let mut process = Process::new("./servo", args, ProcessOptions::new()).unwrap();
    let retval = process.finish();
    assert!(retval == ExitStatus(0));

    let args = ~[~"-o", right_filename.clone(), reftest.right.clone()];
    let mut process = Process::new("./servo", args, ProcessOptions::new()).unwrap();
    let retval = process.finish();
    assert!(retval == ExitStatus(0));

    // check the pngs are bit equal
    let args = ~[left_filename.clone(), right_filename.clone()];
    let mut process = Process::new("cmp", args, ProcessOptions::new()).unwrap();
    let retval = process.finish();

    match reftest.kind {
        Same => assert!(retval == ExitStatus(0)),
        Different => assert!(retval != ExitStatus(0)),
    }
}
<|endoftext|>


<commit_before>extern crate polylabel;
use polylabel::polylabel;

extern crate geo;
use self::geo::{Point, Polygon};

#[test]
fn large_polygon() {
    let points = include!("../data/norway_main.rs");
    let points_ls: Vec<_> = points.iter().map(|e| Point::new(e[0], e[1])).collect();
    let poly = Polygon::new(points_ls.into(), vec![]);
    let _ = polylabel(&poly, &1.0);
}
<commit_msg>Remove standalone test<commit_after><|endoftext|>


<commit_before>use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::position_before_rarrow;
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_ast::visit::FnKind;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::BytePos;

declare_clippy_lint! {
    /// **What it does:** Checks for unit (`()`) expressions that can be removed.
    ///
    /// **Why is this bad?** Such expressions add no value, but can make the code
    /// less readable. Depending on formatting they can make a `break` or `return`
    /// statement look like a function call.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// fn return_unit() -> () {
    ///     ()
    /// }
    /// ```
    pub UNUSED_UNIT,
    style,
    "needless unit expression"
}

declare_lint_pass!(UnusedUnit => [UNUSED_UNIT]);

impl EarlyLintPass for UnusedUnit {
    fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, span: Span, _: ast::NodeId) {
        if_chain! {
            if let ast::FnRetTy::Ty(ref ty) = kind.decl().output;
            if let ast::TyKind::Tup(ref vals) = ty.kind;
            if vals.is_empty() && !ty.span.from_expansion() && get_def(span) == get_def(ty.span);
            then {
                lint_unneeded_unit_return(cx, ty, span);
            }
        }
    }

    fn check_block(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) {
        if_chain! {
            if let Some(stmt) = block.stmts.last();
            if let ast::StmtKind::Expr(ref expr) = stmt.kind;
            if is_unit_expr(expr);
            let ctxt = block.span.ctxt();
            if stmt.span.ctxt() == ctxt && expr.span.ctxt() == ctxt;
            then {
                let sp = expr.span;
                span_lint_and_sugg(
                    cx,
                    UNUSED_UNIT,
                    sp,
                    "unneeded unit expression",
                    "remove the final `()`",
                    String::new(),
                    Applicability::MachineApplicable,
                );
            }
        }
    }

    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
        match e.kind {
            ast::ExprKind::Ret(Some(ref expr)) | ast::ExprKind::Break(_, Some(ref expr)) => {
                if is_unit_expr(expr) && !expr.span.from_expansion() {
                    span_lint_and_sugg(
                        cx,
                        UNUSED_UNIT,
                        expr.span,
                        "unneeded `()`",
                        "remove the `()`",
                        String::new(),
                        Applicability::MachineApplicable,
                    );
                }
            },
            _ => (),
        }
    }

    fn check_poly_trait_ref(&mut self, cx: &EarlyContext<'_>, poly: &ast::PolyTraitRef, _: &ast::TraitBoundModifier) {
        let segments = &poly.trait_ref.path.segments;

        if_chain! {
            if segments.len() == 1;
            if ["Fn", "FnMut", "FnOnce"].contains(&&*segments[0].ident.name.as_str());
            if let Some(args) = &segments[0].args;
            if let ast::GenericArgs::Parenthesized(generic_args) = &**args;
            if let ast::FnRetTy::Ty(ty) = &generic_args.output;
            if ty.kind.is_unit();
            then {
                lint_unneeded_unit_return(cx, ty, generic_args.span);
            }
        }
    }
}

// get the def site
#[must_use]
fn get_def(span: Span) -> Option<Span> {
    if span.from_expansion() {
        Some(span.ctxt().outer_expn_data().def_site)
    } else {
        None
    }
}

// is this expr a `()` unit?
fn is_unit_expr(expr: &ast::Expr) -> bool {
    if let ast::ExprKind::Tup(ref vals) = expr.kind {
        vals.is_empty()
    } else {
        false
    }
}

fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
    let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) {
        position_before_rarrow(&fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
            (
                #[allow(clippy::cast_possible_truncation)]
                ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
                Applicability::MachineApplicable,
            )
        })
    } else {
        (ty.span, Applicability::MaybeIncorrect)
    };
    span_lint_and_sugg(
        cx,
        UNUSED_UNIT,
        ret_span,
        "unneeded unit return type",
        "remove the `-> ()`",
        String::new(),
        appl,
    );
}
<commit_msg>Auto merge of #7458 - flip1995:unused_unit-doc, r=giraffate<commit_after>use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::position_before_rarrow;
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_ast::visit::FnKind;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::BytePos;

declare_clippy_lint! {
    /// **What it does:** Checks for unit (`()`) expressions that can be removed.
    ///
    /// **Why is this bad?** Such expressions add no value, but can make the code
    /// less readable. Depending on formatting they can make a `break` or `return`
    /// statement look like a function call.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// fn return_unit() -> () {
    ///     ()
    /// }
    /// ```
    /// is equivalent to
    /// ```rust
    /// fn return_unit() {}
    /// ```
    pub UNUSED_UNIT,
    style,
    "needless unit expression"
}

declare_lint_pass!(UnusedUnit => [UNUSED_UNIT]);

impl EarlyLintPass for UnusedUnit {
    fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, span: Span, _: ast::NodeId) {
        if_chain! {
            if let ast::FnRetTy::Ty(ref ty) = kind.decl().output;
            if let ast::TyKind::Tup(ref vals) = ty.kind;
            if vals.is_empty() && !ty.span.from_expansion() && get_def(span) == get_def(ty.span);
            then {
                lint_unneeded_unit_return(cx, ty, span);
            }
        }
    }

    fn check_block(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) {
        if_chain! {
            if let Some(stmt) = block.stmts.last();
            if let ast::StmtKind::Expr(ref expr) = stmt.kind;
            if is_unit_expr(expr);
            let ctxt = block.span.ctxt();
            if stmt.span.ctxt() == ctxt && expr.span.ctxt() == ctxt;
            then {
                let sp = expr.span;
                span_lint_and_sugg(
                    cx,
                    UNUSED_UNIT,
                    sp,
                    "unneeded unit expression",
                    "remove the final `()`",
                    String::new(),
                    Applicability::MachineApplicable,
                );
            }
        }
    }

    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
        match e.kind {
            ast::ExprKind::Ret(Some(ref expr)) | ast::ExprKind::Break(_, Some(ref expr)) => {
                if is_unit_expr(expr) && !expr.span.from_expansion() {
                    span_lint_and_sugg(
                        cx,
                        UNUSED_UNIT,
                        expr.span,
                        "unneeded `()`",
                        "remove the `()`",
                        String::new(),
                        Applicability::MachineApplicable,
                    );
                }
            },
            _ => (),
        }
    }

    fn check_poly_trait_ref(&mut self, cx: &EarlyContext<'_>, poly: &ast::PolyTraitRef, _: &ast::TraitBoundModifier) {
        let segments = &poly.trait_ref.path.segments;

        if_chain! {
            if segments.len() == 1;
            if ["Fn", "FnMut", "FnOnce"].contains(&&*segments[0].ident.name.as_str());
            if let Some(args) = &segments[0].args;
            if let ast::GenericArgs::Parenthesized(generic_args) = &**args;
            if let ast::FnRetTy::Ty(ty) = &generic_args.output;
            if ty.kind.is_unit();
            then {
                lint_unneeded_unit_return(cx, ty, generic_args.span);
            }
        }
    }
}

// get the def site
#[must_use]
fn get_def(span: Span) -> Option<Span> {
    if span.from_expansion() {
        Some(span.ctxt().outer_expn_data().def_site)
    } else {
        None
    }
}

// is this expr a `()` unit?
fn is_unit_expr(expr: &ast::Expr) -> bool {
    if let ast::ExprKind::Tup(ref vals) = expr.kind {
        vals.is_empty()
    } else {
        false
    }
}

fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
    let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) {
        position_before_rarrow(&fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
            (
                #[allow(clippy::cast_possible_truncation)]
                ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
                Applicability::MachineApplicable,
            )
        })
    } else {
        (ty.span, Applicability::MaybeIncorrect)
    };
    span_lint_and_sugg(
        cx,
        UNUSED_UNIT,
        ret_span,
        "unneeded unit return type",
        "remove the `-> ()`",
        String::new(),
        appl,
    );
}
<|endoftext|>


<commit_before>use rustc_ast::ast;
use rustc_errors::Applicability;
use rustc_session::Session;
use std::str::FromStr;

/// Deprecation status of attributes known by Clippy.
#[allow(dead_code)]
pub enum DeprecationStatus {
    /// Attribute is deprecated
    Deprecated,
    /// Attribute is deprecated and was replaced by the named attribute
    Replaced(&'static str),
    None,
}

pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[
    ("author", DeprecationStatus::None),
    ("cognitive_complexity", DeprecationStatus::None),
    (
        "cyclomatic_complexity",
        DeprecationStatus::Replaced("cognitive_complexity"),
    ),
    ("dump", DeprecationStatus::None),
];

pub struct LimitStack {
    stack: Vec<u64>,
}

impl Drop for LimitStack {
    fn drop(&mut self) {
        assert_eq!(self.stack.len(), 1);
    }
}

impl LimitStack {
    #[must_use]
    pub fn new(limit: u64) -> Self {
        Self { stack: vec![limit] }
    }
    pub fn limit(&self) -> u64 {
        *self.stack.last().expect("there should always be a value in the stack")
    }
    pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| stack.push(val));
    }
    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
    }
}

pub fn get_attr<'a>(
    sess: &'a Session,
    attrs: &'a [ast::Attribute],
    name: &'static str,
) -> impl Iterator<Item = &'a ast::Attribute> {
    attrs.iter().filter(move |attr| {
        let attr = if let ast::AttrKind::Normal(ref attr) = attr.kind {
            attr
        } else {
            return false;
        };
        let attr_segments = &attr.path.segments;
        if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" {
            if let Some(deprecation_status) =
                BUILTIN_ATTRIBUTES
                    .iter()
                    .find_map(|(builtin_name, deprecation_status)| {
                        if *builtin_name == attr_segments[1].ident.to_string() {
                            Some(deprecation_status)
                        } else {
                            None
                        }
                    })
            {
                let mut db = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute");
                match *deprecation_status {
                    DeprecationStatus::Deprecated => {
                        db.emit();
                        false
                    },
                    DeprecationStatus::Replaced(new_name) => {
                        db.span_suggestion(
                            attr_segments[1].ident.span,
                            "consider using",
                            new_name.to_string(),
                            Applicability::MachineApplicable,
                        );
                        db.emit();
                        false
                    },
                    DeprecationStatus::None => {
                        db.cancel();
                        attr_segments[1].ident.to_string() == name
                    },
                }
            } else {
                sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute");
                false
            }
        } else {
            false
        }
    })
}

fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
    for attr in get_attr(sess, attrs, name) {
        if let Some(ref value) = attr.value_str() {
            if let Ok(value) = FromStr::from_str(&value.as_str()) {
                f(value)
            } else {
                sess.span_err(attr.span, "not a number");
            }
        } else {
            sess.span_err(attr.span, "bad clippy attribute");
        }
    }
}

/// Return true if the attributes contain any of `proc_macro`,
/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
    use rustc_span::Symbol;

    let syms = [
        Symbol::intern("proc_macro"),
        Symbol::intern("proc_macro_derive"),
        Symbol::intern("proc_macro_attribute"),
    ];
    attrs.iter().any(|attr| syms.iter().any(move |&s| attr.check_name(s)))
}
<commit_msg>Auto merge of #5458 - phansch:is-proc-macro-attr, r=matthiaskrgr<commit_after>use rustc_ast::ast;
use rustc_ast::expand::is_proc_macro_attr;
use rustc_errors::Applicability;
use rustc_session::Session;
use std::str::FromStr;

/// Deprecation status of attributes known by Clippy.
#[allow(dead_code)]
pub enum DeprecationStatus {
    /// Attribute is deprecated
    Deprecated,
    /// Attribute is deprecated and was replaced by the named attribute
    Replaced(&'static str),
    None,
}

pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[
    ("author", DeprecationStatus::None),
    ("cognitive_complexity", DeprecationStatus::None),
    (
        "cyclomatic_complexity",
        DeprecationStatus::Replaced("cognitive_complexity"),
    ),
    ("dump", DeprecationStatus::None),
];

pub struct LimitStack {
    stack: Vec<u64>,
}

impl Drop for LimitStack {
    fn drop(&mut self) {
        assert_eq!(self.stack.len(), 1);
    }
}

impl LimitStack {
    #[must_use]
    pub fn new(limit: u64) -> Self {
        Self { stack: vec![limit] }
    }
    pub fn limit(&self) -> u64 {
        *self.stack.last().expect("there should always be a value in the stack")
    }
    pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| stack.push(val));
    }
    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
    }
}

pub fn get_attr<'a>(
    sess: &'a Session,
    attrs: &'a [ast::Attribute],
    name: &'static str,
) -> impl Iterator<Item = &'a ast::Attribute> {
    attrs.iter().filter(move |attr| {
        let attr = if let ast::AttrKind::Normal(ref attr) = attr.kind {
            attr
        } else {
            return false;
        };
        let attr_segments = &attr.path.segments;
        if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" {
            if let Some(deprecation_status) =
                BUILTIN_ATTRIBUTES
                    .iter()
                    .find_map(|(builtin_name, deprecation_status)| {
                        if *builtin_name == attr_segments[1].ident.to_string() {
                            Some(deprecation_status)
                        } else {
                            None
                        }
                    })
            {
                let mut db = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute");
                match *deprecation_status {
                    DeprecationStatus::Deprecated => {
                        db.emit();
                        false
                    },
                    DeprecationStatus::Replaced(new_name) => {
                        db.span_suggestion(
                            attr_segments[1].ident.span,
                            "consider using",
                            new_name.to_string(),
                            Applicability::MachineApplicable,
                        );
                        db.emit();
                        false
                    },
                    DeprecationStatus::None => {
                        db.cancel();
                        attr_segments[1].ident.to_string() == name
                    },
                }
            } else {
                sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute");
                false
            }
        } else {
            false
        }
    })
}

fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
    for attr in get_attr(sess, attrs, name) {
        if let Some(ref value) = attr.value_str() {
            if let Ok(value) = FromStr::from_str(&value.as_str()) {
                f(value)
            } else {
                sess.span_err(attr.span, "not a number");
            }
        } else {
            sess.span_err(attr.span, "bad clippy attribute");
        }
    }
}

/// Return true if the attributes contain any of `proc_macro`,
/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
    attrs.iter().any(is_proc_macro_attr)
}
<|endoftext|>


<commit_before>//! # TreeView Sample
//!
//! This sample demonstrates how to create a TreeView with either a ListStore or TreeStore.

extern crate glib;
extern crate gtk;
extern crate gdk_pixbuf;

use gtk::prelude::*;
use gdk_pixbuf::Pixbuf;

fn append_text_column(tree: &gtk::TreeView) {
    let column = gtk::TreeViewColumn::new();
    let cell = gtk::CellRendererText::new();

    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    tree.append_column(&column);
}

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }

    let window = gtk::Window::new(gtk::WindowType::Toplevel);

    window.set_title("TreeView Sample");
    window.set_position(gtk::WindowPosition::Center);

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    // left pane

    let left_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let left_store = gtk::ListStore::new(&column_types);

    left_tree.set_model(Some(&left_store));
    left_tree.set_headers_visible(false);
    append_text_column(&left_tree);

    // print out when a row is selected

    let left_selection = left_tree.get_selection().unwrap();
    left_selection.connect_changed(|tree_selection| {
        let (left_model, iter) = tree_selection.get_selected().unwrap();
        println!("selected row {}", left_model.get_path(&iter));
    });

    for _ in 0..10 {
        left_store.insert_with_values(None, &[0], &[&"I'm in a list"]);
    }

    // middle pane

    let middle_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let middle_store = gtk::TreeStore::new(&column_types);

    middle_tree.set_model(Some(&middle_store));
    middle_tree.set_headers_visible(false);
    append_text_column(&middle_tree);

    for i in 0..10 {
        // insert_with_values takes two slices: column indices and ToValue
        // trait objects. ToValue is implemented for strings, numeric types,
        // bool and Object descendants
        let iter = middle_store.insert_with_values(None, None, &[0], &[&format!("Hello {}", i)]);

        for _ in 0..i {
            middle_store.insert_with_values(Some(&iter), None, &[0], &[&"I'm a child node"]);
        }
    }

    // right pane
    let right_tree = gtk::TreeView::new();
    let right_column_types = [Pixbuf::static_type(), String::static_type()];
    let right_store = gtk::TreeStore::new(&right_column_types);
    let renderer = gtk::CellRendererPixbuf::new();
    let col = gtk::TreeViewColumn::new();

    col.set_title("Picture");
    col.pack_start(&renderer, false);

    col.add_attribute(&renderer, "pixbuf", 0);

    let renderer2 = gtk::CellRendererText::new();
    col.pack_start(&renderer2, true);
    col.add_attribute(&renderer2, "text", 1);
    let image = match Pixbuf::new_from_file("./resources/eye.png") {
        Ok(i) => i,
        Err(e) => {
            println!("Error while creating image: {}", e);
            if e.kind() == Some(glib::FileError::Noent) {
                println!("Relaunch this example from the same level as the `resources` folder");
            }
            return;
        }
    };

    right_tree.append_column(&col);
    right_tree.set_model(Some(&right_store));
    right_tree.set_headers_visible(true);

    for _ in 0..10 {
        right_store.insert_with_values(None, None, &[0, 1],
                                       &[&image, &"I'm a child node with an image"]);
    }

    // display the panes

    let split_pane = gtk::Box::new(gtk::Orientation::Horizontal, 10);

    split_pane.set_size_request(-1, -1);
    split_pane.add(&left_tree);
    split_pane.add(&middle_tree);
    split_pane.add(&right_tree);

    window.add(&split_pane);
    window.show_all();
    gtk::main();
}
<commit_msg>Make selections example visual<commit_after>//! # TreeView Sample
//!
//! This sample demonstrates how to create a TreeView with either a ListStore or TreeStore.

extern crate glib;
extern crate gtk;
extern crate gdk_pixbuf;

use gtk::prelude::*;
use gdk_pixbuf::Pixbuf;

fn append_text_column(tree: &gtk::TreeView) {
    let column = gtk::TreeViewColumn::new();
    let cell = gtk::CellRendererText::new();

    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    tree.append_column(&column);
}

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }

    let window = gtk::Window::new(gtk::WindowType::Toplevel);

    window.set_title("TreeView Sample");
    window.set_position(gtk::WindowPosition::Center);

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    // left pane

    let left_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let left_store = gtk::ListStore::new(&column_types);

    left_tree.set_model(Some(&left_store));
    left_tree.set_headers_visible(false);
    append_text_column(&left_tree);

    for _ in 0..10 {
        left_store.insert_with_values(None, &[0], &[&"I'm in a list"]);
    }

    // middle pane

    let middle_tree = gtk::TreeView::new();
    let column_types = [String::static_type()];
    let middle_store = gtk::TreeStore::new(&column_types);

    middle_tree.set_model(Some(&middle_store));
    middle_tree.set_headers_visible(false);
    append_text_column(&middle_tree);

    for i in 0..10 {
        // insert_with_values takes two slices: column indices and ToValue
        // trait objects. ToValue is implemented for strings, numeric types,
        // bool and Object descendants
        let iter = middle_store.insert_with_values(None, None, &[0], &[&format!("Hello {}", i)]);

        for _ in 0..i {
            middle_store.insert_with_values(Some(&iter), None, &[0], &[&"I'm a child node"]);
        }
    }

    // right pane
    let right_tree = gtk::TreeView::new();
    let right_column_types = [Pixbuf::static_type(), String::static_type()];
    let right_store = gtk::TreeStore::new(&right_column_types);
    let renderer = gtk::CellRendererPixbuf::new();
    let col = gtk::TreeViewColumn::new();

    col.set_title("Picture");
    col.pack_start(&renderer, false);

    col.add_attribute(&renderer, "pixbuf", 0);

    let renderer2 = gtk::CellRendererText::new();
    col.pack_start(&renderer2, true);
    col.add_attribute(&renderer2, "text", 1);
    let image = match Pixbuf::new_from_file("./resources/eye.png") {
        Ok(i) => i,
        Err(e) => {
            println!("Error while creating image: {}", e);
            if e.kind() == Some(glib::FileError::Noent) {
                println!("Relaunch this example from the same level as the `resources` folder");
            }
            return;
        }
    };

    right_tree.append_column(&col);
    right_tree.set_model(Some(&right_store));
    right_tree.set_headers_visible(true);

    for _ in 0..10 {
        right_store.insert_with_values(None, None, &[0, 1],
                                       &[&image, &"I'm a child node with an image"]);
    }

    // selection and path manipulation

    let left_selection = left_tree.get_selection();
    let right_tree1 = right_tree.clone();
    left_selection.connect_changed(move |tree_selection| {
        let (left_model, iter) = tree_selection.get_selected().unwrap();
        let mut path = left_model.get_path(&iter);
        // get the top-level element path
        while path.get_depth() > 1 {
            path.up();
        }
        right_tree1.get_selection().select_path(&path);
    });

    // display the panes

    let split_pane = gtk::Box::new(gtk::Orientation::Horizontal, 10);

    split_pane.set_size_request(-1, -1);
    split_pane.add(&left_tree);
    split_pane.add(&middle_tree);
    split_pane.add(&right_tree);

    window.add(&split_pane);
    window.show_all();
    gtk::main();
}
<|endoftext|>


<commit_before>use cgmath::prelude::*;
use cgmath::{Matrix4, Point2, Point3, Vector3};

use rand;

use crate::aabb::{self, AABB};
use crate::color::Color;
use crate::index_ptr::IndexPtr;
use crate::material::Material;
use crate::pt_renderer::{Intersect, Ray};
use crate::util::ConvArr;
use crate::vertex::Vertex;
use crate::Float;

#[derive(Default)]
pub struct TriangleBuilder {
    vertices: Vec<IndexPtr<Vertex>>,
}

impl TriangleBuilder {
    pub fn new() -> Self {
        Self {
            vertices: Vec::new(),
        }
    }

    pub fn add_vertex(&mut self, vertex: IndexPtr<Vertex>) {
        self.vertices.push(vertex);
    }

    pub fn build(self, ng: [f32; 3], material: IndexPtr<Material>) -> Result<Triangle, String> {
        if self.vertices.len() != 3 {
            Err("Triangle doesn't have 3 vertices!".to_string())
        } else {
            Ok(Triangle::new(
                self.vertices[0].clone(),
                self.vertices[1].clone(),
                self.vertices[2].clone(),
                Vector3::from_arr(ng),
                material,
            ))
        }
    }
}

/// Tracable triangle
#[derive(Clone, Debug)]
pub struct Triangle {
    v1: IndexPtr<Vertex>,
    v2: IndexPtr<Vertex>,
    v3: IndexPtr<Vertex>,
    /// Geometric normal
    ng: Vector3<Float>,
    to_barycentric: Matrix4<Float>,
    pub material: IndexPtr<Material>,
}

impl Triangle {
    fn new(
        v1: IndexPtr<Vertex>,
        v2: IndexPtr<Vertex>,
        v3: IndexPtr<Vertex>,
        ng: Vector3<Float>,
        material: IndexPtr<Material>,
    ) -> Self {
        let p1 = v1.p;
        let p2 = v2.p;
        let p3 = v3.p;
        let z = (p2 - p1).cross(p3 - p1).normalize();
        let from_barycentric = Matrix4::from_cols(
            (p2 - p1).extend(0.0),
            (p3 - p1).extend(0.0),
            z.extend(0.0),
            p1.to_homogeneous(),
        );
        let to_barycentric = from_barycentric
            .invert()
            .expect("Non invertible barycentric tranform");
        Self {
            v1,
            v2,
            v3,
            ng,
            to_barycentric,
            material,
        }
    }

    fn normal(&self, u: Float, v: Float) -> Vector3<Float> {
        let n1 = self.v1.n;
        let n2 = self.v2.n;
        let n3 = self.v3.n;
        (1.0 - u - v) * n1 + u * n2 + v * n3
    }

    fn tex_coords(&self, u: Float, v: Float) -> Point2<Float> {
        let t1 = self.v1.t;
        let t2 = self.v2.t;
        let t3 = self.v3.t;
        (1.0 - u - v) * t1 + (u * t2 - (-v) * t3)
    }

    pub fn aabb(&self) -> AABB {
        let mut min = self.v1.p;
        min = aabb::min_point(&min, &self.v2.p);
        min = aabb::min_point(&min, &self.v3.p);
        let mut max = self.v1.p;
        max = aabb::max_point(&max, &self.v2.p);
        max = aabb::max_point(&max, &self.v3.p);
        AABB { min, max }
    }

    pub fn le(&self, dir: Vector3<Float>) -> Color {
        if let Some(le) = self.material.emissive {
            self.ng.dot(dir).max(0.0) * le
        } else {
            Color::black()
        }
    }

    pub fn center(&self) -> Point3<Float> {
        Point3::centroid(&[self.v1.p, self.v2.p, self.v3.p])
    }

    pub fn area(&self) -> Float {
        0.5 / self.to_barycentric.determinant().abs()
    }

    pub fn random_point(&self) -> (Point3<Float>, Vector3<Float>) {
        let r1: Float = rand::random();
        let r2: Float = rand::random();
        let sr1 = r1.sqrt();
        let u = 1.0 - sr1;
        let v = r2 * sr1;
        (self.pos(u, v), self.normal(u, v))
    }

    fn pos(&self, u: Float, v: Float) -> Point3<Float> {
        // Have to substract one component since cgmath points cannot by summed
        // and there is not a cleaner method to convert to Vector3
        (1.0 - u - v) * self.v1.p + (u * self.v2.p - (-v) * self.v3.p)
    }
}

#[derive(Debug)]
pub struct Hit<'a> {
    pub tri: &'a Triangle,
    pub t: Float,
    pub u: Float,
    pub v: Float,
}

impl<'a> Intersect<'a, Hit<'a>> for Triangle {
    fn intersect(&self, ray: &Ray) -> Option<Hit> {
        let bary_o = self.to_barycentric * ray.orig.to_homogeneous();
        let bary_d = self.to_barycentric * ray.dir.extend(0.0);
        let t = -bary_o.z / bary_d.z;
        let u = bary_o.x + t * bary_d.x;
        let v = bary_o.y + t * bary_d.y;
        if u >= 0.0 && v >= 0.0 && u + v <= 1.0 && t > 0.0 && t < ray.length {
            Some(Hit { tri: self, t, u, v })
        } else {
            None
        }
    }
}

impl Hit<'_> {
    pub fn pos(&self) -> Point3<Float> {
        self.tri.pos(self.u, self.v)
    }

    pub fn normal(&self) -> Vector3<Float> {
        self.tri.normal(self.u, self.v)
    }

    pub fn tex_coords(&self) -> Point2<Float> {
        self.tri.tex_coords(self.u, self.v)
    }
}
<commit_msg>Fix direct radiance from triangle<commit_after>use cgmath::prelude::*;
use cgmath::{Matrix4, Point2, Point3, Vector3};

use rand;

use crate::aabb::{self, AABB};
use crate::color::Color;
use crate::index_ptr::IndexPtr;
use crate::material::Material;
use crate::pt_renderer::{Intersect, Ray};
use crate::util::ConvArr;
use crate::vertex::Vertex;
use crate::Float;

#[derive(Default)]
pub struct TriangleBuilder {
    vertices: Vec<IndexPtr<Vertex>>,
}

impl TriangleBuilder {
    pub fn new() -> Self {
        Self {
            vertices: Vec::new(),
        }
    }

    pub fn add_vertex(&mut self, vertex: IndexPtr<Vertex>) {
        self.vertices.push(vertex);
    }

    pub fn build(self, ng: [f32; 3], material: IndexPtr<Material>) -> Result<Triangle, String> {
        if self.vertices.len() != 3 {
            Err("Triangle doesn't have 3 vertices!".to_string())
        } else {
            Ok(Triangle::new(
                self.vertices[0].clone(),
                self.vertices[1].clone(),
                self.vertices[2].clone(),
                Vector3::from_arr(ng),
                material,
            ))
        }
    }
}

/// Tracable triangle
#[derive(Clone, Debug)]
pub struct Triangle {
    v1: IndexPtr<Vertex>,
    v2: IndexPtr<Vertex>,
    v3: IndexPtr<Vertex>,
    /// Geometric normal
    ng: Vector3<Float>,
    to_barycentric: Matrix4<Float>,
    pub material: IndexPtr<Material>,
}

impl Triangle {
    fn new(
        v1: IndexPtr<Vertex>,
        v2: IndexPtr<Vertex>,
        v3: IndexPtr<Vertex>,
        ng: Vector3<Float>,
        material: IndexPtr<Material>,
    ) -> Self {
        let p1 = v1.p;
        let p2 = v2.p;
        let p3 = v3.p;
        let z = (p2 - p1).cross(p3 - p1).normalize();
        let from_barycentric = Matrix4::from_cols(
            (p2 - p1).extend(0.0),
            (p3 - p1).extend(0.0),
            z.extend(0.0),
            p1.to_homogeneous(),
        );
        let to_barycentric = from_barycentric
            .invert()
            .expect("Non invertible barycentric tranform");
        Self {
            v1,
            v2,
            v3,
            ng,
            to_barycentric,
            material,
        }
    }

    fn normal(&self, u: Float, v: Float) -> Vector3<Float> {
        let n1 = self.v1.n;
        let n2 = self.v2.n;
        let n3 = self.v3.n;
        (1.0 - u - v) * n1 + u * n2 + v * n3
    }

    fn tex_coords(&self, u: Float, v: Float) -> Point2<Float> {
        let t1 = self.v1.t;
        let t2 = self.v2.t;
        let t3 = self.v3.t;
        (1.0 - u - v) * t1 + (u * t2 - (-v) * t3)
    }

    pub fn aabb(&self) -> AABB {
        let mut min = self.v1.p;
        min = aabb::min_point(&min, &self.v2.p);
        min = aabb::min_point(&min, &self.v3.p);
        let mut max = self.v1.p;
        max = aabb::max_point(&max, &self.v2.p);
        max = aabb::max_point(&max, &self.v3.p);
        AABB { min, max }
    }

    pub fn le(&self, dir: Vector3<Float>) -> Color {
        if let Some(le) = self.material.emissive {
            if self.ng.dot(dir) > 0.0 {
                return le;
            }
        }
        Color::black()
    }

    pub fn center(&self) -> Point3<Float> {
        Point3::centroid(&[self.v1.p, self.v2.p, self.v3.p])
    }

    pub fn area(&self) -> Float {
        0.5 / self.to_barycentric.determinant().abs()
    }

    pub fn random_point(&self) -> (Point3<Float>, Vector3<Float>) {
        let r1: Float = rand::random();
        let r2: Float = rand::random();
        let sr1 = r1.sqrt();
        let u = 1.0 - sr1;
        let v = r2 * sr1;
        (self.pos(u, v), self.normal(u, v))
    }

    fn pos(&self, u: Float, v: Float) -> Point3<Float> {
        // Have to substract one component since cgmath points cannot by summed
        // and there is not a cleaner method to convert to Vector3
        (1.0 - u - v) * self.v1.p + (u * self.v2.p - (-v) * self.v3.p)
    }
}

#[derive(Debug)]
pub struct Hit<'a> {
    pub tri: &'a Triangle,
    pub t: Float,
    pub u: Float,
    pub v: Float,
}

impl<'a> Intersect<'a, Hit<'a>> for Triangle {
    fn intersect(&self, ray: &Ray) -> Option<Hit> {
        let bary_o = self.to_barycentric * ray.orig.to_homogeneous();
        let bary_d = self.to_barycentric * ray.dir.extend(0.0);
        let t = -bary_o.z / bary_d.z;
        let u = bary_o.x + t * bary_d.x;
        let v = bary_o.y + t * bary_d.y;
        if u >= 0.0 && v >= 0.0 && u + v <= 1.0 && t > 0.0 && t < ray.length {
            Some(Hit { tri: self, t, u, v })
        } else {
            None
        }
    }
}

impl Hit<'_> {
    pub fn pos(&self) -> Point3<Float> {
        self.tri.pos(self.u, self.v)
    }

    pub fn normal(&self) -> Vector3<Float> {
        self.tri.normal(self.u, self.v)
    }

    pub fn tex_coords(&self) -> Point2<Float> {
        self.tri.tex_coords(self.u, self.v)
    }
}
<|endoftext|>