<commit_before>use analysis::table::Table;
use ast::Expression;
use error::ErrorStack;
use to_javascript::ToJavaScript;

#[derive(Debug)]
struct Compiler {
    global: Table<Expression>,
    errors: ErrorStack,
}

impl Compiler {
    fn new() -> Compiler {
        Compiler {
            global: Table::new(None),
            errors: ErrorStack(vec![]),
        }
    }

    fn compile(tree: &[Expression]) -> String {
        tree
            .iter()
            // TODO: Remove unwrap
            .map(|expr| expr.eval().unwrap())
            .collect::<Vec<String>>()
            .join(";")
    }
}
<commit_msg>Make compiler struct and functions public, handle errors<commit_after>use analysis::table::Table;
use ast::Expression;
use error::ErrorStack;
use to_javascript::ToJavaScript;

#[derive(Debug)]
pub struct Compiler {
    global: Table<Expression>,
    errors: ErrorStack,
}

impl Compiler {
    pub fn new() -> Compiler {
        Compiler {
            global: Table::new(None),
            errors: ErrorStack(vec![]),
        }
    }

    pub fn compile(&mut self, tree: &[Expression]) -> String {
        tree
            .iter()
            // TODO: Remove unwrap
            .map(|expr| expr.eval())
            .filter_map(move |expr| {
                if expr.is_err() {
                    self.errors.0.push(expr.clone().unwrap_err());
                }

                expr.ok()
            })
            .collect::<Vec<String>>()
            .join(";")
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

use kafka::consumer::{Consumer, FetchOffset};
use std::{self, thread, time};
use error::*;

/// A consumer from Kafka
pub struct KafkaConsumer {
    consumer: Consumer,
    messages: Vec<Vec<u8>>,
}

impl Iterator for KafkaConsumer {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Vec<u8>> {
        if self.messages.is_empty() {
            let kafka_consumer = &mut self.consumer;
            loop {
                match kafka_consumer.poll() {
                    Ok(x) => match x.iter().take(1).next() {
                        Some(y) => {
                            self.messages.append(&mut y.messages()
                                .iter()
                                .map(|z| z.value.to_vec())
                                .collect::<Vec<_>>());
                            kafka_consumer
                                .consume_messageset(y)
                                .expect("Couldn't mark messageset as consumed");
                            kafka_consumer
                                .commit_consumed()
                                .expect("Couldn't commit consumption");
                            break;
                        }
                        None => {
                            thread::sleep(time::Duration::from_secs(1));
                            continue;
                        }
                    },
                    Err(_) => return None,
                }
            }
        }
        self.messages.pop()
    }
}

impl KafkaConsumer {
    /// Return a KafkaConsumer with some basic kafka connection properties
    pub fn new(brokers: &str, topic: &str, from_beginning: bool) -> Result<KafkaConsumer> {
        let fetch_offset = if from_beginning {
            FetchOffset::Earliest
        } else {
            FetchOffset::Latest
        };
        match Consumer::from_hosts(
            brokers
                .split(',')
                .map(std::borrow::ToOwned::to_owned)
                .collect::<Vec<String>>(),
        ).with_topic(topic.to_owned())
            .with_fallback_offset(fetch_offset)
            .create()
        {
            Ok(consumer) => Ok(KafkaConsumer {
                consumer: consumer,
                messages: vec![],
            }),
            Err(e) => Err(StreamDelimitError::KafkaInitializeError(e))?,
        }
    }
}
<commit_msg>Change KafkaConsumer loop to consume all message sets (#80)<commit_after>#![deny(missing_docs)]

use kafka::consumer::{Consumer, FetchOffset};
use std;
use std::collections::VecDeque;
use error::*;

/// A consumer from Kafka
pub struct KafkaConsumer {
    consumer: Consumer,
    messages: VecDeque<Vec<u8>>,
}

impl Iterator for KafkaConsumer {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Vec<u8>> {
        if self.messages.is_empty() {
            let kafka_consumer = &mut self.consumer;
            loop {
                match kafka_consumer.poll() {
                    Ok(mss) => {
                        for ms in mss.iter() {
                            self.messages.append(&mut ms.messages()
                                .iter()
                                .map(|z| z.value.to_vec())
                                .collect::<VecDeque<_>>());
                            kafka_consumer
                                .consume_messageset(ms)
                                .expect("Couldn't mark messageset as consumed");
                        }
                        kafka_consumer
                            .commit_consumed()
                            .expect("Couldn't commit consumption");
                        break;
                    }
                    Err(_) => return None,
                }
            }
        }
        self.messages.pop_front()
    }
}

impl KafkaConsumer {
    /// Return a KafkaConsumer with some basic kafka connection properties
    pub fn new(brokers: &str, topic: &str, from_beginning: bool) -> Result<KafkaConsumer> {
        let fetch_offset = if from_beginning {
            FetchOffset::Earliest
        } else {
            FetchOffset::Latest
        };
        match Consumer::from_hosts(
            brokers
                .split(',')
                .map(std::borrow::ToOwned::to_owned)
                .collect::<Vec<String>>(),
        ).with_topic(topic.to_owned())
            .with_fallback_offset(fetch_offset)
            .create()
        {
            Ok(consumer) => Ok(KafkaConsumer {
                consumer: consumer,
                messages: VecDeque::new(),
            }),
            Err(e) => Err(StreamDelimitError::KafkaInitializeError(e))?,
        }
    }
}
<|endoftext|>


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

#![feature(const_int_ops)]
#![feature(test)]

extern crate test;
use test::black_box as b;

const BE_U32: u32 = 55u32.to_be();
const LE_U32: u32 = 55u32.to_le();

fn main() {
    assert_eq!(BE_U32, b(55u32).to_be());
    assert_eq!(LE_U32, b(55u32).to_le());

    #[cfg(not(target_arch = "asmjs"))]
    {
        const BE_U128: u128 = 999999u128.to_be();
        const LE_I128: i128 = -999999i128.to_le();
        assert_eq!(BE_U128, b(999999u128).to_be());
        assert_eq!(LE_I128, b(-999999i128).to_le());
    }
}
<commit_msg>Rollup merge of #52876 - cuviper:const-endianness-be, r=kennytm<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(const_int_ops)]
#![feature(test)]

extern crate test;
use test::black_box as b;

const BE_U32: u32 = 55u32.to_be();
const LE_U32: u32 = 55u32.to_le();

fn main() {
    assert_eq!(BE_U32, b(55u32).to_be());
    assert_eq!(LE_U32, b(55u32).to_le());

    #[cfg(not(target_arch = "asmjs"))]
    {
        const BE_U128: u128 = 999999u128.to_be();
        const LE_I128: i128 = (-999999i128).to_le();
        assert_eq!(BE_U128, b(999999u128).to_be());
        assert_eq!(LE_I128, b(-999999i128).to_le());
    }
}
<|endoftext|>


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

mod solvers;

use geom::*;
use geom_ext::*;
use std::f64;

const HIGH_TIME: f64 = 1e50;

//TODO check Hitbox consistency when submitting to Collider for a change (e.g. make sure shape width/height is at least padding)

#[derive(PartialEq, Clone, Debug)]
pub struct Hitbox {
    pub shape: PlacedShape,
    pub vel: PlacedShape,
    pub group: Option<u32>,
    pub interactivity_change: bool,
    pub duration: f64
}

impl Hitbox {
    pub fn new(shape: PlacedShape) -> Hitbox {
        Hitbox {
            shape : shape,
            vel : PlacedShape::zero(shape.kind()),
            group : Some(0),
            interactivity_change : false,
            duration : f64::INFINITY
        }
    }

    fn advance(&mut self, orig_time: f64, new_time: f64) {
        assert!(orig_time <= new_time, "requires orig_time <= new_time");
        let delta = new_time - orig_time;
        if delta != 0.0 {
            self.shape = self.advanced_shape(delta);
            let end_time = orig_time + self.duration;
            assert!(new_time <= end_time, "tried to advance Hitbox beyond its duration");
            self.duration = end_time - new_time;
        }
    }

    fn advanced_shape(&self, time: f64) -> PlacedShape {
        assert!(time <= HIGH_TIME, "requires time <= {}", HIGH_TIME);
        self.shape + self.vel*time
    }

    fn bounding_box(&self) -> PlacedShape {
        self.bounding_box_for(self.duration)
    }

    fn bounding_box_for(&self, duration: f64) -> PlacedShape {
        if self.vel.is_zero() {
            self.shape.as_rect()
        } else {
            let end_shape = self.advanced_shape(duration);
            self.shape.bounding_box(&end_shape)
        }
    }

    fn collide_time(&self, other: &Hitbox) -> f64 {
        solvers::collide_time(self, other)
    }

    fn separate_time(&self, other: &Hitbox, padding: f64) -> f64 {
        solvers::separate_time(self, other, padding)
    }
}
<commit_msg>added tests for collision solvers<commit_after>// Copyright 2016 Matthew D. Michelotti
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

mod solvers;

use geom::*;
use geom_ext::*;
use std::f64;

const HIGH_TIME: f64 = 1e50;

//TODO check Hitbox consistency when submitting to Collider for a change (e.g. make sure shape width/height is at least padding)

#[derive(PartialEq, Clone, Debug)]
pub struct Hitbox {
    pub shape: PlacedShape,
    pub vel: PlacedShape,
    pub group: Option<u32>,
    pub interactivity_change: bool,
    pub duration: f64
}

impl Hitbox {
    pub fn new(shape: PlacedShape) -> Hitbox {
        Hitbox {
            shape : shape,
            vel : PlacedShape::zero(shape.kind()),
            group : Some(0),
            interactivity_change : false,
            duration : f64::INFINITY
        }
    }

    fn advance(&mut self, orig_time: f64, new_time: f64) {
        assert!(orig_time <= new_time, "requires orig_time <= new_time");
        let delta = new_time - orig_time;
        if delta != 0.0 {
            self.shape = self.advanced_shape(delta);
            let end_time = orig_time + self.duration;
            assert!(new_time <= end_time, "tried to advance Hitbox beyond its duration");
            self.duration = end_time - new_time;
        }
    }

    fn advanced_shape(&self, time: f64) -> PlacedShape {
        assert!(time <= HIGH_TIME, "requires time <= {}", HIGH_TIME);
        self.shape + self.vel*time
    }

    fn bounding_box(&self) -> PlacedShape {
        self.bounding_box_for(self.duration)
    }

    fn bounding_box_for(&self, duration: f64) -> PlacedShape {
        if self.vel.is_zero() {
            self.shape.as_rect()
        } else {
            let end_shape = self.advanced_shape(duration);
            self.shape.bounding_box(&end_shape)
        }
    }

    fn collide_time(&self, other: &Hitbox) -> f64 {
        solvers::collide_time(self, other)
    }

    fn separate_time(&self, other: &Hitbox, padding: f64) -> f64 {
        solvers::separate_time(self, other, padding)
    }
}

#[cfg(test)]
mod tests {
    use geom::*;
    use core::*;
    use std::f64;

    #[test]
    fn test_rect_rect_collision() {
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(-11.0, 0.0), Shape::new_rect(2.0, 2.0)));
        a.vel.pos = Vec2::new(2.0, 0.0);
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(12.0, 2.0), Shape::new_rect(2.0, 4.0)));
        b.vel.pos = Vec2::new(-1.0, 0.0);
        b.duration = 100.0;
        assert!(a.collide_time(&b) == 7.0);
        assert!(b.collide_time(&a) == 7.0);
        assert!(a.separate_time(&b, 0.1) == 0.0);
    }

    #[test]
    fn test_circle_circle_collision() {
        let sqrt2 = (2.0f64).sqrt();
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(-0.1*sqrt2, 0.0), Shape::new_circle(2.0)));
        a.vel.pos = Vec2::new(0.1, 0.0);
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(3.0*sqrt2, 0.0), Shape::new_circle(2.0 + sqrt2*0.1)));
        b.vel.pos = Vec2::new(-2.0, 1.0);
        b.vel.shape = Shape::new_circle(-0.1);
        b.duration = 100.0;
        assert!((a.collide_time(&b) - sqrt2).abs() < 1e-7);
        assert!(a.separate_time(&b, 0.1) == 0.0);
    }

    #[test]
    fn test_rect_circle_collision() {
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(-11.0, 0.0), Shape::new_circle(2.0)));
        a.vel.pos = Vec2::new(2.0, 0.0);
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(12.0, 2.0), Shape::new_rect(2.0, 4.0)));
        b.vel.pos = Vec2::new(-1.0, 0.0);
        b.duration = 100.0;
        assert!(a.collide_time(&b) == 7.0);
        assert!(b.collide_time(&a) == 7.0);
        assert!(a.separate_time(&b, 0.1) == 0.0);
    }

    #[test]
    fn test_rect_rect_separation() {
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(0.0, 0.0), Shape::new_rect(6.0, 4.0)));
        a.vel.pos = Vec2::new(1.0, 1.0);
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(1.0, 0.0), Shape::new_rect(4.0, 4.0)));
        b.vel.pos = Vec2::new(0.5, 0.0);
        b.duration = 100.0;
        assert!(a.separate_time(&b, 0.1) == 4.1);
        assert!(b.separate_time(&a, 0.1) == 4.1);
        assert!(a.collide_time(&b) == 0.0);
    }

    #[test]
    fn test_circle_circle_separation() {
        let sqrt2 = (2.0f64).sqrt();
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(2.0, 5.0), Shape::new_circle(2.0)));
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(3.0, 4.0), Shape::new_circle(1.8)));
        b.vel.pos = Vec2::new(-1.0, 1.0);
        b.duration = 100.0;
        assert!(a.separate_time(&b, 0.1) == 1.0 + sqrt2);
        assert!(b.separate_time(&a, 0.1) == 1.0 + sqrt2);
        assert!(a.collide_time(&b) == 0.0);
    }

    #[test]
    fn test_rect_circle_separation() {
        let sqrt2 = (2.0f64).sqrt();
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(4.0, 2.0), Shape::new_rect(4.0, 6.0)));
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(3.0, 4.0), Shape::new_circle(3.8)));
        b.vel.pos = Vec2::new(-1.0, 1.0);
        b.duration = 100.0;
        assert!(a.separate_time(&b, 0.1) == 1.0 + sqrt2);
        assert!(b.separate_time(&a, 0.1) == 1.0 + sqrt2);
        assert!(a.collide_time(&b) == 0.0);
    }

    #[test]
    fn test_no_collision() {
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(-11.0, 0.0), Shape::new_rect(2.0, 2.0)));
        a.vel.pos = Vec2::new(2.0, 0.0);
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(12.0, 2.0), Shape::new_rect(2.0, 4.0)));
        b.vel.pos = Vec2::new(-1.0, 1.0);
        b.duration = 100.0;
        assert!(a.collide_time(&b) == f64::INFINITY);
        assert!(a.separate_time(&b, 0.1) == 0.0);

        b.shape.shape == Shape::new_circle(2.0);
        b.vel.shape == Shape::zero_circle();
        assert!(a.collide_time(&b) == f64::INFINITY);
        assert!(a.separate_time(&b, 0.1) == 0.0);

        a.shape.shape == Shape::new_circle(2.0);
        a.vel.shape == Shape::zero_circle();
        assert!(a.collide_time(&b) == f64::INFINITY);
        assert!(a.separate_time(&b, 0.1) == 0.0);
    }

    #[test]
    fn test_no_separation() {
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(5.0, 1.0), Shape::new_rect(2.0, 2.0)));
        a.vel.pos = Vec2::new(2.0, 1.0);
        a.duration = 100.0;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(5.0, 1.0), Shape::new_rect(2.0, 4.0)));
        b.vel.pos = Vec2::new(2.0, 1.0);
        b.duration = 100.0;
        assert!(a.separate_time(&b, 0.1) == f64::INFINITY);
        assert!(a.collide_time(&b) == 0.0);

        b.shape.shape == Shape::new_circle(2.0);
        b.vel.shape == Shape::zero_circle();
        assert!(a.separate_time(&b, 0.1) == f64::INFINITY);
        assert!(a.collide_time(&b) == 0.0);

        a.shape.shape == Shape::new_circle(2.0);
        a.vel.shape == Shape::zero_circle();
        assert!(a.separate_time(&b, 0.1) == f64::INFINITY);
        assert!(a.collide_time(&b) == 0.0);
    }

    #[test]
    fn test_low_duration() {
        let sqrt2 = (2.0f64).sqrt();
        let mut a = Hitbox::new(PlacedShape::new(Vec2::new(0.0, 0.0), Shape::new_circle(2.0)));
        a.duration = 4.0 - sqrt2 + 0.01;
        let mut b = Hitbox::new(PlacedShape::new(Vec2::new(4.0, 4.0), Shape::new_circle(2.0)));
        b.vel.pos = Vec2::new(-1.0, -1.0);
        b.duration = 4.0 - sqrt2 + 0.01;
        assert!(a.collide_time(&b) == 4.0 - sqrt2);
        a.duration -= 0.02;
        assert!(a.collide_time(&b) == f64::INFINITY);
        b.duration -= 0.02;
        assert!(a.collide_time(&b) == f64::INFINITY);
    }
}
<|endoftext|>


