<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    Address, EventKey, HashValue, MoveModuleBytecode, MoveModuleId, MoveResource, MoveResourceType,
    MoveScriptBytecode, MoveType, MoveValue, U64,
};

use diem_crypto::hash::CryptoHash;
use diem_types::{
    block_metadata::BlockMetadata,
    contract_event::ContractEvent,
    transaction::{Script, SignedTransaction, TransactionInfoTrait},
};
use move_core_types::identifier::Identifier;
use resource_viewer::AnnotatedMoveValue;

use serde::Serialize;
use std::{
    boxed::Box,
    convert::{From, Into, TryFrom, TryInto},
};

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Transaction {
    PendingTransaction(PendingTransaction),
    UserTransaction(Box<UserTransaction>),
    GenesisTransaction(GenesisTransaction),
    BlockMetadataTransaction(BlockMetadataTransaction),
}

impl Transaction {
    pub fn hash(txn: SignedTransaction) -> HashValue {
        diem_types::transaction::Transaction::UserTransaction(txn)
            .hash()
            .into()
    }
}

impl From<(SignedTransaction, TransactionPayload)> for Transaction {
    fn from((txn, payload): (SignedTransaction, TransactionPayload)) -> Self {
        Transaction::PendingTransaction(PendingTransaction {
            sender: txn.sender().into(),
            sequence_number: txn.sequence_number().into(),
            max_gas_amount: txn.max_gas_amount().into(),
            gas_unit_price: txn.gas_unit_price().into(),
            gas_currency_code: txn.gas_currency_code().to_owned(),
            expiration_timestamp_secs: txn.expiration_timestamp_secs().into(),
            hash: Transaction::hash(txn),
            payload,
        })
    }
}

impl<T: TransactionInfoTrait> From<(u64, &SignedTransaction, &T, TransactionPayload, Vec<Event>)>
    for Transaction
{
    fn from(
        (version, txn, info, payload, events): (
            u64,
            &SignedTransaction,
            &T,
            TransactionPayload,
            Vec<Event>,
        ),
    ) -> Self {
        Transaction::UserTransaction(Box::new(UserTransaction {
            version: version.into(),
            hash: info.transaction_hash().into(),
            state_root_hash: info.state_root_hash().into(),
            event_root_hash: info.event_root_hash().into(),
            gas_used: info.gas_used().into(),
            success: info.status().is_success(),

            sender: txn.sender().into(),
            sequence_number: txn.sequence_number().into(),
            max_gas_amount: txn.max_gas_amount().into(),
            gas_unit_price: txn.gas_unit_price().into(),
            gas_currency_code: txn.gas_currency_code().to_owned(),
            expiration_timestamp_secs: txn.expiration_timestamp_secs().into(),
            events,
            payload,
        }))
    }
}

impl<T: TransactionInfoTrait> From<(u64, &T, WriteSetPayload, Vec<Event>)> for Transaction {
    fn from((version, info, payload, events): (u64, &T, WriteSetPayload, Vec<Event>)) -> Self {
        Transaction::GenesisTransaction(GenesisTransaction {
            version: version.into(),
            hash: info.transaction_hash().into(),
            state_root_hash: info.state_root_hash().into(),
            event_root_hash: info.event_root_hash().into(),
            gas_used: info.gas_used().into(),
            success: info.status().is_success(),

            payload: GenesisPayload::WriteSetPayload(payload),
            events,
        })
    }
}

