<commit_before>use domain::message_type::{MessageTypeV2, MessageFamilies, MESSAGE_VERSION_V1, DID};
use domain::a2a::RemoteMessageType;
use domain::protocol_type::{ProtocolType, ProtocolTypes};
use std::collections::HashMap;

#[derive(Deserialize, Serialize, Debug)]
pub enum Payloads {
    PayloadV1(PayloadV1),
    PayloadV2(PayloadV2),
}

#[derive(Deserialize, Serialize, Debug)]
pub struct PayloadV1 {
    #[serde(rename = "@type")]
    pub type_: PayloadTypeV1,
    #[serde(rename = "@msg")]
    pub msg: Vec<i8>,
}

#[derive(Deserialize, Serialize, Debug)]
pub struct PayloadV2 {
    #[serde(rename = "@type")]
    pub type_: PayloadTypeV2,
    #[serde(rename = "@id")]
    pub id: String,
    #[serde(rename = "@msg")]
    pub msg: String,
    #[serde(rename = "~thread")]
    pub thread: Thread,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum PayloadTypes {
    PayloadTypeV1(PayloadTypeV1),
    PayloadTypeV2(PayloadTypeV2),
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PayloadTypeV1 {
    pub name: String,
    pub ver: String,
    pub fmt: String,
}

pub type PayloadTypeV2 = MessageTypeV2;

#[derive(Debug, Deserialize, Serialize)]
pub enum PayloadKinds {
    CredOffer,
    CredReq,
    Cred,
    Proof,
    ProofRequest,
    Other(String)
}

impl PayloadKinds {
    pub fn family(&self) -> MessageFamilies {
        match self {
            PayloadKinds::CredOffer => MessageFamilies::CredentialExchange,
            PayloadKinds::CredReq => MessageFamilies::CredentialExchange,
            PayloadKinds::Cred => MessageFamilies::CredentialExchange,
            PayloadKinds::Proof => MessageFamilies::CredentialExchange,
            PayloadKinds::ProofRequest => MessageFamilies::CredentialExchange,
            PayloadKinds::Other(family) => MessageFamilies::Other(family.to_string()),
        }
    }

    fn name<'a>(&'a self) -> &'a str {
        match ProtocolType::get() {
            ProtocolTypes::V1 => {
                match self {
                    PayloadKinds::CredOffer => "CRED_OFFER",
                    PayloadKinds::CredReq => "CRED_REQ",
                    PayloadKinds::Cred => "CRED",
                    PayloadKinds::ProofRequest => "PROOF_REQUEST",
                    PayloadKinds::Proof => "PROOF",
                    PayloadKinds::Other(kind) => kind,
                }
            }
            ProtocolTypes::V2 => {
                match self {
                    PayloadKinds::CredOffer => "credential-offer",
                    PayloadKinds::CredReq => "credential-request",
                    PayloadKinds::Cred => "credential",
                    PayloadKinds::ProofRequest => "presentation-request",
                    PayloadKinds::Proof => "presentation",
                    PayloadKinds::Other(kind) => kind,
                }
            }
        }
    }
}

impl PayloadTypes {
    pub fn build_v1(kind: PayloadKinds, fmt: &str) -> PayloadTypeV1 {
        PayloadTypeV1 {
            name: kind.name().to_string(),
            ver: MESSAGE_VERSION_V1.to_string(),
            fmt: fmt.to_string(),
        }
    }

    pub fn build_v2(kind: PayloadKinds) -> PayloadTypeV2 {
        PayloadTypeV2 {
            did: DID.to_string(),
            family: kind.family(),
            version: kind.family().version().to_string(),
            type_: kind.name().to_string(),
        }
    }
}

impl From<RemoteMessageType> for PayloadKinds {
    fn from(type_: RemoteMessageType) -> PayloadKinds {
        match type_ {
            RemoteMessageType::ConnReq => PayloadKinds::Other("connReq".to_string()),
            RemoteMessageType::ConnReqAnswer => PayloadKinds::Other("ConnReqAnswer".to_string()),
            RemoteMessageType::CredOffer => PayloadKinds::CredOffer,
            RemoteMessageType::CredReq => PayloadKinds::CredReq,
            RemoteMessageType::Cred => PayloadKinds::Cred,
            RemoteMessageType::ProofReq => PayloadKinds::ProofRequest,
            RemoteMessageType::Proof => PayloadKinds::Proof,
            RemoteMessageType::Other(other) => PayloadKinds::Other(other.to_string()),
        }
    }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Thread {
    pub thid: Option<String>,
    pub pthid: Option<String>,
    pub sender_order: u32,
    pub received_orders: HashMap<String, u32>,
}

impl Thread {
    pub fn new() -> Thread {
        Thread {
            thid: None,
            pthid: None,
            sender_order: 0,
            received_orders: HashMap::new(),
        }
    }
}<commit_msg>VE-998 - fix payload serialization for Dummy Agent<commit_after>use domain::message_type::{MessageTypeV2, MessageFamilies, MESSAGE_VERSION_V1, DID};
use domain::a2a::RemoteMessageType;
use domain::protocol_type::{ProtocolType, ProtocolTypes};
use std::collections::HashMap;

#[derive(Deserialize, Serialize, Debug)]
#[serde(untagged)]
pub enum Payloads {
    PayloadV1(PayloadV1),
    PayloadV2(PayloadV2),
}

#[derive(Deserialize, Serialize, Debug)]
pub struct PayloadV1 {
    #[serde(rename = "@type")]
    pub type_: PayloadTypeV1,
    #[serde(rename = "@msg")]
    pub msg: Vec<i8>,
}

#[derive(Deserialize, Serialize, Debug)]
pub struct PayloadV2 {
    #[serde(rename = "@type")]
    pub type_: PayloadTypeV2,
    #[serde(rename = "@id")]
    pub id: String,
    #[serde(rename = "@msg")]
    pub msg: String,
    #[serde(rename = "~thread")]
    pub thread: Thread,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum PayloadTypes {
    PayloadTypeV1(PayloadTypeV1),
    PayloadTypeV2(PayloadTypeV2),
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PayloadTypeV1 {
    pub name: String,
    pub ver: String,
    pub fmt: String,
}

pub type PayloadTypeV2 = MessageTypeV2;

#[derive(Debug, Deserialize, Serialize)]
pub enum PayloadKinds {
    CredOffer,
    CredReq,
    Cred,
    Proof,
    ProofRequest,
    Other(String)
}

impl PayloadKinds {
    pub fn family(&self) -> MessageFamilies {
        match self {
            PayloadKinds::CredOffer => MessageFamilies::CredentialExchange,
            PayloadKinds::CredReq => MessageFamilies::CredentialExchange,
            PayloadKinds::Cred => MessageFamilies::CredentialExchange,
            PayloadKinds::Proof => MessageFamilies::CredentialExchange,
            PayloadKinds::ProofRequest => MessageFamilies::CredentialExchange,
            PayloadKinds::Other(family) => MessageFamilies::Other(family.to_string()),
        }
    }

    fn name<'a>(&'a self) -> &'a str {
        match ProtocolType::get() {
            ProtocolTypes::V1 => {
                match self {
                    PayloadKinds::CredOffer => "CRED_OFFER",
                    PayloadKinds::CredReq => "CRED_REQ",
                    PayloadKinds::Cred => "CRED",
                    PayloadKinds::ProofRequest => "PROOF_REQUEST",
                    PayloadKinds::Proof => "PROOF",
                    PayloadKinds::Other(kind) => kind,
                }
            }
            ProtocolTypes::V2 => {
                match self {
                    PayloadKinds::CredOffer => "credential-offer",
                    PayloadKinds::CredReq => "credential-request",
                    PayloadKinds::Cred => "credential",
                    PayloadKinds::ProofRequest => "presentation-request",
                    PayloadKinds::Proof => "presentation",
                    PayloadKinds::Other(kind) => kind,
                }
            }
        }
    }
}

impl PayloadTypes {
    pub fn build_v1(kind: PayloadKinds, fmt: &str) -> PayloadTypeV1 {
        PayloadTypeV1 {
            name: kind.name().to_string(),
            ver: MESSAGE_VERSION_V1.to_string(),
            fmt: fmt.to_string(),
        }
    }

    pub fn build_v2(kind: PayloadKinds) -> PayloadTypeV2 {
        PayloadTypeV2 {
            did: DID.to_string(),
            family: kind.family(),
            version: kind.family().version().to_string(),
            type_: kind.name().to_string(),
        }
    }
}

impl From<RemoteMessageType> for PayloadKinds {
    fn from(type_: RemoteMessageType) -> PayloadKinds {
        match type_ {
            RemoteMessageType::ConnReq => PayloadKinds::Other("connReq".to_string()),
            RemoteMessageType::ConnReqAnswer => PayloadKinds::Other("ConnReqAnswer".to_string()),
            RemoteMessageType::CredOffer => PayloadKinds::CredOffer,
            RemoteMessageType::CredReq => PayloadKinds::CredReq,
            RemoteMessageType::Cred => PayloadKinds::Cred,
            RemoteMessageType::ProofReq => PayloadKinds::ProofRequest,
            RemoteMessageType::Proof => PayloadKinds::Proof,
            RemoteMessageType::Other(other) => PayloadKinds::Other(other.to_string()),
        }
    }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Thread {
    pub thid: Option<String>,
    pub pthid: Option<String>,
    pub sender_order: u32,
    pub received_orders: HashMap<String, u32>,
}

impl Thread {
    pub fn new() -> Thread {
        Thread {
            thid: None,
            pthid: None,
            sender_order: 0,
            received_orders: HashMap::new(),
        }
    }
}<|endoftext|>


<commit_before>use super::traits::{EdgeWeight, Edges, Graph};
use closed01::Closed01;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
use petgraph::{EdgeDirection, Directed};
use petgraph::Graph as PetGraph;
use std::fmt::Debug;

#[derive(Debug)]
pub struct Edge {
    /// Node index type. Our graphs never exceed 4 billion nodes.
    pointing_node: u32,
    weight: EdgeWeight,
}

impl Edge {
    pub fn new_unweighted(node_idx: usize) -> Edge {
        Edge::new(node_idx, Closed01::zero())
    }