<commit_before>//! AST types representing various typed SQL expressions. Almost all types
//! implement either [`Expression`](trait.Expression.html) or
//! [`AsExpression`](trait.AsExpression.html).
//!
//! The most common expression to work with is a
//! [`Column`](../query_source/trait.Column.html). There are various methods
//! that you can call on these, found in
//! [`expression_methods`](expression_methods/index.html), or operators which
//! you can find in [`ops`](ops/index.html).
//!
//! Any primitive which implements [`ToSql`](../types/trait.ToSql.html) will
//! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
//! used as an argument to any of the methods described here.
#[macro_use]
#[doc(hidden)]
pub mod ops;

#[doc(hidden)]
pub mod aliased;
#[doc(hidden)]
pub mod array_comparison;
#[doc(hidden)]
pub mod bound;
#[doc(hidden)]
pub mod count;
pub mod expression_methods;
pub mod extensions;
#[doc(hidden)]
pub mod functions;
#[doc(hidden)]
pub mod grouped;
pub mod helper_types;
#[doc(hidden)]
pub mod max;
#[doc(hidden)]
pub mod ordering;
#[doc(hidden)]
pub mod predicates;
pub mod sql_literal;

/// Reexports various top level functions and core extensions that are too
/// generic to export by default. This module exists to conveniently glob import
/// in functions where you need them.
pub mod dsl {
    #[doc(inline)]
    pub use super::array_comparison::any;
    #[doc(inline)]
    pub use super::count::{count, count_star};
    #[doc(inline)]
    pub use super::functions::date_and_time::*;
    #[doc(inline)]
    pub use super::max::max;

    pub use super::extensions::*;
}

pub use self::dsl::*;
pub use self::sql_literal::SqlLiteral;

use query_builder::{QueryBuilder, BuildQueryResult};
use types::NativeSqlType;

/// Represents a typed fragment of SQL. Apps should not need to implement this
/// type directly, but it may be common to use this as type boundaries.
/// Libraries should consider using
/// [`infix_predicate!`](../macro.infix_predicate!.html) or
/// [`postfix_predicate!`](../macro.postfix_predicate!.html) instead of
/// implementing this directly.
pub trait Expression {
    type SqlType: NativeSqlType;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult;

    #[doc(hidden)]
    fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        self.to_sql(out)
    }
}