impl<T: TransactionInfoTrait> From<(u64, &BlockMetadata, &T)> for Transaction {
    fn from((version, txn, info): (u64, &BlockMetadata, &T)) -> Self {
        Transaction::BlockMetadataTransaction(BlockMetadataTransaction {
            version: version.into(),
            hash: info.transaction_hash().into(),
            state_root_hash: info.state_root_hash().into(),
            event_root_hash: info.event_root_hash().into(),
            gas_used: info.gas_used().into(),
            success: info.status().is_success(),

            id: txn.id().into(),
            round: txn.round().into(),
            previous_block_votes: txn
                .previous_block_votes()
                .clone()
                .iter()
                .map(|a| (*a).into())
                .collect(),
            proposer: txn.proposer().into(),
        })
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct PendingTransaction {
    pub hash: HashValue,
    pub sender: Address,
    pub sequence_number: U64,
    pub max_gas_amount: U64,
    pub gas_unit_price: U64,
    pub gas_currency_code: String,
    pub expiration_timestamp_secs: U64,
    pub payload: TransactionPayload,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct UserTransaction {
    pub version: U64,
    pub hash: HashValue,
    pub state_root_hash: HashValue,
    pub event_root_hash: HashValue,
    pub gas_used: U64,
    pub success: bool,

    // user txn specific fields
    pub sender: Address,
    pub sequence_number: U64,
    pub max_gas_amount: U64,
    pub gas_unit_price: U64,
    pub gas_currency_code: String,
    pub expiration_timestamp_secs: U64,
    pub payload: TransactionPayload,
    pub events: Vec<Event>,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct GenesisTransaction {
    pub version: U64,
    pub hash: HashValue,
    pub state_root_hash: HashValue,
    pub event_root_hash: HashValue,
    pub gas_used: U64,
    pub success: bool,

    // genesis txn specific fields
    pub payload: GenesisPayload,
    pub events: Vec<Event>,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct BlockMetadataTransaction {
    pub version: U64,
    pub hash: HashValue,
    pub state_root_hash: HashValue,
    pub event_root_hash: HashValue,
    pub gas_used: U64,
    pub success: bool,

    // block metadata txn specific fields
    pub id: HashValue,
    pub round: U64,
    pub previous_block_votes: Vec<Address>,
    pub proposer: Address,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct Event {
    pub key: EventKey,
    pub sequence_number: U64,
    #[serde(rename = "type")]
    pub typ: MoveType,
    pub data: MoveValue,
}

impl From<(&ContractEvent, AnnotatedMoveValue)> for Event {
    fn from((event, data): (&ContractEvent, AnnotatedMoveValue)) -> Self {
        match event {
            ContractEvent::V0(v0) => Self {
                key: (*v0.key()).into(),
                sequence_number: v0.sequence_number().into(),
                typ: v0.type_tag().clone().into(),
                data: data.into(),
            },
        }
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum GenesisPayload {
    WriteSetPayload(WriteSetPayload),
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TransactionPayload {
    ScriptFunctionPayload {
        module: MoveModuleId,
        function: Identifier,
        type_arguments: Vec<MoveType>,
        arguments: Vec<MoveValue>,
    },
    ScriptPayload(ScriptPayload),
    ModulePayload(MoveModuleBytecode),
    WriteSetPayload(WriteSetPayload),
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct ScriptPayload {
    pub code: MoveScriptBytecode,
    pub type_arguments: Vec<MoveType>,
    pub arguments: Vec<MoveValue>,
}

impl TryFrom<&Script> for ScriptPayload {
    type Error = anyhow::Error;

    fn try_from(script: &Script) -> anyhow::Result<Self> {
        Ok(Self {
            code: script.code().try_into()?,
            type_arguments: script
                .ty_args()
                .iter()
                .map(|arg| arg.clone().into())
                .collect(),
            arguments: script.args().iter().map(|arg| arg.clone().into()).collect(),
        })
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum WriteSetPayload {
    ScriptWriteSet {
        execute_as: Address,
        script: ScriptPayload,
    },
    DirectWriteSet {
        changes: Vec<WriteSetChange>,
        events: Vec<Event>,
    },
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum WriteSetChange {
    DeleteModule {
        address: Address,
        module: MoveModuleId,
    },
    DeleteResource {
        address: Address,
        resource: MoveResourceType,
    },
    WriteModule {
        address: Address,
        data: MoveModuleBytecode,
    },
    WriteResource {
        address: Address,
        data: MoveResource,
    },
}
<commit_msg>[api] use serde flatten to extract same fields in the transactions into a shared TransactionInfo struct<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    Address, EventKey, HashValue, MoveModuleBytecode, MoveModuleId, MoveResource, MoveResourceType,
    MoveScriptBytecode, MoveType, MoveValue, U64,
};

use diem_crypto::hash::CryptoHash;
use diem_types::{
    block_metadata::BlockMetadata,
    contract_event::ContractEvent,
    transaction::{Script, SignedTransaction, TransactionInfoTrait},
};
use move_core_types::identifier::Identifier;
use resource_viewer::AnnotatedMoveValue;

use serde::Serialize;
use std::{
    boxed::Box,
    convert::{From, Into, TryFrom, TryInto},
};

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Transaction {
    PendingTransaction(PendingTransaction),
    UserTransaction(Box<UserTransaction>),
    GenesisTransaction(GenesisTransaction),
    BlockMetadataTransaction(BlockMetadataTransaction),
}

impl Transaction {
    pub fn hash(txn: SignedTransaction) -> HashValue {
        diem_types::transaction::Transaction::UserTransaction(txn)
            .hash()
            .into()
    }
}

impl From<(SignedTransaction, TransactionPayload)> for Transaction {
    fn from((txn, payload): (SignedTransaction, TransactionPayload)) -> Self {
        Transaction::PendingTransaction(PendingTransaction {
            sender: txn.sender().into(),
            sequence_number: txn.sequence_number().into(),
            max_gas_amount: txn.max_gas_amount().into(),
            gas_unit_price: txn.gas_unit_price().into(),
            gas_currency_code: txn.gas_currency_code().to_owned(),
            expiration_timestamp_secs: txn.expiration_timestamp_secs().into(),
            hash: Transaction::hash(txn),
            payload,
        })
    }
}

impl<T: TransactionInfoTrait> From<(u64, &SignedTransaction, &T, TransactionPayload, Vec<Event>)>
    for Transaction
{
    fn from(
        (version, txn, info, payload, events): (
            u64,
            &SignedTransaction,
            &T,
            TransactionPayload,
            Vec<Event>,
        ),
    ) -> Self {
        Transaction::UserTransaction(Box::new(UserTransaction {
            info: (version, info).into(),
            sender: txn.sender().into(),
            sequence_number: txn.sequence_number().into(),
            max_gas_amount: txn.max_gas_amount().into(),
            gas_unit_price: txn.gas_unit_price().into(),
            gas_currency_code: txn.gas_currency_code().to_owned(),
            expiration_timestamp_secs: txn.expiration_timestamp_secs().into(),
            events,
            payload,
        }))
    }
}

impl<T: TransactionInfoTrait> From<(u64, &T, WriteSetPayload, Vec<Event>)> for Transaction {
    fn from((version, info, payload, events): (u64, &T, WriteSetPayload, Vec<Event>)) -> Self {
        Transaction::GenesisTransaction(GenesisTransaction {
            info: (version, info).into(),
            payload: GenesisPayload::WriteSetPayload(payload),
            events,
        })
    }
}

impl<T: TransactionInfoTrait> From<(u64, &BlockMetadata, &T)> for Transaction {
    fn from((version, txn, info): (u64, &BlockMetadata, &T)) -> Self {
        Transaction::BlockMetadataTransaction(BlockMetadataTransaction {
            info: (version, info).into(),
            id: txn.id().into(),
            round: txn.round().into(),
            previous_block_votes: txn
                .previous_block_votes()
                .clone()
                .iter()
                .map(|a| (*a).into())
                .collect(),
            proposer: txn.proposer().into(),
        })
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct TransactionInfo {
    pub version: U64,
    pub hash: HashValue,
    pub state_root_hash: HashValue,
    pub event_root_hash: HashValue,
    pub gas_used: U64,
    pub success: bool,
}

impl<T: TransactionInfoTrait> From<(u64, &T)> for TransactionInfo {
    fn from((version, info): (u64, &T)) -> Self {
        Self {
            version: version.into(),
            hash: info.transaction_hash().into(),
            state_root_hash: info.state_root_hash().into(),
            event_root_hash: info.event_root_hash().into(),
            gas_used: info.gas_used().into(),
            success: info.status().is_success(),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct PendingTransaction {
    pub hash: HashValue,
    pub sender: Address,
    pub sequence_number: U64,
    pub max_gas_amount: U64,
    pub gas_unit_price: U64,
    pub gas_currency_code: String,
    pub expiration_timestamp_secs: U64,
    pub payload: TransactionPayload,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct UserTransaction {
    #[serde(flatten)]
    pub info: TransactionInfo,
    pub sender: Address,
    pub sequence_number: U64,
    pub max_gas_amount: U64,
    pub gas_unit_price: U64,
    pub gas_currency_code: String,
    pub expiration_timestamp_secs: U64,
    pub payload: TransactionPayload,
    pub events: Vec<Event>,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct GenesisTransaction {
    #[serde(flatten)]
    pub info: TransactionInfo,
    pub payload: GenesisPayload,
    pub events: Vec<Event>,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct BlockMetadataTransaction {
    #[serde(flatten)]
    pub info: TransactionInfo,
    pub id: HashValue,
    pub round: U64,
    pub previous_block_votes: Vec<Address>,
    pub proposer: Address,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct Event {
    pub key: EventKey,
    pub sequence_number: U64,
    #[serde(rename = "type")]
    pub typ: MoveType,
    pub data: MoveValue,
}

impl From<(&ContractEvent, AnnotatedMoveValue)> for Event {
    fn from((event, data): (&ContractEvent, AnnotatedMoveValue)) -> Self {
        match event {
            ContractEvent::V0(v0) => Self {
                key: (*v0.key()).into(),
                sequence_number: v0.sequence_number().into(),
                typ: v0.type_tag().clone().into(),
                data: data.into(),
            },
        }
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum GenesisPayload {
    WriteSetPayload(WriteSetPayload),
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TransactionPayload {
    ScriptFunctionPayload {
        module: MoveModuleId,
        function: Identifier,
        type_arguments: Vec<MoveType>,
        arguments: Vec<MoveValue>,
    },
    ScriptPayload(ScriptPayload),
    ModulePayload(MoveModuleBytecode),
    WriteSetPayload(WriteSetPayload),
}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct ScriptPayload {
    pub code: MoveScriptBytecode,
    pub type_arguments: Vec<MoveType>,
    pub arguments: Vec<MoveValue>,
}

impl TryFrom<&Script> for ScriptPayload {
    type Error = anyhow::Error;

    fn try_from(script: &Script) -> anyhow::Result<Self> {
        Ok(Self {
            code: script.code().try_into()?,
            type_arguments: script
                .ty_args()
                .iter()
                .map(|arg| arg.clone().into())
                .collect(),
            arguments: script.args().iter().map(|arg| arg.clone().into()).collect(),
        })
    }
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum WriteSetPayload {
    ScriptWriteSet {
        execute_as: Address,
        script: ScriptPayload,
    },
    DirectWriteSet {
        changes: Vec<WriteSetChange>,
        events: Vec<Event>,
    },
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum WriteSetChange {
    DeleteModule {
        address: Address,
        module: MoveModuleId,
    },
    DeleteResource {
        address: Address,
        resource: MoveResourceType,
    },
    WriteModule {
        address: Address,
        data: MoveModuleBytecode,
    },
    WriteResource {
        address: Address,
        data: MoveResource,
    },
}
<|endoftext|>


<commit_before>use std;

// These tests used to be separate files, but I wanted to refactor all
// the common code.

import cmp::Eq;
import std::ebml;
import io::Writer;
import std::serialization::{serialize_uint, deserialize_uint};

fn test_ser_and_deser<A:Eq>(a1: A,
                            expected: ~str,
                            ebml_ser_fn: fn(ebml::Writer, A),
                            ebml_deser_fn: fn(ebml::EbmlDeserializer) -> A,
                            io_ser_fn: fn(io::Writer, A)) {

    // check the pretty printer:
    io_ser_fn(io::stdout(), a1);
    let s = io::with_str_writer(|w| io_ser_fn(w, a1) );
    debug!("s == %?", s);
    assert s == expected;

    // check the EBML serializer:
    let buf = io::mem_buffer();
    let w = ebml::Writer(buf as io::Writer);
    ebml_ser_fn(w, a1);
    let d = ebml::Doc(@io::mem_buffer_buf(buf));
    let a2 = ebml_deser_fn(ebml::ebml_deserializer(d));
    io::print(~"\na1 = ");
    io_ser_fn(io::stdout(), a1);
    io::print(~"\na2 = ");
    io_ser_fn(io::stdout(), a2);
    io::print(~"\n");
    assert a1 == a2;

}

#[auto_serialize]
enum expr {
    val(uint),
    plus(@expr, @expr),
    minus(@expr, @expr)
}

impl expr : cmp::Eq {
    pure fn eq(&&other: expr) -> bool {
        match self {
            val(e0a) => {
                match other {
                    val(e0b) => e0a == e0b,
                    _ => false
                }
            }
            plus(e0a, e1a) => {
                match other {
                    plus(e0b, e1b) => e0a == e0b && e1a == e1b,
                    _ => false
                }
            }
            minus(e0a, e1a) => {
                match other {
                    minus(e0b, e1b) => e0a == e0b && e1a == e1b,
                    _ => false
                }
            }
        }
    }
}

#[auto_serialize]
type spanned<T> = {lo: uint, hi: uint, node: T};

impl<T:cmp::Eq> spanned<T> : cmp::Eq {
    pure fn eq(&&other: spanned<T>) -> bool {
        self.lo == other.lo && self.hi == other.hi && self.node.eq(other.node)
    }
}

#[auto_serialize]
type spanned_uint = spanned<uint>;

#[auto_serialize]
type some_rec = {v: uint_vec};

#[auto_serialize]
enum an_enum = some_rec;

#[auto_serialize]
type uint_vec = ~[uint];

#[auto_serialize]
type point = {x: uint, y: uint};

#[auto_serialize]
enum quark<T> {
    top(T),
    bottom(T)
}

#[auto_serialize]
type uint_quark = quark<uint>;

#[auto_serialize]
enum c_like { a, b, c }

fn main() {

    test_ser_and_deser(plus(@minus(@val(3u), @val(10u)),
                            @plus(@val(22u), @val(5u))),
                       ~"plus(@minus(@val(3u), @val(10u)), \
                        @plus(@val(22u), @val(5u)))",
                       serialize_expr,
                       deserialize_expr,
                       serialize_expr);

    test_ser_and_deser({lo: 0u, hi: 5u, node: 22u},
                       ~"{lo: 0u, hi: 5u, node: 22u}",
                       serialize_spanned_uint,
                       deserialize_spanned_uint,
                       serialize_spanned_uint);

    test_ser_and_deser(an_enum({v: ~[1u, 2u, 3u]}),
                       ~"an_enum({v: [1u, 2u, 3u]})",
                       serialize_an_enum,
                       deserialize_an_enum,
                       serialize_an_enum);

    test_ser_and_deser({x: 3u, y: 5u},
                       ~"{x: 3u, y: 5u}",
                       serialize_point,
                       deserialize_point,
                       serialize_point);

    test_ser_and_deser(~[1u, 2u, 3u],
                       ~"[1u, 2u, 3u]",
                       serialize_uint_vec,
                       deserialize_uint_vec,
                       serialize_uint_vec);

    test_ser_and_deser(top(22u),
                       ~"top(22u)",
                       serialize_uint_quark,
                       deserialize_uint_quark,
                       serialize_uint_quark);

    test_ser_and_deser(bottom(222u),
                       ~"bottom(222u)",
                       serialize_uint_quark,
                       deserialize_uint_quark,
                       serialize_uint_quark);

    test_ser_and_deser(a,
                       ~"a",
                       serialize_c_like,
                       deserialize_c_like,
                       serialize_c_like);

    test_ser_and_deser(b,
                       ~"b",
                       serialize_c_like,
                       deserialize_c_like,
                       serialize_c_like);
}
<commit_msg>Fix auto_serialize test.<commit_after>use std;

// These tests used to be separate files, but I wanted to refactor all
// the common code.

import cmp::Eq;
import std::ebml;
import io::Writer;
import std::serialization::{serialize_uint, deserialize_uint};

fn test_ser_and_deser<A:Eq>(a1: A,
                            expected: ~str,
                            ebml_ser_fn: fn(ebml::Writer, A),
                            ebml_deser_fn: fn(ebml::EbmlDeserializer) -> A,
                            io_ser_fn: fn(io::Writer, A)) {

    // check the pretty printer:
    io_ser_fn(io::stdout(), a1);
    let s = io::with_str_writer(|w| io_ser_fn(w, a1) );
    debug!("s == %?", s);
    assert s == expected;

    // check the EBML serializer:
    let buf = io::mem_buffer();
    let w = ebml::Writer(buf as io::Writer);
    ebml_ser_fn(w, a1);
    let d = ebml::Doc(@io::mem_buffer_buf(buf));
    let a2 = ebml_deser_fn(ebml::ebml_deserializer(d));
    io::print(~"\na1 = ");
    io_ser_fn(io::stdout(), a1);
    io::print(~"\na2 = ");
    io_ser_fn(io::stdout(), a2);
    io::print(~"\n");
    assert a1 == a2;

}

#[auto_serialize]
enum expr {
    val(uint),
    plus(@expr, @expr),
    minus(@expr, @expr)
}

impl an_enum : cmp::Eq {
    pure fn eq(&&other: an_enum) -> bool {
        self.v == other.v
    }
}

impl point : cmp::Eq {
    pure fn eq(&&other: point) -> bool {
        self.x == other.x &&
            self.y == other.y
    }
}

impl<T:cmp::Eq> quark<T> : cmp::Eq {
    pure fn eq(&&other: quark<T>) -> bool {
        match self {
          top(ref q) => match other {
            top(ref r) => q == r,
            bottom(_) => false
          },
          bottom(ref q) => match other {
            top(_) => false,
            bottom(ref r) => q == r
          }
        }
    }
}

impl c_like : cmp::Eq {
    pure fn eq(&&other: c_like) -> bool {
        self as int == other as int
    }
}

impl expr : cmp::Eq {
    pure fn eq(&&other: expr) -> bool {
        match self {
            val(e0a) => {
                match other {
                    val(e0b) => e0a == e0b,
                    _ => false
                }
            }
            plus(e0a, e1a) => {
                match other {
                    plus(e0b, e1b) => e0a == e0b && e1a == e1b,
                    _ => false
                }
            }
            minus(e0a, e1a) => {
                match other {
                    minus(e0b, e1b) => e0a == e0b && e1a == e1b,
                    _ => false
                }
            }
        }
    }
}

#[auto_serialize]
type spanned<T> = {lo: uint, hi: uint, node: T};

impl<T:cmp::Eq> spanned<T> : cmp::Eq {
    pure fn eq(&&other: spanned<T>) -> bool {
        self.lo == other.lo && self.hi == other.hi && self.node.eq(other.node)
    }
}

#[auto_serialize]
type spanned_uint = spanned<uint>;

#[auto_serialize]
type some_rec = {v: uint_vec};

#[auto_serialize]
enum an_enum = some_rec;

#[auto_serialize]
type uint_vec = ~[uint];

#[auto_serialize]
type point = {x: uint, y: uint};

#[auto_serialize]
enum quark<T> {
    top(T),
    bottom(T)
}

#[auto_serialize]
type uint_quark = quark<uint>;

#[auto_serialize]
enum c_like { a, b, c }

fn main() {

    test_ser_and_deser(plus(@minus(@val(3u), @val(10u)),
                            @plus(@val(22u), @val(5u))),
                       ~"plus(@minus(@val(3u), @val(10u)), \
                        @plus(@val(22u), @val(5u)))",
                       serialize_expr,
                       deserialize_expr,
                       serialize_expr);

    test_ser_and_deser({lo: 0u, hi: 5u, node: 22u},
                       ~"{lo: 0u, hi: 5u, node: 22u}",
                       serialize_spanned_uint,
                       deserialize_spanned_uint,
                       serialize_spanned_uint);

    test_ser_and_deser(an_enum({v: ~[1u, 2u, 3u]}),
                       ~"an_enum({v: [1u, 2u, 3u]})",
                       serialize_an_enum,
                       deserialize_an_enum,
                       serialize_an_enum);

    test_ser_and_deser({x: 3u, y: 5u},
                       ~"{x: 3u, y: 5u}",
                       serialize_point,
                       deserialize_point,
                       serialize_point);

    test_ser_and_deser(~[1u, 2u, 3u],
                       ~"[1u, 2u, 3u]",
                       serialize_uint_vec,
                       deserialize_uint_vec,
                       serialize_uint_vec);

    test_ser_and_deser(top(22u),
                       ~"top(22u)",
                       serialize_uint_quark,
                       deserialize_uint_quark,
                       serialize_uint_quark);

    test_ser_and_deser(bottom(222u),
                       ~"bottom(222u)",
                       serialize_uint_quark,
                       deserialize_uint_quark,
                       serialize_uint_quark);

    test_ser_and_deser(a,
                       ~"a",
                       serialize_c_like,
                       deserialize_c_like,
                       serialize_c_like);

    test_ser_and_deser(b,
                       ~"b",
                       serialize_c_like,
                       deserialize_c_like,
                       serialize_c_like);
}
<|endoftext|>


<commit_before>#![crate_name = "foo"]

mod hidden {
    // @has foo/hidden/struct.Foo.html
    // @has - '//p/a' '../../foo/struct.FooBar.html'
    pub struct Foo {}

    // @has foo/hidden/bar/index.html
    // @has - '//p/a' '../../foo/baz/index.html'
    pub mod bar {
        // @has foo/hidden/bar/struct.Thing.html
        // @has - '//p/a' '../../foo/baz/struct.Thing.html'
        pub struct Thing {}
    }
}

// @has foo/struct.FooBar.html
pub use hidden::Foo as FooBar;

// @has foo/baz/index.html
// @has foo/baz/struct.Thing.html
pub use hidden::bar as baz;
<commit_msg>Add more tests for renamed items<commit_after>#![crate_name = "foo"]

mod hidden {
    // @has foo/hidden/struct.Foo.html
    // @has - '//p/a' '../../foo/struct.FooBar.html'
    pub struct Foo {}
    pub union U { a: usize }
    pub enum Empty {}
    pub const C: usize = 1;
    pub static S: usize = 1;

    // @has foo/hidden/bar/index.html
    // @has - '//p/a' '../../foo/baz/index.html'
    pub mod bar {
        // @has foo/hidden/bar/struct.Thing.html
        // @has - '//p/a' '../../foo/baz/struct.Thing.html'
        pub struct Thing {}
    }
}

// @has foo/struct.FooBar.html
pub use hidden::Foo as FooBar;
// @has foo/union.FooU.html
pub use hidden::U as FooU;
// @has foo/enum.FooEmpty.html
pub use hidden::Empty as FooEmpty;
// @has foo/constant.FooC.html
pub use hidden::C as FooC;
// @has foo/static.FooS.html
pub use hidden::S as FooS;

// @has foo/baz/index.html
// @has foo/baz/struct.Thing.html
pub use hidden::bar as baz;
<|endoftext|>


<commit_before>// Copyright (c) 2018 The predicates-rs Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/license/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.

//! Definition of `Predicate` for wrapping a `Fn(&T) -> bool`

use std::fmt;
use std::marker::PhantomData;

use Predicate;

/// Predicate that wraps a function over a reference that returns a `bool`.
/// This type is returned by the `predicate::function` function.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
{
    function: F,
    name: &'static str,
    _phantom: PhantomData<T>,
}

impl<F, T> FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
{
    /// Provide a descriptive name for this function.
    ///
    /// # Examples
    ///
    /// ```
    /// use predicates::prelude::*;
    ///
    /// struct Example {
    ///     string: String,
    ///     number: i32,
    /// }
    ///
    /// let string_check = predicate::function(|x: &Example| x.string == "hello")
    ///     .fn_name("is_hello");
    /// println!("predicate: {}", string_check);
    /// ```
    pub fn fn_name(mut self, name: &'static str) -> Self {
        self.name = name;
        self
    }
}

impl<F, T> Predicate<T> for FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
{
    fn eval(&self, variable: &T) -> bool {
        (self.function)(variable)
    }
}

impl<F, T> fmt::Display for FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}(var)", self.name)
    }
}

/// Creates a new predicate that wraps over the given function. The returned
/// type implements `Predicate` and therefore has all combinators available to
/// it.
///
/// # Examples
///
/// ```
/// use predicates::prelude::*;
///
/// struct Example {
///     string: String,
///     number: i32,
/// }
///
/// let string_check = predicate::function(|x: &Example| x.string == "hello");
/// let number_check = predicate::function(|x: &Example| x.number == 42);
/// let predicate_fn = string_check.and(number_check);
/// let good_example = Example { string: "hello".into(), number: 42 };
/// assert_eq!(true, predicate_fn.eval(&good_example));
/// let bad_example = Example { string: "goodbye".into(), number: 0 };
/// assert_eq!(false, predicate_fn.eval(&bad_example));
/// ```
pub fn function<F, T>(function: F) -> FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
{
    FnPredicate {
        function,
        name: "fn",
        _phantom: PhantomData,
    }
}
<commit_msg>Use T: ?Sized everywhere for FnPredicate so slices and str work<commit_after>// Copyright (c) 2018 The predicates-rs Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/license/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.

//! Definition of `Predicate` for wrapping a `Fn(&T) -> bool`

use std::fmt;
use std::marker::PhantomData;

use Predicate;

/// Predicate that wraps a function over a reference that returns a `bool`.
/// This type is returned by the `predicate::function` function.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
    T: ?Sized,
{
    function: F,
    name: &'static str,
    _phantom: PhantomData<T>,
}

impl<F, T> FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
    T: ?Sized,
{
    /// Provide a descriptive name for this function.
    ///
    /// # Examples
    ///
    /// ```
    /// use predicates::prelude::*;
    ///
    /// struct Example {
    ///     string: String,
    ///     number: i32,
    /// }
    ///
    /// let string_check = predicate::function(|x: &Example| x.string == "hello")
    ///     .fn_name("is_hello");
    /// println!("predicate: {}", string_check);
    /// ```
    pub fn fn_name(mut self, name: &'static str) -> Self {
        self.name = name;
        self
    }
}

impl<F, T> Predicate<T> for FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
    T: ?Sized,
{
    fn eval(&self, variable: &T) -> bool {
        (self.function)(variable)
    }
}

impl<F, T> fmt::Display for FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
    T: ?Sized,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}(var)", self.name)
    }
}

/// Creates a new predicate that wraps over the given function. The returned
/// type implements `Predicate` and therefore has all combinators available to
/// it.
///
/// # Examples
///
/// ```
/// use predicates::prelude::*;
///
/// struct Example {
///     string: String,
///     number: i32,
/// }
///
/// let string_check = predicate::function(|x: &Example| x.string == "hello");
/// let number_check = predicate::function(|x: &Example| x.number == 42);
/// let predicate_fn = string_check.and(number_check);
/// let good_example = Example { string: "hello".into(), number: 42 };
/// assert_eq!(true, predicate_fn.eval(&good_example));
/// let bad_example = Example { string: "goodbye".into(), number: 0 };
/// assert_eq!(false, predicate_fn.eval(&bad_example));
/// ```
pub fn function<F, T>(function: F) -> FnPredicate<F, T>
where
    F: Fn(&T) -> bool,
    T: ?Sized,
{
    FnPredicate {
        function,
        name: "fn",
        _phantom: PhantomData,
    }
}

#[test]
fn str_function() {
    let f = function(|x: &str| x == "hello");
    assert!(f.eval(&"hello"));
    assert!(!f.eval(&"goodbye"));
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// 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.

/*!
GPIO interface.

GPIOConf is a MCU-specific struct, that requires a `PinConf` for a pin
and a direction.
*/

#[cfg(mcu_lpc17xx)] pub use hal::lpc17xx::gpio::GPIOConf;
#[cfg(mcu_stm32f4)] pub use hal::stm32f4::gpio::GPIOConf;

/// GPIO direction.
pub enum Direction {
  In,
  Out,
}

#[deriving(Eq)]
pub enum Level {
  Low,
  High,
}
<commit_msg>Change deriving target of gpio.rs<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// 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.

/*!
GPIO interface.

GPIOConf is a MCU-specific struct, that requires a `PinConf` for a pin
and a direction.
*/

#[cfg(mcu_lpc17xx)] pub use hal::lpc17xx::gpio::GPIOConf;
#[cfg(mcu_stm32f4)] pub use hal::stm32f4::gpio::GPIOConf;

/// GPIO direction.
pub enum Direction {
  In,
  Out,
}

#[deriving(PartialEq)]
pub enum Level {
  Low,
  High,
}
<|endoftext|>


<commit_before>use libc;

pub const TIOCGWINSZ: libc::c_int = 0x5413;
pub const TIOCSWINSZ: libc::c_int = 0x5414;

#[repr(C)]
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub struct Winsize {
    pub ws_row: libc::c_ushort,    /* rows, in characters */
    pub ws_col: libc::c_ushort,    /* columns, in characters */
    pub ws_xpixel: libc::c_ushort, /* horizontal size, pixels */
    pub ws_ypixel: libc::c_ushort  /* vertical size, pixels */
}
<commit_msg>Fix failing build on macos<commit_after>use libc;

#[cfg(target_os="macos")]
pub const TIOCGWINSZ: libc::c_ulonglong = 0x5413;
#[cfg(target_os="macos")]
pub const TIOCSWINSZ: libc::c_ulonglong = 0x5414;

#[cfg(target_os="linux")]
pub const TIOCGWINSZ: libc::c_int = 0x5413;
#[cfg(target_os="linux")]
pub const TIOCSWINSZ: libc::c_int = 0x5414;

#[repr(C)]
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub struct Winsize {
    pub ws_row: libc::c_ushort,    /* rows, in characters */
    pub ws_col: libc::c_ushort,    /* columns, in characters */
    pub ws_xpixel: libc::c_ushort, /* horizontal size, pixels */
    pub ws_ypixel: libc::c_ushort  /* vertical size, pixels */
}
<|endoftext|>


<commit_before>extern crate kafka;
extern crate getopts;

use std::{env, fmt, process};
use std::fs::File;
use std::io::{self, stdin, stderr, Write, BufRead, BufReader};

use kafka::client::{KafkaClient, Compression};
use kafka::producer::{Producer, Record};

// how many brokers do we require to acknowledge the send messages
const REQUIRED_ACKS: i16 = 1;
// how long do we allow wainting for the acknowledgement
const ACK_TIMEOUT: i32 = 100;

/// This is a very simple command line application sending every
/// non-empty line of standard input to a specified kafka topic; one
/// by one (not the most efficient way, of course).
///
/// Alternatively, messages can be read from an input file and sent do
/// kafka in batches (the typical use-case).
fn main() {
    let cfg = match Config::from_cmdline() {
        Ok(cfg) => cfg,
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    };
    if let Err(e) = produce(&cfg) {
        println!("{}", e);
        process::exit(1);
    }
}

fn produce(cfg: &Config) -> Result<(), Error> {
    let mut client = KafkaClient::new(cfg.brokers.clone());
    client.set_compression(cfg.compression);
    try!(client.load_metadata_all());

    // ~ verify that the remote brokers do know about the target topic
    if !client.topics().contains(&cfg.topic) {
        return Err(Error::Literal(format!("No such topic at {:?}: {}", cfg.brokers, cfg.topic)));
    }
    match cfg.input_file {
        None => {
            let stdin = stdin();
            let mut stdin = stdin.lock();
            produce_impl(&mut stdin, client, &cfg)
        }
        Some(ref file) => {
            let mut r = BufReader::new(try!(File::open(file)));
            produce_impl(&mut r, client, &cfg)
        }
    }
}

fn produce_impl(src: &mut BufRead, client: KafkaClient, cfg: &Config) -> Result<(), Error> {
    let mut producer = try!(Producer::from_client(client)
                            .with_ack_timeout(ACK_TIMEOUT)
                            .with_required_acks(REQUIRED_ACKS)
                            .create());
    if cfg.batch_size < 2 {
        produce_impl_nobatch(&mut producer, src, cfg)
    } else {
        produce_impl_inbatches(&mut producer, src, cfg)
    }
}

fn produce_impl_nobatch(producer: &mut Producer, src: &mut BufRead, cfg: &Config) -> Result<(), Error> {
    let mut stderr = stderr();
    let mut rec = Record::from_value(&cfg.topic, String::new());
    loop {
        rec.value.clear();
        if try!(src.read_line(&mut rec.value)) == 0 {
            break; // ~ EOF reached
        }
        if rec.value.trim().is_empty() {
            continue; // ~ skip empty lines
        }
        // ~ directly send to kafka
        let r = try!(producer.send(&rec));
        let _ = write!(stderr, "debug: {:?}\n", r);
    }
    Ok(())
}

// This implementation wants to be efficient.  It buffers N lines from
// the source and sends these in batches to Kafka.  Line buffers
// across batches are re-used for the sake of avoiding allocations.
fn produce_impl_inbatches(producer: &mut Producer, src: &mut BufRead, cfg: &Config)
                          -> Result<(), Error>
{
    assert!(cfg.batch_size > 1);

    // ~ a buffer of prepared records to be send in a batch to Kafka
    // ~ in the loop following, we'll only modify the 'value' of the
    // cached records
    let mut rec_stash: Vec<Record<(), String>> =
        (0 .. cfg.batch_size)
        .map(|_| Record::from_value(&cfg.topic, String::new()))
        .collect();
    // ~ points to the next free slot in `rec_stash`.  if it reaches
    // `rec_stash.len()` we'll send `rec_stash` to kafka
    let mut next_rec = 0;
    loop {
        // ~ send out a batch if it's ready
        if next_rec == rec_stash.len() {
            try!(send_batch(producer, &rec_stash));
            next_rec = 0;
        }
        let mut rec = &mut rec_stash[next_rec];
        if try!(src.read_line(&mut rec.value)) == 0 {
            break; // ~ EOF reached
        }
        if rec.value.trim().is_empty() {
            continue; // ~ skip empty lines
        }
        // ~ ok, we got a line. read the next one in a new buffer
        next_rec += 1;
    }
    // ~ flush pending messages - if any
    if next_rec > 0 {
        try!(send_batch(producer, &rec_stash[..next_rec]));
    }
    Ok(())
}

fn send_batch(producer: &mut Producer, batch: &[Record<(), String>]) -> Result<(), Error> {
    let rs = try!(producer.send_all(batch));
    for r in rs {
        if let Err(e) = r.offset {
            return Err(From::from(e));
        }
    }
    Ok(())
}

// --------------------------------------------------------------------

enum Error {
    Kafka(kafka::error::Error),
    Io(io::Error),
    Literal(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::Kafka(ref e) => write!(f, "kafka-error: {}", e),
            &Error::Io(ref e) => write!(f, "io-error: {}", e),
            &Error::Literal(ref s) => write!(f, "{}", s),
        }
    }
}

impl From<kafka::error::Error> for Error {
    fn from(e: kafka::error::Error) -> Self { Error::Kafka(e) }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self { Error::Io(e) }
}

// --------------------------------------------------------------------

struct Config {
    brokers: Vec<String>,
    topic: String,
    input_file: Option<String>,
    compression: Compression,
    batch_size: usize,
}

impl Config {
    fn from_cmdline() -> Result<Config, Error> {
        let args: Vec<String> = env::args().collect();
        let mut opts = getopts::Options::new();
        opts.optflag("h", "help", "Print this help screen");
        opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
        opts.optopt("", "topic", "Specify target topic", "NAME");
        opts.optopt("", "input", "Specify input file", "FILE");
        opts.optopt("", "compression", "Compress messages [NONE, GZIP, SNAPPY]", "TYPE");
        opts.optopt("", "batch-size", "Send N message in one batch.", "N");

        let m = match opts.parse(&args[1..]) {
            Ok(m) => m,
            Err(e) => return Err(Error::Literal(e.to_string())),
        };
        if m.opt_present("help") {
            let brief = format!("{} [options]", args[0]);
            return Err(Error::Literal(opts.usage(&brief)));
        }
        Ok(Config {
            brokers: m.opt_str("brokers")
                .unwrap_or_else(|| "localhost:9092".to_owned())
                .split(',')
                .map(|s| s.trim().to_owned())
                .collect(),
            topic: m.opt_str("topic")
                .unwrap_or_else(|| "my-topic".to_owned()),
            input_file: m.opt_str("input"),
            compression: {
                let s = m.opt_str("compression")
                    .unwrap_or_else(|| "NONE".to_owned());
                match s.trim() {
                    "none" | "NONE" => Compression::NONE,
                    "gzip" | "GZIP" => Compression::GZIP,
                    "snappy" | "SNAPPY" => Compression::SNAPPY,
                    _ => return Err(Error::Literal(format!("Unknown compression type: {}", s))),
                }
            },
            batch_size: {
                match m.opt_str("batch-size") {
                    None => 1,
                    Some(s) => {
                        match s.parse::<usize>() {
                            Ok(n) => n,
                            Err(_) => return Err(Error::Literal(format!("Not a number: {}", s))),
                        }
                    }
                }
            },
        })
    }
}
<commit_msg>#! console-producer: fix sending lines in batch mode<commit_after>extern crate kafka;
extern crate getopts;

use std::{env, fmt, process};
use std::fs::File;
use std::io::{self, stdin, stderr, Write, BufRead, BufReader};

use kafka::client::{KafkaClient, Compression};
use kafka::producer::{Producer, Record};

// how many brokers do we require to acknowledge the send messages
const REQUIRED_ACKS: i16 = 1;
// how long do we allow wainting for the acknowledgement
const ACK_TIMEOUT: i32 = 100;

/// This is a very simple command line application sending every
/// non-empty line of standard input to a specified kafka topic; one
/// by one (not the most efficient way, of course).
///
/// Alternatively, messages can be read from an input file and sent do
/// kafka in batches (the typical use-case).
fn main() {
    let cfg = match Config::from_cmdline() {
        Ok(cfg) => cfg,
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    };
    if let Err(e) = produce(&cfg) {
        println!("{}", e);
        process::exit(1);
    }
}

fn produce(cfg: &Config) -> Result<(), Error> {
    let mut client = KafkaClient::new(cfg.brokers.clone());
    client.set_compression(cfg.compression);
    try!(client.load_metadata_all());

    // ~ verify that the remote brokers do know about the target topic
    if !client.topics().contains(&cfg.topic) {
        return Err(Error::Literal(format!("No such topic at {:?}: {}", cfg.brokers, cfg.topic)));
    }
    match cfg.input_file {
        None => {
            let stdin = stdin();
            let mut stdin = stdin.lock();
            produce_impl(&mut stdin, client, &cfg)
        }
        Some(ref file) => {
            let mut r = BufReader::new(try!(File::open(file)));
            produce_impl(&mut r, client, &cfg)
        }
    }
}

fn produce_impl(src: &mut BufRead, client: KafkaClient, cfg: &Config) -> Result<(), Error> {
    let mut producer = try!(Producer::from_client(client)
                            .with_ack_timeout(ACK_TIMEOUT)
                            .with_required_acks(REQUIRED_ACKS)
                            .create());
    if cfg.batch_size < 2 {
        produce_impl_nobatch(&mut producer, src, cfg)
    } else {
        produce_impl_inbatches(&mut producer, src, cfg)
    }
}

fn produce_impl_nobatch(producer: &mut Producer, src: &mut BufRead, cfg: &Config) -> Result<(), Error> {
    let mut stderr = stderr();
    let mut rec = Record::from_value(&cfg.topic, String::new());
    loop {
        rec.value.clear();
        if try!(src.read_line(&mut rec.value)) == 0 {
            break; // ~ EOF reached
        }
        if rec.value.trim().is_empty() {
            continue; // ~ skip empty lines
        }
        // ~ directly send to kafka
        let r = try!(producer.send(&rec));
        let _ = write!(stderr, "debug: {:?}\n", r);
    }
    Ok(())
}

// This implementation wants to be efficient.  It buffers N lines from
// the source and sends these in batches to Kafka.  Line buffers
// across batches are re-used for the sake of avoiding allocations.
fn produce_impl_inbatches(producer: &mut Producer, src: &mut BufRead, cfg: &Config)
                          -> Result<(), Error>
{
    assert!(cfg.batch_size > 1);

    // ~ a buffer of prepared records to be send in a batch to Kafka
    // ~ in the loop following, we'll only modify the 'value' of the
    // cached records
    let mut rec_stash: Vec<Record<(), String>> =
        (0 .. cfg.batch_size)
        .map(|_| Record::from_value(&cfg.topic, String::new()))
        .collect();
    // ~ points to the next free slot in `rec_stash`.  if it reaches
    // `rec_stash.len()` we'll send `rec_stash` to kafka
    let mut next_rec = 0;
    loop {
        // ~ send out a batch if it's ready
        if next_rec == rec_stash.len() {
            try!(send_batch(producer, &rec_stash));
            next_rec = 0;
        }
        let mut rec = &mut rec_stash[next_rec];
        rec.value.clear();
        if try!(src.read_line(&mut rec.value)) == 0 {
            break; // ~ EOF reached
        }
        if rec.value.trim().is_empty() {
            continue; // ~ skip empty lines
        }
        // ~ ok, we got a line. read the next one in a new buffer
        next_rec += 1;
    }
    // ~ flush pending messages - if any
    if next_rec > 0 {
        try!(send_batch(producer, &rec_stash[..next_rec]));
    }
    Ok(())
}

fn send_batch(producer: &mut Producer, batch: &[Record<(), String>]) -> Result<(), Error> {
    let rs = try!(producer.send_all(batch));
    for r in rs {
        if let Err(e) = r.offset {
            return Err(From::from(e));
        }
    }
    Ok(())
}

// --------------------------------------------------------------------

enum Error {
    Kafka(kafka::error::Error),
    Io(io::Error),
    Literal(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::Kafka(ref e) => write!(f, "kafka-error: {}", e),
            &Error::Io(ref e) => write!(f, "io-error: {}", e),
            &Error::Literal(ref s) => write!(f, "{}", s),
        }
    }
}

impl From<kafka::error::Error> for Error {
    fn from(e: kafka::error::Error) -> Self { Error::Kafka(e) }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self { Error::Io(e) }
}

// --------------------------------------------------------------------

struct Config {
    brokers: Vec<String>,
    topic: String,
    input_file: Option<String>,
    compression: Compression,
    batch_size: usize,
}

impl Config {
    fn from_cmdline() -> Result<Config, Error> {
        let args: Vec<String> = env::args().collect();
        let mut opts = getopts::Options::new();
        opts.optflag("h", "help", "Print this help screen");
        opts.optopt("", "brokers", "Specify kafka brokers (comma separated)", "HOSTS");
        opts.optopt("", "topic", "Specify target topic", "NAME");
        opts.optopt("", "input", "Specify input file", "FILE");
        opts.optopt("", "compression", "Compress messages [NONE, GZIP, SNAPPY]", "TYPE");
        opts.optopt("", "batch-size", "Send N message in one batch.", "N");

        let m = match opts.parse(&args[1..]) {
            Ok(m) => m,
            Err(e) => return Err(Error::Literal(e.to_string())),
        };
        if m.opt_present("help") {
            let brief = format!("{} [options]", args[0]);
            return Err(Error::Literal(opts.usage(&brief)));
        }
        Ok(Config {
            brokers: m.opt_str("brokers")
                .unwrap_or_else(|| "localhost:9092".to_owned())
                .split(',')
                .map(|s| s.trim().to_owned())
                .collect(),
            topic: m.opt_str("topic")
                .unwrap_or_else(|| "my-topic".to_owned()),
            input_file: m.opt_str("input"),
            compression: {
                let s = m.opt_str("compression")
                    .unwrap_or_else(|| "NONE".to_owned());
                match s.trim() {
                    "none" | "NONE" => Compression::NONE,
                    "gzip" | "GZIP" => Compression::GZIP,
                    "snappy" | "SNAPPY" => Compression::SNAPPY,
                    _ => return Err(Error::Literal(format!("Unknown compression type: {}", s))),
                }
            },
            batch_size: {
                match m.opt_str("batch-size") {
                    None => 1,
                    Some(s) => {
                        match s.parse::<usize>() {
                            Ok(n) => n,
                            Err(_) => return Err(Error::Literal(format!("Not a number: {}", s))),
                        }
                    }
                }
            },
        })
    }
}
<|endoftext|>


<commit_before>use std::ascii::AsciiExt;
use std::cmp::min;

pub fn compute_matches<'a>(choices: &[&'a str], query: &str) -> Vec<&'a str> {
    struct ScoredChoice<'a> {
        score: f64,
        choice: &'a str,
    };
    let mut ret = Vec::new();
    for choice in choices.iter() {
        let score = score(&choice, query);
        if score > 0_f64 {
            ret.push(ScoredChoice{ score: score, choice: &choice });
        }
    }
    ret.sort_by(|x, y| y.score.partial_cmp(&x.score).unwrap());
    ret.iter().map(|s| s.choice).collect()
}

#[allow(dead_code)]
fn get_slice_indices(length: usize, workers: usize, idx: usize) -> (usize, usize) {
    let lb = (length as f64 / workers as f64) * idx as f64;
    let ub = (length as f64 / workers as f64) * (idx + 1) as f64;
    (lb as usize, ub as usize)
}

#[test]
fn get_slice_indices_test() {
    assert_eq!(get_slice_indices(100, 1, 0), (0, 100));

    assert_eq!(get_slice_indices(100, 2, 1), (50, 100));
    assert_eq!(get_slice_indices(100, 2, 0), (0, 50));

    assert_eq!(get_slice_indices(100, 3, 0), (0, 33));
    assert_eq!(get_slice_indices(100, 3, 1), (33, 66));
    assert_eq!(get_slice_indices(100, 3, 2), (66, 100));

    assert_eq!(get_slice_indices(100, 4, 0), (0, 25));
    assert_eq!(get_slice_indices(100, 4, 1), (25, 50));
    assert_eq!(get_slice_indices(100, 4, 2), (50, 75));
    assert_eq!(get_slice_indices(100, 4, 3), (75, 100));

    assert_eq!(get_slice_indices(12, 12, 11), (11, 12));
    assert_eq!(get_slice_indices(12, 12, 0), (0, 1));

    assert_eq!(get_slice_indices(1, 2, 0), (0, 0));
    assert_eq!(get_slice_indices(1, 2, 1), (0, 1));
}

fn score(choice: &str, query: &str) -> f64 {
    if query.len() == 0 {
        return 1.0;
    }
    if choice.len() == 0 {
        return 0.0;
    }

    let query = query.to_ascii_lowercase();
    let choice = choice.to_ascii_lowercase();

    match compute_match_length(&choice, &query) {
        None => return 0.0,
        Some(match_length) => {
            let score = query.len() as f64 / match_length as f64;
            return score as f64 / choice.len() as f64;
        }
    }
}

fn compute_match_length(string: &str, chars: &str) -> Option<usize> {
    let (first_char, rest) = match chars.slice_shift_char() {
        Some((f, r)) => (f, r),
        None => return None,
    };
    let indices = find_char_in_string(string, first_char);

    let mut current_min = None;
    for i in indices.iter() {
        let last_index = find_end_of_match(string, rest, *i);
        if last_index.is_some() {
            let idx = last_index.unwrap() - *i + 1;
            if current_min.is_some() {
                let cm = min(current_min.unwrap(), idx);
                current_min = Some(cm);
            } else {
                current_min = Some(idx)
            }
        }
    }
    return current_min;
}

fn find_char_in_string(string: &str, char: char) -> Vec<usize> {
    let mut indices = Vec::new();
    for (i, c) in string.chars().enumerate() {
        if char == c {
            indices.push(i);
        }
    }
    return indices;
}

fn find_end_of_match(string: &str, rest_of_query: &str, first_index: usize) -> Option<usize> {
    let mut last_index = first_index + 1;
    for c in rest_of_query.chars() {
        match string[last_index..].find(c) {
            None => return None,
            Some(ref i) => {
                last_index += *i + 1;
            }
        }
    }
    return Some(last_index - 1);
}

#[test]
fn find_end_of_match_test() {
    assert_eq!(find_end_of_match("a", "a", 0), None);
    assert_eq!(find_end_of_match("ba", "a", 1), None);
    assert_eq!(find_end_of_match("aaa", "aa", 0), Some(2));
    assert_eq!(find_end_of_match("aaa", "b", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "this is a match", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "his is a match", 0), Some(19));
    assert_eq!(find_end_of_match("./rust/x86_64-apple-darwin/test/run-pass/process-spawn-with-unicode-params-πЯ音æ∞/child.stage2-x86_64-apple-darwin", "ust", 2), Some(5));
}

#[test]
fn basic_scoring() {
    assert_eq!(score("", "a"), 0.0);
    assert_eq!(score("a", ""), 1.0);
    assert_eq!(score("short", "longer"), 0.0);
    assert_eq!(score("a", "b"), 0.0);
    assert_eq!(score("ab", "ac"), 0.0);

    assert!(score("a", "a") > 0.0);
    assert!(score("ab", "a") > 0.0);
    assert!(score("ba", "a") > 0.0);
    assert!(score("bab", "a") > 0.0);
    assert!(score("babababab", "aaaa") > 0.0);

    assert_eq!(score("a", "a"), 1_f64 / "a".len() as f64);
    assert_eq!(score("ab", "ab"), 0.5);
    assert_eq!(score("a long string", "a long string"), 1_f64 / "a long string".len() as f64);
    assert_eq!(score("spec/search_spec.rb", "sear"), 1_f64 / "spec/search_spec.rb".len() as f64);
}

#[test]
fn character_matching() {
    assert!(score("/! symbols $^", "/!$^") > 0.0);

    assert_eq!(score("a", "A"), 1.0);
    assert_eq!(score("A", "a"), 1.0);

    assert_eq!(score("a", "aa"), 0.0);
}

#[test]
fn match_equality() {
    assert!(score("selecta.gemspec", "asp") > score("algorithm4_spec.rb", "asp"));
    assert!(score("README.md", "em") > score("benchmark.rb", "em"));
    assert!(score("search.rb", "sear") > score("spec/search_spec.rb", "sear"));

    assert!(score("fbb", "fbb") > score("foo bar baz", "fbb"));
    assert!(score("foo", "foo") > score("longer foo", "foo"));
    assert!(score("foo", "foo") > score("foo longer", "foo"));
    assert!(score("1/2/3/4", "1/2/3") > score("1/9/2/3/4", "1/2/3"));

    assert!(score("long 12 long", "12") > score("1 long 2", "12"));

    assert_eq!(score("121padding2", "12"), 1.0 / "121padding2".len() as f64);
    assert_eq!(score("1padding212", "12"), 1.0 / "1padding212".len() as f64);
}
<commit_msg>Add regression test for Unicode issue<commit_after>use std::ascii::AsciiExt;
use std::cmp::min;

pub fn compute_matches<'a>(choices: &[&'a str], query: &str) -> Vec<&'a str> {
    struct ScoredChoice<'a> {
        score: f64,
        choice: &'a str,
    };
    let mut ret = Vec::new();
    for choice in choices.iter() {
        let score = score(&choice, query);
        if score > 0_f64 {
            ret.push(ScoredChoice{ score: score, choice: &choice });
        }
    }
    ret.sort_by(|x, y| y.score.partial_cmp(&x.score).unwrap());
    ret.iter().map(|s| s.choice).collect()
}

#[allow(dead_code)]
fn get_slice_indices(length: usize, workers: usize, idx: usize) -> (usize, usize) {
    let lb = (length as f64 / workers as f64) * idx as f64;
    let ub = (length as f64 / workers as f64) * (idx + 1) as f64;
    (lb as usize, ub as usize)
}

#[test]
fn get_slice_indices_test() {
    assert_eq!(get_slice_indices(100, 1, 0), (0, 100));

    assert_eq!(get_slice_indices(100, 2, 1), (50, 100));
    assert_eq!(get_slice_indices(100, 2, 0), (0, 50));

    assert_eq!(get_slice_indices(100, 3, 0), (0, 33));
    assert_eq!(get_slice_indices(100, 3, 1), (33, 66));
    assert_eq!(get_slice_indices(100, 3, 2), (66, 100));

    assert_eq!(get_slice_indices(100, 4, 0), (0, 25));
    assert_eq!(get_slice_indices(100, 4, 1), (25, 50));
    assert_eq!(get_slice_indices(100, 4, 2), (50, 75));
    assert_eq!(get_slice_indices(100, 4, 3), (75, 100));

    assert_eq!(get_slice_indices(12, 12, 11), (11, 12));
    assert_eq!(get_slice_indices(12, 12, 0), (0, 1));

    assert_eq!(get_slice_indices(1, 2, 0), (0, 0));
    assert_eq!(get_slice_indices(1, 2, 1), (0, 1));
}

fn score(choice: &str, query: &str) -> f64 {
    if query.len() == 0 {
        return 1.0;
    }
    if choice.len() == 0 {
        return 0.0;
    }

    let query = query.to_ascii_lowercase();
    let choice = choice.to_ascii_lowercase();

    match compute_match_length(&choice, &query) {
        None => return 0.0,
        Some(match_length) => {
            let score = query.len() as f64 / match_length as f64;
            return score as f64 / choice.len() as f64;
        }
    }
}

fn compute_match_length(string: &str, chars: &str) -> Option<usize> {
    let (first_char, rest) = match chars.slice_shift_char() {
        Some((f, r)) => (f, r),
        None => return None,
    };
    let indices = find_char_in_string(string, first_char);

    let mut current_min = None;
    for i in indices.iter() {
        let last_index = find_end_of_match(string, rest, *i);
        if last_index.is_some() {
            let idx = last_index.unwrap() - *i + 1;
            if current_min.is_some() {
                let cm = min(current_min.unwrap(), idx);
                current_min = Some(cm);
            } else {
                current_min = Some(idx)
            }
        }
    }
    return current_min;
}

fn find_char_in_string(string: &str, char: char) -> Vec<usize> {
    let mut indices = Vec::new();
    for (i, c) in string.chars().enumerate() {
        if char == c {
            indices.push(i);
        }
    }
    return indices;
}

fn find_end_of_match(string: &str, rest_of_query: &str, first_index: usize) -> Option<usize> {
    let mut last_index = first_index + 1;
    for c in rest_of_query.chars() {
        match string[last_index..].find(c) {
            None => return None,
            Some(ref i) => {
                last_index += *i + 1;
            }
        }
    }
    return Some(last_index - 1);
}

#[test]
fn find_end_of_match_test() {
    assert_eq!(find_end_of_match("a", "a", 0), None);
    assert_eq!(find_end_of_match("ba", "a", 1), None);
    assert_eq!(find_end_of_match("aaa", "aa", 0), Some(2));
    assert_eq!(find_end_of_match("aaa", "b", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "this is a match", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "his is a match", 0), Some(19));
    assert_eq!(find_end_of_match("./rust/x86_64-apple-darwin/test/run-pass/process-spawn-with-unicode-params-πЯ音æ∞/child.stage2-x86_64-apple-darwin", "ust", 2), Some(5));
}

#[test]
fn unicode_boundary_handling_test() {
    score("./rust/x86_64-apple-darwin/test/run-pass/process-spawn-with-unicode-params-πЯ音æ∞/child.stage2-x86_64-apple-darwin", "he");
}

#[test]
fn basic_scoring() {
    assert_eq!(score("", "a"), 0.0);
    assert_eq!(score("a", ""), 1.0);
    assert_eq!(score("short", "longer"), 0.0);
    assert_eq!(score("a", "b"), 0.0);
    assert_eq!(score("ab", "ac"), 0.0);

    assert!(score("a", "a") > 0.0);
    assert!(score("ab", "a") > 0.0);
    assert!(score("ba", "a") > 0.0);
    assert!(score("bab", "a") > 0.0);
    assert!(score("babababab", "aaaa") > 0.0);

    assert_eq!(score("a", "a"), 1_f64 / "a".len() as f64);
    assert_eq!(score("ab", "ab"), 0.5);
    assert_eq!(score("a long string", "a long string"), 1_f64 / "a long string".len() as f64);
    assert_eq!(score("spec/search_spec.rb", "sear"), 1_f64 / "spec/search_spec.rb".len() as f64);
}

#[test]
fn character_matching() {
    assert!(score("/! symbols $^", "/!$^") > 0.0);

    assert_eq!(score("a", "A"), 1.0);
    assert_eq!(score("A", "a"), 1.0);

    assert_eq!(score("a", "aa"), 0.0);
}

#[test]
fn match_equality() {
    assert!(score("selecta.gemspec", "asp") > score("algorithm4_spec.rb", "asp"));
    assert!(score("README.md", "em") > score("benchmark.rb", "em"));
    assert!(score("search.rb", "sear") > score("spec/search_spec.rb", "sear"));

    assert!(score("fbb", "fbb") > score("foo bar baz", "fbb"));
    assert!(score("foo", "foo") > score("longer foo", "foo"));
    assert!(score("foo", "foo") > score("foo longer", "foo"));
    assert!(score("1/2/3/4", "1/2/3") > score("1/9/2/3/4", "1/2/3"));

    assert!(score("long 12 long", "12") > score("1 long 2", "12"));

    assert_eq!(score("121padding2", "12"), 1.0 / "121padding2".len() as f64);
    assert_eq!(score("1padding212", "12"), 1.0 / "1padding212".len() as f64);
}
<|endoftext|>


<commit_before>extern crate ispc;

fn main() {
    ispc::compile_library("mandelbrot", &["src/mandelbrot.ispc"]);
}

<commit_msg>Testing instrumenting in mandel<commit_after>extern crate ispc;

fn main() {
    let mut cfg = ispc::Config::new();
    cfg.file("src/mandelbrot.ispc");
    cfg.instrument();
    cfg.compile("mandelbrot");
    //ispc::compile_library("mandelbrot", &["src/mandelbrot.ispc"]);
}

<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::collections::HashMap;
use std::path::*;
use std::string::String;

use case::*;

pub fn split_namespace_name(name: &str) -> (Option<&str>, &str) {
    let mut parts = name.split('.');
    let name = parts.next_back().unwrap();
    let ns = parts.next_back();
    assert!(ns.is_none() || parts.next().is_none());
    (ns, name)
}

/* unused :(
pub fn strip_prefix<'a>(prefix: &str, name: &'a str) -> &'a str {
    let mut skip = 0;
    let mut prefix_upper = prefix.to_ascii_uppercase();
    prefix_upper.push('_');
    if name.starts_with(&prefix_upper) {
        skip = prefix_upper.len();
    }
    else if name.starts_with(prefix) {
        skip = prefix.len();
    }
    &name[skip..]
}

pub fn strip_suffix<'a>(name: &'a str, suffix: &str) -> Option<&'a str> {
    if name.ends_with(suffix) {
        Some(&name[..name.len() - suffix.len()])
    }
    else {
        None
    }
}
*/

pub fn file_name(full_name: &str) -> String {
    let (_, class_name) = split_namespace_name(full_name);
    let mut name = PathBuf::from(module_name(class_name));
    let added = name.set_extension("rs");
    assert!(added);
    name.to_str().unwrap().into()
}

pub fn file_name_sys(name: &str) -> String {
    let mut path = PathBuf::from("src").join(name);
    let added = path.set_extension("rs");
    assert!(added);
    path.to_str().unwrap().into()
}

pub fn crate_name(name: &str) -> String {
    let name = name.to_snake();
    if name.starts_with("g_") {
        format!("g{}", &name[2..])
    }
    else {
        name
    }
}

pub fn module_name(name: &str) -> String {
    mangle_keywords(name.to_snake()).into_owned()
}

// If the mangling happened, guaranteed to return Owned.
pub fn mangle_keywords<'a, S: Into<Cow<'a, str>>>(name: S) -> Cow<'a, str> {
    let name = name.into();
    if let Some(s) = KEYWORDS.get(&*name) {
        s.clone().into()
    }
    else {
        name
    }
}

lazy_static! {
    static ref KEYWORDS: HashMap<&'static str, String> = {
        let mut map = HashMap::new();
        [
            "abstract", "alignof", "as", "become", "box", "break", "const",
            "continue", "crate", "do", "else", "enum", "extern", "false", "final",
            "fn", "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod",
            "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
            "ref", "return", "Self", "self", "sizeof", "static", "struct", "super",
            "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
            "where", "while", "yield",
        ].iter().map(|k| map.insert(*k, format!("{}_", k))).count();
        map
    };
}

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

    #[test]
    fn split_no_namespace() {
        let (ns, name) = split_namespace_name("GObject");
        assert_eq!(ns, None);
        assert_eq!(name, "GObject");
    }

    #[test]
    fn split_full_name() {
        let (ns, name) = split_namespace_name("Gtk.StatusIcon");
        assert_eq!(ns, Some("Gtk"));
        assert_eq!(name, "StatusIcon");
    }

    /*
    #[test]
    fn strip_prefix_g() {
        assert_eq!(strip_prefix("G", "GBusType"), "BusType");
        assert_eq!(strip_prefix("G", "G_BUS_TYPE_NONE"), "BUS_TYPE_NONE");
    }

    #[test]
    fn strip_prefix_gtk() {
        assert_eq!(strip_prefix("Gtk", "GtkAlign"), "Align");
        assert_eq!(strip_prefix("Gtk", "GTK_ALIGN_FILL"), "ALIGN_FILL");
    }
    */

    #[test]
    fn crate_name_works() {
        assert_eq!(crate_name("GdkPixbuf"), "gdk_pixbuf");
        assert_eq!(crate_name("GLib"), "glib");
        assert_eq!(crate_name("Gtk"), "gtk");
    }

    #[test]
    fn file_name_works() {
        assert_eq!(file_name("Gtk.StatusIcon"), "status_icon.rs");
    }

    #[test]
    fn file_name_sys_works() {
        let expected: String = PathBuf::from("src").join("funcs.rs")
            .to_str().unwrap().into();
        assert_eq!(file_name_sys("funcs"), expected);
    }
}
<commit_msg>Remove `file_name`, which has become redundant<commit_after>use std::borrow::Cow;
use std::collections::HashMap;
use std::path::*;
use std::string::String;

use case::*;

pub fn split_namespace_name(name: &str) -> (Option<&str>, &str) {
    let mut parts = name.split('.');
    let name = parts.next_back().unwrap();
    let ns = parts.next_back();
    assert!(ns.is_none() || parts.next().is_none());
    (ns, name)
}

/* unused :(
pub fn strip_prefix<'a>(prefix: &str, name: &'a str) -> &'a str {
    let mut skip = 0;
    let mut prefix_upper = prefix.to_ascii_uppercase();
    prefix_upper.push('_');
    if name.starts_with(&prefix_upper) {
        skip = prefix_upper.len();
    }
    else if name.starts_with(prefix) {
        skip = prefix.len();
    }
    &name[skip..]
}

pub fn strip_suffix<'a>(name: &'a str, suffix: &str) -> Option<&'a str> {
    if name.ends_with(suffix) {
        Some(&name[..name.len() - suffix.len()])
    }
    else {
        None
    }
}
*/

pub fn file_name_sys(name: &str) -> String {
    let mut path = PathBuf::from("src").join(name);
    let added = path.set_extension("rs");
    assert!(added);
    path.to_str().unwrap().into()
}

pub fn crate_name(name: &str) -> String {
    let name = name.to_snake();
    if name.starts_with("g_") {
        format!("g{}", &name[2..])
    }
    else {
        name
    }
}

pub fn module_name(name: &str) -> String {
    mangle_keywords(name.to_snake()).into_owned()
}

// If the mangling happened, guaranteed to return Owned.
pub fn mangle_keywords<'a, S: Into<Cow<'a, str>>>(name: S) -> Cow<'a, str> {
    let name = name.into();
    if let Some(s) = KEYWORDS.get(&*name) {
        s.clone().into()
    }
    else {
        name
    }
}

lazy_static! {
    static ref KEYWORDS: HashMap<&'static str, String> = {
        let mut map = HashMap::new();
        [
            "abstract", "alignof", "as", "become", "box", "break", "const",
            "continue", "crate", "do", "else", "enum", "extern", "false", "final",
            "fn", "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod",
            "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
            "ref", "return", "Self", "self", "sizeof", "static", "struct", "super",
            "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
            "where", "while", "yield",
        ].iter().map(|k| map.insert(*k, format!("{}_", k))).count();
        map
    };
}

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

    #[test]
    fn split_no_namespace() {
        let (ns, name) = split_namespace_name("GObject");
        assert_eq!(ns, None);
        assert_eq!(name, "GObject");
    }

    #[test]
    fn split_full_name() {
        let (ns, name) = split_namespace_name("Gtk.StatusIcon");
        assert_eq!(ns, Some("Gtk"));
        assert_eq!(name, "StatusIcon");
    }

    /*
    #[test]
    fn strip_prefix_g() {
        assert_eq!(strip_prefix("G", "GBusType"), "BusType");
        assert_eq!(strip_prefix("G", "G_BUS_TYPE_NONE"), "BUS_TYPE_NONE");
    }

    #[test]
    fn strip_prefix_gtk() {
        assert_eq!(strip_prefix("Gtk", "GtkAlign"), "Align");
        assert_eq!(strip_prefix("Gtk", "GTK_ALIGN_FILL"), "ALIGN_FILL");
    }
    */

    #[test]
    fn crate_name_works() {
        assert_eq!(crate_name("GdkPixbuf"), "gdk_pixbuf");
        assert_eq!(crate_name("GLib"), "glib");
        assert_eq!(crate_name("Gtk"), "gtk");
    }

    #[test]
    fn file_name_sys_works() {
        let expected: String = PathBuf::from("src").join("funcs.rs")
            .to_str().unwrap().into();
        assert_eq!(file_name_sys("funcs"), expected);
    }
}
<|endoftext|>


<commit_before>extern crate hypernsga;
extern crate nsga2;
extern crate rand;
extern crate criterion_stats;

#[macro_use]
extern crate glium;
#[macro_use]
extern crate imgui;
extern crate time;

use hypernsga::graph;
use hypernsga::domain_graph::{Neuron, NeuronNetworkBuilder, GraphSimilarity};
use hypernsga::cppn::{CppnDriver, GeometricActivationFunction};
use hypernsga::mating::MatingMethodWeights;
use hypernsga::prob::Prob;
use hypernsga::weight::{WeightPerturbanceMethod, WeightRange};
use hypernsga::substrate::{Substrate, Position3d, Position2d, NodeConnectivity};
use hypernsga::distribute::DistributeInterval;
use nsga2::driver::{Driver, DriverConfig};
use nsga2::selection::{SelectNSGP};
use nsga2::population::{UnratedPopulation, RankedPopulation};
use std::marker::PhantomData;
use std::f64::INFINITY;
use criterion_stats::univariate::Sample;
use std::env;

use imgui::*;
use self::support::Support;

mod support;

const CLEAR_COLOR: (f32, f32, f32, f32) = (1.0, 1.0, 1.0, 1.0);

fn gui<'a>(ui: &Ui<'a>, iteration: usize, best_fitness: f64) {
    ui.window(im_str!("Evolutionary Graph Optimization"))
        .size((300.0, 100.0), ImGuiSetCond_FirstUseEver)
        .build(|| {
            ui.text(im_str!("Iteration: {}", iteration));
            ui.text(im_str!("Best Fitness: {:?}", best_fitness));
            ui.separator();
            let mouse_pos = ui.imgui().mouse_pos();
            ui.text(im_str!("Mouse Position: ({:.1},{:.1})", mouse_pos.0, mouse_pos.1));
        })
}

fn main() {
    let mut support = Support::init();

    let mut rng = rand::thread_rng();
    let graph_file = env::args().nth(1).unwrap();
    println!("graph: {}", graph_file);

    let target_opt = GraphSimilarity {
        target_graph: graph::load_graph_normalized(&graph_file),
        edge_score: true,
        iters: 50,
        eps: 0.01,
    };

    // XXX
    let mut substrate: Substrate<Position2d, Neuron> = Substrate::new();
    let node_count = target_opt.target_graph_node_count();

    println!("{:?}", node_count);

    let min = -3.0;
    let max = 3.0;

    // Input layer
    {
        for x in DistributeInterval::new(node_count.inputs, min, max) {
            substrate.add_node(Position2d::new(x, 0.75), Neuron::Input, NodeConnectivity::Out);
        }
    }

    // Hidden
    {
        for x in DistributeInterval::new(node_count.hidden, min, max) {
            substrate.add_node(Position2d::new(x, 0.5), Neuron::Hidden, NodeConnectivity::InOut);
        }
    }

    // Outputs
    {
        for x in DistributeInterval::new(node_count.outputs, min, max) {
            substrate.add_node(Position2d::new(x, 0.25), Neuron::Output, NodeConnectivity::In);
        }
    }

    let driver_config = DriverConfig {
        mu: 100,
        lambda: 200,
        k: 2,
        ngen: 10000,
        num_objectives: 3,
        parallel_weight: INFINITY,
    };

    let selection = SelectNSGP {
        objective_eps: 0.01,
    };

    let driver: CppnDriver<_,_,_,Neuron,NeuronNetworkBuilder<Position2d>> = CppnDriver {
        mating_method_weights: MatingMethodWeights {
            mutate_add_node: 5,
            mutate_drop_node: 0,
            mutate_modify_node: 0,
            mutate_connect: 20,
            mutate_disconnect: 5,
            mutate_weights: 100,
            crossover_weights: 0,
        },
        activation_functions: vec![
            //GeometricActivationFunction::Linear,
            GeometricActivationFunction::BipolarGaussian,
            GeometricActivationFunction::BipolarSigmoid,
            GeometricActivationFunction::Sine,
        ],
        mutate_element_prob: Prob::new(0.05),
        weight_perturbance: WeightPerturbanceMethod::JiggleGaussian{sigma: 0.1},
        link_weight_range: WeightRange::bipolar(3.0),
        link_weight_creation_sigma: 0.1,

        mutate_add_node_random_link_weight: false,
        mutate_drop_node_tournament_k: 10,
        mutate_modify_node_tournament_k: 2,
        mate_retries: 100,

        link_expression_threshold: 0.01,

        substrate_configuration: substrate.to_configuration(),
        domain_fitness: &target_opt,
        _netbuilder: PhantomData,

        start_connected: false,
        start_link_weight_range: WeightRange::bipolar(0.1),
        start_symmetry: vec![], //Some(3.0), None, Some(3.0)],
        start_initial_nodes: 0,
    };

    let mut generation: usize = 0;

    // create `generation 0`
    let mut parents = {
        let initial = driver.initial_population(&mut rng, driver_config.mu);
        driver.merge_and_select(driver.empty_parent_population(), initial, &mut rng, &driver_config, &selection)
    };

    loop {
        {
            let best_individual = parents.individuals().iter().max_by_key(|ind| (ind.fitness().domain_fitness * 1_000_000.0) as usize);
            let best_fitness = best_individual.map(|ind| ind.fitness().domain_fitness).unwrap_or(0.0);

            support.render(CLEAR_COLOR, |ui| {
                gui(ui, generation, best_fitness);
            });
            let active = support.update_events();
            if !active { break }
        }

        // create next generation
        generation += 1;
        let offspring = driver.reproduce(&parents, &mut rng, &driver_config);
        parents = driver.merge_and_select(parents, offspring, &mut rng, &driver_config, &selection);
    }
}
<commit_msg>Start stop<commit_after>extern crate hypernsga;
extern crate nsga2;
extern crate rand;
extern crate criterion_stats;

#[macro_use]
extern crate glium;
#[macro_use]
extern crate imgui;
extern crate time;

use hypernsga::graph;
use hypernsga::domain_graph::{Neuron, NeuronNetworkBuilder, GraphSimilarity};
use hypernsga::cppn::{CppnDriver, GeometricActivationFunction};
use hypernsga::mating::MatingMethodWeights;
use hypernsga::prob::Prob;
use hypernsga::weight::{WeightPerturbanceMethod, WeightRange};
use hypernsga::substrate::{Substrate, Position3d, Position2d, NodeConnectivity};
use hypernsga::distribute::DistributeInterval;
use nsga2::driver::{Driver, DriverConfig};
use nsga2::selection::{SelectNSGP};
use nsga2::population::{UnratedPopulation, RankedPopulation};
use std::marker::PhantomData;
use std::f64::INFINITY;
use criterion_stats::univariate::Sample;
use std::env;

use imgui::*;
use self::support::Support;

mod support;

const CLEAR_COLOR: (f32, f32, f32, f32) = (1.0, 1.0, 1.0, 1.0);

fn gui<'a>(ui: &Ui<'a>, iteration: usize, best_fitness: f64, running: &mut bool) {
    ui.window(im_str!("Evolutionary Graph Optimization"))
        .size((300.0, 100.0), ImGuiSetCond_FirstUseEver)
        .build(|| {
            ui.text(im_str!("Iteration: {}", iteration));
            ui.text(im_str!("Best Fitness: {:?}", best_fitness));
            ui.separator();
            if *running {
               if ui.small_button(im_str!("STOP")) {
                   *running = false;
               }
            } else {
               if ui.small_button(im_str!("START")) {
                   *running = true;
               }
            }
            ui.separator();
            let mouse_pos = ui.imgui().mouse_pos();
            ui.text(im_str!("Mouse Position: ({:.1},{:.1})", mouse_pos.0, mouse_pos.1));
        })
}

fn main() {
    let mut support = Support::init();

    let mut rng = rand::thread_rng();
    let graph_file = env::args().nth(1).unwrap();
    println!("graph: {}", graph_file);

    let target_opt = GraphSimilarity {
        target_graph: graph::load_graph_normalized(&graph_file),
        edge_score: true,
        iters: 50,
        eps: 0.01,
    };

    // XXX
    let mut substrate: Substrate<Position2d, Neuron> = Substrate::new();
    let node_count = target_opt.target_graph_node_count();

    println!("{:?}", node_count);

    let min = -3.0;
    let max = 3.0;

    // Input layer
    {
        for x in DistributeInterval::new(node_count.inputs, min, max) {
            substrate.add_node(Position2d::new(x, 0.75), Neuron::Input, NodeConnectivity::Out);
        }
    }

    // Hidden
    {
        for x in DistributeInterval::new(node_count.hidden, min, max) {
            substrate.add_node(Position2d::new(x, 0.5), Neuron::Hidden, NodeConnectivity::InOut);
        }
    }

    // Outputs
    {
        for x in DistributeInterval::new(node_count.outputs, min, max) {
            substrate.add_node(Position2d::new(x, 0.25), Neuron::Output, NodeConnectivity::In);
        }
    }

    let driver_config = DriverConfig {
        mu: 100,
        lambda: 200,
        k: 2,
        ngen: 10000,
        num_objectives: 3,
        parallel_weight: INFINITY,
    };

    let selection = SelectNSGP {
        objective_eps: 0.01,
    };

    let driver: CppnDriver<_,_,_,Neuron,NeuronNetworkBuilder<Position2d>> = CppnDriver {
        mating_method_weights: MatingMethodWeights {
            mutate_add_node: 5,
            mutate_drop_node: 0,
            mutate_modify_node: 0,
            mutate_connect: 20,
            mutate_disconnect: 5,
            mutate_weights: 100,
            crossover_weights: 0,
        },
        activation_functions: vec![
            //GeometricActivationFunction::Linear,
            GeometricActivationFunction::BipolarGaussian,
            GeometricActivationFunction::BipolarSigmoid,
            GeometricActivationFunction::Sine,
        ],
        mutate_element_prob: Prob::new(0.05),
        weight_perturbance: WeightPerturbanceMethod::JiggleGaussian{sigma: 0.1},
        link_weight_range: WeightRange::bipolar(3.0),
        link_weight_creation_sigma: 0.1,

        mutate_add_node_random_link_weight: false,
        mutate_drop_node_tournament_k: 10,
        mutate_modify_node_tournament_k: 2,
        mate_retries: 100,

        link_expression_threshold: 0.01,

        substrate_configuration: substrate.to_configuration(),
        domain_fitness: &target_opt,
        _netbuilder: PhantomData,

        start_connected: false,
        start_link_weight_range: WeightRange::bipolar(0.1),
        start_symmetry: vec![], //Some(3.0), None, Some(3.0)],
        start_initial_nodes: 0,
    };

    let mut generation: usize = 0;

    // create `generation 0`
    let mut parents = {
        let initial = driver.initial_population(&mut rng, driver_config.mu);
        driver.merge_and_select(driver.empty_parent_population(), initial, &mut rng, &driver_config, &selection)
    };

    let mut best_fitness = {
            let best_individual = parents.individuals().iter().max_by_key(|ind| (ind.fitness().domain_fitness * 1_000_000.0) as usize);
            best_individual.map(|ind| ind.fitness().domain_fitness).unwrap_or(0.0)
    };

    let mut running = true;

    loop {
        {
            support.render(CLEAR_COLOR, |ui| {
                gui(ui, generation, best_fitness, &mut running);
            });
            let active = support.update_events();
            if !active { break }
        }

        if running {
            // create next generation
            generation += 1;
            let offspring = driver.reproduce(&parents, &mut rng, &driver_config);
            parents = driver.merge_and_select(parents, offspring, &mut rng, &driver_config, &selection);

            let best_individual = parents.individuals().iter().max_by_key(|ind| (ind.fitness().domain_fitness * 1_000_000.0) as usize);
            best_fitness = best_individual.map(|ind| ind.fitness().domain_fitness).unwrap_or(0.0);
        }
    }
}
<|endoftext|>


<commit_before>use petgraph::graphmap::DiGraphMap;

pub struct GraphBuilder;
pub struct Edge;

impl GraphBuilder {
    pub fn new() -> Self {
        Self {}
    }

    pub fn build(self) -> DiGraphMap<Mod, Edge> {
        DiGraphMap::new()
    }

    // TODO: add_crate_root();
    // TODO: add_mod();
    // TODO: add_dep();
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Mod;

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

    #[test]
    fn new_builder_produces_an_empty_directed_graph() {
        let builder = GraphBuilder::new();
        let graph: DiGraphMap<Mod, Edge> = builder.build();
        assert_eq!(0, graph.node_count());
        assert_eq!(0, graph.edge_count());
    }
}
<commit_msg>Change GraphBuilder.build to return a Result<commit_after>use petgraph::graphmap::DiGraphMap;

pub struct Edge;

pub struct GraphBuilder;

impl GraphBuilder {
    pub fn new() -> Self {
        Self {}
    }

    pub fn build(self) -> Result<DiGraphMap<Mod, Edge>, GraphError> {
        Ok(DiGraphMap::new())
    }

    // TODO: add_crate_root();
    // TODO: add_mod();
    // TODO: add_dep();
}

#[derive(Debug)]
pub enum GraphError {}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Mod;

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

    #[test]
    fn new_builder_produces_an_empty_directed_graph() {
        let builder = GraphBuilder::new();
        let graph: DiGraphMap<Mod, Edge> = builder.build().unwrap();
        assert_eq!(0, graph.node_count());
        assert_eq!(0, graph.edge_count());
    }
}
<|endoftext|>


<commit_before>use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use std::iter;
use syn::{Data, DataEnum, DeriveInput, Field, Fields, Ident, Index};
use utils::{add_extra_type_param_bound_op_output, get_import_root, named_to_vec, unnamed_to_vec};

pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
    let import_root = get_import_root();
    let trait_ident = Ident::new(trait_name, Span::call_site());
    let method_name = trait_name.to_lowercase();
    let method_ident = &Ident::new(&method_name, Span::call_site());
    let input_type = &input.ident;

    let generics = add_extra_type_param_bound_op_output(&input.generics, &trait_ident);
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

    let (output_type, block) = match input.data {
        Data::Struct(ref data_struct) => match data_struct.fields {
            Fields::Unnamed(ref fields) => (
                quote!(#input_type#ty_generics),
                tuple_content(input_type, &unnamed_to_vec(fields), method_ident),
            ),
            Fields::Named(ref fields) => (
                quote!(#input_type#ty_generics),
                struct_content(input_type, &named_to_vec(fields), method_ident),
            ),
            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
        },
        Data::Enum(ref data_enum) => enum_output_type_and_content(input, data_enum, method_ident),

        _ => panic!(format!(
            "Only structs and enums can use derive({})",
            trait_name
        )),
    };

    quote!(
        impl#impl_generics #import_root::ops::#trait_ident for #input_type#ty_generics #where_clause {
            type Output = #output_type;
            fn #method_ident(self) -> #output_type {
                #block
            }
        }
    )
}

fn tuple_content<T: ToTokens>(
    input_type: &T,
    fields: &[&Field],
    method_ident: &Ident,
) -> TokenStream {
    let mut exprs = vec![];

    for i in 0..fields.len() {
        let i = Index::from(i);
        // generates `self.0.add()`
        let expr = quote!(self.#i.#method_ident());
        exprs.push(expr);
    }

    quote!(#input_type(#(#exprs),*))
}

fn struct_content(input_type: &Ident, fields: &[&Field], method_ident: &Ident) -> TokenStream {
    let mut exprs = vec![];

    for field in fields {
        // It's safe to unwrap because struct fields always have an identifier
        let field_id = field.ident.as_ref();
        // generates `x: self.x.not()`
        let expr = quote!(#field_id: self.#field_id.#method_ident());
        exprs.push(expr)
    }

    quote!(#input_type{#(#exprs),*})
}

fn enum_output_type_and_content(
    input: &DeriveInput,
    data_enum: &DataEnum,
    method_ident: &Ident,
) -> (TokenStream, TokenStream) {
    let input_type = &input.ident;
    let (_, ty_generics, _) = input.generics.split_for_impl();
    let mut matches = vec![];
    let mut method_iter = iter::repeat(method_ident);
    // If the enum contains unit types that means it can error.
    let has_unit_type = data_enum.variants.iter().any(|v| v.fields == Fields::Unit);

    for variant in &data_enum.variants {
        let subtype = &variant.ident;
        let subtype = quote!(#input_type::#subtype);

        match variant.fields {
            Fields::Unnamed(ref fields) => {
                // The patern that is outputted should look like this:
                // (Subtype(vars)) => Ok(TypePath(exprs))
                let size = unnamed_to_vec(fields).len();
                let vars: &Vec<_> = &(0..size)
                    .map(|i| Ident::new(&format!("__{}", i), Span::call_site()))
                    .collect();
                let method_iter = method_iter.by_ref();
                let mut body = quote!(#subtype(#(#vars.#method_iter()),*));
                if has_unit_type {
                    body = quote!(::std::result::Result::Ok(#body))
                }
                let matcher = quote! {
                    #subtype(#(#vars),*) => {
                        #body
                    }
                };
                matches.push(matcher);
            }
            Fields::Named(ref fields) => {
                // The patern that is outputted should look like this:
                // (Subtype{a: __l_a, ...} => {
                //     Ok(Subtype{a: __l_a.neg(__r_a), ...})
                // }
                let field_vec = named_to_vec(fields);
                let size = field_vec.len();
                let field_names: &Vec<_> = &field_vec
                    .iter()
                    .map(|f| f.ident.as_ref().unwrap())
                    .collect();
                let vars: &Vec<_> = &(0..size)
                    .map(|i| Ident::new(&format!("__{}", i), Span::call_site()))
                    .collect();
                let method_iter = method_iter.by_ref();
                let mut body = quote!(#subtype{#(#field_names: #vars.#method_iter()),*});
                if has_unit_type {
                    body = quote!(::std::result::Result::Ok(#body))
                }
                let matcher = quote! {
                    #subtype{#(#field_names: #vars),*} => {
                        #body
                    }
                };
                matches.push(matcher);
            }
            Fields::Unit => {
                let message = format!("Cannot {}() unit variants", method_ident.to_string());
                matches.push(quote!(#subtype => ::std::result::Result::Err(#message)));
            }
        }
    }

    let body = quote!(
        match self {
            #(#matches),*
        }
    );

    let output_type = if has_unit_type {
        quote!(::std::result::Result<#input_type#ty_generics, &'static str>)
    } else {
        quote!(#input_type#ty_generics)
    };

    (output_type, body)
}
<commit_msg>Add inline attribute to Neg and Not traits (#71)<commit_after>use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use std::iter;
use syn::{Data, DataEnum, DeriveInput, Field, Fields, Ident, Index};
use utils::{add_extra_type_param_bound_op_output, get_import_root, named_to_vec, unnamed_to_vec};

pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
    let import_root = get_import_root();
    let trait_ident = Ident::new(trait_name, Span::call_site());
    let method_name = trait_name.to_lowercase();
    let method_ident = &Ident::new(&method_name, Span::call_site());
    let input_type = &input.ident;

    let generics = add_extra_type_param_bound_op_output(&input.generics, &trait_ident);
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

    let (output_type, block) = match input.data {
        Data::Struct(ref data_struct) => match data_struct.fields {
            Fields::Unnamed(ref fields) => (
                quote!(#input_type#ty_generics),
                tuple_content(input_type, &unnamed_to_vec(fields), method_ident),
            ),
            Fields::Named(ref fields) => (
                quote!(#input_type#ty_generics),
                struct_content(input_type, &named_to_vec(fields), method_ident),
            ),
            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
        },
        Data::Enum(ref data_enum) => enum_output_type_and_content(input, data_enum, method_ident),

        _ => panic!(format!(
            "Only structs and enums can use derive({})",
            trait_name
        )),
    };

    quote!(
        impl#impl_generics #import_root::ops::#trait_ident for #input_type#ty_generics #where_clause {
            type Output = #output_type;
            #[inline]
            fn #method_ident(self) -> #output_type {
                #block
            }
        }
    )
}

fn tuple_content<T: ToTokens>(
    input_type: &T,
    fields: &[&Field],
    method_ident: &Ident,
) -> TokenStream {
    let mut exprs = vec![];

    for i in 0..fields.len() {
        let i = Index::from(i);
        // generates `self.0.add()`
        let expr = quote!(self.#i.#method_ident());
        exprs.push(expr);
    }

    quote!(#input_type(#(#exprs),*))
}

fn struct_content(input_type: &Ident, fields: &[&Field], method_ident: &Ident) -> TokenStream {
    let mut exprs = vec![];

    for field in fields {
        // It's safe to unwrap because struct fields always have an identifier
        let field_id = field.ident.as_ref();
        // generates `x: self.x.not()`
        let expr = quote!(#field_id: self.#field_id.#method_ident());
        exprs.push(expr)
    }

    quote!(#input_type{#(#exprs),*})
}

fn enum_output_type_and_content(
    input: &DeriveInput,
    data_enum: &DataEnum,
    method_ident: &Ident,
) -> (TokenStream, TokenStream) {
    let input_type = &input.ident;
    let (_, ty_generics, _) = input.generics.split_for_impl();
    let mut matches = vec![];
    let mut method_iter = iter::repeat(method_ident);
    // If the enum contains unit types that means it can error.
    let has_unit_type = data_enum.variants.iter().any(|v| v.fields == Fields::Unit);

    for variant in &data_enum.variants {
        let subtype = &variant.ident;
        let subtype = quote!(#input_type::#subtype);

        match variant.fields {
            Fields::Unnamed(ref fields) => {
                // The patern that is outputted should look like this:
                // (Subtype(vars)) => Ok(TypePath(exprs))
                let size = unnamed_to_vec(fields).len();
                let vars: &Vec<_> = &(0..size)
                    .map(|i| Ident::new(&format!("__{}", i), Span::call_site()))
                    .collect();
                let method_iter = method_iter.by_ref();
                let mut body = quote!(#subtype(#(#vars.#method_iter()),*));
                if has_unit_type {
                    body = quote!(::std::result::Result::Ok(#body))
                }
                let matcher = quote! {
                    #subtype(#(#vars),*) => {
                        #body
                    }
                };
                matches.push(matcher);
            }
            Fields::Named(ref fields) => {
                // The patern that is outputted should look like this:
                // (Subtype{a: __l_a, ...} => {
                //     Ok(Subtype{a: __l_a.neg(__r_a), ...})
                // }
                let field_vec = named_to_vec(fields);
                let size = field_vec.len();
                let field_names: &Vec<_> = &field_vec
                    .iter()
                    .map(|f| f.ident.as_ref().unwrap())
                    .collect();
                let vars: &Vec<_> = &(0..size)
                    .map(|i| Ident::new(&format!("__{}", i), Span::call_site()))
                    .collect();
                let method_iter = method_iter.by_ref();
                let mut body = quote!(#subtype{#(#field_names: #vars.#method_iter()),*});
                if has_unit_type {
                    body = quote!(::std::result::Result::Ok(#body))
                }
                let matcher = quote! {
                    #subtype{#(#field_names: #vars),*} => {
                        #body
                    }
                };
                matches.push(matcher);
            }
            Fields::Unit => {
                let message = format!("Cannot {}() unit variants", method_ident.to_string());
                matches.push(quote!(#subtype => ::std::result::Result::Err(#message)));
            }
        }
    }

    let body = quote!(
        match self {
            #(#matches),*
        }
    );

    let output_type = if has_unit_type {
        quote!(::std::result::Result<#input_type#ty_generics, &'static str>)
    } else {
        quote!(#input_type#ty_generics)
    };

    (output_type, body)
}
<|endoftext|>


<commit_before>#![no_std]

#[macro_use]
extern crate enum_map;

#[test]
fn test_u8() {
    let map = enum_map! { b'a' => b'e', _ => 0 };
    assert_eq!(map[b'a'], b'e');
    assert_eq!(map[b'b'], 0);
}
<commit_msg>No need to use byte characters as arguments in enum map u8 test<commit_after>#![no_std]

#[macro_use]
extern crate enum_map;

#[test]
fn test_u8() {
    let map = enum_map! { b'a' => 4, _ => 0 };
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
}
<|endoftext|>