    pub fn new(node_idx: usize, weight: EdgeWeight) -> Edge {
        assert!(node_idx <= u32::max_value() as usize);
        Edge {
            pointing_node: node_idx as u32,
            weight: weight,
        }
    }
}

#[derive(Debug)]
pub struct EdgeList {
    edges: Vec<Edge>,
}

impl EdgeList {
    pub fn new(edges: Vec<Edge>) -> EdgeList {
        EdgeList { edges: edges }
    }
}

impl Edges for EdgeList {
    #[inline]
    fn num_edges(&self) -> usize {
        self.edges.len()
    }

    #[inline]
    fn nth_edge(&self, n: usize) -> Option<usize> {
        self.edges.get(n).map(|n| n.pointing_node as usize)
    }

    #[inline]
    fn nth_edge_weight(&self, n: usize) -> Option<EdgeWeight> {
        self.edges.get(n).map(|n| n.weight)
    }
}

#[derive(Debug)]
pub struct Node<T: Debug + Clone> {
    in_edges: EdgeList,
    out_edges: EdgeList,
    node_value: T,
}

impl<T: Debug + Clone> Node<T> {
    pub fn new(in_edges: EdgeList, out_edges: EdgeList, node_value: T) -> Node<T> {
        Node {
            in_edges: in_edges,
            out_edges: out_edges,
            node_value: node_value,
        }
    }

    pub fn node_value(&self) -> &T {
        &self.node_value
    }

    pub fn add_in_edge(&mut self, edge: Edge) {
        self.in_edges.edges.push(edge);
    }

    pub fn add_out_edge(&mut self, edge: Edge) {
        self.out_edges.edges.push(edge);
    }

    fn degree(&self) -> usize {
        self.in_edges.num_edges() + self.out_edges.num_edges()
    }
}

#[derive(Debug)]
pub struct OwnedGraph<T: Debug + Clone> {
    nodes: Vec<Node<T>>,
}

impl<T: Debug + Clone> OwnedGraph<T> {
    pub fn new(nodes: Vec<Node<T>>) -> OwnedGraph<T> {
        OwnedGraph { nodes: nodes }
    }

    pub fn from_petgraph(pg: &PetGraph<T, (), Directed>) -> OwnedGraph<T> {
        OwnedGraph {
            nodes: pg.node_indices()
                     .map(|i| {
                         Node::new(EdgeList::new(pg.edges_directed(i, EdgeDirection::Incoming)
                                                   .map(|(j, _w)| Edge::new_unweighted(j.index()))
                                                   .collect()),
                                   EdgeList::new(pg.edges_directed(i, EdgeDirection::Outgoing)
                                                   .map(|(j, _w)| Edge::new_unweighted(j.index()))
                                                   .collect()),
                                   pg.node_weight(i).unwrap().clone())
                     })
                     .collect(),
        }
    }

    pub fn len(&self) -> usize {
        self.nodes.len()
    }

    pub fn push_empty_node(&mut self, node_value: T) -> usize {
        let idx = self.nodes.len();
        self.nodes.push(Node::new(EdgeList::new(Vec::new()),
                                  EdgeList::new(Vec::new()),
                                  node_value));
        return idx;
    }
}

impl<T: Debug + Clone> Graph for OwnedGraph<T> {
    type EDGE = EdgeList;
    type NODE = T;
    fn num_nodes(&self) -> usize {
        self.nodes.len()
    }

    #[inline]
    fn node_value(&self, node_idx: usize) -> &Self::NODE {
        self.nodes[node_idx].node_value()
    }

    #[inline]
    fn node_degree(&self, node_idx: usize) -> usize {
        self.nodes[node_idx].degree()
    }

    #[inline]
    fn in_edges_of<'b>(&'b self, node_idx: usize) -> &'b Self::EDGE {
        &&self.nodes[node_idx].in_edges
    }

    #[inline]
    fn out_edges_of<'b>(&'b self, node_idx: usize) -> &'b Self::EDGE {
        &self.nodes[node_idx].out_edges
    }
}

pub struct GraphBuilder<K: Ord, T: Debug + Clone> {
    // maps node_id to index in node_in_edges/node_out_edges.
    node_map: BTreeMap<K, usize>,
    graph: OwnedGraph<T>,
}

impl<K: Ord, T: Debug + Clone> GraphBuilder<K, T> {
    pub fn new() -> GraphBuilder<K, T> {
        GraphBuilder {
            node_map: BTreeMap::new(),
            graph: OwnedGraph::new(Vec::new()),
        }
    }

    pub fn graph(self) -> OwnedGraph<T> {
        self.graph
    }

    /// Panics if `node_id` already exists.
    pub fn add_node(&mut self, node_id: K, node_value: T) -> usize {
        match self.node_map.entry(node_id) {
            Entry::Vacant(e) => {
                let next_id = self.graph.push_empty_node(node_value);
                e.insert(next_id);
                return next_id;
            }
            Entry::Occupied(_) => {
                panic!();
            }
        }
    }

    pub fn add_edge_unweighted(&mut self, source_node_id: K, target_node_id: K) {
        self.add_edge(source_node_id, target_node_id, Closed01::zero());
    }

    pub fn add_edge(&mut self, source_node_id: K, target_node_id: K, weight: EdgeWeight) {
        let source_index = *self.node_map.get(&source_node_id).unwrap();
        let target_index = *self.node_map.get(&target_node_id).unwrap();
        self.graph.nodes[source_index].add_out_edge(Edge::new(target_index, weight));
        self.graph.nodes[target_index].add_in_edge(Edge::new(source_index, weight));
    }
}
<commit_msg>OwnedGraph::from_petgraph(): Take edge weight into account.<commit_after>use super::traits::{EdgeWeight, Edges, Graph};
use closed01::Closed01;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
use petgraph::{EdgeDirection, Directed};
use petgraph::Graph as PetGraph;
use std::fmt::Debug;

#[derive(Debug)]
pub struct Edge {
    /// Node index type. Our graphs never exceed 4 billion nodes.
    pointing_node: u32,
    weight: EdgeWeight,
}

impl Edge {
    pub fn new_unweighted(node_idx: usize) -> Edge {
        Edge::new(node_idx, Closed01::zero())
    }

    pub fn new(node_idx: usize, weight: EdgeWeight) -> Edge {
        assert!(node_idx <= u32::max_value() as usize);
        Edge {
            pointing_node: node_idx as u32,
            weight: weight,
        }
    }
}

#[derive(Debug)]
pub struct EdgeList {
    edges: Vec<Edge>,
}

impl EdgeList {
    pub fn new(edges: Vec<Edge>) -> EdgeList {
        EdgeList { edges: edges }
    }
}

impl Edges for EdgeList {
    #[inline]
    fn num_edges(&self) -> usize {
        self.edges.len()
    }

    #[inline]
    fn nth_edge(&self, n: usize) -> Option<usize> {
        self.edges.get(n).map(|n| n.pointing_node as usize)
    }

    #[inline]
    fn nth_edge_weight(&self, n: usize) -> Option<EdgeWeight> {
        self.edges.get(n).map(|n| n.weight)
    }
}

#[derive(Debug)]
pub struct Node<T: Debug + Clone> {
    in_edges: EdgeList,
    out_edges: EdgeList,
    node_value: T,
}

impl<T: Debug + Clone> Node<T> {
    pub fn new(in_edges: EdgeList, out_edges: EdgeList, node_value: T) -> Node<T> {
        Node {
            in_edges: in_edges,
            out_edges: out_edges,
            node_value: node_value,
        }
    }

    pub fn node_value(&self) -> &T {
        &self.node_value
    }

    pub fn add_in_edge(&mut self, edge: Edge) {
        self.in_edges.edges.push(edge);
    }

    pub fn add_out_edge(&mut self, edge: Edge) {
        self.out_edges.edges.push(edge);
    }

    fn degree(&self) -> usize {
        self.in_edges.num_edges() + self.out_edges.num_edges()
    }
}

#[derive(Debug)]
pub struct OwnedGraph<T: Debug + Clone> {
    nodes: Vec<Node<T>>,
}

impl<T: Debug + Clone> OwnedGraph<T> {
    pub fn new(nodes: Vec<Node<T>>) -> OwnedGraph<T> {
        OwnedGraph { nodes: nodes }
    }

    pub fn from_petgraph(pg: &PetGraph<T, EdgeWeight, Directed>) -> OwnedGraph<T> {
        OwnedGraph {
            nodes: pg.node_indices()
                     .map(|i| {
                         Node::new(EdgeList::new(pg.edges_directed(i, EdgeDirection::Incoming)
                                                   .map(|(j, &w)| Edge::new(j.index(), w))
                                                   .collect()),
                                   EdgeList::new(pg.edges_directed(i, EdgeDirection::Outgoing)
                                                   .map(|(j, &w)| Edge::new(j.index(), w))
                                                   .collect()),
                                   pg.node_weight(i).unwrap().clone())
                     })
                     .collect(),
        }
    }

    pub fn len(&self) -> usize {
        self.nodes.len()
    }

    pub fn push_empty_node(&mut self, node_value: T) -> usize {
        let idx = self.nodes.len();
        self.nodes.push(Node::new(EdgeList::new(Vec::new()),
                                  EdgeList::new(Vec::new()),
                                  node_value));
        return idx;
    }
}

impl<T: Debug + Clone> Graph for OwnedGraph<T> {
    type EDGE = EdgeList;
    type NODE = T;
    fn num_nodes(&self) -> usize {
        self.nodes.len()
    }

    #[inline]
    fn node_value(&self, node_idx: usize) -> &Self::NODE {
        self.nodes[node_idx].node_value()
    }

    #[inline]
    fn node_degree(&self, node_idx: usize) -> usize {
        self.nodes[node_idx].degree()
    }

    #[inline]
    fn in_edges_of<'b>(&'b self, node_idx: usize) -> &'b Self::EDGE {
        &&self.nodes[node_idx].in_edges
    }

    #[inline]
    fn out_edges_of<'b>(&'b self, node_idx: usize) -> &'b Self::EDGE {
        &self.nodes[node_idx].out_edges
    }
}

pub struct GraphBuilder<K: Ord, T: Debug + Clone> {
    // maps node_id to index in node_in_edges/node_out_edges.
    node_map: BTreeMap<K, usize>,
    graph: OwnedGraph<T>,
}

impl<K: Ord, T: Debug + Clone> GraphBuilder<K, T> {
    pub fn new() -> GraphBuilder<K, T> {
        GraphBuilder {
            node_map: BTreeMap::new(),
            graph: OwnedGraph::new(Vec::new()),
        }
    }

    pub fn graph(self) -> OwnedGraph<T> {
        self.graph
    }