impl<T: Expression + ?Sized> Expression for Box<T> {
    type SqlType = T::SqlType;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_sql(&**self, out)
    }

    fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_insert_sql(&**self, out)
    }
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
    type SqlType = T::SqlType;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_sql(&**self, out)
    }

    fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_insert_sql(&**self, out)
    }
}

/// Describes how a type can be represented as an expression for a given type.
/// These types couldn't just implement [`Expression`](trait.Expression.html)
/// directly, as many things can be used as an expression of multiple types.
/// (`String` for example, can be used as either
/// [`VarChar`](../types/struct.VarChar.html) or
/// [`Text`](../types/struct.Text.html)).
///
/// This trait allows us to use primitives on the right hand side of various
/// expressions. For example `name.eq("Sean")`
pub trait AsExpression<T: NativeSqlType> {
    type Expression: Expression<SqlType=T>;

    fn as_expression(self) -> Self::Expression;
}

impl<T: Expression> AsExpression<T::SqlType> for T {
    type Expression = Self;

    fn as_expression(self) -> Self {
        self
    }
}

/// Indicates that an expression can be selected from a source. The second type
/// argument is optional, but is used to indicate that the right side of a left
/// outer join is nullable, even if it wasn't before.
///
/// Columns will implement this for their table. Certain special types, like
/// `CountStar` and [`Bound`](bound/struct.Bound.html) will implement this for
/// all sources. All other expressions will inherit this from their children.
pub trait SelectableExpression<
    QS,
    Type: NativeSqlType = <Self as Expression>::SqlType,
>: Expression {
}

impl<T: ?Sized, ST, QS> SelectableExpression<QS, ST> for Box<T> where
    T: SelectableExpression<QS, ST>,
    ST: NativeSqlType,
    Box<T>: Expression,
{
}

impl<'a, T: ?Sized, ST, QS> SelectableExpression<QS, ST> for &'a T where
    T: SelectableExpression<QS, ST>,
    ST: NativeSqlType,
    &'a T: Expression,
{
}

/// Marker trait to indicate that an expression does not include any aggregate
/// functions. Used to ensure that aggregate expressions aren't mixed with
/// non-aggregate expressions in a select clause, and that they're never
/// included in a where clause.
pub trait NonAggregate: Expression {
}

impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {
}

impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {
}

/// Helper trait used when boxing expressions. This exists to work around the
/// fact that Rust will not let us use non-core types as bounds on a trait
/// object (you could not return `Box<Expression+NonAggregate>`)
pub trait BoxableExpression<QS, ST: NativeSqlType>: Expression + SelectableExpression<QS, ST> + NonAggregate {
}

impl<QS, T, ST> BoxableExpression<QS, ST> for T where
    ST: NativeSqlType,
    T: Expression + SelectableExpression<QS, ST> + NonAggregate,
{
}
<commit_msg>Don't link to `ops`, which is hidden now<commit_after>//! AST types representing various typed SQL expressions. Almost all types
//! implement either [`Expression`](trait.Expression.html) or
//! [`AsExpression`](trait.AsExpression.html).
//!
//! The most common expression to work with is a
//! [`Column`](../query_source/trait.Column.html). There are various methods
//! that you can call on these, found in
//! [`expression_methods`](expression_methods/index.html). You can also call
//! numeric operators on types which have been passed to
//! [`operator_allowed!`](../macro.operator_allowed.html) or
//! [`numeric_expr!`](../macro.numeric_expr.html).
//!
//! Any primitive which implements [`ToSql`](../types/trait.ToSql.html) will
//! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
//! used as an argument to any of the methods described here.
#[macro_use]
#[doc(hidden)]
pub mod ops;

#[doc(hidden)]
pub mod aliased;
#[doc(hidden)]
pub mod array_comparison;
#[doc(hidden)]
pub mod bound;
#[doc(hidden)]
pub mod count;
pub mod expression_methods;
pub mod extensions;
#[doc(hidden)]
pub mod functions;
#[doc(hidden)]
pub mod grouped;
pub mod helper_types;
#[doc(hidden)]
pub mod max;
#[doc(hidden)]
pub mod ordering;
#[doc(hidden)]
pub mod predicates;
pub mod sql_literal;

/// Reexports various top level functions and core extensions that are too
/// generic to export by default. This module exists to conveniently glob import
/// in functions where you need them.
pub mod dsl {
    #[doc(inline)]
    pub use super::array_comparison::any;
    #[doc(inline)]
    pub use super::count::{count, count_star};
    #[doc(inline)]
    pub use super::functions::date_and_time::*;
    #[doc(inline)]
    pub use super::max::max;

    pub use super::extensions::*;
}

pub use self::dsl::*;
pub use self::sql_literal::SqlLiteral;

use query_builder::{QueryBuilder, BuildQueryResult};
use types::NativeSqlType;

/// Represents a typed fragment of SQL. Apps should not need to implement this
/// type directly, but it may be common to use this as type boundaries.
/// Libraries should consider using
/// [`infix_predicate!`](../macro.infix_predicate!.html) or
/// [`postfix_predicate!`](../macro.postfix_predicate!.html) instead of
/// implementing this directly.
pub trait Expression {
    type SqlType: NativeSqlType;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult;

    #[doc(hidden)]
    fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        self.to_sql(out)
    }
}

impl<T: Expression + ?Sized> Expression for Box<T> {
    type SqlType = T::SqlType;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_sql(&**self, out)
    }

    fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_insert_sql(&**self, out)
    }
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
    type SqlType = T::SqlType;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_sql(&**self, out)
    }

    fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        Expression::to_insert_sql(&**self, out)
    }
}

/// Describes how a type can be represented as an expression for a given type.
/// These types couldn't just implement [`Expression`](trait.Expression.html)
/// directly, as many things can be used as an expression of multiple types.
/// (`String` for example, can be used as either
/// [`VarChar`](../types/struct.VarChar.html) or
/// [`Text`](../types/struct.Text.html)).
///
/// This trait allows us to use primitives on the right hand side of various
/// expressions. For example `name.eq("Sean")`
pub trait AsExpression<T: NativeSqlType> {
    type Expression: Expression<SqlType=T>;

    fn as_expression(self) -> Self::Expression;
}

impl<T: Expression> AsExpression<T::SqlType> for T {
    type Expression = Self;

    fn as_expression(self) -> Self {
        self
    }
}

/// Indicates that an expression can be selected from a source. The second type
/// argument is optional, but is used to indicate that the right side of a left
/// outer join is nullable, even if it wasn't before.
///
/// Columns will implement this for their table. Certain special types, like
/// `CountStar` and [`Bound`](bound/struct.Bound.html) will implement this for
/// all sources. All other expressions will inherit this from their children.
pub trait SelectableExpression<
    QS,
    Type: NativeSqlType = <Self as Expression>::SqlType,
>: Expression {
}

impl<T: ?Sized, ST, QS> SelectableExpression<QS, ST> for Box<T> where
    T: SelectableExpression<QS, ST>,
    ST: NativeSqlType,
    Box<T>: Expression,
{
}

impl<'a, T: ?Sized, ST, QS> SelectableExpression<QS, ST> for &'a T where
    T: SelectableExpression<QS, ST>,
    ST: NativeSqlType,
    &'a T: Expression,
{
}

/// Marker trait to indicate that an expression does not include any aggregate
/// functions. Used to ensure that aggregate expressions aren't mixed with
/// non-aggregate expressions in a select clause, and that they're never
/// included in a where clause.
pub trait NonAggregate: Expression {
}

impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {
}

impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {
}

/// Helper trait used when boxing expressions. This exists to work around the
/// fact that Rust will not let us use non-core types as bounds on a trait
/// object (you could not return `Box<Expression+NonAggregate>`)
pub trait BoxableExpression<QS, ST: NativeSqlType>: Expression + SelectableExpression<QS, ST> + NonAggregate {
}

impl<QS, T, ST> BoxableExpression<QS, ST> for T where
    ST: NativeSqlType,
    T: Expression + SelectableExpression<QS, ST> + NonAggregate,
{
}
<|endoftext|>


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

extern crate toml;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};

static HOSTS: &'static [&'static str] = &[
    "aarch64-unknown-linux-gnu",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "armv7-unknown-linux-gnueabihf",
    "i686-apple-darwin",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-linux-gnu",
    "mips-unknown-linux-gnu",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "x86_64-apple-darwin",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-netbsd",
];

static TARGETS: &'static [&'static str] = &[
    "aarch64-apple-ios",
    "aarch64-linux-android",
    "aarch64-unknown-linux-gnu",
    "arm-linux-androideabi",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "arm-unknown-linux-musleabi",
    "arm-unknown-linux-musleabihf",
    "armv7-apple-ios",
    "armv7-linux-androideabi",
    "armv7-unknown-linux-gnueabihf",
    "armv7-unknown-linux-musleabihf",
    "armv7s-apple-ios",
    "asmjs-unknown-emscripten",
    "i386-apple-ios",
    "i586-pc-windows-msvc",
    "i586-unknown-linux-gnu",
    "i686-apple-darwin",
    "i686-linux-android",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-freebsd",
    "i686-unknown-linux-gnu",
    "i686-unknown-linux-musl",
    "mips-unknown-linux-gnu",
    "mips-unknown-linux-musl",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "mipsel-unknown-linux-musl",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "wasm32-unknown-emscripten",
    "x86_64-apple-darwin",
    "x86_64-apple-ios",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-rumprun-netbsd",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-linux-musl",
    "x86_64-unknown-netbsd",
];

static MINGW: &'static [&'static str] = &[
    "i686-pc-windows-gnu",
    "x86_64-pc-windows-gnu",
];

#[derive(RustcEncodable)]
struct Manifest {
    manifest_version: String,
    date: String,
    pkg: HashMap<String, Package>,
}

#[derive(RustcEncodable)]
struct Package {
    version: String,
    target: HashMap<String, Target>,
}

#[derive(RustcEncodable)]
struct Target {
    available: bool,
    url: Option<String>,
    hash: Option<String>,
    components: Option<Vec<Component>>,
    extensions: Option<Vec<Component>>,
}

#[derive(RustcEncodable)]
struct Component {
    pkg: String,
    target: String,
}

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

struct Builder {
    channel: String,
    input: PathBuf,
    output: PathBuf,
    gpg_passphrase: String,
    digests: HashMap<String, String>,
    s3_address: String,
    date: String,
    rust_version: String,
    cargo_version: String,
}

fn main() {
    let mut args = env::args().skip(1);
    let input = PathBuf::from(args.next().unwrap());
    let output = PathBuf::from(args.next().unwrap());
    let date = args.next().unwrap();
    let channel = args.next().unwrap();
    let s3_address = args.next().unwrap();
    let mut passphrase = String::new();
    t!(io::stdin().read_to_string(&mut passphrase));

    Builder {
        channel: channel,
        input: input,
        output: output,
        gpg_passphrase: passphrase,
        digests: HashMap::new(),
        s3_address: s3_address,
        date: date,
        rust_version: String::new(),
        cargo_version: String::new(),
    }.build();
}

impl Builder {
    fn build(&mut self) {
        self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
        self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");

        self.digest_and_sign();
        let manifest = self.build_manifest();
        let manifest = toml::encode(&manifest).to_string();

        let filename = format!("channel-rust-{}.toml", self.channel);
        self.write_manifest(&manifest, &filename);

        if self.channel != "beta" && self.channel != "nightly" {
            self.write_manifest(&manifest, "channel-rust-stable.toml");
        }
    }

    fn digest_and_sign(&mut self) {
        for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
            let filename = file.file_name().unwrap().to_str().unwrap();
            let digest = self.hash(&file);
            self.sign(&file);
            assert!(self.digests.insert(filename.to_string(), digest).is_none());
        }
    }

    fn build_manifest(&mut self) -> Manifest {
        let mut manifest = Manifest {
            manifest_version: "2".to_string(),
            date: self.date.to_string(),
            pkg: HashMap::new(),
        };

        self.package("rustc", &mut manifest.pkg, HOSTS);
        self.package("cargo", &mut manifest.pkg, HOSTS);
        self.package("rust-mingw", &mut manifest.pkg, MINGW);
        self.package("rust-std", &mut manifest.pkg, TARGETS);
        self.package("rust-docs", &mut manifest.pkg, TARGETS);
        self.package("rust-src", &mut manifest.pkg, &["*"]);

        let mut pkg = Package {
            version: self.cached_version("rust").to_string(),
            target: HashMap::new(),
        };
        for host in HOSTS {
            let filename = self.filename("rust", host);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    pkg.target.insert(host.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    });
                    continue
                }
            };
            let mut components = Vec::new();
            let mut extensions = Vec::new();

            // rustc/rust-std/cargo are all required, and so is rust-mingw if it's
            // available for the target.
            components.extend(vec![
                Component { pkg: "rustc".to_string(), target: host.to_string() },
                Component { pkg: "rust-std".to_string(), target: host.to_string() },
                Component { pkg: "cargo".to_string(), target: host.to_string() },
            ]);
            if host.contains("pc-windows-gnu") {
                components.push(Component {
                    pkg: "rust-mingw".to_string(),
                    target: host.to_string(),
                });
            }

            // Docs, other standard libraries, and the source package are all
            // optional.
            extensions.push(Component {
                pkg: "rust-docs".to_string(),
                target: host.to_string(),
            });
            for target in TARGETS {
                if target != host {
                    extensions.push(Component {
                        pkg: "rust-std".to_string(),
                        target: target.to_string(),
                    });
                }
            }
            extensions.push(Component {
                pkg: "rust-src".to_string(),
                target: "*".to_string(),
            });

            pkg.target.insert(host.to_string(), Target {
                available: true,
                url: Some(self.url("rust", host)),
                hash: Some(to_hex(digest.as_ref())),
                components: Some(components),
                extensions: Some(extensions),
            });
        }
        manifest.pkg.insert("rust".to_string(), pkg);

        return manifest
    }

    fn package(&mut self,
               pkgname: &str,
               dst: &mut HashMap<String, Package>,
               targets: &[&str]) {
        let targets = targets.iter().map(|name| {
            let filename = self.filename(pkgname, name);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    return (name.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    })
                }
            };

            (name.to_string(), Target {
                available: true,
                url: Some(self.url(pkgname, name)),
                hash: Some(digest),
                components: None,
                extensions: None,
            })
        }).collect();

        dst.insert(pkgname.to_string(), Package {
            version: self.cached_version(pkgname).to_string(),
            target: targets,
        });
    }

    fn url(&self, component: &str, target: &str) -> String {
        format!("{}/{}/{}",
                self.s3_address,
                self.date,
                self.filename(component, target))
    }

    fn filename(&self, component: &str, target: &str) -> String {
        if component == "rust-src" {
            format!("rust-src-{}.tar.gz", self.channel)
        } else {
            format!("{}-{}-{}.tar.gz", component, self.channel, target)
        }
    }

    fn cached_version(&self, component: &str) -> &str {
        if component == "cargo" {
            &self.cargo_version
        } else {
            &self.rust_version
        }
    }

    fn version(&self, component: &str, target: &str) -> String {
        let mut cmd = Command::new("tar");
        let filename = self.filename(component, target);
        cmd.arg("xf")
           .arg(self.input.join(&filename))
           .arg(format!("{}/version", filename.replace(".tar.gz", "")))
           .arg("-O");
        let version = t!(cmd.output());
        if !version.status.success() {
            panic!("failed to learn version:\n\n{:?}\n\n{}\n\n{}",
                   cmd,
                   String::from_utf8_lossy(&version.stdout),
                   String::from_utf8_lossy(&version.stderr));
        }
        String::from_utf8_lossy(&version.stdout).trim().to_string()
    }

    fn hash(&self, path: &Path) -> String {
        let sha = t!(Command::new("shasum")
                        .arg("-a").arg("256")
                        .arg(path)
                        .output());
        assert!(sha.status.success());

        let filename = path.file_name().unwrap().to_str().unwrap();
        let sha256 = self.output.join(format!("{}.sha256", filename));
        t!(t!(File::create(&sha256)).write_all(&sha.stdout));

        let stdout = String::from_utf8_lossy(&sha.stdout);
        stdout.split_whitespace().next().unwrap().to_string()
    }

    fn sign(&self, path: &Path) {
        let filename = path.file_name().unwrap().to_str().unwrap();
        let asc = self.output.join(format!("{}.asc", filename));
        println!("signing: {:?}", path);
        let mut cmd = Command::new("gpg");
        cmd.arg("--no-tty")
            .arg("--yes")
            .arg("--passphrase-fd").arg("0")
            .arg("--armor")
            .arg("--output").arg(&asc)
            .arg("--detach-sign").arg(path)
            .stdin(Stdio::piped());
        let mut child = t!(cmd.spawn());
        t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes()));
        assert!(t!(child.wait()).success());
    }

    fn write_manifest(&self, manifest: &str, name: &str) {
        let dst = self.output.join(name);
        t!(t!(File::create(&dst)).write_all(manifest.as_bytes()));
        self.hash(&dst);
        self.sign(&dst);
    }
}

fn to_hex(digest: &[u8]) -> String {
    let mut ret = String::new();
    for byte in digest {
        ret.push(hex((byte & 0xf0) >> 4));
        ret.push(hex(byte & 0xf));
    }
    return ret;

    fn hex(b: u8) -> char {
        match b {
            0...9 => (b'0' + b) as char,
            _ => (b'a' + b - 10) as char,
        }
    }
}
<commit_msg>Don't include directory names in shasums<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate toml;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};

static HOSTS: &'static [&'static str] = &[
    "aarch64-unknown-linux-gnu",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "armv7-unknown-linux-gnueabihf",
    "i686-apple-darwin",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-linux-gnu",
    "mips-unknown-linux-gnu",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "x86_64-apple-darwin",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-netbsd",
];

static TARGETS: &'static [&'static str] = &[
    "aarch64-apple-ios",
    "aarch64-linux-android",
    "aarch64-unknown-linux-gnu",
    "arm-linux-androideabi",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "arm-unknown-linux-musleabi",
    "arm-unknown-linux-musleabihf",
    "armv7-apple-ios",
    "armv7-linux-androideabi",
    "armv7-unknown-linux-gnueabihf",
    "armv7-unknown-linux-musleabihf",
    "armv7s-apple-ios",
    "asmjs-unknown-emscripten",
    "i386-apple-ios",
    "i586-pc-windows-msvc",
    "i586-unknown-linux-gnu",
    "i686-apple-darwin",
    "i686-linux-android",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-freebsd",
    "i686-unknown-linux-gnu",
    "i686-unknown-linux-musl",
    "mips-unknown-linux-gnu",
    "mips-unknown-linux-musl",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "mipsel-unknown-linux-musl",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "wasm32-unknown-emscripten",
    "x86_64-apple-darwin",
    "x86_64-apple-ios",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-rumprun-netbsd",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-linux-musl",
    "x86_64-unknown-netbsd",
];

static MINGW: &'static [&'static str] = &[
    "i686-pc-windows-gnu",
    "x86_64-pc-windows-gnu",
];

#[derive(RustcEncodable)]
struct Manifest {
    manifest_version: String,
    date: String,
    pkg: HashMap<String, Package>,
}

#[derive(RustcEncodable)]
struct Package {
    version: String,
    target: HashMap<String, Target>,
}

#[derive(RustcEncodable)]
struct Target {
    available: bool,
    url: Option<String>,
    hash: Option<String>,
    components: Option<Vec<Component>>,
    extensions: Option<Vec<Component>>,
}

#[derive(RustcEncodable)]
struct Component {
    pkg: String,
    target: String,
}

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