    /// Panics if `node_id` already exists.
    pub fn add_node(&mut self, node_id: K, node_value: T) -> usize {
        match self.node_map.entry(node_id) {
            Entry::Vacant(e) => {
                let next_id = self.graph.push_empty_node(node_value);
                e.insert(next_id);
                return next_id;
            }
            Entry::Occupied(_) => {
                panic!();
            }
        }
    }

    pub fn add_edge_unweighted(&mut self, source_node_id: K, target_node_id: K) {
        self.add_edge(source_node_id, target_node_id, Closed01::zero());
    }

    pub fn add_edge(&mut self, source_node_id: K, target_node_id: K, weight: EdgeWeight) {
        let source_index = *self.node_map.get(&source_node_id).unwrap();
        let target_index = *self.node_map.get(&target_node_id).unwrap();
        self.graph.nodes[source_index].add_out_edge(Edge::new(target_index, weight));
        self.graph.nodes[target_index].add_in_edge(Edge::new(source_index, weight));
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use gobject_ffi;

use glib;
use glib::translate::*;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum PropertyMutability {
    Readable,
    Writable,
    ReadWrite,
}

impl Into<gobject_ffi::GParamFlags> for PropertyMutability {
    fn into(self) -> gobject_ffi::GParamFlags {
        use self::PropertyMutability::*;

        match self {
            Readable => gobject_ffi::G_PARAM_READABLE,
            Writable => gobject_ffi::G_PARAM_WRITABLE,
            ReadWrite => gobject_ffi::G_PARAM_READWRITE,
        }
    }
}

#[derive(Debug, Clone)]
pub enum Property<'a> {
    Boolean(&'a str, &'a str, &'a str, bool, PropertyMutability),
    Int(
        &'a str,
        &'a str,
        &'a str,
        (i32, i32),
        i32,
        PropertyMutability,
    ),
    Int64(
        &'a str,
        &'a str,
        &'a str,
        (i64, i64),
        i64,
        PropertyMutability,
    ),
    UInt(
        &'a str,
        &'a str,
        &'a str,
        (u32, u32),
        u32,
        PropertyMutability,
    ),
    UInt64(
        &'a str,
        &'a str,
        &'a str,
        (u64, u64),
        u64,
        PropertyMutability,
    ),
    Float(
        &'a str,
        &'a str,
        &'a str,
        (f32, f32),
        f32,
        PropertyMutability,
    ),
    Double(
        &'a str,
        &'a str,
        &'a str,
        (f64, f64),
        f64,
        PropertyMutability,
    ),
    String(
        &'a str,
        &'a str,
        &'a str,
        Option<&'a str>,
        PropertyMutability,
    ),
    Boxed(&'a str, &'a str, &'a str, glib::Type, PropertyMutability),
    Object(&'a str, &'a str, &'a str, glib::Type, PropertyMutability),
}

impl<'a> Into<*mut gobject_ffi::GParamSpec> for &'a Property<'a> {
    fn into(self) -> *mut gobject_ffi::GParamSpec {
        unsafe {
            match *self {
                Property::Boolean(name, nick, description, default, mutability) => {
                    gobject_ffi::g_param_spec_boolean(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        default.to_glib(),
                        mutability.into(),
                    )
                }
                Property::Int(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_int(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::Int64(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_int64(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::UInt(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_uint(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::UInt64(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_uint64(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::Float(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_float(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::Double(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_double(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::String(name, nick, description, default, mutability) => {
                    gobject_ffi::g_param_spec_string(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        default.to_glib_none().0,
                        mutability.into(),
                    )
                }
                Property::Boxed(name, nick, description, type_, mutability) => {
                    gobject_ffi::g_param_spec_boxed(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        type_.to_glib(),
                        mutability.into(),
                    )
                }
                Property::Object(name, nick, description, type_, mutability) => {
                    gobject_ffi::g_param_spec_object(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        type_.to_glib(),
                        mutability.into(),
                    )
                }
            }
        }
    }
}
<commit_msg>Require a get_type() function for boxed/object properties<commit_after>// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use gobject_ffi;

use glib;
use glib::translate::*;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum PropertyMutability {
    Readable,
    Writable,
    ReadWrite,
}

impl Into<gobject_ffi::GParamFlags> for PropertyMutability {
    fn into(self) -> gobject_ffi::GParamFlags {
        use self::PropertyMutability::*;

        match self {
            Readable => gobject_ffi::G_PARAM_READABLE,
            Writable => gobject_ffi::G_PARAM_WRITABLE,
            ReadWrite => gobject_ffi::G_PARAM_READWRITE,
        }
    }
}

#[derive(Debug, Clone)]
pub enum Property<'a> {
    Boolean(&'a str, &'a str, &'a str, bool, PropertyMutability),
    Int(
        &'a str,
        &'a str,
        &'a str,
        (i32, i32),
        i32,
        PropertyMutability,
    ),
    Int64(
        &'a str,
        &'a str,
        &'a str,
        (i64, i64),
        i64,
        PropertyMutability,
    ),
    UInt(
        &'a str,
        &'a str,
        &'a str,
        (u32, u32),
        u32,
        PropertyMutability,
    ),
    UInt64(
        &'a str,
        &'a str,
        &'a str,
        (u64, u64),
        u64,
        PropertyMutability,
    ),
    Float(
        &'a str,
        &'a str,
        &'a str,
        (f32, f32),
        f32,
        PropertyMutability,
    ),
    Double(
        &'a str,
        &'a str,
        &'a str,
        (f64, f64),
        f64,
        PropertyMutability,
    ),
    String(
        &'a str,
        &'a str,
        &'a str,
        Option<&'a str>,
        PropertyMutability,
    ),
    Boxed(&'a str, &'a str, &'a str, fn() -> glib::Type, PropertyMutability),
    Object(&'a str, &'a str, &'a str, fn() -> glib::Type, PropertyMutability),
}

impl<'a> Into<*mut gobject_ffi::GParamSpec> for &'a Property<'a> {
    fn into(self) -> *mut gobject_ffi::GParamSpec {
        unsafe {
            match *self {
                Property::Boolean(name, nick, description, default, mutability) => {
                    gobject_ffi::g_param_spec_boolean(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        default.to_glib(),
                        mutability.into(),
                    )
                }
                Property::Int(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_int(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::Int64(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_int64(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::UInt(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_uint(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::UInt64(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_uint64(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::Float(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_float(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::Double(name, nick, description, (min, max), default, mutability) => {
                    gobject_ffi::g_param_spec_double(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        min,
                        max,
                        default,
                        mutability.into(),
                    )
                }
                Property::String(name, nick, description, default, mutability) => {
                    gobject_ffi::g_param_spec_string(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        default.to_glib_none().0,
                        mutability.into(),
                    )
                }
                Property::Boxed(name, nick, description, get_type, mutability) => {
                    gobject_ffi::g_param_spec_boxed(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        get_type().to_glib(),
                        mutability.into(),
                    )
                }
                Property::Object(name, nick, description, get_type, mutability) => {
                    gobject_ffi::g_param_spec_object(
                        name.to_glib_none().0,
                        nick.to_glib_none().0,
                        description.to_glib_none().0,
                        get_type().to_glib(),
                        mutability.into(),
                    )
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate macros;

use std::collections::HashMap;

#[test]
fn test_empty() {
    let expected: HashMap<u32, u32> = HashMap::new();
    let computed: HashMap<u32, u32> = hashmap!();
    assert_eq!(computed, expected);
}

#[test]
#[ignore]
fn test_no_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert(1, "one");
    expected.insert(2, "two");
    assert_eq!(hashmap!(1 => "one", 2 => "two"), expected);
}

#[test]
#[ignore]
fn test_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert('h', 89);
    expected.insert('a', 1);
    expected.insert('s', 19);
    expected.insert('h', 8);
    assert_eq!(
        hashmap!(
            'h' => 89,
            'a' => 1,
            's' => 19,
            'h' => 8,
        ),
        expected
    );
}

#[test]
#[ignore]
fn test_nested() {
    let mut expected = HashMap::new();
    expected.insert("non-empty", {
        let mut subhashmap = HashMap::new();
        subhashmap.insert(23, 623);
        subhashmap.insert(34, 21);
        subhashmap
    });
    expected.insert("empty", HashMap::new());
    assert_eq!(
        hashmap!(
            "non-empty" => hashmap!(
                23 => 623,
                34 => 21
            ),
            "empty" => hashmap!()
        ),
        expected
    );
}

mod test {
    #[test]
    #[ignore]
    fn type_not_in_scope() {
        let expected: ::std::collections::HashMap<(), ()> = hashmap!();
    }
}
<commit_msg>macro: suppress unused_variable warning in test<commit_after>#[macro_use]
extern crate macros;

use std::collections::HashMap;

#[test]
fn test_empty() {
    let expected: HashMap<u32, u32> = HashMap::new();
    let computed: HashMap<u32, u32> = hashmap!();
    assert_eq!(computed, expected);
}

#[test]
#[ignore]
fn test_no_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert(1, "one");
    expected.insert(2, "two");
    assert_eq!(hashmap!(1 => "one", 2 => "two"), expected);
}

#[test]
#[ignore]
fn test_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert('h', 89);
    expected.insert('a', 1);
    expected.insert('s', 19);
    expected.insert('h', 8);
    assert_eq!(
        hashmap!(
            'h' => 89,
            'a' => 1,
            's' => 19,
            'h' => 8,
        ),
        expected
    );
}

#[test]
#[ignore]
fn test_nested() {
    let mut expected = HashMap::new();
    expected.insert("non-empty", {
        let mut subhashmap = HashMap::new();
        subhashmap.insert(23, 623);
        subhashmap.insert(34, 21);
        subhashmap
    });
    expected.insert("empty", HashMap::new());
    assert_eq!(
        hashmap!(
            "non-empty" => hashmap!(
                23 => 623,
                34 => 21
            ),
            "empty" => hashmap!()
        ),
        expected
    );
}

mod test {
    #[test]
    #[ignore]
    fn type_not_in_scope() {
        let _expected: ::std::collections::HashMap<(), ()> = hashmap!();
    }
}
<|endoftext|>


<commit_before>use nalgebra;
use num::Num;
use std::cmp;
use std::convert::From;
use std::marker::PhantomData;
use std::ops;

pub trait ClampRange {
    type Output;

    fn max_value() -> Self::Output;
    fn min_value() -> Self::Output;
}

pub struct Clamped<T, R>(T, PhantomData<R>)
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>;

impl<T, R> Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    pub fn new(value: T) -> Self {
        Clamped(nalgebra::clamp(value, R::min_value(), R::max_value()), PhantomData)
    }

    pub fn max_value() -> Self {
        Clamped(R::max_value(), PhantomData)
    }

    pub fn min_value() -> Self {
        Clamped(R::min_value(), PhantomData)
    }
}

impl<T, R> Clone for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    fn clone(&self) -> Self {
        Clamped(self.0, PhantomData)
    }
}

impl<T, R> Copy for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T> {}

impl<T, R> From<T> for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

impl<T, R> cmp::Eq for Clamped<T, R>
    where T: Copy + cmp::Eq + Num + cmp::PartialOrd,
          R: ClampRange<Output = T> {}

impl<T, R> cmp::Ord for Clamped<T, R>
    where T: Copy + Num + cmp::Ord + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T, R> cmp::PartialEq for Clamped<T, R>
    where T: Copy + Num + cmp::PartialEq + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }
}

impl<T, R> cmp::PartialOrd for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T, R> ops::Add for Clamped<T, R>
    where T: ops::Add<Output = T> + Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        Self::new(self.0.add(other.0))
    }
}

impl<T, R> ops::Deref for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, R> ops::Div for Clamped<T, R>
    where T: Copy + ops::Div<Output = T> + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    type Output = Self;

    fn div(self, other: Self) -> Self::Output {
        Self::new(self.0.div(other.0))
    }
}

impl<T, R> ops::Mul for Clamped<T, R>
    where T: Copy + ops::Mul<Output = T> + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    type Output = Self;

    fn mul(self, other: Self) -> Self::Output {
        Self::new(self.0.mul(other.0))
    }
}

impl<T, R> ops::Neg for Clamped<T, R>
    where T: Copy + ops::Neg<Output = T> + Num + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    type Output = Self;

    fn neg(self) -> Self::Output {
        Self::new(self.0.neg())
    }
}

impl<T, R> ops::Sub for Clamped<T, R>
    where T: Copy + Num + ops::Sub<Output = T> + cmp::PartialOrd,
          R: ClampRange<Output = T>
{
    type Output = Self;

    fn sub(self, other: Self) -> Self::Output {
        Self::new(self.0.sub(other.0))
    }
}
<commit_msg>Rename `ClampRange` to `ClampedRange`.<commit_after>use nalgebra;
use num::Num;
use std::cmp;
use std::convert::From;
use std::marker::PhantomData;
use std::ops;

pub trait ClampedRange {
    type Output;

    fn max_value() -> Self::Output;
    fn min_value() -> Self::Output;
}

pub struct Clamped<T, R>(T, PhantomData<R>)
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>;

impl<T, R> Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    pub fn new(value: T) -> Self {
        Clamped(nalgebra::clamp(value, R::min_value(), R::max_value()), PhantomData)
    }

    pub fn max_value() -> Self {
        Clamped(R::max_value(), PhantomData)
    }

    pub fn min_value() -> Self {
        Clamped(R::min_value(), PhantomData)
    }
}

impl<T, R> Clone for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    fn clone(&self) -> Self {
        Clamped(self.0, PhantomData)
    }
}

impl<T, R> Copy for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T> {}

impl<T, R> From<T> for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

impl<T, R> cmp::Eq for Clamped<T, R>
    where T: Copy + cmp::Eq + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T> {}

impl<T, R> cmp::Ord for Clamped<T, R>
    where T: Copy + Num + cmp::Ord + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T, R> cmp::PartialEq for Clamped<T, R>
    where T: Copy + Num + cmp::PartialEq + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }
}

impl<T, R> cmp::PartialOrd for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T, R> ops::Add for Clamped<T, R>
    where T: ops::Add<Output = T> + Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        Self::new(self.0.add(other.0))
    }
}

impl<T, R> ops::Deref for Clamped<T, R>
    where T: Copy + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, R> ops::Div for Clamped<T, R>
    where T: Copy + ops::Div<Output = T> + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    type Output = Self;

    fn div(self, other: Self) -> Self::Output {
        Self::new(self.0.div(other.0))
    }
}

impl<T, R> ops::Mul for Clamped<T, R>
    where T: Copy + ops::Mul<Output = T> + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    type Output = Self;

    fn mul(self, other: Self) -> Self::Output {
        Self::new(self.0.mul(other.0))
    }
}

impl<T, R> ops::Neg for Clamped<T, R>
    where T: Copy + ops::Neg<Output = T> + Num + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    type Output = Self;

    fn neg(self) -> Self::Output {
        Self::new(self.0.neg())
    }
}

impl<T, R> ops::Sub for Clamped<T, R>
    where T: Copy + Num + ops::Sub<Output = T> + cmp::PartialOrd,
          R: ClampedRange<Output = T>
{
    type Output = Self;

    fn sub(self, other: Self) -> Self::Output {
        Self::new(self.0.sub(other.0))
    }
}
<|endoftext|>


<commit_before>use std::convert::{From, TryFrom, TryInto};
use std::ops::{Deref, DerefMut};
use std::str::FromStr;
use std::fmt;
use stack::Stack;
use operate::Operate;

#[derive(Debug, Copy, Clone)]
pub enum Arithm<T, O: Operate<T>> {
    Operand(T),
    Operator(O),
}

#[derive(Debug)]
pub struct Expression<T, O: Operate<T>>(Vec<Arithm<T, O>>);

impl<T: Copy, O: Operate<T> + Copy> Expression<T, O> {
    pub fn operate(&self) -> Result<T, O::Err> {
        let mut stack = Stack::new();
        for arithm in &self.0 {
            match *arithm {
                Arithm::Operand(operand) => stack.push(operand),
                Arithm::Operator(operator) => operator.operate(&mut stack)?,
            }
        }
        Ok(stack.pop().unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum ExprResult<A, B> {
    TooManyOperands,
    NotEnoughOperand,
    InvalidToken(A, B),
}

use self::ExprResult::*;

impl<'a, T, O> TryFrom<&'a str> for Expression<T, O>
    where T: FromStr,
          O: Operate<T> + TryFrom<&'a str>
{
    type Err = ExprResult<<T as FromStr>::Err, <O as TryFrom<&'a str>>::Err>;
    fn try_from(expr: &'a str) -> Result<Self, Self::Err> {
        let mut final_expr = Vec::new();
        let mut num_operands: usize = 0;
        for token in expr.split_whitespace() {
            let arithm = match token.parse() {
                Ok(operand) => {
                    num_operands += 1;
                    Arithm::Operand(operand)
                }
                Err(operand_err) => {
                    match TryInto::<O>::try_into(token) {
                        Ok(operator) => {
                            let needed = operator.operands_needed();
                            num_operands = num_operands.checked_sub(needed)
                                .ok_or(NotEnoughOperand)?;
                            num_operands += operator.operands_generated();
                            Arithm::Operator(operator)
                        }
                        Err(operator_err) => return Err(InvalidToken(operand_err, operator_err)),
                    }
                }
            };
            final_expr.push(arithm);
        }
        match num_operands {
            0 => Err(NotEnoughOperand),
            1 => Ok(Expression(final_expr)),
            _ => Err(TooManyOperands),
        }
    }
}

impl<T, O: Operate<T>> From<Vec<Arithm<T, O>>> for Expression<T, O> {
    fn from(expr: Vec<Arithm<T, O>>) -> Self {
        Expression(expr)
    }
}

impl<T, O: Operate<T>> Into<Vec<Arithm<T, O>>> for Expression<T, O> {
    fn into(self) -> Vec<Arithm<T, O>> {
        self.0
    }
}

impl<T, O: Operate<T>> Deref for Expression<T, O> {
    type Target = Vec<Arithm<T, O>>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, O: Operate<T>> DerefMut for Expression<T, O> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<T, O> fmt::Display for Expression<T, O>
    where T: fmt::Display,
          O: Operate<T> + fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for arithm in &self.0 {
            match *arithm {
                Arithm::Operand(ref operand) => operand.fmt(f)?,
                Arithm::Operator(ref operator) => operator.fmt(f)?,
            }
            f.write_str(" ")?
        }
        Ok(())
    }
}
<commit_msg>expression: Add clarity to `use` keyword<commit_after>use std::convert::{From, TryFrom, TryInto};
use std::ops::{Deref, DerefMut};
use std::str::FromStr;
use std::fmt;
use stack::Stack;
use operate::Operate;

#[derive(Debug, Copy, Clone)]
pub enum Arithm<T, O: Operate<T>> {
    Operand(T),
    Operator(O),
}

#[derive(Debug)]
pub struct Expression<T, O: Operate<T>>(Vec<Arithm<T, O>>);

impl<T: Copy, O: Operate<T> + Copy> Expression<T, O> {
    pub fn operate(&self) -> Result<T, O::Err> {
        let mut stack = Stack::new();
        for arithm in &self.0 {
            match *arithm {
                Arithm::Operand(operand) => stack.push(operand),
                Arithm::Operator(operator) => operator.operate(&mut stack)?,
            }
        }
        Ok(stack.pop().unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum ExprResult<A, B> {
    TooManyOperands,
    NotEnoughOperand,
    InvalidToken(A, B),
}

impl<'a, T, O> TryFrom<&'a str> for Expression<T, O>
    where T: FromStr,
          O: Operate<T> + TryFrom<&'a str>
{
    type Err = ExprResult<<T as FromStr>::Err, <O as TryFrom<&'a str>>::Err>;
    fn try_from(expr: &'a str) -> Result<Self, Self::Err> {
        use self::ExprResult::*;
        let mut final_expr = Vec::new();
        let mut num_operands: usize = 0;
        for token in expr.split_whitespace() {
            let arithm = match token.parse() {
                Ok(operand) => {
                    num_operands += 1;
                    Arithm::Operand(operand)
                }
                Err(operand_err) => {
                    match TryInto::<O>::try_into(token) {
                        Ok(operator) => {
                            let needed = operator.operands_needed();
                            num_operands = num_operands.checked_sub(needed)
                                .ok_or(NotEnoughOperand)?;
                            num_operands += operator.operands_generated();
                            Arithm::Operator(operator)
                        }
                        Err(operator_err) => return Err(InvalidToken(operand_err, operator_err)),
                    }
                }
            };
            final_expr.push(arithm);
        }
        match num_operands {
            0 => Err(NotEnoughOperand),
            1 => Ok(Expression(final_expr)),
            _ => Err(TooManyOperands),
        }
    }
}

impl<T, O: Operate<T>> From<Vec<Arithm<T, O>>> for Expression<T, O> {
    fn from(expr: Vec<Arithm<T, O>>) -> Self {
        Expression(expr)
    }
}

impl<T, O: Operate<T>> Into<Vec<Arithm<T, O>>> for Expression<T, O> {
    fn into(self) -> Vec<Arithm<T, O>> {
        self.0
    }
}

impl<T, O: Operate<T>> Deref for Expression<T, O> {
    type Target = Vec<Arithm<T, O>>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, O: Operate<T>> DerefMut for Expression<T, O> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<T, O> fmt::Display for Expression<T, O>
    where T: fmt::Display,
          O: Operate<T> + fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for arithm in &self.0 {
            match *arithm {
                Arithm::Operand(ref operand) => operand.fmt(f)?,
                Arithm::Operator(ref operator) => operator.fmt(f)?,
            }
            f.write_str(" ")?
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::fs::File;
use std::error::Error;
use std::fs;
use std::fmt;
use std::io::{Seek, Read, SeekFrom};
use std::collections::HashMap;

#[derive(Debug)]
pub enum FsError {
    FileNotFound,
    InvalidDirectory
}
impl Error for FsError {
    fn description(&self) -> &str {
        match *self {
            FsError::FileNotFound => "the folder does not exist or cannot be read from",
            FsError::InvalidDirectory => "the specified directory is not a valid directory",
        }
    }
}
impl fmt::Display for FsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FsError::FileNotFound => write!(f, "the folder specified could not be found or read from"),
            FsError::InvalidDirectory => write!(f, "the specified directory is not a valid directory"),
        }
    }
}

#[derive(Debug,Clone)]
pub enum CompressionType {
    /// The archive is not compressed and the raw data is the real data.
    None,
    /// The archive is compressed with the Bzip2 compression algorithm.
    Bzip2,
    /// The archive is compressed with (a slightly modified, headerless) Gzip codec.
    Gzip,
    /// The archive is compressed with a modified LZMA2 variant (without size field).
    Lzma
}

#[derive(Debug)]
pub struct FileSystem {
    path: PathBuf,
    mainfile: MainFile,
    indices: HashMap<u32, IndexFile>
}

#[derive(Debug)]
pub struct MainFile {
    file: Option<File>
}

#[derive(Debug)]
pub struct IndexFile {
    id: u32,
    file: File
}

#[derive(Debug,Clone)]
pub struct IndexEntry {
    index: u32,
    id: u32,
    size: u32,
    offset: u64
}

#[derive(Debug,Clone)]
pub struct EntryHeader {
    entry: IndexEntry,
    raw_size: u32,
    real_size: u32,
    compression: CompressionType
}

impl CompressionType {
    /// Fetches the appropriate type of compression based on the header field
    /// in the archive header.
    pub fn from_code(code: u8) -> CompressionType {
        match code {
            1 => CompressionType::Bzip2,
            2 => CompressionType::Gzip,
            3 => CompressionType::Lzma,
            _ => CompressionType::None
        }
    }
}

impl IndexEntry {
    pub fn index(&self) -> u32 {
        self.index
    }

    /// Gets the id of this block.
    pub fn id(&self) -> u32 {
        self.id
    }

    /// Gets the absolute size of the entry data, not counting the 8-10
    /// byte header in the blocks.
    pub fn size(&self) -> u32 {
        self.size
    }

    /// Gets the absolute offset of the very first 520-byte block of this
    /// entry in the main data file.
    pub fn offset(&self) -> u64 {
        self.offset
    }
}

impl IndexFile {
    pub fn last_entry(&self) -> u64 {
         self.file.metadata().unwrap().len() / 6u64
    }

    pub fn entry(&mut self, id: u32) -> Option<IndexEntry> {
        let ref mut file = self.file;
        let mut tmp: [u8; 6] = [0; 6];

        // Seek to the proper position and read into the temp buffer
        let seek_offset = id as u64 * 6u64;
        let res1 = file.seek(SeekFrom::Start(seek_offset));
        let res2 = file.read(&mut tmp);

        // Check if the seek and read operation succeeded
        if res1.is_err() || res2.is_err() {
            return None;
        }

        // Check if the operations returned the expected results
        if res1.unwrap() != seek_offset || res2.unwrap() != 6 {
            return None;
        }

        // Decode the size and offset from the temp buffer
        let size: u32 = ((tmp[0] as u32) << 16) | ((tmp[1] as u32) << 8) | (tmp[2] as u32);
        let offset: u64 = ((tmp[3] as u64) << 16) | ((tmp[4] as u64) << 8) | (tmp[5] as u64);

        Some(IndexEntry {index: self.id, id: id, size: size, offset: offset * 520u64})
    }
}

impl FileSystem {
    pub fn new(string: &'static str) -> Result<FileSystem, FsError> {
        // Declare some nice variables!!!
        let path = PathBuf::from(string);
        let metadata = fs::metadata(&path);

        // Make sure the folder exists
        if !metadata.is_ok() {
            return Err(FsError::FileNotFound);
        }

        // Make sure it is a directory
        if !metadata.unwrap().is_dir() {
            return Err(FsError::InvalidDirectory);
        }

        // Create mainfile path
        let mut mainfile_path = PathBuf::from(string);
        mainfile_path.push("main_file_cache.dat2");

        // Find all valid index files
        let mut indices: HashMap<u32, IndexFile> = HashMap::new();
        let entries = fs::read_dir(&path).unwrap();
        for entry in entries {
            let e = entry.unwrap();
            let fname = e.file_name().into_string().unwrap();

            // Is this an index?
            if fname.starts_with("main_file_cache.idx") {
                // Parse the index id into an integer
                let idx = fname[19..].parse::<u32>().unwrap();

                // Add the index file to our map with indices
                indices.insert(idx, IndexFile {id: idx, file: File::open(e.path()).unwrap()});
            }
        }

        // Create the filesystem object and return it
        let file = File::open(mainfile_path).ok();
        let mainfile = MainFile{file: file};

        Ok(FileSystem {path: path, mainfile: mainfile, indices: indices})
    }

    /// Gets the mainfile, that is, the main_file_cache.dat2 entry in the folder
    /// that holds the actual binary data of the filesystem entries.
    pub fn mainfile(&mut self) -> &mut MainFile {
        &mut self.mainfile
    }

    /// Gets an index with a specific id if it exists. The index can only exist if the file exists
    /// on the file system.
    pub fn index(&mut self, index: u32) -> Option<&mut IndexFile> {
        self.indices.get_mut(&index)
    }
}

impl MainFile {
    /// Checks if the file exists.
    pub fn exists(&self) -> bool {
        self.file.is_some()
    }

    /// Gets the backing file, if existant. Returns a new instance with a fresh seek pointer.
    pub fn file(&mut self) -> Option<&mut File> {
        self.file.as_mut()
    }

    /// Calculates the number of data blocks in the mainfile (if existant). This is done by
    /// taking the file size and dividing that by 520 (rouding up), because each block
    /// takes up 520 bytes of data.
    pub fn num_blocks(&self) -> Option<u64> {
        match self.file {
            Some(ref x) => Some((x.metadata().unwrap().len() + 519u64) / 520u64),
            None => None
        }
    }

    /// Reads a block of data, specified by the block id. The data is read at 520 * block_id
    /// and is exactly 520 bytes big. It is not guaranteed all 520 bytes are occupied if the
    /// block is the last one, thus possible to be trimmed.
    pub fn read_block(&mut self, block: u32) -> Option<[u8; 520]> {
        // Do we have a valid file?
        if self.file.is_none() {
            return None;
        }

        let mut data: [u8; 520] = [0; 520];
        let file = self.file().unwrap();

        // Seek to the right position and read the data
        file.seek(SeekFrom::Start(block as u64 * 520u64));
        file.read(&mut data);

        return Some(data);
    }

    pub fn read_header(&mut self, entry: IndexEntry) -> Option<EntryHeader> {
        // Do we have a valid file?
        if self.file.is_none() {
            return None;
        }

        let mut hdr: [u8; 9] = [0; 9];
        let file = self.file().unwrap();

        // Seek to the right position and read the data, skipping the block header at start
        let block_header_len = if entry.id() > 0xFFFF { 10 } else { 8 };
        file.seek(SeekFrom::Start(entry.offset() + block_header_len));
        file.read(&mut hdr);

        // Parse the 9 bytes of important info
        let compression_type = hdr[0];
        let raw_size: u32 = ((hdr[1] as u32) << 24) | ((hdr[2] as u32) << 16) | ((hdr[3] as u32) << 8) | (hdr[4] as u32);
        let real_size: u32 = ((hdr[5] as u32) << 24) | ((hdr[6] as u32) << 16) | ((hdr[7] as u32) << 8) | (hdr[8] as u32);

        // Return the new entry header
        return Some(EntryHeader {
            entry: entry,
            raw_size: raw_size,
            real_size: real_size,
            compression: CompressionType::from_code(compression_type)
        });
    }

    pub fn read_entry(&mut self, entry: IndexEntry) -> Option<&[u8]> {
        // Do we have a valid file?
        if self.file.is_none() {
            return None;
        }

        // Create a vec with what we assume is the size. If not, the vec will
        // perfectly resize itself, so it's only an estimation to help us speed up.
        let mut data: Vec<i8> = Vec::with_capacity(entry.size() as usize);

        let file = self.file().unwrap();

        None
    }

}
<commit_msg>Add some logic for block reading<commit_after>use std::path::PathBuf;
use std::fs::File;
use std::error::Error;
use std::fs;
use std::fmt;
use std::io::{Seek, Read, SeekFrom};
use std::collections::HashMap;

#[derive(Debug)]
pub enum FsError {
    FileNotFound,
    InvalidDirectory
}
impl Error for FsError {
    fn description(&self) -> &str {
        match *self {
            FsError::FileNotFound => "the folder does not exist or cannot be read from",
            FsError::InvalidDirectory => "the specified directory is not a valid directory",
        }
    }
}
impl fmt::Display for FsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FsError::FileNotFound => write!(f, "the folder specified could not be found or read from"),
            FsError::InvalidDirectory => write!(f, "the specified directory is not a valid directory"),
        }
    }
}

#[derive(Debug,Clone)]
pub enum CompressionType {
    /// The archive is not compressed and the raw data is the real data.
    None,
    /// The archive is compressed with the Bzip2 compression algorithm.
    Bzip2,
    /// The archive is compressed with (a slightly modified, headerless) Gzip codec.
    Gzip,
    /// The archive is compressed with a modified LZMA2 variant (without size field).
    Lzma
}

#[derive(Debug)]
pub struct FileSystem {
    path: PathBuf,
    mainfile: MainFile,
    indices: HashMap<u32, IndexFile>
}

#[derive(Debug)]
pub struct MainFile {
    file: Option<File>
}

#[derive(Debug)]
pub struct IndexFile {
    id: u32,
    file: File
}

#[derive(Debug,Clone)]
pub struct IndexEntry {
    index: u32,
    id: u32,
    size: u32,
    offset: u64
}

#[derive(Debug,Clone)]
pub struct EntryHeader {
    entry: IndexEntry,
    raw_size: u32,
    real_size: u32,
    compression: CompressionType
}

impl CompressionType {
    /// Fetches the appropriate type of compression based on the header field
    /// in the archive header.
    pub fn from_code(code: u8) -> CompressionType {
        match code {
            1 => CompressionType::Bzip2,
            2 => CompressionType::Gzip,
            3 => CompressionType::Lzma,
            _ => CompressionType::None
        }
    }
}

impl IndexEntry {
    pub fn index(&self) -> u32 {
        self.index
    }

    /// Gets the id of this block.
    pub fn id(&self) -> u32 {
        self.id
    }

    /// Gets the absolute size of the entry data, not counting the 8-10
    /// byte header in the blocks.
    pub fn size(&self) -> u32 {
        self.size
    }

    /// Gets the absolute offset of the very first 520-byte block of this
    /// entry in the main data file.
    pub fn offset(&self) -> u64 {
        self.offset
    }

    pub fn block(&self) -> u32 {
        (self.offset / 520u64) as u32
    }
}

impl IndexFile {
    pub fn last_entry(&self) -> u64 {
         self.file.metadata().unwrap().len() / 6u64
    }

    pub fn entry(&mut self, id: u32) -> Option<IndexEntry> {
        let ref mut file = self.file;
        let mut tmp: [u8; 6] = [0; 6];

        // Seek to the proper position and read into the temp buffer
        let seek_offset = id as u64 * 6u64;
        let res1 = file.seek(SeekFrom::Start(seek_offset));
        let res2 = file.read(&mut tmp);

        // Check if the seek and read operation succeeded
        if res1.is_err() || res2.is_err() {
            return None;
        }

        // Check if the operations returned the expected results
        if res1.unwrap() != seek_offset || res2.unwrap() != 6 {
            return None;
        }

        // Decode the size and offset from the temp buffer
        let size: u32 = ((tmp[0] as u32) << 16) | ((tmp[1] as u32) << 8) | (tmp[2] as u32);
        let offset: u64 = ((tmp[3] as u64) << 16) | ((tmp[4] as u64) << 8) | (tmp[5] as u64);

        Some(IndexEntry {index: self.id, id: id, size: size, offset: offset * 520u64})
    }
}

impl FileSystem {
    pub fn new(string: &'static str) -> Result<FileSystem, FsError> {
        // Declare some nice variables!!!
        let path = PathBuf::from(string);
        let metadata = fs::metadata(&path);

        // Make sure the folder exists
        if !metadata.is_ok() {
            return Err(FsError::FileNotFound);
        }

        // Make sure it is a directory
        if !metadata.unwrap().is_dir() {
            return Err(FsError::InvalidDirectory);
        }

        // Create mainfile path
        let mut mainfile_path = PathBuf::from(string);
        mainfile_path.push("main_file_cache.dat2");

        // Find all valid index files
        let mut indices: HashMap<u32, IndexFile> = HashMap::new();
        let entries = fs::read_dir(&path).unwrap();
        for entry in entries {
            let e = entry.unwrap();
            let fname = e.file_name().into_string().unwrap();

            // Is this an index?
            if fname.starts_with("main_file_cache.idx") {
                // Parse the index id into an integer
                let idx = fname[19..].parse::<u32>().unwrap();

                // Add the index file to our map with indices
                indices.insert(idx, IndexFile {id: idx, file: File::open(e.path()).unwrap()});
            }
        }

        // Create the filesystem object and return it
        let file = File::open(mainfile_path).ok();
        let mainfile = MainFile{file: file};

        Ok(FileSystem {path: path, mainfile: mainfile, indices: indices})
    }

    /// Gets the mainfile, that is, the main_file_cache.dat2 entry in the folder
    /// that holds the actual binary data of the filesystem entries.
    pub fn mainfile(&mut self) -> &mut MainFile {
        &mut self.mainfile
    }

    /// Gets an index with a specific id if it exists. The index can only exist if the file exists
    /// on the file system.
    pub fn index(&mut self, index: u32) -> Option<&mut IndexFile> {
        self.indices.get_mut(&index)
    }
}

impl MainFile {
    /// Checks if the file exists.
    pub fn exists(&self) -> bool {
        self.file.is_some()
    }

    /// Gets the backing file, if existant. Returns a new instance with a fresh seek pointer.
    pub fn file(&mut self) -> Option<&mut File> {
        self.file.as_mut()
    }

    /// Calculates the number of data blocks in the mainfile (if existant). This is done by
    /// taking the file size and dividing that by 520 (rouding up), because each block
    /// takes up 520 bytes of data.
    pub fn num_blocks(&self) -> Option<u64> {
        match self.file {
            Some(ref x) => Some((x.metadata().unwrap().len() + 519u64) / 520u64),
            None => None
        }
    }

    /// Reads a block of data, specified by the block id. The data is read at 520 * block_id
    /// and is exactly 520 bytes big. It is not guaranteed all 520 bytes are occupied if the
    /// block is the last one, thus possible to be trimmed.
    pub fn read_block(&mut self, block: u32) -> Option<[u8; 520]> {
        // Do we have a valid file?
        if self.file.is_none() {
            return None;
        }

        let mut data: [u8; 520] = [0; 520];
        let file = self.file().unwrap();

        // Seek to the right position and read the data
        file.seek(SeekFrom::Start(block as u64 * 520u64));
        file.read(&mut data);

        return Some(data);
    }

    pub fn read_header(&mut self, entry: IndexEntry) -> Option<EntryHeader> {
        // Do we have a valid file?
        if self.file.is_none() {
            return None;
        }

        let mut hdr: [u8; 9] = [0; 9];
        let file = self.file().unwrap();

        // Seek to the right position and read the data, skipping the block header at start
        let block_header_len = if entry.id() > 0xFFFF { 10 } else { 8 };
        file.seek(SeekFrom::Start(entry.offset() + block_header_len));
        file.read(&mut hdr);

        // Parse the 9 bytes of important info
        let compression_type = hdr[0];
        let raw_size: u32 = ((hdr[1] as u32) << 24) | ((hdr[2] as u32) << 16) | ((hdr[3] as u32) << 8) | (hdr[4] as u32);
        let real_size: u32 = ((hdr[5] as u32) << 24) | ((hdr[6] as u32) << 16) | ((hdr[7] as u32) << 8) | (hdr[8] as u32);

        // Return the new entry header
        return Some(EntryHeader {
            entry: entry,
            raw_size: raw_size,
            real_size: real_size,
            compression: CompressionType::from_code(compression_type)
        });
    }

    pub fn read_entry(&mut self, entry: IndexEntry) -> Option<&[u8]> {
        // Do we have a valid file?
        if self.file.is_none() {
            return None;
        }

        // Create a vec with what we assume is the size. If not, the vec will
        // perfectly resize itself, so it's only an estimation to help us speed up.
        let mut data: Vec<i8> = Vec::with_capacity(entry.size() as usize);
        let mut file = self.file().unwrap();

        let mut current_block = entry.block();
        let mut done = false;
        while !done {
            let block_data = self.read_block(current_block);

            done = true;
        }

        None
    }

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;

use lighthouse_metrics::{
    inc_counter, try_create_int_counter, IntCounter, Result as MetricsResult,
};
use slog::Logger;
use slog_term::Decorator;
use std::io::{Result, Write};

pub const MAX_MESSAGE_WIDTH: usize = 40;

lazy_static! {
    pub static ref INFOS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("info_total", "Count of infos logged");
    pub static ref WARNS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("warn_total", "Count of warns logged");
    pub static ref ERRORS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("error_total", "Count of errors logged");
    pub static ref CRITS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("crit_total", "Count of crits logged");
}

pub struct AlignedTermDecorator<D: Decorator> {
    wrapped: D,
    message_width: usize,
}

impl<D: Decorator> AlignedTermDecorator<D> {
    pub fn new(decorator: D, message_width: usize) -> Self {
        AlignedTermDecorator {
            wrapped: decorator,
            message_width,
        }
    }
}

impl<D: Decorator> Decorator for AlignedTermDecorator<D> {
    fn with_record<F>(
        &self,
        record: &slog::Record,
        _logger_values: &slog::OwnedKVList,
        f: F,
    ) -> Result<()>
    where
        F: FnOnce(&mut dyn slog_term::RecordDecorator) -> std::io::Result<()>,
    {
        match record.level() {
            slog::Level::Info => inc_counter(&INFOS_TOTAL),
            slog::Level::Warning => inc_counter(&WARNS_TOTAL),
            slog::Level::Error => inc_counter(&ERRORS_TOTAL),
            slog::Level::Critical => inc_counter(&CRITS_TOTAL),
            _ => (),
        }

        self.wrapped.with_record(record, _logger_values, |deco| {
            f(&mut AlignedRecordDecorator::new(deco, self.message_width))
        })
    }
}

struct AlignedRecordDecorator<'a> {
    wrapped: &'a mut dyn slog_term::RecordDecorator,
    message_count: usize,
    message_active: bool,
    ignore_comma: bool,
    message_width: usize,
}

impl<'a> AlignedRecordDecorator<'a> {
    fn new(
        decorator: &'a mut dyn slog_term::RecordDecorator,
        message_width: usize,
    ) -> AlignedRecordDecorator<'a> {
        AlignedRecordDecorator {
            wrapped: decorator,
            message_count: 0,
            ignore_comma: false,
            message_active: false,
            message_width,
        }
    }
}

impl<'a> Write for AlignedRecordDecorator<'a> {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        if self.ignore_comma {
            //don't write comma
            self.ignore_comma = false;
            Ok(buf.len())
        } else if self.message_active {
            self.wrapped.write(buf).map(|n| {
                self.message_count += n;
                n
            })
        } else {
            self.wrapped.write(buf)
        }
    }

    fn flush(&mut self) -> Result<()> {
        self.wrapped.flush()
    }
}

impl<'a> slog_term::RecordDecorator for AlignedRecordDecorator<'a> {
    fn reset(&mut self) -> Result<()> {
        self.message_active = false;
        self.message_count = 0;
        self.ignore_comma = false;
        self.wrapped.reset()
    }

    fn start_whitespace(&mut self) -> Result<()> {
        self.wrapped.start_whitespace()
    }

    fn start_msg(&mut self) -> Result<()> {
        self.message_active = true;
        self.ignore_comma = false;
        self.wrapped.start_msg()
    }

    fn start_timestamp(&mut self) -> Result<()> {
        self.wrapped.start_timestamp()
    }

    fn start_level(&mut self) -> Result<()> {
        self.wrapped.start_level()
    }

    fn start_comma(&mut self) -> Result<()> {
        if self.message_active && self.message_count + 1 < self.message_width {
            self.ignore_comma = true;
        }
        self.wrapped.start_comma()
    }

    fn start_key(&mut self) -> Result<()> {
        if self.message_active && self.message_count + 1 < self.message_width {
            write!(
                self,
                "{}",
                " ".repeat(self.message_width - self.message_count)
            )?;
            self.message_active = false;
            self.message_count = 0;
            self.ignore_comma = false;
        }
        self.wrapped.start_key()
    }

    fn start_value(&mut self) -> Result<()> {
        self.wrapped.start_value()
    }

    fn start_separator(&mut self) -> Result<()> {
        self.wrapped.start_separator()
    }
}

/// Return a logger suitable for test usage.
///
/// By default no logs will be printed, but they can be enabled via
/// the `test_logger` feature.  This feature can be enabled for any
/// dependent crate by passing `--features logging/test_logger`, e.g.
/// ```bash
/// cargo test -p beacon_chain --features logging/test_logger
/// ```
pub fn test_logger() -> Logger {
    use sloggers::Build;

    if cfg!(feature = "test_logger") {
        sloggers::terminal::TerminalLoggerBuilder::new()
            .level(sloggers::types::Severity::Debug)
            .build()
            .expect("Should build test_logger")
    } else {
        sloggers::null::NullLoggerBuilder
            .build()
            .expect("Should build null_logger")
    }
}
<commit_msg>Ensure consistent log formatting (#2819)<commit_after>#[macro_use]
extern crate lazy_static;

use lighthouse_metrics::{
    inc_counter, try_create_int_counter, IntCounter, Result as MetricsResult,
};
use slog::Logger;
use slog_term::Decorator;
use std::io::{Result, Write};

pub const MAX_MESSAGE_WIDTH: usize = 40;

lazy_static! {
    pub static ref INFOS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("info_total", "Count of infos logged");
    pub static ref WARNS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("warn_total", "Count of warns logged");
    pub static ref ERRORS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("error_total", "Count of errors logged");
    pub static ref CRITS_TOTAL: MetricsResult<IntCounter> =
        try_create_int_counter("crit_total", "Count of crits logged");
}

pub struct AlignedTermDecorator<D: Decorator> {
    wrapped: D,
    message_width: usize,
}

impl<D: Decorator> AlignedTermDecorator<D> {
    pub fn new(decorator: D, message_width: usize) -> Self {
        AlignedTermDecorator {
            wrapped: decorator,
            message_width,
        }
    }
}

impl<D: Decorator> Decorator for AlignedTermDecorator<D> {
    fn with_record<F>(
        &self,
        record: &slog::Record,
        _logger_values: &slog::OwnedKVList,
        f: F,
    ) -> Result<()>
    where
        F: FnOnce(&mut dyn slog_term::RecordDecorator) -> std::io::Result<()>,
    {
        match record.level() {
            slog::Level::Info => inc_counter(&INFOS_TOTAL),
            slog::Level::Warning => inc_counter(&WARNS_TOTAL),
            slog::Level::Error => inc_counter(&ERRORS_TOTAL),
            slog::Level::Critical => inc_counter(&CRITS_TOTAL),
            _ => (),
        }

        self.wrapped.with_record(record, _logger_values, |deco| {
            f(&mut AlignedRecordDecorator::new(deco, self.message_width))
        })
    }
}

struct AlignedRecordDecorator<'a> {
    wrapped: &'a mut dyn slog_term::RecordDecorator,
    message_count: usize,
    message_active: bool,
    ignore_comma: bool,
    message_width: usize,
}

impl<'a> AlignedRecordDecorator<'a> {
    fn new(
        decorator: &'a mut dyn slog_term::RecordDecorator,
        message_width: usize,
    ) -> AlignedRecordDecorator<'a> {
        AlignedRecordDecorator {
            wrapped: decorator,
            message_count: 0,
            ignore_comma: false,
            message_active: false,
            message_width,
        }
    }

    fn filtered_write(&mut self, buf: &[u8]) -> Result<usize> {
        if self.ignore_comma {
            //don't write comma
            self.ignore_comma = false;
            Ok(buf.len())
        } else if self.message_active {
            self.wrapped.write(buf).map(|n| {
                self.message_count += n;
                n
            })
        } else {
            self.wrapped.write(buf)
        }
    }
}

impl<'a> Write for AlignedRecordDecorator<'a> {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        if buf.iter().any(|c| is_ascii_control(c)) {
            let filtered = buf
                .iter()
                .cloned()
                .map(|c| if !is_ascii_control(&c) { c } else { b'_' })
                .collect::<Vec<u8>>();
            self.filtered_write(&filtered)
        } else {
            self.filtered_write(buf)
        }
    }

    fn flush(&mut self) -> Result<()> {
        self.wrapped.flush()
    }
}

impl<'a> slog_term::RecordDecorator for AlignedRecordDecorator<'a> {
    fn reset(&mut self) -> Result<()> {
        self.message_active = false;
        self.message_count = 0;
        self.ignore_comma = false;
        self.wrapped.reset()
    }

    fn start_whitespace(&mut self) -> Result<()> {
        self.wrapped.start_whitespace()
    }

    fn start_msg(&mut self) -> Result<()> {
        self.message_active = true;
        self.ignore_comma = false;
        self.wrapped.start_msg()
    }

    fn start_timestamp(&mut self) -> Result<()> {
        self.wrapped.start_timestamp()
    }

    fn start_level(&mut self) -> Result<()> {
        self.wrapped.start_level()
    }

    fn start_comma(&mut self) -> Result<()> {
        if self.message_active && self.message_count + 1 < self.message_width {
            self.ignore_comma = true;
        }
        self.wrapped.start_comma()
    }

    fn start_key(&mut self) -> Result<()> {
        if self.message_active && self.message_count + 1 < self.message_width {
            write!(
                self,
                "{}",
                " ".repeat(self.message_width - self.message_count)
            )?;
            self.message_active = false;
            self.message_count = 0;
            self.ignore_comma = false;
        }
        self.wrapped.start_key()
    }

    fn start_value(&mut self) -> Result<()> {
        self.wrapped.start_value()
    }

    fn start_separator(&mut self) -> Result<()> {
        self.wrapped.start_separator()
    }
}

/// Function to filter out ascii control codes.
///
/// This helps to keep log formatting consistent.
/// Whitespace and padding control codes are excluded.
fn is_ascii_control(character: &u8) -> bool {
    matches!(
        character,
        b'\x00'..=b'\x08' |
        b'\x0b'..=b'\x0c' |
        b'\x0e'..=b'\x1f' |
        b'\x7f' |
        b'\x81'..=b'\x9f'
    )
}

/// Return a logger suitable for test usage.
///
/// By default no logs will be printed, but they can be enabled via
/// the `test_logger` feature.  This feature can be enabled for any
/// dependent crate by passing `--features logging/test_logger`, e.g.
/// ```bash
/// cargo test -p beacon_chain --features logging/test_logger
/// ```
pub fn test_logger() -> Logger {
    use sloggers::Build;

    if cfg!(feature = "test_logger") {
        sloggers::terminal::TerminalLoggerBuilder::new()
            .level(sloggers::types::Severity::Debug)
            .build()
            .expect("Should build test_logger")
    } else {
        sloggers::null::NullLoggerBuilder
            .build()
            .expect("Should build null_logger")
    }
}
<|endoftext|>


<commit_before>use mapper::Mapper;

use r6502::cpu6502::Cpu6502;

use sdl2::EventPump;
use sdl2::event::Event;
use sdl2::keyboard::KeyboardUtil;
use sdl2::keyboard::{self, Keycode};

pub struct Input {
    events: EventPump,
    keyboard: KeyboardUtil,
}

impl Input {
    pub fn new(events: EventPump, keyboard: KeyboardUtil) -> Input {
        Input {
            events: events,
            keyboard: keyboard,
        }
    }

    pub fn keyboard_inputs(&mut self) -> KeyboardInputs {
        KeyboardInputs {
            input: self,
        }
    }

    /* TODO: keep track of mod keys ourselves */
    fn map_keycode(opt_code: Option<Keycode>, keyboard: &KeyboardUtil) -> Option<u8> {
        let code = match opt_code {
            Some(code) => code,
            None => return None,
        };
        let keystate = keyboard.mod_state();
        let mut ch = match code {
            Keycode::A => 'A' as u8,
            Keycode::B => 'B' as u8,
            Keycode::C => 'C' as u8,
            Keycode::D => 'D' as u8,
            Keycode::E => 'E' as u8,
            Keycode::F => 'F' as u8,
            Keycode::G => 'G' as u8,
            Keycode::H => 'H' as u8,
            Keycode::I => 'I' as u8,
            Keycode::J => 'J' as u8,
            Keycode::K => 'K' as u8,
            Keycode::L => 'L' as u8,
            Keycode::M => 'M' as u8,
            Keycode::N => 'N' as u8,
            Keycode::O => 'O' as u8,
            Keycode::P => 'P' as u8,
            Keycode::Q => 'Q' as u8,
            Keycode::R => 'R' as u8,
            Keycode::S => 'S' as u8,
            Keycode::T => 'T' as u8,
            Keycode::U => 'U' as u8,
            Keycode::V => 'V' as u8,
            Keycode::W => 'W' as u8,
            Keycode::X => 'X' as u8,
            Keycode::Y => 'Y' as u8,
            Keycode::Z => 'Z' as u8,
            Keycode::RightBracket => ']' as u8,
            Keycode::Space => ' ' as u8,
            Keycode::Quote => '\'' as u8,
            Keycode::Comma => ',' as u8,
            Keycode::Minus => '-' as u8,
            Keycode::Period => '.' as u8,
            Keycode::Slash => '/' as u8,
            Keycode::Num0 => '0' as u8,
            Keycode::Num1 => '1' as u8,
            Keycode::Num2 => '2' as u8,
            Keycode::Num3 => '3' as u8,
            Keycode::Num4 => '4' as u8,
            Keycode::Num5 => '5' as u8,
            Keycode::Num6 => '6' as u8,
            Keycode::Num7 => '7' as u8,
            Keycode::Num8 => '8' as u8,
            Keycode::Num9 => '9' as u8,
            Keycode::Semicolon => ';' as u8,
            Keycode::Equals => '=' as u8,
            Keycode::Return => 0x0D,
            Keycode::Left | Keycode::Backspace => 0x08,
            Keycode::Right => 0x15,
            Keycode::Escape => 0x1B,
            _ => return None,
        };
        if keystate.intersects(keyboard::LSHIFTMOD | keyboard::RSHIFTMOD) {
            ch = match code {
                Keycode::Num1 => '!' as u8,
                Keycode::Num2 => '@' as u8,
                Keycode::Num3 => '#' as u8,
                Keycode::Num4 => '$' as u8,
                Keycode::Num5 => '%' as u8,
                Keycode::Num6 => '^' as u8,
                Keycode::Num7 => '&' as u8,
                Keycode::Num8 => '*' as u8,
                Keycode::Num9 => '(' as u8,
                Keycode::Num0 => ')' as u8,
                Keycode::Equals => '+' as u8,
                Keycode::Semicolon => ':' as u8,
                Keycode::Quote => '"' as u8,
                Keycode::Comma => '<' as u8,
                Keycode::Period => '>' as u8,
                Keycode::Slash => '?' as u8,
                _ => ch,
            };
        }
        if keystate.intersects(keyboard::LCTRLMOD | keyboard::RCTRLMOD) {
            ch = match code {
                Keycode::A => 0x81,
                Keycode::B => 0x82,
                Keycode::C => 0x83,
                Keycode::D => 0x84,
                Keycode::E => 0x85,
                Keycode::F => 0x86,
                Keycode::G => 0x87,
                Keycode::H => 0x88,
                Keycode::I => 0x89,
                Keycode::J => 0x8A,
                Keycode::K => 0x8B,
                Keycode::L => 0x8C,
                Keycode::M => 0x8D,
                Keycode::N => 0x8E,
                Keycode::O => 0x8F,
                Keycode::P => 0x90,
                Keycode::Q => 0x91,
                Keycode::R => 0x92,
                Keycode::S => 0x93,
                Keycode::T => 0x94,
                Keycode::U => 0x95,
                Keycode::V => 0x96,
                Keycode::W => 0x97,
                Keycode::X => 0x98,
                Keycode::Y => 0x99,
                Keycode::Z => 0x9A,
                _ => ch,
            };
            if keystate.intersects(keyboard::LSHIFTMOD | keyboard::RSHIFTMOD) {
                ch = match code {
                    Keycode::M => 0x9D,
                    Keycode::N => 0x9E,
                    Keycode::P => 0x80,
                    _ => ch,
                }
            }
        }
        Some(ch | 0x80)
    }
}

pub struct KeyboardInputs<'a> {
    input: &'a mut Input,
}

impl<'a> Iterator for KeyboardInputs<'a> {
    type Item = KeyboardInput;
    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if let Some(event) = self.input.events.poll_event() {
                match event {
                    Event::Quit { .. } => return Some(KeyboardInput::Quit),
                    Event::KeyDown { keycode, .. } => {
                        if keycode == Some(Keycode::F2) {
                            return Some(KeyboardInput::Reset);
                        }
                        else if let Some(val) = Input::map_keycode(keycode, &self.input.keyboard) {
                            return Some(KeyboardInput::Key(val));
                        }
                    }
                    _ => {}
                }
            }
            else {
                return None;
            }
        }
    }
}

pub enum KeyboardInput {
    Quit,
    Reset,
    Key(u8),
}
<commit_msg>input: change chars to byte-chars<commit_after>use sdl2::EventPump;
use sdl2::event::Event;
use sdl2::keyboard::KeyboardUtil;
use sdl2::keyboard::{self, Keycode};

pub struct Input {
    events: EventPump,
    keyboard: KeyboardUtil,
}

impl Input {
    pub fn new(events: EventPump, keyboard: KeyboardUtil) -> Input {
        Input {
            events: events,
            keyboard: keyboard,
        }
    }

    pub fn keyboard_inputs(&mut self) -> KeyboardInputs {
        KeyboardInputs {
            input: self,
        }
    }

    /* TODO: keep track of mod keys ourselves */
    fn map_keycode(opt_code: Option<Keycode>, keyboard: &KeyboardUtil) -> Option<u8> {
        let code = match opt_code {
            Some(code) => code,
            None => return None,
        };
        let keystate = keyboard.mod_state();
        let mut ch = match code {
            Keycode::A => b'A' as u8,
            Keycode::B => b'B' as u8,
            Keycode::C => b'C' as u8,
            Keycode::D => b'D' as u8,
            Keycode::E => b'E' as u8,
            Keycode::F => b'F' as u8,
            Keycode::G => b'G' as u8,
            Keycode::H => b'H' as u8,
            Keycode::I => b'I' as u8,
            Keycode::J => b'J' as u8,
            Keycode::K => b'K' as u8,
            Keycode::L => b'L' as u8,
            Keycode::M => b'M' as u8,
            Keycode::N => b'N' as u8,
            Keycode::O => b'O' as u8,
            Keycode::P => b'P' as u8,
            Keycode::Q => b'Q' as u8,
            Keycode::R => b'R' as u8,
            Keycode::S => b'S' as u8,
            Keycode::T => b'T' as u8,
            Keycode::U => b'U' as u8,
            Keycode::V => b'V' as u8,
            Keycode::W => b'W' as u8,
            Keycode::X => b'X' as u8,
            Keycode::Y => b'Y' as u8,
            Keycode::Z => b'Z' as u8,
            Keycode::RightBracket => b']' as u8,
            Keycode::Space => b' ' as u8,
            Keycode::Quote => b'\'' as u8,
            Keycode::Comma => b',' as u8,
            Keycode::Minus => b'-' as u8,
            Keycode::Period => b'.' as u8,
            Keycode::Slash => b'/' as u8,
            Keycode::Num0 => b'0' as u8,
            Keycode::Num1 => b'1' as u8,
            Keycode::Num2 => b'2' as u8,
            Keycode::Num3 => b'3' as u8,
            Keycode::Num4 => b'4' as u8,
            Keycode::Num5 => b'5' as u8,
            Keycode::Num6 => b'6' as u8,
            Keycode::Num7 => b'7' as u8,
            Keycode::Num8 => b'8' as u8,
            Keycode::Num9 => b'9' as u8,
            Keycode::Semicolon => b';' as u8,
            Keycode::Equals => b'=' as u8,
            Keycode::Return => 0x0D,
            Keycode::Left | Keycode::Backspace => 0x08,
            Keycode::Right => 0x15,
            Keycode::Escape => 0x1B,
            _ => return None,
        };
        if keystate.intersects(keyboard::LSHIFTMOD | keyboard::RSHIFTMOD) {
            ch = match code {
                Keycode::Num1 => b'!' as u8,
                Keycode::Num2 => b'@' as u8,
                Keycode::Num3 => b'#' as u8,
                Keycode::Num4 => b'$' as u8,
                Keycode::Num5 => b'%' as u8,
                Keycode::Num6 => b'^' as u8,
                Keycode::Num7 => b'&' as u8,
                Keycode::Num8 => b'*' as u8,
                Keycode::Num9 => b'(' as u8,
                Keycode::Num0 => b')' as u8,
                Keycode::Equals => b'+' as u8,
                Keycode::Semicolon => b':' as u8,
                Keycode::Quote => b'"' as u8,
                Keycode::Comma => b'<' as u8,
                Keycode::Period => b'>' as u8,
                Keycode::Slash => b'?' as u8,
                _ => ch,
            };
        }
        if keystate.intersects(keyboard::LCTRLMOD | keyboard::RCTRLMOD) {
            ch = match code {
                Keycode::A => 0x81,
                Keycode::B => 0x82,
                Keycode::C => 0x83,
                Keycode::D => 0x84,
                Keycode::E => 0x85,
                Keycode::F => 0x86,
                Keycode::G => 0x87,
                Keycode::H => 0x88,
                Keycode::I => 0x89,
                Keycode::J => 0x8A,
                Keycode::K => 0x8B,
                Keycode::L => 0x8C,
                Keycode::M => 0x8D,
                Keycode::N => 0x8E,
                Keycode::O => 0x8F,
                Keycode::P => 0x90,
                Keycode::Q => 0x91,
                Keycode::R => 0x92,
                Keycode::S => 0x93,
                Keycode::T => 0x94,
                Keycode::U => 0x95,
                Keycode::V => 0x96,
                Keycode::W => 0x97,
                Keycode::X => 0x98,
                Keycode::Y => 0x99,
                Keycode::Z => 0x9A,
                _ => ch,
            };
            if keystate.intersects(keyboard::LSHIFTMOD | keyboard::RSHIFTMOD) {
                ch = match code {
                    Keycode::M => 0x9D,
                    Keycode::N => 0x9E,
                    Keycode::P => 0x80,
                    _ => ch,
                }
            }
        }
        Some(ch | 0x80)
    }
}

pub struct KeyboardInputs<'a> {
    input: &'a mut Input,
}

impl<'a> Iterator for KeyboardInputs<'a> {
    type Item = KeyboardInput;
    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if let Some(event) = self.input.events.poll_event() {
                match event {
                    Event::Quit { .. } => return Some(KeyboardInput::Quit),
                    Event::KeyDown { keycode, .. } => {
                        if keycode == Some(Keycode::F2) {
                            return Some(KeyboardInput::Reset);
                        }
                        else if let Some(val) = Input::map_keycode(keycode, &self.input.keyboard) {
                            return Some(KeyboardInput::Key(val));
                        }
                    }
                    _ => {}
                }
            }
            else {
                return None;
            }
        }
    }
}

pub enum KeyboardInput {
    Quit,
    Reset,
    Key(u8),
}
<|endoftext|>