struct Builder {
    channel: String,
    input: PathBuf,
    output: PathBuf,
    gpg_passphrase: String,
    digests: HashMap<String, String>,
    s3_address: String,
    date: String,
    rust_version: String,
    cargo_version: String,
}

fn main() {
    let mut args = env::args().skip(1);
    let input = PathBuf::from(args.next().unwrap());
    let output = PathBuf::from(args.next().unwrap());
    let date = args.next().unwrap();
    let channel = args.next().unwrap();
    let s3_address = args.next().unwrap();
    let mut passphrase = String::new();
    t!(io::stdin().read_to_string(&mut passphrase));

    Builder {
        channel: channel,
        input: input,
        output: output,
        gpg_passphrase: passphrase,
        digests: HashMap::new(),
        s3_address: s3_address,
        date: date,
        rust_version: String::new(),
        cargo_version: String::new(),
    }.build();
}

impl Builder {
    fn build(&mut self) {
        self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
        self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");

        self.digest_and_sign();
        let manifest = self.build_manifest();
        let manifest = toml::encode(&manifest).to_string();

        let filename = format!("channel-rust-{}.toml", self.channel);
        self.write_manifest(&manifest, &filename);

        if self.channel != "beta" && self.channel != "nightly" {
            self.write_manifest(&manifest, "channel-rust-stable.toml");
        }
    }

    fn digest_and_sign(&mut self) {
        for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
            let filename = file.file_name().unwrap().to_str().unwrap();
            let digest = self.hash(&file);
            self.sign(&file);
            assert!(self.digests.insert(filename.to_string(), digest).is_none());
        }
    }

    fn build_manifest(&mut self) -> Manifest {
        let mut manifest = Manifest {
            manifest_version: "2".to_string(),
            date: self.date.to_string(),
            pkg: HashMap::new(),
        };

        self.package("rustc", &mut manifest.pkg, HOSTS);
        self.package("cargo", &mut manifest.pkg, HOSTS);
        self.package("rust-mingw", &mut manifest.pkg, MINGW);
        self.package("rust-std", &mut manifest.pkg, TARGETS);
        self.package("rust-docs", &mut manifest.pkg, TARGETS);
        self.package("rust-src", &mut manifest.pkg, &["*"]);

        let mut pkg = Package {
            version: self.cached_version("rust").to_string(),
            target: HashMap::new(),
        };
        for host in HOSTS {
            let filename = self.filename("rust", host);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    pkg.target.insert(host.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    });
                    continue
                }
            };
            let mut components = Vec::new();
            let mut extensions = Vec::new();

            // rustc/rust-std/cargo are all required, and so is rust-mingw if it's
            // available for the target.
            components.extend(vec![
                Component { pkg: "rustc".to_string(), target: host.to_string() },
                Component { pkg: "rust-std".to_string(), target: host.to_string() },
                Component { pkg: "cargo".to_string(), target: host.to_string() },
            ]);
            if host.contains("pc-windows-gnu") {
                components.push(Component {
                    pkg: "rust-mingw".to_string(),
                    target: host.to_string(),
                });
            }

            // Docs, other standard libraries, and the source package are all
            // optional.
            extensions.push(Component {
                pkg: "rust-docs".to_string(),
                target: host.to_string(),
            });
            for target in TARGETS {
                if target != host {
                    extensions.push(Component {
                        pkg: "rust-std".to_string(),
                        target: target.to_string(),
                    });
                }
            }
            extensions.push(Component {
                pkg: "rust-src".to_string(),
                target: "*".to_string(),
            });

            pkg.target.insert(host.to_string(), Target {
                available: true,
                url: Some(self.url("rust", host)),
                hash: Some(to_hex(digest.as_ref())),
                components: Some(components),
                extensions: Some(extensions),
            });
        }
        manifest.pkg.insert("rust".to_string(), pkg);

        return manifest
    }

    fn package(&mut self,
               pkgname: &str,
               dst: &mut HashMap<String, Package>,
               targets: &[&str]) {
        let targets = targets.iter().map(|name| {
            let filename = self.filename(pkgname, name);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    return (name.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    })
                }
            };

            (name.to_string(), Target {
                available: true,
                url: Some(self.url(pkgname, name)),
                hash: Some(digest),
                components: None,
                extensions: None,
            })
        }).collect();

        dst.insert(pkgname.to_string(), Package {
            version: self.cached_version(pkgname).to_string(),
            target: targets,
        });
    }

    fn url(&self, component: &str, target: &str) -> String {
        format!("{}/{}/{}",
                self.s3_address,
                self.date,
                self.filename(component, target))
    }

    fn filename(&self, component: &str, target: &str) -> String {
        if component == "rust-src" {
            format!("rust-src-{}.tar.gz", self.channel)
        } else {
            format!("{}-{}-{}.tar.gz", component, self.channel, target)
        }
    }

    fn cached_version(&self, component: &str) -> &str {
        if component == "cargo" {
            &self.cargo_version
        } else {
            &self.rust_version
        }
    }

    fn version(&self, component: &str, target: &str) -> String {
        let mut cmd = Command::new("tar");
        let filename = self.filename(component, target);
        cmd.arg("xf")
           .arg(self.input.join(&filename))
           .arg(format!("{}/version", filename.replace(".tar.gz", "")))
           .arg("-O");
        let version = t!(cmd.output());
        if !version.status.success() {
            panic!("failed to learn version:\n\n{:?}\n\n{}\n\n{}",
                   cmd,
                   String::from_utf8_lossy(&version.stdout),
                   String::from_utf8_lossy(&version.stderr));
        }
        String::from_utf8_lossy(&version.stdout).trim().to_string()
    }

    fn hash(&self, path: &Path) -> String {
        let sha = t!(Command::new("shasum")
                        .arg("-a").arg("256")
                        .arg(path.file_name().unwrap())
                        .current_dir(path.parent().unwrap())
                        .output());
        assert!(sha.status.success());

        let filename = path.file_name().unwrap().to_str().unwrap();
        let sha256 = self.output.join(format!("{}.sha256", filename));
        t!(t!(File::create(&sha256)).write_all(&sha.stdout));

        let stdout = String::from_utf8_lossy(&sha.stdout);
        stdout.split_whitespace().next().unwrap().to_string()
    }

    fn sign(&self, path: &Path) {
        let filename = path.file_name().unwrap().to_str().unwrap();
        let asc = self.output.join(format!("{}.asc", filename));
        println!("signing: {:?}", path);
        let mut cmd = Command::new("gpg");
        cmd.arg("--no-tty")
            .arg("--yes")
            .arg("--passphrase-fd").arg("0")
            .arg("--armor")
            .arg("--output").arg(&asc)
            .arg("--detach-sign").arg(path)
            .stdin(Stdio::piped());
        let mut child = t!(cmd.spawn());
        t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes()));
        assert!(t!(child.wait()).success());
    }

    fn write_manifest(&self, manifest: &str, name: &str) {
        let dst = self.output.join(name);
        t!(t!(File::create(&dst)).write_all(manifest.as_bytes()));
        self.hash(&dst);
        self.sign(&dst);
    }
}

fn to_hex(digest: &[u8]) -> String {
    let mut ret = String::new();
    for byte in digest {
        ret.push(hex((byte & 0xf0) >> 4));
        ret.push(hex(byte & 0xf));
    }
    return ret;

    fn hex(b: u8) -> char {
        match b {
            0...9 => (b'0' + b) as char,
            _ => (b'a' + b - 10) as char,
        }
    }
}
<|endoftext|>


<commit_before>fn rotate<T: Clone>(list: &[T], n: i32) -> ~[T] {
    let mut res = ~[];
    if n >= 0 {
        res.push_all(list.slice_from(n as uint));
        res.push_all(list.slice_to(n as uint));
        res
    } else {
        res.push_all(list.slice_from(list.len() + n as uint));
        res.push_all(list.slice_to(list.len() + n as uint));
        res
    }

}

fn main() {
    let list = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    println!("{:?}", rotate(list, 3));
    println!("{:?}", rotate(list, -2));
}

<commit_msg>Cleanup Problem 19<commit_after>// The author of this work hereby waives all claim of copyright (economic and
// moral) in this work and immediately places it in the public domain; it may
// be used, distorted or destroyed in any manner whatsoever without further
// attribution or notice to the creator.

//! Problem 19: Vectors: rotate
//!
//! Rotate a vector N places to the left.
//!
//! Your function could have this signature:
//! `fn rotate<T>(vec: ~[T], n: int) -> ~[T]`

fn rotate<T: Clone>(vec: ~[T], n: int) -> ~[T] {
    let mut res = ~[];
    let l = vec.len() as int;
    let r: uint = (((n % l) + l) % l) as uint;

    res.push_all(vec.slice_from(r));
    res.push_all(vec.slice_to(r));
    res
}

#[test]
fn rotate_left() {
    let vec = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    assert_eq!(rotate(vec, 3), ~['d', 'e', 'f', 'g', 'h', 'a', 'b', 'c']);
}

#[test]
fn rotate_right() {
    let vec = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    assert_eq!(rotate(vec, -2), ~['g', 'h', 'a', 'b', 'c', 'd', 'e', 'f']);
}

#[test]
fn rotate_mod() {
    let vec = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    assert_eq!(rotate(vec, -10), ~['g', 'h', 'a', 'b', 'c', 'd', 'e', 'f']);
}

<|endoftext|>


<commit_before>use memory::FrameAllocator;
use memory::paging::{ENTRY_COUNT, Page};
use memory::paging::entry::*;
use core::ops::{Index, IndexMut};
use core::marker::PhantomData;

pub const P4: *mut Table<Level4> = 0xffffffff_fffff000 as *mut _;

pub struct Table<L: TableLevel> {
    entries: [Entry; ENTRY_COUNT],
    _phantom: PhantomData<L>,
}

impl<L> Table<L> where L: TableLevel
{
    pub fn zero(&mut self) {
        for entry in self.entries.iter_mut() {
            entry.set_unused();
        }
    }
}

impl<L> Table<L> where L: HierachicalLevel
{
    pub fn next_table(&self, index: usize) -> Option<&Table<L::NextLevel>> {
        self.next_table_address(index).map(|t| unsafe { &*(t as *const _) })
    }

    pub fn next_table_mut(&mut self, index: usize) -> Option<&mut Table<L::NextLevel>> {
        self.next_table_address(index).map(|t| unsafe { &mut *(t as *mut _) })
    }

    pub fn next_table_create<A>(&mut self,
                                index: usize,
                                allocator: &mut A)
                                -> &mut Table<L::NextLevel>
        where A: FrameAllocator
    {
        if let None = self.next_table_address(index) {
            assert!(!self.entries[index].flags().contains(HUGE_PAGE),
                    "mapping code does not support huge pages");
            let frame = allocator.allocate_frame().expect("no frames available");
            self.entries[index].set(frame, PRESENT | WRITABLE);
            self.next_table_mut(index).unwrap().zero();
        }
        self.next_table_mut(index).unwrap()
    }

    fn next_table_address(&self, index: usize) -> Option<usize> {
        let entry_flags = self[index].flags();
        if entry_flags.contains(PRESENT) && !entry_flags.contains(HUGE_PAGE) {
            let table_page = Page::containing_address(self as *const _ as usize);
            assert!(table_page.number >= 0o_777_000_000_000);
            let next_table_page = Page {
                number: ((table_page.number << 9) & 0o_777_777_777_777) | index,
            };
            Some(next_table_page.start_address())
        } else {
            None
        }
    }
}

impl<L> Index<usize> for Table<L> where L: TableLevel
{
    type Output = Entry;

    fn index(&self, index: usize) -> &Entry {
        &self.entries[index]
    }
}

impl<L> IndexMut<usize> for Table<L> where L: TableLevel
{
    fn index_mut(&mut self, index: usize) -> &mut Entry {
        &mut self.entries[index]
    }
}

pub trait TableLevel {}

pub enum Level4 {}
#[allow(dead_code)]
enum Level3 {}
#[allow(dead_code)]
enum Level2 {}
#[allow(dead_code)]
enum Level1 {}

impl TableLevel for Level4 {}
impl TableLevel for Level3 {}
impl TableLevel for Level2 {}
impl TableLevel for Level1 {}

trait HierachicalLevel: TableLevel {
    type NextLevel: TableLevel;
}

impl HierachicalLevel for Level4 {
    type NextLevel = Level3;
}

impl HierachicalLevel for Level3 {
    type NextLevel = Level2;
}

impl HierachicalLevel for Level2 {
    type NextLevel = Level1;
}
<commit_msg>Reorganize imports<commit_after>use memory::FrameAllocator;
use memory::paging::ENTRY_COUNT;
use memory::paging::entry::*;
use core::ops::{Index, IndexMut};
use core::marker::PhantomData;

pub const P4: *mut Table<Level4> = 0xffffffff_fffff000 as *mut _;

pub struct Table<L: TableLevel> {
    entries: [Entry; ENTRY_COUNT],
    _phantom: PhantomData<L>,
}

impl<L> Table<L> where L: TableLevel
{
    pub fn zero(&mut self) {
        for entry in self.entries.iter_mut() {
            entry.set_unused();
        }
    }
}

impl<L> Table<L> where L: HierachicalLevel
{
    pub fn next_table(&self, index: usize) -> Option<&Table<L::NextLevel>> {
        self.next_table_address(index).map(|t| unsafe { &*(t as *const _) })
    }

    pub fn next_table_mut(&mut self, index: usize) -> Option<&mut Table<L::NextLevel>> {
        self.next_table_address(index).map(|t| unsafe { &mut *(t as *mut _) })
    }

    pub fn next_table_create<A>(&mut self,
                                index: usize,
                                allocator: &mut A)
                                -> &mut Table<L::NextLevel>
        where A: FrameAllocator
    {
        if let None = self.next_table_address(index) {
            assert!(!self.entries[index].flags().contains(HUGE_PAGE),
                    "mapping code does not support huge pages");
            let frame = allocator.allocate_frame().expect("no frames available");
            self.entries[index].set(frame, PRESENT | WRITABLE);
            self.next_table_mut(index).unwrap().zero();
        }
        self.next_table_mut(index).unwrap()
    }

    fn next_table_address(&self, index: usize) -> Option<usize> {
        use memory::paging::Page;

        let entry_flags = self[index].flags();
        if entry_flags.contains(PRESENT) && !entry_flags.contains(HUGE_PAGE) {
            let table_page = Page::containing_address(self as *const _ as usize);
            assert!(table_page.number >= 0o_777_000_000_000);
            let next_table_page = Page {
                number: ((table_page.number << 9) & 0o_777_777_777_777) | index,
            };
            Some(next_table_page.start_address())
        } else {
            None
        }
    }
}

impl<L> Index<usize> for Table<L> where L: TableLevel
{
    type Output = Entry;

    fn index(&self, index: usize) -> &Entry {
        &self.entries[index]
    }
}

impl<L> IndexMut<usize> for Table<L> where L: TableLevel
{
    fn index_mut(&mut self, index: usize) -> &mut Entry {
        &mut self.entries[index]
    }
}

pub trait TableLevel {}

pub enum Level4 {}
#[allow(dead_code)]
enum Level3 {}
#[allow(dead_code)]
enum Level2 {}
#[allow(dead_code)]
enum Level1 {}

impl TableLevel for Level4 {}
impl TableLevel for Level3 {}
impl TableLevel for Level2 {}
impl TableLevel for Level1 {}

trait HierachicalLevel: TableLevel {
    type NextLevel: TableLevel;
}

impl HierachicalLevel for Level4 {
    type NextLevel = Level3;
}

impl HierachicalLevel for Level3 {
    type NextLevel = Level2;
}

impl HierachicalLevel for Level2 {
    type NextLevel = Level1;
}
<|endoftext|>


<commit_before>//   Copyright 2017 Justin Noah <justinnoah@gmail.com>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

use rusqlite::{Connection, SQLITE_OPEN_READ_WRITE, SQLITE_OPEN_CREATE,
               SQLITE_OPEN_FULL_MUTEX, SQLITE_OPEN_URI};

/// Using a slightly modified set of rusqlite open flags, open and return a connection
pub fn db_connect(path: &String) -> Connection {
    let flags = { SQLITE_OPEN_READ_WRITE | SQLITE_OPEN_CREATE |
                  SQLITE_OPEN_FULL_MUTEX | SQLITE_OPEN_URI };

    debug!("Connection to {:?} has been established", path);
    Connection::open_with_flags(path, flags).unwrap()
}

// Initialize the database
pub fn db_init(conn: &Connection) {
    conn.execute("
        CREATE TABLE IF NOT EXISTS torrent (
            info_hash   TEXT,
            ip          TEXT,
            port        INTEGER,
            peer_id     TEXT,
            remaining   INTEGER,
            last_active INTEGER,
            PRIMARY KEY (info_hash, ip, port, peer_id)
        );",
        &[]
    ).unwrap();
}

pub fn db_prune(conn: &Connection) {
    conn.execute(
        "DELETE FROM torrent
        WHERE (strftime('%s','now') - last_active) > 1860;",
        &[]
    ).unwrap();
}
<commit_msg>temporary file handle to in memory db<commit_after>//   Copyright 2017 Justin Noah <justinnoah@gmail.com>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

use std::env::temp_dir;

use rusqlite::{Connection, SQLITE_OPEN_READ_WRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_MEMORY,
               SQLITE_OPEN_FULL_MUTEX, SQLITE_OPEN_URI, SQLITE_OPEN_SHARED_CACHE};

/// Using a slightly modified set of rusqlite open flags, open and return a connection
pub fn db_connect(path: &String) -> Connection {
    let flags = { SQLITE_OPEN_READ_WRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY |
                  SQLITE_OPEN_FULL_MUTEX | SQLITE_OPEN_URI |
                  SQLITE_OPEN_SHARED_CACHE };

    let mut db_handle = temp_dir();
    db_handle.push("tblb");
    Connection::open_with_flags(db_handle, flags).unwrap()
}

// Initialize the database
pub fn db_init(conn: &Connection) {
    conn.execute("
        CREATE TABLE IF NOT EXISTS torrent (
            info_hash   TEXT,
            ip          TEXT,
            port        INTEGER,
            peer_id     TEXT,
            remaining   INTEGER,
            last_active INTEGER,
            PRIMARY KEY (info_hash, ip, port, peer_id)
        );",
        &[]
    ).unwrap();
}

pub fn db_prune(conn: &Connection) {
    conn.execute(
        "DELETE FROM torrent
        WHERE (strftime('%s','now') - last_active) > 1860;",
        &[]
    ).unwrap();
}
<|endoftext|>


<commit_before>#![feature(type_ascription)]

extern crate env_logger;
extern crate clap;
extern crate serde;
extern crate serde_json;
extern crate time;
extern crate rand;
#[macro_use]
extern crate log;
extern crate colored;

extern crate iron;
extern crate params;
extern crate hyper;
extern crate router;

extern crate exonum;
extern crate blockchain_explorer;
extern crate timestamping;

use std::env;
use std::io;
use std::path::Path;
use std::thread;
use std::collections::BTreeMap;

use iron::prelude::*;
use iron::status;
use iron::mime::{Mime, TopLevel, SubLevel};
use params::{Params, Value};
use router::Router;

use serde_json::value::ToJson;
use clap::{Arg, App, SubCommand};
use log::{LogRecord, LogLevel};
use env_logger::LogBuilder;
use colored::*;

use exonum::node::{Node, Configuration, TxSender, NodeChannel};
use exonum::storage::{Database, MemoryDB, LevelDB, LevelDBOptions, Map};
use exonum::storage::Error as StorageError;
use exonum::crypto::{gen_keypair, HexValue, FromHexError, Hash};
use exonum::config::ConfigFile;
use exonum::node::config::GenesisConfig;
use exonum::events::Error as EventsError;
use exonum::blockchain::Blockchain;

use timestamping::{TimestampingBlockchain, TimestampTx, Content};

pub type TimestampTxSender<B> = TxSender<B, NodeChannel<B>>;

#[derive(Clone)]
pub struct TimestampingApi<D: Database> {
    blockchain: TimestampingBlockchain<D>,
    channel: TimestampTxSender<TimestampingBlockchain<D>>,
}

#[derive(Debug)]
enum ApiError {
    Storage(StorageError),
    Events(EventsError),
    FromHex(FromHexError),
    Io(std::io::Error),
    FileNotFound(Hash),
    FileToBig,
    FileExists(Hash),
    IncorrectRequest,
}

impl std::fmt::Display for ApiError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl std::error::Error for ApiError {
    fn description(&self) -> &str {
        match *self {
            ApiError::Storage(_) => "Storage",
            ApiError::Events(_) => "Events",
            ApiError::FromHex(_) => "FromHex",
            ApiError::Io(_) => "Io",
            ApiError::FileNotFound(_) => "FileNotFound",
            ApiError::FileToBig => "FileToBig",
            ApiError::FileExists(_) => "FileExists",
            ApiError::IncorrectRequest => "IncorrectRequest",
        }
    }
}

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

impl From<StorageError> for ApiError {
    fn from(e: StorageError) -> ApiError {
        ApiError::Storage(e)
    }
}

impl From<EventsError> for ApiError {
    fn from(e: EventsError) -> ApiError {
        ApiError::Events(e)
    }
}

impl From<FromHexError> for ApiError {
    fn from(e: FromHexError) -> ApiError {
        ApiError::FromHex(e)
    }
}

impl From<ApiError> for IronError {
    fn from(e: ApiError) -> IronError {
        use std::error::Error;

        let mut body = BTreeMap::new();
        body.insert("type", e.description().into());
        let code = match e {
            ApiError::FileExists(hash) => {
                body.insert("hash", hash.to_hex());
                status::Conflict
            }
            ApiError::FileNotFound(hash) => {
                body.insert("hash", hash.to_hex());
                status::Conflict
            }
            _ => status::Conflict,
        };
        IronError {
            error: Box::new(e),
            response: Response::with((code, body.to_json().to_string())),
        }
    }
}

impl<D> TimestampingApi<D>
    where D: Database
{
    fn put_content(&self, hash_str: &str, description: &str) -> Result<TimestampTx, ApiError> {
        let hash = Hash::from_hex(hash_str)?;
        if self.blockchain.view().contents().get(&hash)?.is_some() {
            return Err(ApiError::FileExists(hash));
        }
        // Create transaction
        let (_, dummy_key) = gen_keypair();
        let ts = time::now().to_timespec();
        let tx = TimestampTx::new(&description,
                                  ts,
                                  &hash,
                                  &dummy_key);
        self.channel.send(tx.clone())?;
        Ok(tx)
    }

    fn get_content(&self, hash_str: &str) -> Result<Content, ApiError> {
        let hash = Hash::from_hex(hash_str)?;
        let view = self.blockchain.view();
        view.contents()
            .get(&hash)?
            .ok_or_else(|| ApiError::FileNotFound(hash))
    }
}

fn run_node<D: Database>(blockchain: TimestampingBlockchain<D>,
                         node_cfg: Configuration,
                         port: Option<u16>) {
    if let Some(port) = port {
        let mut node = Node::new(blockchain.clone(), node_cfg.clone());
        let channel = node.channel();

        let api_thread = thread::spawn(move || {
            let timestamping_api = TimestampingApi {
                channel: channel.clone(),
                blockchain: blockchain.clone(),
            };

            let mut router = Router::new();

            // Receive a message by POST and play it back.
            let api = timestamping_api.clone();
            let put_content = move |req: &mut Request| -> IronResult<Response> {
                let map = req.get_ref::<Params>().unwrap();

                let find_str = |path: &[&str]| -> Result<String, ApiError> {
                    let value = map.find(path);
                    if let Some(&Value::String(ref s)) = value {
                        Ok(s.to_string())
                    } else {
                        Err(ApiError::IncorrectRequest)
                    }
                };

                let hash = find_str(&["hash"])?;
                let description = find_str(&["description"])
                    .unwrap_or("".to_string());

                let tx = api.put_content(&hash, &description)?;
                let content_type = Mime(TopLevel::Application, SubLevel::Json, Vec::new());
                let response =
                    Response::with((content_type, status::Ok, tx.to_json().to_string()));
                return Ok(response);
            };

            let api = timestamping_api.clone();
            let get_content = move |req: &mut Request| -> IronResult<Response> {
                let ref hash = req.extensions.get::<Router>().unwrap().find("hash").unwrap();
                let content = api.get_content(&hash)?;

                let content_type = Mime(TopLevel::Application, SubLevel::Json, Vec::new());
                let response =
                    Response::with((content_type, status::Ok, content.to_json().to_string()));
                Ok(response)
            };

            router.get("/timestamping/content/:hash", get_content, "get_content");
            router.post("/timestamping/content", put_content, "put_content");

            let host = format!("localhost:{}", port);
            Iron::new(router).http(host.as_str()).unwrap();
        });

        node.run().unwrap();
        api_thread.join().unwrap();
    } else {
        Node::new(blockchain, node_cfg).run().unwrap();
    }
}

fn main() {
    let format = |record: &LogRecord| {
        let now = time::now_utc();
        let level = match record.level() {
            LogLevel::Error => "ERROR".red(),
            LogLevel::Warn => "WARN".yellow(),
            LogLevel::Info => "INFO".green(),
            LogLevel::Debug => "DEBUG".cyan(),
            LogLevel::Trace => "TRACE".white(),
        };
        format!("{} - [ {} ] - {}",
                now.asctime().to_string().bold(),
                level,
                record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init().unwrap();

    let app = App::new("Simple timestamping demo program")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Aleksey S. <aleksei.sidorov@xdev.re>")
        .about("Demo timestamping validator node")
        .arg(Arg::with_name("CONFIG")
            .short("c")
            .long("config")
            .value_name("CONFIG_PATH")
            .help("Sets a node config file")
            .required(true)
            .takes_value(true))
        .subcommand(SubCommand::with_name("generate")
            .about("Generates default configuration file")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("START_PORT")
                .short("p")
                .long("port")
                .value_name("START_PORT")
                .help("Port for first validator")
                .takes_value(true))
            .arg(Arg::with_name("COUNT")
                .help("Validators count")
                .required(true)
                .index(1)))
        .subcommand(SubCommand::with_name("run")
            .about("Run demo node with the given validator id")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("LEVELDB_PATH")
                .short("d")
                .long("leveldb-path")
                .value_name("LEVELDB_PATH")
                .help("Use leveldb database with the given path")
                .takes_value(true))
            .arg(Arg::with_name("HTTP_PORT")
                .short("p")
                .long("port")
                .value_name("HTTP_PORT")
                .help("Run http server on given port")
                .takes_value(true))
            .arg(Arg::with_name("PEERS")
                .long("known-peers")
                .value_name("PEERS")
                .help("Comma separated list of known validator ids")
                .takes_value(true))
            .arg(Arg::with_name("VALIDATOR")
                .help("Sets a validator id")
                .required(true)
                .index(1)));

    let matches = app.get_matches();
    let path = Path::new(matches.value_of("CONFIG").unwrap());
    match matches.subcommand() {
        ("generate", Some(matches)) => {
            let count: u8 = matches.value_of("COUNT").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("START_PORT").map(|x| x.parse().unwrap());
            let cfg = GenesisConfig::gen(count, port);
            ConfigFile::save(&cfg, &path).unwrap();
            println!("The configuration was successfully written to file {:?}",
                     path);
        }
        ("run", Some(matches)) => {
            let cfg: GenesisConfig = ConfigFile::load(path).unwrap();
            let idx: usize = matches.value_of("VALIDATOR").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("HTTP_PORT").map(|x| x.parse().unwrap());
            let peers = match matches.value_of("PEERS") {
                Some(string) => {
                    string.split(" ")
                        .map(|x| -> usize { x.parse().unwrap() })
                        .map(|x| cfg.validators[x].address)
                        .collect()
                }
                None => {
                    cfg.validators
                        .iter()
                        .map(|v| v.address)
                        .collect()
                }
            };
            let node_cfg = cfg.gen_node_configuration(idx, peers);
            match matches.value_of("LEVELDB_PATH") {
                Some(ref db_path) => {
                    println!("Using levedb storage with path: {}", db_path);
                    let mut options = LevelDBOptions::new();
                    options.create_if_missing = true;
                    let leveldb = LevelDB::new(&Path::new(db_path), options).unwrap();

                    let blockchain = TimestampingBlockchain { db: leveldb };
                    run_node(blockchain, node_cfg, port);
                }
                None => {
                    println!("Using memorydb storage");

                    let blockchain = TimestampingBlockchain { db: MemoryDB::new() };
                    run_node(blockchain, node_cfg, port);
                }
            };
        }
        _ => {
            unreachable!("Wrong subcommand");
        }
    }
}
<commit_msg>Reduce string copying<commit_after>#![feature(type_ascription)]

extern crate env_logger;
extern crate clap;
extern crate serde;
extern crate serde_json;
extern crate time;
extern crate rand;
#[macro_use]
extern crate log;
extern crate colored;

extern crate iron;
extern crate params;
extern crate hyper;
extern crate router;

extern crate exonum;
extern crate blockchain_explorer;
extern crate timestamping;

use std::env;
use std::io;
use std::path::Path;
use std::thread;
use std::collections::BTreeMap;

use iron::prelude::*;
use iron::status;
use iron::mime::{Mime, TopLevel, SubLevel};
use params::{Params, Value};
use router::Router;

use serde_json::value::ToJson;
use clap::{Arg, App, SubCommand};
use log::{LogRecord, LogLevel};
use env_logger::LogBuilder;
use colored::*;

use exonum::node::{Node, Configuration, TxSender, NodeChannel};
use exonum::storage::{Database, MemoryDB, LevelDB, LevelDBOptions, Map};
use exonum::storage::Error as StorageError;
use exonum::crypto::{gen_keypair, HexValue, FromHexError, Hash};
use exonum::config::ConfigFile;
use exonum::node::config::GenesisConfig;
use exonum::events::Error as EventsError;
use exonum::blockchain::Blockchain;

use timestamping::{TimestampingBlockchain, TimestampTx, Content};

pub type TimestampTxSender<B> = TxSender<B, NodeChannel<B>>;

#[derive(Clone)]
pub struct TimestampingApi<D: Database> {
    blockchain: TimestampingBlockchain<D>,
    channel: TimestampTxSender<TimestampingBlockchain<D>>,
}

#[derive(Debug)]
enum ApiError {
    Storage(StorageError),
    Events(EventsError),
    FromHex(FromHexError),
    Io(std::io::Error),
    FileNotFound(Hash),
    FileToBig,
    FileExists(Hash),
    IncorrectRequest,
}

impl std::fmt::Display for ApiError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl std::error::Error for ApiError {
    fn description(&self) -> &str {
        match *self {
            ApiError::Storage(_) => "Storage",
            ApiError::Events(_) => "Events",
            ApiError::FromHex(_) => "FromHex",
            ApiError::Io(_) => "Io",
            ApiError::FileNotFound(_) => "FileNotFound",
            ApiError::FileToBig => "FileToBig",
            ApiError::FileExists(_) => "FileExists",
            ApiError::IncorrectRequest => "IncorrectRequest",
        }
    }
}

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

impl From<StorageError> for ApiError {
    fn from(e: StorageError) -> ApiError {
        ApiError::Storage(e)
    }
}

impl From<EventsError> for ApiError {
    fn from(e: EventsError) -> ApiError {
        ApiError::Events(e)
    }
}

impl From<FromHexError> for ApiError {
    fn from(e: FromHexError) -> ApiError {
        ApiError::FromHex(e)
    }
}

impl From<ApiError> for IronError {
    fn from(e: ApiError) -> IronError {
        use std::error::Error;

        let mut body = BTreeMap::new();
        body.insert("type", e.description().into());
        let code = match e {
            ApiError::FileExists(hash) => {
                body.insert("hash", hash.to_hex());
                status::Conflict
            }
            ApiError::FileNotFound(hash) => {
                body.insert("hash", hash.to_hex());
                status::Conflict
            }
            _ => status::Conflict,
        };
        IronError {
            error: Box::new(e),
            response: Response::with((code, body.to_json().to_string())),
        }
    }
}

impl<D> TimestampingApi<D>
    where D: Database
{
    fn put_content(&self, hash_str: &str, description: &str) -> Result<TimestampTx, ApiError> {
        let hash = Hash::from_hex(hash_str)?;
        if self.blockchain.view().contents().get(&hash)?.is_some() {
            return Err(ApiError::FileExists(hash));
        }
        // Create transaction
        let (_, dummy_key) = gen_keypair();
        let ts = time::now().to_timespec();
        let tx = TimestampTx::new(&description, ts, &hash, &dummy_key);
        self.channel.send(tx.clone())?;
        Ok(tx)
    }

    fn get_content(&self, hash_str: &str) -> Result<Content, ApiError> {
        let hash = Hash::from_hex(hash_str)?;
        let view = self.blockchain.view();
        view.contents()
            .get(&hash)?
            .ok_or_else(|| ApiError::FileNotFound(hash))
    }
}

fn run_node<D: Database>(blockchain: TimestampingBlockchain<D>,
                         node_cfg: Configuration,
                         port: Option<u16>) {
    if let Some(port) = port {
        let mut node = Node::new(blockchain.clone(), node_cfg.clone());
        let channel = node.channel();

        let api_thread = thread::spawn(move || {
            let timestamping_api = TimestampingApi {
                channel: channel.clone(),
                blockchain: blockchain.clone(),
            };

            let mut router = Router::new();

            // Receive a message by POST and play it back.
            let api = timestamping_api.clone();
            let put_content = move |req: &mut Request| -> IronResult<Response> {
                let map = req.get_ref::<Params>().unwrap();

                fn find_str<'a>(map: &'a params::Map, path: &[&str]) -> Result<&'a str, ApiError> {
                    let value = map.find(path);
                    if let Some(&Value::String(ref s)) = value {
                        Ok(s)
                    } else {
                        Err(ApiError::IncorrectRequest)
                    }
                };

                let hash = find_str(map, &["hash"])?;
                let description = find_str(map, &["description"]).unwrap_or("");

                let tx = api.put_content(hash, description)?;
                let content_type = Mime(TopLevel::Application, SubLevel::Json, Vec::new());
                let response = Response::with((content_type, status::Ok, tx.to_json().to_string()));
                return Ok(response);
            };

            let api = timestamping_api.clone();
            let get_content = move |req: &mut Request| -> IronResult<Response> {
                let ref hash = req.extensions.get::<Router>().unwrap().find("hash").unwrap();
                let content = api.get_content(&hash)?;

                let content_type = Mime(TopLevel::Application, SubLevel::Json, Vec::new());
                let response =
                    Response::with((content_type, status::Ok, content.to_json().to_string()));
                Ok(response)
            };

            router.get("/timestamping/content/:hash", get_content, "get_content");
            router.post("/timestamping/content", put_content, "put_content");

            let host = format!("localhost:{}", port);
            Iron::new(router).http(host.as_str()).unwrap();
        });

        node.run().unwrap();
        api_thread.join().unwrap();
    } else {
        Node::new(blockchain, node_cfg).run().unwrap();
    }
}

fn main() {
    let format = |record: &LogRecord| {
        let now = time::now_utc();
        let level = match record.level() {
            LogLevel::Error => "ERROR".red(),
            LogLevel::Warn => "WARN".yellow(),
            LogLevel::Info => "INFO".green(),
            LogLevel::Debug => "DEBUG".cyan(),
            LogLevel::Trace => "TRACE".white(),
        };
        format!("{} - [ {} ] - {}",
                now.asctime().to_string().bold(),
                level,
                record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init().unwrap();

    let app = App::new("Simple timestamping demo program")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Aleksey S. <aleksei.sidorov@xdev.re>")
        .about("Demo timestamping validator node")
        .arg(Arg::with_name("CONFIG")
            .short("c")
            .long("config")
            .value_name("CONFIG_PATH")
            .help("Sets a node config file")
            .required(true)
            .takes_value(true))
        .subcommand(SubCommand::with_name("generate")
            .about("Generates default configuration file")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("START_PORT")
                .short("p")
                .long("port")
                .value_name("START_PORT")
                .help("Port for first validator")
                .takes_value(true))
            .arg(Arg::with_name("COUNT")
                .help("Validators count")
                .required(true)
                .index(1)))
        .subcommand(SubCommand::with_name("run")
            .about("Run demo node with the given validator id")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("LEVELDB_PATH")
                .short("d")
                .long("leveldb-path")
                .value_name("LEVELDB_PATH")
                .help("Use leveldb database with the given path")
                .takes_value(true))
            .arg(Arg::with_name("HTTP_PORT")
                .short("p")
                .long("port")
                .value_name("HTTP_PORT")
                .help("Run http server on given port")
                .takes_value(true))
            .arg(Arg::with_name("PEERS")
                .long("known-peers")
                .value_name("PEERS")
                .help("Comma separated list of known validator ids")
                .takes_value(true))
            .arg(Arg::with_name("VALIDATOR")
                .help("Sets a validator id")
                .required(true)
                .index(1)));

    let matches = app.get_matches();
    let path = Path::new(matches.value_of("CONFIG").unwrap());
    match matches.subcommand() {
        ("generate", Some(matches)) => {
            let count: u8 = matches.value_of("COUNT").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("START_PORT").map(|x| x.parse().unwrap());
            let cfg = GenesisConfig::gen(count, port);
            ConfigFile::save(&cfg, &path).unwrap();
            println!("The configuration was successfully written to file {:?}",
                     path);
        }
        ("run", Some(matches)) => {
            let cfg: GenesisConfig = ConfigFile::load(path).unwrap();
            let idx: usize = matches.value_of("VALIDATOR").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("HTTP_PORT").map(|x| x.parse().unwrap());
            let peers = match matches.value_of("PEERS") {
                Some(string) => {
                    string.split(" ")
                        .map(|x| -> usize { x.parse().unwrap() })
                        .map(|x| cfg.validators[x].address)
                        .collect()
                }
                None => {
                    cfg.validators
                        .iter()
                        .map(|v| v.address)
                        .collect()
                }
            };
            let node_cfg = cfg.gen_node_configuration(idx, peers);
            match matches.value_of("LEVELDB_PATH") {
                Some(ref db_path) => {
                    println!("Using levedb storage with path: {}", db_path);
                    let mut options = LevelDBOptions::new();
                    options.create_if_missing = true;
                    let leveldb = LevelDB::new(&Path::new(db_path), options).unwrap();

                    let blockchain = TimestampingBlockchain { db: leveldb };
                    run_node(blockchain, node_cfg, port);
                }
                None => {
                    println!("Using memorydb storage");

                    let blockchain = TimestampingBlockchain { db: MemoryDB::new() };
                    run_node(blockchain, node_cfg, port);
                }
            };
        }
        _ => {
            unreachable!("Wrong subcommand");
        }
    }
}
<|endoftext|>