<commit_before>extern crate env_logger;
extern crate hyper;
extern crate hubcaps;

use hyper::Client;
use hubcaps::{Credentials, Github};
use std::env;

fn main() {
    env_logger::init().unwrap();
    match env::var("GITHUB_TOKEN").ok() {
        Some(token) => {
            let client = Client::new();
            let github = Github::new(format!("hubcaps/{}", env!("CARGO_PKG_VERSION")),
                                     &client,
                                     Credentials::Token(token));
            for gist in github.gists().list().unwrap() {
                println!("{:#?}", gist)
            }
        }
        _ => println!("example missing GITHUB_TOKEN"),
    }
}
<commit_msg>fix broken example<commit_after>extern crate env_logger;
extern crate hyper;
extern crate hubcaps;

use hyper::Client;
use hubcaps::{Credentials, Github};
use std::env;

fn main() {
    env_logger::init().unwrap();
    match env::var("GITHUB_TOKEN").ok() {
        Some(token) => {
            let client = Client::new();
            let github = Github::new(format!("hubcaps/{}", env!("CARGO_PKG_VERSION")),
                                     &client,
                                     Credentials::Token(token));
            for gist in github.gists().list(&Default::default()).unwrap() {
                println!("{:#?}", gist)
            }
        }
        _ => println!("example missing GITHUB_TOKEN"),
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]

#[plugin]
#[no_link]
extern crate json_macros;

extern crate "rustc-serialize" as rustc_serialize;

use rustc_serialize::Encodable;
use rustc_serialize::json::{self, PrettyEncoder};

#[derive(RustcDecodable, RustcEncodable)]
struct Photo {
    url: String,
    dimensions: (u32, u32),
}

#[derive(RustcDecodable, RustcEncodable)]
struct User {
    name: String,
    post_count: u32,
    likes_burgers: bool,
    avatar: Option<Photo>,
}

fn main() {
    println!("24 days of Rust - json (day 6)");
    println!("{:?}", json::encode(&42));
    println!("{:?}", json::encode(&vec!["to", "be", "or", "not", "to", "be"]));
    println!("{:?}", json::encode(&Some(true)));
    let user = User {
        name: "Zbyszek".to_string(),
        post_count: 100u32,
        likes_burgers: true,
        avatar: Some(Photo {
            url: "http://lorempixel.com/160/160/".to_string(),
            dimensions: (160u32, 160u32),
        }),
    };
    println!("{:?}", json::encode(&user));
    let mut buffer: Vec<u8> = Vec::new();
    {
        let mut encoder = PrettyEncoder::new(&mut buffer);
        user.encode(&mut encoder).ok().expect("JSON encode error");
    }
    let encoded = String::from_utf8(buffer).unwrap();
    println!("{}", encoded);
    let incoming_request = "{\"name\":\"John\",\"post_count\":2,\"likes_burgers\":false,\"avatar\":null}";
    let decoded: User = json::decode(incoming_request).unwrap();
    println!("My name is {} and I {} burgers",
        decoded.name, if decoded.likes_burgers { "love" } else { "don't like" });
    assert!(decoded.avatar.is_none());
    let new_request = "{\"id\":64,\"title\":\"24days\",\"stats\":{\"pageviews\":1500}}";
    if let Ok(request_json) = json::Json::from_str(new_request) {
        if let Some(ref stats) = request_json.find("stats") {
            if let Some(ref pageviews) = stats.find("pageviews") {
                println!("Pageviews: {}", pageviews);
            }
        }
    }
    let config = json!({
        "hostname": "localhost",
        "port": 6543,
        "allowed_methods": ["get", "post"],
        "limits": {
            "bandwidth": (500 * 16),
            "rate": null
        }
    });
    println!("Configuration: {}", config);
    println!("Bandwidth: {}", config.search("bandwidth").unwrap());
}
<commit_msg>Fixed day 6 (PrettyEncoder merged with Encoder).<commit_after>#![feature(plugin)]

#[plugin]
#[no_link]
extern crate json_macros;

extern crate "rustc-serialize" as rustc_serialize;

use rustc_serialize::Encodable;
use rustc_serialize::json::{self, Encoder};

#[derive(RustcDecodable, RustcEncodable)]
struct Photo {
    url: String,
    dimensions: (u32, u32),
}

#[derive(RustcDecodable, RustcEncodable)]
struct User {
    name: String,
    post_count: u32,
    likes_burgers: bool,
    avatar: Option<Photo>,
}

fn main() {
    println!("24 days of Rust - json (day 6)");
    println!("{:?}", json::encode(&42));
    println!("{:?}", json::encode(&vec!["to", "be", "or", "not", "to", "be"]));
    println!("{:?}", json::encode(&Some(true)));
    let user = User {
        name: "Zbyszek".to_string(),
        post_count: 100u32,
        likes_burgers: true,
        avatar: Some(Photo {
            url: "http://lorempixel.com/160/160/".to_string(),
            dimensions: (160u32, 160u32),
        }),
    };
    println!("{:?}", json::encode(&user));
    let mut buffer: Vec<u8> = Vec::new();
    {
        let mut encoder = Encoder::new_pretty(&mut buffer);
        user.encode(&mut encoder).ok().expect("JSON encode error");
    }
    let encoded = String::from_utf8(buffer).unwrap();
    println!("{}", encoded);
    let incoming_request = "{\"name\":\"John\",\"post_count\":2,\"likes_burgers\":false,\"avatar\":null}";
    let decoded: User = json::decode(incoming_request).unwrap();
    println!("My name is {} and I {} burgers",
        decoded.name, if decoded.likes_burgers { "love" } else { "don't like" });
    assert!(decoded.avatar.is_none());
    let new_request = "{\"id\":64,\"title\":\"24days\",\"stats\":{\"pageviews\":1500}}";
    if let Ok(request_json) = json::Json::from_str(new_request) {
        if let Some(ref stats) = request_json.find("stats") {
            if let Some(ref pageviews) = stats.find("pageviews") {
                println!("Pageviews: {}", pageviews);
            }
        }
    }
    let config = json!({
        "hostname": "localhost",
        "port": 6543,
        "allowed_methods": ["get", "post"],
        "limits": {
            "bandwidth": (500 * 16),
            "rate": null
        }
    });
    println!("Configuration: {}", config);
    println!("Bandwidth: {}", config.search("bandwidth").unwrap());
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate itertools;

use std::iter::AdditiveIterator;
use itertools::Itertools;

fn main() {
    println!("24 days of Rust - itertools (day 7)");
    let mut words = "hello supercalifragilisticexpialidocious programmer".words();
    words.apply(|word| println!("{} is {} characters long", word, word.len()));
    let even = range(1, 10u).map(|x| x * 2);
    let odd = range(1, 5u).map(|x| x * 2 + 1);
    println!("{}", even.interleave(odd).collect::<Vec<_>>());
    let it = range(1, 10u);
    println!("{}", it.intersperse(15u).collect::<Vec<_>>());
    let numbers = range(1, 4u);
    let chars = vec!['a', 'b', 'c'];
    for (i, c) in iproduct!(numbers, chars.iter()) {
        println!("{}: {}", i, c);
    }
    let log = "GET / 4096\nGET /home/ 16301\nPOST /home/ 49\nGET / 4096\n";
    let lines = log.lines();
    let rows = icompr!(line.words().collect::<Vec<_>>() for line in lines);
    let bytes = icompr!(row[2] for row in rows if row[0] != "POST");
    let total = icompr!(b.parse::<uint>().unwrap() for b in bytes).sum();
    println!("Total GET throughput: {} bytes", total);
}
<commit_msg>Disabled icompr! macro example.<commit_after>#[macro_use]
extern crate itertools;

use std::iter::AdditiveIterator;
use itertools::Itertools;

fn main() {
    println!("24 days of Rust - itertools (day 7)");
    let mut words = "hello supercalifragilisticexpialidocious programmer".words();
    words.apply(|word| println!("{} is {} characters long", word, word.len()));
    let even = range(1, 10u).map(|x| x * 2);
    let odd = range(1, 5u).map(|x| x * 2 + 1);
    println!("{:?}", even.interleave(odd).collect::<Vec<_>>());
    let it = range(1, 10u);
    println!("{:?}", it.intersperse(15u).collect::<Vec<_>>());
    let numbers = range(1, 4u);
    let chars = vec!['a', 'b', 'c'];
    for (i, c) in iproduct!(numbers, chars.iter()) {
        println!("{}: {}", i, c);
    }
    /*
    let log = "GET / 4096\nGET /home/ 16301\nPOST /home/ 49\nGET / 4096\n";
    let lines = log.lines();
    let rows = icompr!(line.words().collect::<Vec<_>>() for line in lines);
    let bytes = icompr!(row[2] for row in rows if row[0] != "POST");
    let total = icompr!(b.parse::<uint>().unwrap() for b in bytes).sum();
    println!("Total GET throughput: {} bytes", total);
    */
}
<|endoftext|>


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

//! A cell that with volatile setter and getter.

use core::marker::{Copy, InvariantType};
use core::intrinsics::{volatile_load, volatile_store};

/// This structure is used to represent a hardware register.
/// It is mostly used by the ioreg family of macros.
pub struct VolatileCell<T> {
  value: T,
  invariant: InvariantType<T>,
}

impl<T: Copy> Copy for VolatileCell<T> {}

impl<T> VolatileCell<T> {
  /// Create a cell with initial value.
  pub fn new(value: T) -> VolatileCell<T> {
    VolatileCell {
      value: value,
      invariant: InvariantType::<T>,
    }
  }

  /// Get register value.
  #[inline]
  pub fn get(&self) -> T {
    unsafe {
      volatile_load(&self.value)
    }
  }

  /// Set register value.
  #[inline]
  pub fn set(&self, value: T) {
    unsafe {
      volatile_store(&self.value as *const T as *mut T, value)
    }
  }
}
<commit_msg>volatile cell - invariant type removal , deprecated<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A cell that with volatile setter and getter.

use core::marker::{Copy, InvariantType};
use core::intrinsics::{volatile_load, volatile_store};

/// This structure is used to represent a hardware register.
/// It is mostly used by the ioreg family of macros.
pub struct VolatileCell<T> {
  value: T,
}

impl<T: Copy> Copy for VolatileCell<T> {}

impl<T> VolatileCell<T> {
  /// Create a cell with initial value.
  pub fn new(value: T) -> VolatileCell<T> {
    VolatileCell {
      value: value,
    }
  }

  /// Get register value.
  #[inline]
  pub fn get(&self) -> T {
    unsafe {
      volatile_load(&self.value)
    }
  }

  /// Set register value.
  #[inline]
  pub fn set(&self, value: T) {
    unsafe {
      volatile_store(&self.value as *const T as *mut T, value)
    }
  }
}
<|endoftext|>


<commit_before>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use super::convert::*;
use super::error::*;
use super::layout::*;

use lapack_traits::LapackScalar;
pub use lapack_traits::UPLO;

pub trait Eigh<EigVal, EigVec> {
    fn eigh(self, UPLO) -> Result<(EigVal, EigVec)>;
}

impl<A, S, Se> Eigh<ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>> for ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

impl<'a, A, S, Se, So> Eigh<ArrayBase<Se, Ix1>, ArrayBase<So, Ix2>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Copy,
          S: Data<Elem = A>,
          Se: DataOwned<Elem = A::Real>,
          So: DataOwned<Elem = A> + DataMut
{
    fn eigh(self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<So, Ix2>)> {
        let mut a = replicate(self);
        let s = A::eigh(true, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), a))
    }
}

impl<'a, A, S, Se> Eigh<ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>> for &'a mut ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Se: DataOwned<Elem = A::Real>
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

pub trait EigValsh<EigVal> {
    fn eigvalsh(self, UPLO) -> Result<EigVal>;
}

impl<A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(mut self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let s = A::eigh(false, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

impl<'a, A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for &'a ArrayBase<S, Ix2>
where
    A: LapackScalar + Copy,
    S: Data<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let mut a = self.to_owned();
        let s = A::eigh(false, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

impl<'a, A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for &'a mut ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(mut self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}
<commit_msg>Add moc code<commit_after>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;
use num_traits::Float;

use super::convert::*;
use super::error::*;
use super::layout::*;

use lapack_traits::LapackScalar;
pub use lapack_traits::UPLO;

pub trait Eigh<EigVal, EigVec> {
    fn eigh(self, UPLO) -> Result<(EigVal, EigVec)>;
}

impl<A, S, Se> Eigh<ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>> for ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

impl<'a, A, S, Se, So> Eigh<ArrayBase<Se, Ix1>, ArrayBase<So, Ix2>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Copy,
          S: Data<Elem = A>,
          Se: DataOwned<Elem = A::Real>,
          So: DataOwned<Elem = A> + DataMut
{
    fn eigh(self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, ArrayBase<So, Ix2>)> {
        let mut a = replicate(self);
        let s = A::eigh(true, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), a))
    }
}

impl<'a, A, S, Se> Eigh<ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>> for &'a mut ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Se: DataOwned<Elem = A::Real>
{
    fn eigh(mut self, uplo: UPLO) -> Result<(ArrayBase<Se, Ix1>, &'a mut ArrayBase<S, Ix2>)> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok((ArrayBase::from_vec(s), self))
    }
}

pub trait EigValsh<EigVal> {
    fn eigvalsh(self, UPLO) -> Result<EigVal>;
}

impl<A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(mut self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let s = A::eigh(false, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

impl<'a, A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for &'a ArrayBase<S, Ix2>
where
    A: LapackScalar + Copy,
    S: Data<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let mut a = self.to_owned();
        let s = A::eigh(false, a.square_layout()?, uplo, a.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

impl<'a, A, S, Se> EigValsh<ArrayBase<Se, Ix1>> for &'a mut ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Se: DataOwned<Elem = A::Real>,
{
    fn eigvalsh(mut self, uplo: UPLO) -> Result<ArrayBase<Se, Ix1>> {
        let s = A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)?;
        Ok(ArrayBase::from_vec(s))
    }
}

pub trait SymmetricSqrt<Output> {
    fn ssqrt(self, UPLO) -> Result<Output>;
}

impl<A, S> SymmetricSqrt<ArrayBase<S, Ix2>> for ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
{
    fn ssqrt(self, uplo: UPLO) -> Result<ArrayBase<S, Ix2>> {
        let (mut e, v): (Array1<A::Real>, _) = self.eigh(uplo)?;
        for val in e.iter_mut() {
            *val = val.sqrt();
        }
        // TODO incomplete implement!
        Ok(v)
    }
}
<|endoftext|>


<commit_before>use std::collections::VecMap;
use ast::Value;
use session::{ValueID};

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct DataMode {
    pub down: bool,
    pub up: bool,
}

#[derive(PartialEq, Debug, Clone)]
pub enum ConcatElem {
    Elem(Expr),
    Slice(Expr, usize),
}

#[derive(PartialEq, Debug, Clone)]
pub enum Expr {
    Ignored,
    Const(Value),
    Variable(ValueID),

    Range(f64, f64),

    Flip(Box<Expr>, Box<Expr>),
    Choose(Box<Expr>, Vec<(Value, Value)>),
    Concat(Vec<ConcatElem>),
    BinaryConst(Box<Expr>, BinOp, f64),
}

impl Expr {
    pub fn each_var(&self, f: &mut FnMut(ValueID)) {
        match *self {
            Expr::Variable(id) => f(id),
            Expr::Ignored | Expr::Const(..) | Expr::Range(..) => (),
            Expr::Choose(ref i, _)
            | Expr::BinaryConst(ref i, _, _) => i.each_var(f),
            Expr::Flip(ref a, ref b) => {
                a.each_var(f);
                b.each_var(f);
            }
            Expr::Concat(ref l) => {
                for src in l.iter() {
                    match *src {
                        ConcatElem::Elem(ref i) | ConcatElem::Slice(ref i, _) => i.each_var(f),
                    }
                }
            }
        }
    }

    pub fn eval_down(&self, state: &State) -> Value {
        match *self {
            Expr::Ignored | Expr::Range(..) => panic!("{:?} can't be down-evaluated", self),
            Expr::Variable(id) => state.get(id).clone(),
            Expr::Const(ref v) => v.clone(),

            Expr::Flip(ref d, _) => d.eval_down(state),
            Expr::Choose(ref e, ref c) => eval_choose(&e.eval_down(state), c).unwrap(),

            Expr::Concat(_) => unimplemented!(),

            Expr::BinaryConst(ref e, op, c) => {
                let v = match e.eval_down(state) {
                    Value::Number(v) => v,
                    _ => panic!("Math on non-number value"),
                };
                Value::Number(op.eval(v, c))
            }
        }
    }

    pub fn mode(&self) -> DataMode {
        match *self {
            Expr::Ignored => DataMode { down: false, up: false },
            Expr::Range(..) => DataMode { down: false, up: true },
            Expr::Variable(..) => DataMode { down: true, up: true }, //TODO: results after inference?
            Expr::Const(..) => DataMode { down: true, up: true },
            Expr::Flip(ref d, ref u) => {
                let d = d.mode();
                let u = u.mode();
                DataMode { down: d.down, up: u.up }
            },
            Expr::Choose(ref e, _) => e.mode(),
            Expr::Concat(_) => unimplemented!(),
            Expr::BinaryConst(ref e, _, _) => e.mode()
        }
    }

    pub fn exists_down(&self) -> bool { self.mode().down }
    pub fn exists_up(&self) -> bool { self.mode().up }

    pub fn limit_direction(self, target: DataMode) -> Expr {
        let mode = self.mode();

        if !target.down && !target.up {
            Expr::Ignored
        } else if !target.up && mode.up {
            Expr::Flip(box self, box Expr::Ignored)
        } else if !target.down && mode.down {
            Expr::Flip(box Expr::Ignored, box self)
        } else {
            self
        }
    }

    pub fn eval_up(&self, state: &mut State, v: Value) -> bool {
        match *self {
            Expr::Ignored => true,
            Expr::Range(a, b) => match v {
                Value::Number(n) => n>a && n<b,
                _ => false,
            },
            Expr::Variable(id) => state.set(id, v),
            Expr::Const(ref p) => &v == p,

            Expr::Flip(_, ref u) => u.eval_up(state, v),
            Expr::Choose(ref e, ref choices) => {
                let r = choices.iter()
                    .find(|& &(_, ref b)|{ value_match(b, &v) })
                    .map(|&(ref a, _)| a.clone());

                if let Some(v) = r {
                    e.eval_up(state, v)
                } else {
                    false
                }
            },
            Expr::Concat(_) => unimplemented!(),

            Expr::BinaryConst(ref e, op, c) => {
                let n = match v {
                    Value::Number(n) => n,
                    _ => return false,
                };
                e.eval_up(state, Value::Number(op.invert().eval(n, c)))
            }
        }
    }
}

/// Binary numeric operators
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum BinOp {
    Add,       // a + b
    Sub,       // a - b
    SubSwap,   // b - a

    Mul,       // a * b
    Div,       // a / b
    DivSwap,   // b / a
}

impl BinOp {
    /// a `op` b
    pub fn eval(&self, a: f64, b: f64) -> f64 {
        match *self {
            BinOp::Add     => a + b,
            BinOp::Sub     => a - b,
            BinOp::SubSwap => b - a,
            BinOp::Mul     => a * b,
            BinOp::Div     => a / b,
            BinOp::DivSwap => b / a,
        }
    }

    /// (a `op` b) == (b `op.swap()` a)
    pub fn swap(&self) -> BinOp {
        match *self {
            BinOp::Add     => BinOp::Add,
            BinOp::Sub     => BinOp::SubSwap,
            BinOp::SubSwap => BinOp::Sub,
            BinOp::Mul     => BinOp::Mul,
            BinOp::Div     => BinOp::DivSwap,
            BinOp::DivSwap => BinOp::Div,
        }
    }

    /// ((a `op` b) `op.invert()` b) == a
    pub fn invert(&self) -> BinOp {
        match *self {
            BinOp::Add     => BinOp::Sub,
            BinOp::Sub     => BinOp::Add,
            BinOp::SubSwap => BinOp::SubSwap,
            BinOp::Mul     => BinOp::Div,
            BinOp::Div     => BinOp::Mul,
            BinOp::DivSwap => BinOp::DivSwap,
        }
    }
}

pub struct State {
    registers: VecMap<Value>,
}

impl State {
    pub fn new() -> State {
        let mut s = State {
            registers: VecMap::new()
        };
        // TODO: shouldn't be necessary (we currently read from 0 on ignores)
        s.registers.insert(0, ::ast::Value::Symbol("invalid".to_string()));
        s
    }

    pub fn get(&self, reg: ValueID) -> &Value {
        debug!("get {}: {:?}", reg, self.registers.get(&reg));
        &self.registers[reg]
    }

    pub fn set(&mut self, reg: ValueID, v: Value) -> bool {
        debug!("set {}: {:?}", reg, v);
        // TODO: should assert the register is not already set, once exec doesn't run things twice
        self.registers.insert(reg, v);
        true
    }

    pub fn get_var(&self, v: ::session::Var) -> &Value {
        self.get(v.id)
    }

    fn get_num(&self, reg: ValueID) -> f64 {
        match *self.get(reg) {
            Value::Number(v) => v,
            Value::Integer(v) => v as f64, // TODO: explicit conversion?
            _ => panic!(),
        }
    }

    fn get_vec<'s>(&'s self, reg: ValueID) -> &'s [Value] {
        match *self.get(reg) {
            Value::Vector(ref v) => v,
            _ => panic!(),
        }
    }

}

fn value_match(a: &Value, b: &Value) -> bool {
    a == b
}

pub fn eval_choose(v: &Value, choices: &[(Value, Value)]) -> Option<Value> {
    choices.iter().find(|& &(ref a, _)|{ value_match(a, v) }).map(|&(_, ref b)| b.clone())
}
<commit_msg>Add minimal tests to expr module<commit_after>use std::collections::VecMap;
use ast::Value;
use session::{ValueID};

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct DataMode {
    pub down: bool,
    pub up: bool,
}

#[derive(PartialEq, Debug, Clone)]
pub enum ConcatElem {
    Elem(Expr),
    Slice(Expr, usize),
}

#[derive(PartialEq, Debug, Clone)]
pub enum Expr {
    Ignored,
    Const(Value),
    Variable(ValueID),

    Range(f64, f64),

    Flip(Box<Expr>, Box<Expr>),
    Choose(Box<Expr>, Vec<(Value, Value)>),
    Concat(Vec<ConcatElem>),
    BinaryConst(Box<Expr>, BinOp, f64),
}

impl Expr {
    pub fn each_var(&self, f: &mut FnMut(ValueID)) {
        match *self {
            Expr::Variable(id) => f(id),
            Expr::Ignored | Expr::Const(..) | Expr::Range(..) => (),
            Expr::Choose(ref i, _)
            | Expr::BinaryConst(ref i, _, _) => i.each_var(f),
            Expr::Flip(ref a, ref b) => {
                a.each_var(f);
                b.each_var(f);
            }
            Expr::Concat(ref l) => {
                for src in l.iter() {
                    match *src {
                        ConcatElem::Elem(ref i) | ConcatElem::Slice(ref i, _) => i.each_var(f),
                    }
                }
            }
        }
    }

    pub fn eval_down(&self, state: &State) -> Value {
        match *self {
            Expr::Ignored | Expr::Range(..) => panic!("{:?} can't be down-evaluated", self),
            Expr::Variable(id) => state.get(id).clone(),
            Expr::Const(ref v) => v.clone(),

            Expr::Flip(ref d, _) => d.eval_down(state),
            Expr::Choose(ref e, ref c) => eval_choose(&e.eval_down(state), c).unwrap(),

            Expr::Concat(_) => unimplemented!(),

            Expr::BinaryConst(ref e, op, c) => {
                let v = match e.eval_down(state) {
                    Value::Number(v) => v,
                    _ => panic!("Math on non-number value"),
                };
                Value::Number(op.eval(v, c))
            }
        }
    }

    pub fn mode(&self) -> DataMode {
        match *self {
            Expr::Ignored => DataMode { down: false, up: false },
            Expr::Range(..) => DataMode { down: false, up: true },
            Expr::Variable(..) => DataMode { down: true, up: true }, //TODO: results after inference?
            Expr::Const(..) => DataMode { down: true, up: true },
            Expr::Flip(ref d, ref u) => {
                let d = d.mode();
                let u = u.mode();
                DataMode { down: d.down, up: u.up }
            },
            Expr::Choose(ref e, _) => e.mode(),
            Expr::Concat(_) => unimplemented!(),
            Expr::BinaryConst(ref e, _, _) => e.mode()
        }
    }

    pub fn exists_down(&self) -> bool { self.mode().down }
    pub fn exists_up(&self) -> bool { self.mode().up }

    pub fn limit_direction(self, target: DataMode) -> Expr {
        let mode = self.mode();

        if !target.down && !target.up {
            Expr::Ignored
        } else if !target.up && mode.up {
            Expr::Flip(box self, box Expr::Ignored)
        } else if !target.down && mode.down {
            Expr::Flip(box Expr::Ignored, box self)
        } else {
            self
        }
    }

    pub fn eval_up(&self, state: &mut State, v: Value) -> bool {
        match *self {
            Expr::Ignored => true,
            Expr::Range(a, b) => match v {
                Value::Number(n) => n>a && n<b,
                _ => false,
            },
            Expr::Variable(id) => state.set(id, v),
            Expr::Const(ref p) => &v == p,

            Expr::Flip(_, ref u) => u.eval_up(state, v),
            Expr::Choose(ref e, ref choices) => {
                let r = choices.iter()
                    .find(|& &(_, ref b)|{ value_match(b, &v) })
                    .map(|&(ref a, _)| a.clone());

                if let Some(v) = r {
                    e.eval_up(state, v)
                } else {
                    false
                }
            },
            Expr::Concat(_) => unimplemented!(),

            Expr::BinaryConst(ref e, op, c) => {
                let n = match v {
                    Value::Number(n) => n,
                    _ => return false,
                };
                e.eval_up(state, Value::Number(op.invert().eval(n, c)))
            }
        }
    }
}

/// Binary numeric operators
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum BinOp {
    Add,       // a + b
    Sub,       // a - b
    SubSwap,   // b - a

    Mul,       // a * b
    Div,       // a / b
    DivSwap,   // b / a
}

impl BinOp {
    /// a `op` b
    pub fn eval(&self, a: f64, b: f64) -> f64 {
        match *self {
            BinOp::Add     => a + b,
            BinOp::Sub     => a - b,
            BinOp::SubSwap => b - a,
            BinOp::Mul     => a * b,
            BinOp::Div     => a / b,
            BinOp::DivSwap => b / a,
        }
    }

    /// (a `op` b) == (b `op.swap()` a)
    pub fn swap(&self) -> BinOp {
        match *self {
            BinOp::Add     => BinOp::Add,
            BinOp::Sub     => BinOp::SubSwap,
            BinOp::SubSwap => BinOp::Sub,
            BinOp::Mul     => BinOp::Mul,
            BinOp::Div     => BinOp::DivSwap,
            BinOp::DivSwap => BinOp::Div,
        }
    }

    /// ((a `op` b) `op.invert()` b) == a
    pub fn invert(&self) -> BinOp {
        match *self {
            BinOp::Add     => BinOp::Sub,
            BinOp::Sub     => BinOp::Add,
            BinOp::SubSwap => BinOp::SubSwap,
            BinOp::Mul     => BinOp::Div,
            BinOp::Div     => BinOp::Mul,
            BinOp::DivSwap => BinOp::DivSwap,
        }
    }
}

pub struct State {
    registers: VecMap<Value>,
}

impl State {
    pub fn new() -> State {
        let mut s = State {
            registers: VecMap::new()
        };
        // TODO: shouldn't be necessary (we currently read from 0 on ignores)
        s.registers.insert(0, ::ast::Value::Symbol("invalid".to_string()));
        s
    }

    pub fn get(&self, reg: ValueID) -> &Value {
        debug!("get {}: {:?}", reg, self.registers.get(&reg));
        &self.registers[reg]
    }

    pub fn set(&mut self, reg: ValueID, v: Value) -> bool {
        debug!("set {}: {:?}", reg, v);
        // TODO: should assert the register is not already set, once exec doesn't run things twice
        self.registers.insert(reg, v);
        true
    }

    pub fn get_var(&self, v: ::session::Var) -> &Value {
        self.get(v.id)
    }

    fn get_num(&self, reg: ValueID) -> f64 {
        match *self.get(reg) {
            Value::Number(v) => v,
            Value::Integer(v) => v as f64, // TODO: explicit conversion?
            _ => panic!(),
        }
    }

    fn get_vec<'s>(&'s self, reg: ValueID) -> &'s [Value] {
        match *self.get(reg) {
            Value::Vector(ref v) => v,
            _ => panic!(),
        }
    }

}

fn value_match(a: &Value, b: &Value) -> bool {
    a == b
}

pub fn eval_choose(v: &Value, choices: &[(Value, Value)]) -> Option<Value> {
    choices.iter().find(|& &(ref a, _)|{ value_match(a, v) }).map(|&(_, ref b)| b.clone())
}

#[test]
fn exprs() {
    use session::Session;
    use grammar;
    use resolve;
    let sess = Session::new();
    let scope = resolve::scope::Scope::new();
    let mut state = State::new();

    fn expr<'s>(sess: &'s Session<'s>, scope: &resolve::scope::Scope<'s>, e: &str) -> Expr {
        resolve::expr::value(sess, scope, &grammar::valexpr(e).unwrap())
    }

    let two = expr(&sess, &scope, "2");
    assert_eq!(two.mode(), DataMode { up: true, down: true });
    assert_eq!(two.eval_down(&state), Value::Number(2.0));

    let ignore = expr(&sess, &scope, "_");
    assert_eq!(ignore.mode(), DataMode { up: false, down: false });

    let down = expr(&sess, &scope, "<: #h");
    assert_eq!(down.mode(), DataMode { up: false, down: true });
}
<|endoftext|>


<commit_before>use std::sync::Arc;
use super::attestation_record::validation::{
    validate_attestation,
    AttestationValidationError,
};
use super::attestation_record::{
    AttestationRecord,
    split_one_attestation,
    split_all_attestations,
    AttestationSplitError,
};
use super::{
    AttesterMap,
    ProposerMap,
};
use super::SszBlock;
use super::db::{
    ClientDB,
    DBError,
};
use super::db::stores::{
    BlockStore,
    PoWChainStore,
    ValidatorStore,
};
use super::ssz::{
    Decodable,
    DecodeError,
};
use super::utils::types::Hash256;

#[derive(Debug, PartialEq)]
pub enum BlockStatus {
    NewBlock,
    KnownBlock,
}

#[derive(Debug, PartialEq)]
pub enum SszBlockValidationError {
    FutureSlot,
    UnknownPoWChainRef,
    BadAttestationSsz,
    AttestationValidationError(AttestationValidationError),
    InvalidAttestation,
    NoProposerSignature,
    BadProposerMap,
    DatabaseError(String),
}

/// Validate some SszBlock. An SszBlock varies from a Block in that is a read-only structure
/// that reads directly from encoded SSZ.
///
/// The reason to validate an SzzBlock is to avoid decoding it in its entirety if there is
/// a suspicion that the block might be invalid. Such a suspicion should be applied to
/// all blocks coming from the network.
///
/// Of course, this function will only be more efficient if a block is already serialized.
/// Serializing a complete block and then validating with this function will be less
/// efficient than just validating the original block.
///
/// This function will determine if the block is new, already known or invalid (either
/// intrinsically or due to some application error.)
#[allow(dead_code)]
pub fn validate_ssz_block<T>(b: &SszBlock,
                             expected_slot: u64,
                             cycle_length: u8,
                             last_justified_slot: u64,
                             parent_hashes: Arc<Vec<Hash256>>,
                             proposer_map: Arc<ProposerMap>,
                             attester_map: Arc<AttesterMap>,
                             block_store: Arc<BlockStore<T>>,
                             validator_store: Arc<ValidatorStore<T>>,
                             pow_store: Arc<PoWChainStore<T>>)
    -> Result<BlockStatus, SszBlockValidationError>
    where T: ClientDB + Sized
{
    /*
     * If this block is already known, return immediately.
     */
    if block_store.block_exists(&b.block_hash())? {
        return Ok(BlockStatus::KnownBlock);
    }

    /*
     * Copy the block slot (will be used multiple times)
     */
    let block_slot = b.slot_number();

    /*
     * If the block slot corresponds to a slot in the future (according to the local time),
     * drop it.
     */
    if block_slot > expected_slot {
        return Err(SszBlockValidationError::FutureSlot);
    }

    /*
     * If the PoW chain hash is not known to us, drop it.
     *
     * We only accept blocks that reference a known PoW hash.
     *
     * Note: it is not clear what a "known" PoW chain ref is. Likely,
     * it means "sufficienty deep in the canonical PoW chain".
     */
    if pow_store.block_hash_exists(b.pow_chain_ref())? == false {
        return Err(SszBlockValidationError::UnknownPoWChainRef);
    }

    /*
     * Store a reference to the serialized attestations from the block.
     */
    let attestations_ssz = &b.attestations();

    /*
     * Get a slice of the first serialized attestation (the 0th) and decode it into
     * a full AttestationRecord object.
     */
    let (first_attestation_ssz, next_index) = split_one_attestation(
        &attestations_ssz,
        0)?;
    let (first_attestation, _) = AttestationRecord::ssz_decode(
        &first_attestation_ssz, 0)?;

    /*
     * Validate this first attestation.
     *
     * It is a requirement that the block proposer for this slot
     * must have signed the 0th attestation record.
     */
    let attestation_voters = validate_attestation(
        &first_attestation,
        block_slot,
        cycle_length,
        last_justified_slot,
        parent_hashes.clone(),
        block_store.clone(),
        validator_store.clone(),
        attester_map.clone())?;

    /*
     * If the set of voters is None, the attestation was invalid.
     */
    let attestation_voters = attestation_voters
        .ok_or(SszBlockValidationError::InvalidAttestation)?;

    /*
     * Read the proposer from the map of slot -> validator index.
     */
    let proposer = proposer_map.get(&block_slot)
        .ok_or(SszBlockValidationError::BadProposerMap)?;

    /*
     * If the proposer for this slot was not a voter, reject the block.
     */
    if !attestation_voters.contains(&proposer) {
        return Err(SszBlockValidationError::NoProposerSignature);
    }

    /*
     * Split the remaining attestations into a vector of slices, each containing
     * a single serialized attestation record.
     */
    let other_attestations = split_all_attestations(attestations_ssz,
                                                    next_index)?;

    /*
     * Verify each other AttestationRecord.
     *
     * TODO: make this parallelized.
     */
    for attestation in other_attestations {
        let (a, _) = AttestationRecord::ssz_decode(&attestation, 0)?;
        let attestation_voters = validate_attestation(
            &a,
            block_slot,
            cycle_length,
            last_justified_slot,
            parent_hashes.clone(),
            block_store.clone(),
            validator_store.clone(),
            attester_map.clone())?;
        if attestation_voters.is_none() {
            return Err(SszBlockValidationError::InvalidAttestation);
        }
    }

    /*
     * If we have reached this point, the block is a new valid block that is worthy of
     * processing.
     */
    Ok(BlockStatus::NewBlock)
}

impl From<DBError> for SszBlockValidationError {
    fn from(e: DBError) -> Self {
        SszBlockValidationError::DatabaseError(e.message)
    }
}

impl From<AttestationSplitError> for SszBlockValidationError {
    fn from(e: AttestationSplitError) -> Self {
        match e {
            AttestationSplitError::TooShort =>
                SszBlockValidationError::BadAttestationSsz
        }
    }
}

impl From<DecodeError> for SszBlockValidationError {
    fn from(e: DecodeError) -> Self {
        match e {
            DecodeError::TooShort =>
                SszBlockValidationError::BadAttestationSsz,
            DecodeError::TooLong =>
                SszBlockValidationError::BadAttestationSsz,
        }
    }
}

impl From<AttestationValidationError> for SszBlockValidationError {
    fn from(e: AttestationValidationError) -> Self {
        SszBlockValidationError::AttestationValidationError(e)
    }
}
<commit_msg>Add more unique errors in validate ssz block<commit_after>use std::sync::Arc;
use super::attestation_record::validation::{
    validate_attestation,
    AttestationValidationError,
};
use super::attestation_record::{
    AttestationRecord,
    split_one_attestation,
    split_all_attestations,
    AttestationSplitError,
};
use super::{
    AttesterMap,
    ProposerMap,
};
use super::SszBlock;
use super::db::{
    ClientDB,
    DBError,
};
use super::db::stores::{
    BlockStore,
    PoWChainStore,
    ValidatorStore,
};
use super::ssz::{
    Decodable,
    DecodeError,
};
use super::utils::types::Hash256;

#[derive(Debug, PartialEq)]
pub enum BlockStatus {
    NewBlock,
    KnownBlock,
}

#[derive(Debug, PartialEq)]
pub enum SszBlockValidationError {
    FutureSlot,
    UnknownPoWChainRef,
    BadAttestationSsz,
    AttestationValidationError(AttestationValidationError),
    AttestationSignatureFailed,
    FirstAttestationSignatureFailed,
    NoProposerSignature,
    BadProposerMap,
    DatabaseError(String),
}

/// Validate some SszBlock. An SszBlock varies from a Block in that is a read-only structure
/// that reads directly from encoded SSZ.
///
/// The reason to validate an SzzBlock is to avoid decoding it in its entirety if there is
/// a suspicion that the block might be invalid. Such a suspicion should be applied to
/// all blocks coming from the network.
///
/// Of course, this function will only be more efficient if a block is already serialized.
/// Serializing a complete block and then validating with this function will be less
/// efficient than just validating the original block.
///
/// This function will determine if the block is new, already known or invalid (either
/// intrinsically or due to some application error.)
#[allow(dead_code)]
pub fn validate_ssz_block<T>(b: &SszBlock,
                             expected_slot: u64,
                             cycle_length: u8,
                             last_justified_slot: u64,
                             parent_hashes: Arc<Vec<Hash256>>,
                             proposer_map: Arc<ProposerMap>,
                             attester_map: Arc<AttesterMap>,
                             block_store: Arc<BlockStore<T>>,
                             validator_store: Arc<ValidatorStore<T>>,
                             pow_store: Arc<PoWChainStore<T>>)
    -> Result<BlockStatus, SszBlockValidationError>
    where T: ClientDB + Sized
{
    /*
     * If this block is already known, return immediately.
     */
    if block_store.block_exists(&b.block_hash())? {
        return Ok(BlockStatus::KnownBlock);
    }

    /*
     * Copy the block slot (will be used multiple times)
     */
    let block_slot = b.slot_number();

    /*
     * If the block slot corresponds to a slot in the future (according to the local time),
     * drop it.
     */
    if block_slot > expected_slot {
        return Err(SszBlockValidationError::FutureSlot);
    }

    /*
     * If the PoW chain hash is not known to us, drop it.
     *
     * We only accept blocks that reference a known PoW hash.
     *
     * Note: it is not clear what a "known" PoW chain ref is. Likely,
     * it means "sufficienty deep in the canonical PoW chain".
     */
    if pow_store.block_hash_exists(b.pow_chain_ref())? == false {
        return Err(SszBlockValidationError::UnknownPoWChainRef);
    }

    /*
     * Store a reference to the serialized attestations from the block.
     */
    let attestations_ssz = &b.attestations();

    /*
     * Get a slice of the first serialized attestation (the 0th) and decode it into
     * a full AttestationRecord object.
     */
    let (first_attestation_ssz, next_index) = split_one_attestation(
        &attestations_ssz,
        0)?;
    let (first_attestation, _) = AttestationRecord::ssz_decode(
        &first_attestation_ssz, 0)?;

    /*
     * Validate this first attestation.
     *
     * It is a requirement that the block proposer for this slot
     * must have signed the 0th attestation record.
     */
    let attestation_voters = validate_attestation(
        &first_attestation,
        block_slot,
        cycle_length,
        last_justified_slot,
        parent_hashes.clone(),
        block_store.clone(),
        validator_store.clone(),
        attester_map.clone())?;

    /*
     * If the set of voters is None, the attestation was invalid.
     */
    let attestation_voters = attestation_voters
        .ok_or(SszBlockValidationError::
               FirstAttestationSignatureFailed)?;

    /*
     * Read the proposer from the map of slot -> validator index.
     */
    let proposer = proposer_map.get(&block_slot)
        .ok_or(SszBlockValidationError::BadProposerMap)?;

    /*
     * If the proposer for this slot was not a voter, reject the block.
     */
    if !attestation_voters.contains(&proposer) {
        return Err(SszBlockValidationError::NoProposerSignature);
    }

    /*
     * Split the remaining attestations into a vector of slices, each containing
     * a single serialized attestation record.
     */
    let other_attestations = split_all_attestations(attestations_ssz,
                                                    next_index)?;

    /*
     * Verify each other AttestationRecord.
     *
     * TODO: make this parallelized.
     */
    for attestation in other_attestations {
        let (a, _) = AttestationRecord::ssz_decode(&attestation, 0)?;
        let attestation_voters = validate_attestation(
            &a,
            block_slot,
            cycle_length,
            last_justified_slot,
            parent_hashes.clone(),
            block_store.clone(),
            validator_store.clone(),
            attester_map.clone())?;
        if attestation_voters.is_none() {
            return Err(SszBlockValidationError::
                       AttestationSignatureFailed);
        }
    }

    /*
     * If we have reached this point, the block is a new valid block that is worthy of
     * processing.
     */
    Ok(BlockStatus::NewBlock)
}

impl From<DBError> for SszBlockValidationError {
    fn from(e: DBError) -> Self {
        SszBlockValidationError::DatabaseError(e.message)
    }
}

impl From<AttestationSplitError> for SszBlockValidationError {
    fn from(e: AttestationSplitError) -> Self {
        match e {
            AttestationSplitError::TooShort =>
                SszBlockValidationError::BadAttestationSsz
        }
    }
}

impl From<DecodeError> for SszBlockValidationError {
    fn from(e: DecodeError) -> Self {
        match e {
            DecodeError::TooShort =>
                SszBlockValidationError::BadAttestationSsz,
            DecodeError::TooLong =>
                SszBlockValidationError::BadAttestationSsz,
        }
    }
}

impl From<AttestationValidationError> for SszBlockValidationError {
    fn from(e: AttestationValidationError) -> Self {
        SszBlockValidationError::AttestationValidationError(e)
    }
}
<|endoftext|>


<commit_before>use regex::Regex;
use reqwest::header::{CONTENT_TYPE, USER_AGENT};
use reqwest::{Client, RedirectPolicy};
use std::time::Duration;
use url::{ParseError, Url};
use utils::data_to_dataurl;

lazy_static! {
    static ref REGEX_URL: Regex = Regex::new(r"^https?://").unwrap();
}

pub fn is_data_url(url: &str) -> Result<bool, String> {
    match Url::parse(url) {
        Ok(parsed_url) => Ok(parsed_url.scheme() == "data"),
        Err(err) => Err(format!("{}", err)),
    }
}

pub fn is_valid_url(path: &str) -> bool {
    REGEX_URL.is_match(path)
}

pub fn resolve_url(from: &str, to: &str) -> Result<String, ParseError> {
    let result = if is_valid_url(to) {
        // (anything, http://site.com/css/main.css)
        to.to_string()
    } else {
        Url::parse(from)?.join(to)?.to_string()
    };

    Ok(result)
}

pub fn retrieve_asset(
    url: &str,
    as_dataurl: bool,
    as_mime: &str,
    opt_user_agent: &str,
) -> Result<String, reqwest::Error> {
    if is_data_url(&url).unwrap() {
        Ok(url.to_string())
    } else {
        let client = Client::builder()
            .redirect(RedirectPolicy::limited(3))
            .timeout(Duration::from_secs(10))
            .build()
            .unwrap();
        let mut response = client
            .get(url)
            .header(USER_AGENT, opt_user_agent)
            .send()
            .unwrap();

        if as_dataurl {
            // Convert response into a byte array
            let mut data: Vec<u8> = vec![];
            response.copy_to(&mut data)?;

            // Attempt to obtain MIME type by reading the Content-Type header
            let mimetype = if as_mime == "" {
                response
                    .headers()
                    .get(CONTENT_TYPE)
                    .and_then(|header| header.to_str().ok())
                    .unwrap_or(&as_mime)
            } else {
                as_mime
            };

            Ok(data_to_dataurl(&mimetype, &data))
        } else {
            Ok(response.text().unwrap())
        }
    }
}

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

    #[test]
    fn test_is_valid_url() {
        assert!(is_valid_url("https://www.rust-lang.org/"));
        assert!(is_valid_url("http://kernel.org"));
        assert!(!is_valid_url("./index.html"));
        assert!(!is_valid_url("some-local-page.htm"));
        assert!(!is_valid_url("ftp://1.2.3.4/www/index.html"));
        assert!(!is_valid_url(
            "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
        ));
    }

    #[test]
    fn test_resolve_url() -> Result<(), ParseError> {
        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "../category/signatures.html",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/category/signatures.html"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "category/signatures.html",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/category/signatures.html"
        );

        let resolved_url = resolve_url(
            "saved_page.htm",
            "https://www.kernel.org/category/signatures.html",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/category/signatures.html"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "//www.kernel.org/theme/images/logos/tux.png",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/theme/images/logos/tux.png"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "//another-host.org/theme/images/logos/tux.png",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://another-host.org/theme/images/logos/tux.png"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org/category/signatures.html",
            "/theme/images/logos/tux.png",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/theme/images/logos/tux.png"
        );

        let resolved_url = resolve_url(
            "https://www.w3schools.com/html/html_iframe.asp",
            "default.asp",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.w3schools.com/html/default.asp"
        );

        Ok(())
    }

    #[test]
    fn test_is_data_url() {
        assert!(
            is_data_url("data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h")
                .unwrap_or(false)
        );
        assert!(!is_data_url("https://kernel.org").unwrap_or(false));
        assert!(!is_data_url("//kernel.org").unwrap_or(false));
    }
}
<commit_msg>Add basic verbose output<commit_after>use regex::Regex;
use reqwest::header::{CONTENT_TYPE, USER_AGENT};
use reqwest::{Client, RedirectPolicy};
use std::time::Duration;
use url::{ParseError, Url};
use utils::data_to_dataurl;

lazy_static! {
    static ref REGEX_URL: Regex = Regex::new(r"^https?://").unwrap();
}

pub fn is_data_url(url: &str) -> Result<bool, String> {
    match Url::parse(url) {
        Ok(parsed_url) => Ok(parsed_url.scheme() == "data"),
        Err(err) => Err(format!("{}", err)),
    }
}

pub fn is_valid_url(path: &str) -> bool {
    REGEX_URL.is_match(path)
}

pub fn resolve_url(from: &str, to: &str) -> Result<String, ParseError> {
    let result = if is_valid_url(to) {
        // (anything, http://site.com/css/main.css)
        to.to_string()
    } else {
        Url::parse(from)?.join(to)?.to_string()
    };

    Ok(result)
}

pub fn retrieve_asset(
    url: &str,
    as_dataurl: bool,
    as_mime: &str,
    opt_user_agent: &str,
) -> Result<String, reqwest::Error> {
    if is_data_url(&url).unwrap() {
        Ok(url.to_string())
    } else {
        let client = Client::builder()
            .timeout(Duration::from_secs(10))
            .build()
            .unwrap();
        let mut response = client
            .get(url)
            .header(USER_AGENT, opt_user_agent)
            .send()
            .unwrap();
        let final_url = response.url().as_str();

        if url == final_url {
            eprintln!("[ {} ]", &url);
        } else {
            eprintln!("[ {} -> {} ]", &url, &final_url);
        }

        if as_dataurl {
            // Convert response into a byte array
            let mut data: Vec<u8> = vec![];
            response.copy_to(&mut data)?;

            // Attempt to obtain MIME type by reading the Content-Type header
            let mimetype = if as_mime == "" {
                response
                    .headers()
                    .get(CONTENT_TYPE)
                    .and_then(|header| header.to_str().ok())
                    .unwrap_or(&as_mime)
            } else {
                as_mime
            };

            Ok(data_to_dataurl(&mimetype, &data))
        } else {
            Ok(response.text().unwrap())
        }
    }
}

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

    #[test]
    fn test_is_valid_url() {
        assert!(is_valid_url("https://www.rust-lang.org/"));
        assert!(is_valid_url("http://kernel.org"));
        assert!(!is_valid_url("./index.html"));
        assert!(!is_valid_url("some-local-page.htm"));
        assert!(!is_valid_url("ftp://1.2.3.4/www/index.html"));
        assert!(!is_valid_url(
            "data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
        ));
    }

    #[test]
    fn test_resolve_url() -> Result<(), ParseError> {
        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "../category/signatures.html",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/category/signatures.html"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "category/signatures.html",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/category/signatures.html"
        );

        let resolved_url = resolve_url(
            "saved_page.htm",
            "https://www.kernel.org/category/signatures.html",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/category/signatures.html"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "//www.kernel.org/theme/images/logos/tux.png",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/theme/images/logos/tux.png"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org",
            "//another-host.org/theme/images/logos/tux.png",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://another-host.org/theme/images/logos/tux.png"
        );

        let resolved_url = resolve_url(
            "https://www.kernel.org/category/signatures.html",
            "/theme/images/logos/tux.png",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.kernel.org/theme/images/logos/tux.png"
        );

        let resolved_url = resolve_url(
            "https://www.w3schools.com/html/html_iframe.asp",
            "default.asp",
        )?;
        assert_eq!(
            resolved_url.as_str(),
            "https://www.w3schools.com/html/default.asp"
        );

        Ok(())
    }

    #[test]
    fn test_is_data_url() {
        assert!(
            is_data_url("data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h")
                .unwrap_or(false)
        );
        assert!(!is_data_url("https://kernel.org").unwrap_or(false));
        assert!(!is_data_url("//kernel.org").unwrap_or(false));
    }
}
<|endoftext|>


<commit_before>//! Exposes the `Iron` type, the main entrance point of the
//! `Iron` library.

use std::io::net::ip::{SocketAddr, IpAddr};

use http = http::server;
use super::chain::Chain;
use super::chain::stackchain::StackChain;

use super::response::Response;
use super::request::Request;

/// The "default server", using a `StackChain`.
pub type Server = Iron<StackChain>;

/// The primary entrance point to `Iron`, a `struct` to instantiate a new server.
///
/// The server can be made with a specific `Chain` (using `from_chain`)
/// or with a new `Chain` (using `new`). `Iron` is used to manage the server
/// processes:
/// `Iron.chain.link` is used to add new `Middleware`, and
/// `Iron.listen` is used to kick off a server process.
///
/// `Iron` contains the `Chain` which holds the `Middleware` necessary to run a server.
/// `Iron` is the main interface to adding `Middleware`, and has `Chain` as a
/// public field (for the sake of extensibility).
pub struct Iron<C> {
    /// Add `Middleware` to the `Iron's` `chain` so that requests
    /// are passed through those `Middleware`.
    /// `Middleware` is added to the chain with with `chain.link`.
    pub chain: C,
    ip: Option<IpAddr>,
    port: Option<u16>
}

impl<C: Clone> Clone for Iron<C> {
    fn clone(&self) -> Iron<C> {
        Iron {
            chain: self.chain.clone(),
            ip: self.ip.clone(),
            port: self.port
        }
    }
}

impl<C: Chain> Iron<C> {
    /// Kick off the server process.
    ///
    /// Call this once to begin listening for requests on the server.
    /// This is a blocking operation, and is the final op that should be called
    /// on the `Iron` instance. Once `listen` is called, requests will be
    /// handled as defined through the `Iron's` `chain's` `Middleware`.
    pub fn listen(mut self, ip: IpAddr, port: u16) {
        use http::server::Server;
        self.ip = Some(ip);
        self.port = Some(port);
        self.serve_forever();
    }

    /// Instantiate a new instance of `Iron`.
    ///
    /// This will create a new `Iron`, the base unit of the server.
    ///
    /// Custom chains can be used by explicitly specifying the type, as
    /// `Iron::<CustomChain>::new()`.
    #[inline]
    pub fn new() -> Iron<C> {
        Iron {
            chain: Chain::new(),
            ip: None,
            port: None
        }
    }
}

/// Unused, but required for internal functionality.
///
/// This `impl` allows `Iron` to be used as a `Server` by
/// [rust-http](https://github.com/chris-morgan/rust-http).
/// This is not used by users of this library.
impl<C: Chain> http::Server for Iron<C> {
    fn get_config(&self) -> http::Config {
        http::Config { bind_address: SocketAddr {
            ip: self.ip.unwrap(),
            port: self.port.unwrap()
        } }
    }

    fn handle_request(&self, mut req: Request, res: &mut Response) {
        let mut chain = self.chain.clone();
        let _ = chain.dispatch(&mut req, res, None);
    }
}
<commit_msg>(feat) Clone chain only once through RefCell.<commit_after>//! Exposes the `Iron` type, the main entrance point of the
//! `Iron` library.

use std::io::net::ip::{SocketAddr, IpAddr};
use std::cell::RefCell;

use http = http::server;
use super::chain::Chain;
use super::chain::stackchain::StackChain;

use super::response::Response;
use super::request::Request;

/// The "default server", using a `StackChain`.
pub type Server = Iron<StackChain>;

/// The primary entrance point to `Iron`, a `struct` to instantiate a new server.
///
/// The server can be made with a specific `Chain` (using `from_chain`)
/// or with a new `Chain` (using `new`). `Iron` is used to manage the server
/// processes:
/// `Iron.chain.link` is used to add new `Middleware`, and
/// `Iron.listen` is used to kick off a server process.
///
/// `Iron` contains the `Chain` which holds the `Middleware` necessary to run a server.
/// `Iron` is the main interface to adding `Middleware`, and has `Chain` as a
/// public field (for the sake of extensibility).
pub struct Iron<C> {
    /// Add `Middleware` to the `Iron's` `chain` so that requests
    /// are passed through those `Middleware`.
    /// `Middleware` is added to the chain with with `chain.link`.
    pub chain: C,
}

// The struct which actually listens and serves requests.
//
// IronListener holds its chain behind a RefCell to avoid a
// second clone in the implementation of .serve_forever().
#[deriving(Clone)]
struct IronListener<C> {
    chain: RefCell<C>,
    ip: IpAddr,
    port: u16
}

impl<C: Chain> Iron<C> {
    /// Kick off the server process.
    ///
    /// Call this once to begin listening for requests on the server.
    /// This is a blocking operation, and is the final op that should be called
    /// on the `Iron` instance. Once `listen` is called, requests will be
    /// handled as defined through the `Iron's` `chain's` `Middleware`.
    pub fn listen(self, ip: IpAddr, port: u16) {
        use http::server::Server;

        IronListener {
            chain: RefCell::new(self.chain),
            ip: ip,
            port: port
        }.serve_forever();
    }

    /// Instantiate a new instance of `Iron`.
    ///
    /// This will create a new `Iron`, the base unit of the server.
    ///
    /// Custom chains can be used by explicitly specifying the type as
    /// in: `let customServer: Iron<CustomChain> = Iron::new();`
    #[inline]
    pub fn new() -> Iron<C> {
        Iron {
            chain: Chain::new(),
        }
    }
}

impl<C: Chain> http::Server for IronListener<C> {
    fn get_config(&self) -> http::Config {
        http::Config {
            bind_address: SocketAddr {
                ip: self.ip,
                port: self.port
            }
        }
    }

    fn handle_request(&self, mut req: Request, res: &mut Response) {
        let _ = self.chain.borrow_mut().dispatch(&mut req, res, None);
    }
}
<|endoftext|>


<commit_before>//! This module exports different types for JSON interactions.
//! It encapsulates the differences between serde_json and simd-json to allow
//! ignoring those in the rest of the codebase.

use serde::de::{Deserialize, DeserializeOwned};
use serde::ser::Serialize;

use crate::Result;

#[cfg(not(feature = "simd-json"))]
pub type Value = serde_json::Value;
#[cfg(feature = "simd-json")]
pub type Value = simd_json::OwnedValue;

#[cfg(not(feature = "simd-json"))]
pub use serde_json::json;
#[cfg(not(feature = "simd-json"))]
use serde_json::Number;
#[cfg(feature = "simd-json")]
pub use simd_json::json;

#[cfg(not(feature = "simd-json"))]
pub type JsonMap = serde_json::Map<String, Value>;
#[cfg(feature = "simd-json")]
pub type JsonMap = simd_json::owned::Object;

#[cfg(not(feature = "simd-json"))]
pub const NULL: Value = Value::Null;
#[cfg(feature = "simd-json")]
pub const NULL: Value = Value::Static(simd_json::StaticNode::Null);

#[cfg(not(feature = "simd-json"))]
pub(crate) fn to_vec<T>(v: &T) -> Result<Vec<u8>>
where
    T: Serialize,
{
    Ok(serde_json::to_vec(v)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn to_vec<T>(v: &T) -> Result<Vec<u8>>
where
    T: Serialize,
{
    Ok(simd_json::to_vec(v)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn to_string<T>(v: &T) -> Result<String>
where
    T: Serialize,
{
    Ok(serde_json::to_string(v)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn to_string<T>(v: &T) -> Result<String>
where
    T: Serialize,
{
    Ok(simd_json::to_string(v)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_str<'a, T>(s: &'a mut str) -> Result<T>
where
    T: Deserialize<'a>,
{
    Ok(serde_json::from_str(s)?)
}
#[cfg(feature = "simd-json")]
pub(crate) fn from_str<'a, T>(s: &'a mut str) -> Result<T>
where
    T: Deserialize<'a>,
{
    Ok(simd_json::from_str(s)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_reader<R, T>(r: R) -> Result<T>
where
    T: DeserializeOwned,
    R: std::io::Read,
{
    Ok(serde_json::from_reader(r)?)
}
#[cfg(feature = "simd-json")]
pub(crate) fn from_reader<R, T>(r: R) -> Result<T>
where
    T: DeserializeOwned,
    R: std::io::Read,
{
    Ok(simd_json::from_reader(r)?)
}
#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_value<T>(v: Value) -> Result<T>
where
    T: DeserializeOwned,
{
    Ok(serde_json::from_value(v)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn from_value<T>(v: Value) -> Result<T>
where
    T: DeserializeOwned,
{
    Ok(simd_json::serde::from_owned_value(v)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn to_value<T>(value: T) -> Result<Value>
where
    T: Serialize,
{
    Ok(serde_json::to_value(value)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn to_value<T>(value: T) -> Result<Value>
where
    T: Serialize,
{
    Ok(simd_json::serde::to_owned_value(value)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_number<T>(n: T) -> Value
where
    serde_json::Number: From<T>,
{
    Value::Number(Number::from(n))
}

#[cfg(feature = "simd-json")]
pub(crate) fn from_number<T>(n: T) -> Value
where
    Value: From<T>,
{
    Value::from(n)
}

pub mod prelude {
    #[cfg(feature = "simd-json")]
    pub use simd_json::{Builder, Mutable, Value as ValueTrait, ValueAccess};

    pub use super::*;
}
<commit_msg>Expose more types and functions from `serde_json` and `simd-json`<commit_after>//! This module exports different types for JSON interactions.
//! It encapsulates the differences between serde_json and simd-json to allow
//! ignoring those in the rest of the codebase.

use serde::de::{Deserialize, DeserializeOwned};
use serde::ser::Serialize;

use crate::Result;

#[cfg(not(feature = "simd-json"))]
pub type Value = serde_json::Value;
#[cfg(feature = "simd-json")]
pub type Value = simd_json::OwnedValue;

#[cfg(not(feature = "simd-json"))]
pub use serde_json::json;
#[cfg(not(feature = "simd-json"))]
pub use serde_json::Error as JsonError;
#[cfg(not(feature = "simd-json"))]
use serde_json::Number;
#[cfg(feature = "simd-json")]
pub use simd_json::json;
#[cfg(feature = "simd-json")]
pub use simd_json::Error as JsonError;

#[cfg(not(feature = "simd-json"))]
pub type JsonMap = serde_json::Map<String, Value>;
#[cfg(feature = "simd-json")]
pub type JsonMap = simd_json::owned::Object;

#[cfg(not(feature = "simd-json"))]
pub const NULL: Value = Value::Null;
#[cfg(feature = "simd-json")]
pub const NULL: Value = Value::Static(simd_json::StaticNode::Null);

#[cfg(not(feature = "simd-json"))]
pub(crate) fn to_vec<T>(v: &T) -> Result<Vec<u8>>
where
    T: Serialize,
{
    Ok(serde_json::to_vec(v)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn to_vec<T>(v: &T) -> Result<Vec<u8>>
where
    T: Serialize,
{
    Ok(simd_json::to_vec(v)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn to_string<T>(v: &T) -> Result<String>
where
    T: Serialize,
{
    Ok(serde_json::to_string(v)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn to_string<T>(v: &T) -> Result<String>
where
    T: Serialize,
{
    Ok(simd_json::to_string(v)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_str<'a, T>(s: &'a mut str) -> Result<T>
where
    T: Deserialize<'a>,
{
    Ok(serde_json::from_str(s)?)
}
#[cfg(feature = "simd-json")]
pub(crate) fn from_str<'a, T>(s: &'a mut str) -> Result<T>
where
    T: Deserialize<'a>,
{
    Ok(simd_json::from_str(s)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_reader<R, T>(r: R) -> Result<T>
where
    T: DeserializeOwned,
    R: std::io::Read,
{
    Ok(serde_json::from_reader(r)?)
}
#[cfg(feature = "simd-json")]
pub(crate) fn from_reader<R, T>(r: R) -> Result<T>
where
    T: DeserializeOwned,
    R: std::io::Read,
{
    Ok(simd_json::from_reader(r)?)
}
#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_value<T>(v: Value) -> Result<T>
where
    T: DeserializeOwned,
{
    Ok(serde_json::from_value(v)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn from_value<T>(v: Value) -> Result<T>
where
    T: DeserializeOwned,
{
    Ok(simd_json::serde::from_owned_value(v)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn to_value<T>(value: T) -> Result<Value>
where
    T: Serialize,
{
    Ok(serde_json::to_value(value)?)
}

#[cfg(feature = "simd-json")]
pub(crate) fn to_value<T>(value: T) -> Result<Value>
where
    T: Serialize,
{
    Ok(simd_json::serde::to_owned_value(value)?)
}

#[cfg(not(feature = "simd-json"))]
pub(crate) fn from_number<T>(n: T) -> Value
where
    serde_json::Number: From<T>,
{
    Value::Number(Number::from(n))
}

#[cfg(feature = "simd-json")]
pub(crate) fn from_number<T>(n: T) -> Value
where
    Value: From<T>,
{
    Value::from(n)
}

pub mod prelude {
    #[cfg(not(feature = "simd-json"))]
    pub use serde_json::{
        from_reader,
        from_slice,
        from_str,
        from_value,
        to_string,
        to_string_pretty,
        to_value,
        to_vec,
        to_vec_pretty,
    };

    #[cfg(feature = "simd-json")]
    pub use simd_json::{
        from_reader,
        from_slice,
        from_str,
        serde::from_owned_value as from_value,
        serde::to_owned_value as to_value,
        to_string,
        to_string_pretty,
        to_vec,
        to_vec_pretty,
    };

    #[cfg(feature = "simd-json")]
    pub use simd_json::{Builder, Mutable, Value as ValueTrait, ValueAccess};

    pub use super::*;
}
<|endoftext|>


<commit_before>#![allow(unused_must_use)]
extern crate pad;
#[macro_use]
extern crate quicli;
extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate term;

use pad::PadStr;
use reqwest::Url;

use std::process;
use std::str;

use quicli::prelude::*;

#[macro_use]
mod macros;

/// cargo-search on steroids
#[derive(Debug, StructOpt)]
struct Cli {
    /// how many packages to display
    #[structopt(long = "limit", short = "l", default_value = "10")]
    limit: usize,
    /// the crates.io search result page to display
    #[structopt(long = "page", default_value = "1")]
    page: usize,
    /// quiet output, display only crate, version and downloads
    #[structopt(long = "quiet", short = "q")]
    quiet: bool,
    /// query string for crates.io
    query: String,
}

#[derive(Debug, Deserialize)]
struct Args {
    flag_info: bool,
    arg_query: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct Meta {
    total: i32,
}

#[derive(Debug, Serialize, Deserialize)]
struct Response {
    crates: Vec<EncodableCrate>,
    meta: Meta,
}

// structs from crates.io backend

#[derive(Debug, Serialize, Deserialize)]
struct EncodableCrate {
    id: String,
    name: String,
    updated_at: String,
    versions: Option<Vec<i32>>,
    created_at: String,
    downloads: i32,
    max_version: String,
    description: Option<String>,
    homepage: Option<String>,
    documentation: Option<String>,
    keywords: Option<Vec<String>>,
    license: Option<String>,
    repository: Option<String>,
    links: CrateLinks,
}

#[derive(Debug, Serialize, Deserialize)]
struct CrateLinks {
    version_downloads: String,
    versions: Option<String>,
    owners: Option<String>,
    reverse_dependencies: String,
}

fn query_crates_io(
    query: &str,
    page: usize,
    per_page: usize,
) -> Result<(i32, Vec<EncodableCrate>)> {
    let url = Url::parse_with_params(
        "https://crates.io/api/v1/crates",
        &[
            ("q", query),
            ("page", &page.to_string()),
            ("per_page", &per_page.to_string()),
        ],
    )?;
    let body = reqwest::get(url)?.text()?;
    let data: Response = serde_json::from_str(&body)?;
    Ok((data.meta.total, data.crates))
}

fn show_crate(t: &mut Box<term::StdoutTerminal>, cr: &EncodableCrate, quiet: bool, max_len: usize) {
    p_green!(t, "{}", cr.name.pad_to_width(max_len));
    p_white!(
        t,
        " = \"{}\"    \t(downloads: {})\n",
        cr.max_version,
        cr.downloads
    );

    if !quiet {
        cr.description
            .as_ref()
            .map(|description| p_yellow!(t, " -> {}\n", description.clone().trim()));
        cr.documentation
            .as_ref()
            .map(|documentation| p_white!(t, "    docs: {}\n", documentation));
        cr.homepage
            .as_ref()
            .map(|homepage| p_white!(t, "    home: {}\n", homepage));
        p_white!(t, "\n");
    }
}

main!(|args: Cli| {
    let mut t = term::stdout().unwrap();

    // TODO: Add decoding of updated_at and allow to use it for sorting
    let (total, mut crates) =
        query_crates_io(&args.query, args.page, args.limit).unwrap_or_else(|e| {
            p_red!(t, "[error]: {}\n", e);
            process::exit(1)
        });
    crates.sort_by(|c1, c2| c2.downloads.cmp(&c1.downloads));

    p_white!(
        t,
        "Displaying {} crates from page {} out of the {} found.\n\n",
        crates.len(),
        args.page,
        total,
    );
    let max_len = (&crates).iter().map(|ref cr| cr.name.len()).max().unwrap();
    for cr in &crates {
        show_crate(&mut t, &cr, args.quiet, max_len);
    }

    t.reset().unwrap();
});
<commit_msg>allow sorting by downloads or recent downloads<commit_after>#![allow(unused_must_use)]
extern crate pad;
#[macro_use]
extern crate quicli;
extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate term;

use pad::PadStr;
use reqwest::Url;

use std::process;
use std::str;

use quicli::prelude::*;

#[macro_use]
mod macros;

#[derive(Debug, StructOpt)]
#[structopt(name = "cargo")]
enum Cli {
    #[structopt(name = "ssearch", about = "cargo search on steroids")]
    Ssearch {
        /// how many packages to display
        #[structopt(long = "limit", short = "l", default_value = "10")]
        limit: usize,
        /// the crates.io search result page to display
        #[structopt(long = "page", default_value = "1")]
        page: usize,
        /// quiet output, display only crate, version and downloads
        #[structopt(long = "quiet", short = "q")]
        quiet: bool,
        /// sort by recent downloads instead of overall downloads
        #[structopt(long = "recent", short = "r")]
        recent: bool,
        /// query string for crates.io
        query: String,
    },
}

#[derive(Debug, Deserialize)]
struct Args {
    flag_info: bool,
    arg_query: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct Meta {
    total: i32,
}

#[derive(Debug, Serialize, Deserialize)]
struct Response {
    crates: Vec<EncodableCrate>,
    meta: Meta,
}

// structs from crates.io backend

#[derive(Debug, Serialize, Deserialize)]
struct EncodableCrate {
    id: String,
    name: String,
    updated_at: String,
    versions: Option<Vec<i32>>,
    created_at: String,
    downloads: i32,
    max_version: String,
    description: Option<String>,
    homepage: Option<String>,
    documentation: Option<String>,
    keywords: Option<Vec<String>>,
    license: Option<String>,
    repository: Option<String>,
    links: CrateLinks,
}

#[derive(Debug, Serialize, Deserialize)]
struct CrateLinks {
    version_downloads: String,
    versions: Option<String>,
    owners: Option<String>,
    reverse_dependencies: String,
}

fn query_crates_io(
    query: &str,
    page: usize,
    per_page: usize,
    recent: bool,
) -> Result<(i32, Vec<EncodableCrate>)> {
    let sort = if recent {
        "recent-downloads"
    } else {
        "downloads"
    };
    let url = Url::parse_with_params(
        "https://crates.io/api/v1/crates",
        &[
            ("q", query),
            ("page", &page.to_string()),
            ("per_page", &per_page.to_string()),
            ("sort", &sort),
        ],
    )?;
    let body = reqwest::get(url)?.text()?;
    let data: Response = serde_json::from_str(&body)?;
    Ok((data.meta.total, data.crates))
}

fn show_crate(t: &mut Box<term::StdoutTerminal>, cr: &EncodableCrate, quiet: bool, max_len: usize) {
    p_green!(t, "{}", cr.name.pad_to_width(max_len));
    p_white!(
        t,
        " = \"{}\"    \t(downloads: {})\n",
        cr.max_version,
        cr.downloads
    );

    if !quiet {
        cr.description
            .as_ref()
            .map(|description| p_yellow!(t, " -> {}\n", description.clone().trim()));
        cr.documentation
            .as_ref()
            .map(|documentation| p_white!(t, "    docs: {}\n", documentation));
        cr.homepage
            .as_ref()
            .map(|homepage| p_white!(t, "    home: {}\n", homepage));
        p_white!(t, "\n");
    }
}

main!(|args: Cli| {
    let Cli::Ssearch {
        query,
        page,
        limit,
        quiet,
        recent,
    } = args;

    let mut t = term::stdout().unwrap();

    // TODO: Add decoding of updated_at and allow to use it for sorting
    let (total, crates) = query_crates_io(&query, page, limit, recent).unwrap_or_else(|e| {
        p_red!(t, "[error]: {}\n", e);
        process::exit(1)
    });

    p_white!(
        t,
        "Displaying {} crates from page {} out of the {} found.\n\n",
        crates.len(),
        page,
        total,
    );
    let max_len = (&crates).iter().map(|ref cr| cr.name.len()).max().unwrap();
    for cr in &crates {
        show_crate(&mut t, &cr, quiet, max_len);
    }

    t.reset().unwrap();
});
<|endoftext|>


<commit_before>extern crate rand;

use std::io;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashMap;

use rand::Rng;

mod request;
mod turn;
mod region;
mod superregion;

use request::Request;
use turn::Turn;
use region::Region;
use superregion::SuperRegion;

fn main()
{
	std::env::set_var("RUST_BACKTRACE","1");
	let input = io::stdin();
	let input = BufReader::new(input);
	let input = input.lines();
	let input = input
		.map(Result::unwrap)
		.filter(|s|s.len()>0)
		.map(|s|s.parse::<Request>())
		.map(Result::unwrap);

	let mut rng = rand::thread_rng();

	let mut name_you = String::new();
	let mut name_other = String::new();

	let mut sup_regions: HashMap<usize,SuperRegion> = HashMap::new();
	let mut regions: HashMap<usize,Region> = HashMap::new();

	let mut armies_left = 0;

	for req in input
	{
		use request::Request::*;
		match req
		{
			ListSuperRegions(sregions) =>
			{
				sup_regions.extend(sregions.iter().map(|sr|(sr.id,sr.clone())));
			},
			ListRegions(regs) =>
			{
				regions.extend(regs.iter().map(|r|(r.id,r.clone())));
			},
			ListNeighbours(relations) =>
			{
				for (id,neighbours) in relations
				{
					regions.get_mut(&id).unwrap().neighbours.extend(neighbours.iter());
					for n in neighbours
					{
						regions.get_mut(&n).unwrap().neighbours.push(id);
					}
				}
				for (_,r) in regions.iter_mut()
				{
					rng.shuffle(&mut r.neighbours);
				}
			},
			RequestStartingRegions(_avail) =>
			{
				println!("give me randomly");
			},
			SettingNameYou(name) => name_you = name,
			SettingNameOther(name) => name_other = name,
			SettingArmies(count) =>
			{
				armies_left = count;
			},
			UpdateMap(updates) =>
			{
				for u in updates
				{
					let mut reg = regions.get_mut(&u.0).unwrap();
					reg.player = u.1;
					reg.count = u.2;
				}
			},
			TurnOther(_turns) =>
			{
				//TODO: analyze enemy
			},
			TurnPlace =>
			{
				let mut v = Vec::new();
				{
					let regs = regions.values()
						.filter(|r|r.player == name_you)
						.filter(|r|r.neighbours.iter()
							.map(|o|regions.get(o))
							.map(Option::unwrap)
							.filter(|o|o.player == name_other)
							.any(|o|o.count >= r.count)
						)
						.take(3)
						.collect::<Vec<_>>();

					let count = if regs.len() > 0
					{
						armies_left/regs.len()
					}
					else
					{
						1
					};
					for r in regs.iter()
					{
						v.push(
							Turn::Place
							{
								name: name_you.clone(),
								region: r.id,
								count: count,
							}
						);
						armies_left -= count;
					}
					while armies_left > 0
					{
						for r in regions.values()
							.filter(|r|r.player == name_you)
						{
							if armies_left <= 0
							{
								break;
							}
							for n in regions.get(&r.id).unwrap().neighbours.iter()
							{
								if regions.get(&n).unwrap().player != name_you
								{
									v.push(
										Turn::Place
										{
											name: name_you.clone(),
											region: r.id,
											count: 1,
										}
									);
									armies_left -= 1;
									break;
								}
							}
						}
					}
				}
				if v.len() <= 0
				{
					v.push(Turn::Noop);
				}
				{
					let v = v.iter()
						.filter(|t|
							if let &&Turn::Place{count,..} = t
							{
								count > 0
							}
							else
							{
								true
							}
						)
						.map(|t|format!("{}",t))
						.collect::<Vec<_>>();
					println!("{}",v.join(","));
				}
				for r in v.iter()
				{
					if let &Turn::Place{region,count,..} = r
					{
						regions.get_mut(&region).unwrap().count += count;
					}
				}
			},
			TurnArmies =>
			{
				let mut v = Vec::new();
				let regs = regions.values()
					.filter(|r|r.player == name_you)
					.filter_map(|r|
					{
						let x =r.neighbours.iter()
						.map(|o|regions.get(o))
						.map(Option::unwrap)
						.filter(|o|o.player != name_you)
						.filter(|o|o.count*5 <= r.count*2)
						.next()
						.map(|o|o.id);
						if let Some(x) = x
						{
							Some(((r.id,(r.count*2)/3),x))
						}
						else
						{
							None
						}
					})
					.collect::<Vec<_>>();
				for ((r,count),n) in regs
				{
					v.push(
						Turn::Turn
						{
							name: name_you.clone(),
							source: r,
							target: n,
							count: count,
						}
					);
				}
				if v.len() <= 0
				{
					v.push(Turn::Noop);
				}
				let v = v.iter().map(|t|format!("{}",t)).collect::<Vec<_>>();
				println!("{}",v.join(","));
			},
		}
	}
}

<commit_msg>minor adjustments: send average of enemy and own troups, send if double<commit_after>extern crate rand;

use std::io;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashMap;

use rand::Rng;

mod request;
mod turn;
mod region;
mod superregion;

use request::Request;
use turn::Turn;
use region::Region;
use superregion::SuperRegion;

fn main()
{
	std::env::set_var("RUST_BACKTRACE","1");
	let input = io::stdin();
	let input = BufReader::new(input);
	let input = input.lines();
	let input = input
		.map(Result::unwrap)
		.filter(|s|s.len()>0)
		.map(|s|s.parse::<Request>())
		.map(Result::unwrap);

	let mut rng = rand::thread_rng();

	let mut name_you = String::new();
	let mut name_other = String::new();

	let mut sup_regions: HashMap<usize,SuperRegion> = HashMap::new();
	let mut regions: HashMap<usize,Region> = HashMap::new();

	let mut armies_left = 0;

	for req in input
	{
		use request::Request::*;
		match req
		{
			ListSuperRegions(sregions) =>
			{
				sup_regions.extend(sregions.iter().map(|sr|(sr.id,sr.clone())));
			},
			ListRegions(regs) =>
			{
				regions.extend(regs.iter().map(|r|(r.id,r.clone())));
			},
			ListNeighbours(relations) =>
			{
				for (id,neighbours) in relations
				{
					regions.get_mut(&id).unwrap().neighbours.extend(neighbours.iter());
					for n in neighbours
					{
						regions.get_mut(&n).unwrap().neighbours.push(id);
					}
				}
				for (_,r) in regions.iter_mut()
				{
					rng.shuffle(&mut r.neighbours);
				}
			},
			RequestStartingRegions(_avail) =>
			{
				println!("give me randomly");
			},
			SettingNameYou(name) => name_you = name,
			SettingNameOther(name) => name_other = name,
			SettingArmies(count) =>
			{
				armies_left = count;
			},
			UpdateMap(updates) =>
			{
				for u in updates
				{
					let mut reg = regions.get_mut(&u.0).unwrap();
					reg.player = u.1;
					reg.count = u.2;
				}
			},
			TurnOther(_turns) =>
			{
				//TODO: analyze enemy
			},
			TurnPlace =>
			{
				let mut v = Vec::new();
				{
					let regs = regions.values()
						.filter(|r|r.player == name_you)
						.filter(|r|r.neighbours.iter()
							.map(|o|regions.get(o))
							.map(Option::unwrap)
							.filter(|o|o.player == name_other)
							.any(|o|o.count >= r.count)
						)
						.take(3)
						.collect::<Vec<_>>();

					let count = if regs.len() > 0
					{
						armies_left/regs.len()
					}
					else
					{
						1
					};
					for r in regs.iter()
					{
						v.push(
							Turn::Place
							{
								name: name_you.clone(),
								region: r.id,
								count: count,
							}
						);
						armies_left -= count;
					}
					while armies_left > 0
					{
						for r in regions.values()
							.filter(|r|r.player == name_you)
						{
							if armies_left <= 0
							{
								break;
							}
							for n in regions.get(&r.id).unwrap().neighbours.iter()
							{
								if regions.get(&n).unwrap().player != name_you
								{
									v.push(
										Turn::Place
										{
											name: name_you.clone(),
											region: r.id,
											count: 1,
										}
									);
									armies_left -= 1;
									break;
								}
							}
						}
					}
				}
				if v.len() <= 0
				{
					v.push(Turn::Noop);
				}
				{
					let v = v.iter()
						.filter(|t|
							if let &&Turn::Place{count,..} = t
							{
								count > 0
							}
							else
							{
								true
							}
						)
						.map(|t|format!("{}",t))
						.collect::<Vec<_>>();
					println!("{}",v.join(","));
				}
				for r in v.iter()
				{
					if let &Turn::Place{region,count,..} = r
					{
						regions.get_mut(&region).unwrap().count += count;
					}
				}
			},
			TurnArmies =>
			{
				let mut v = Vec::new();
				let regs = regions.values()
					.filter(|r|r.player == name_you)
					.filter_map(|r|
					{
						let x = r.neighbours.iter()
						.map(|o|regions.get(o))
						.map(Option::unwrap)
						.filter(|o|o.player != name_you)
						.filter(|o|o.count*2 <= r.count)
						.next()
						.map(|o|o.id);
						if let Some(x) = x
						{
							Some(((r.id,regions[&x].count),x))
						}
						else
						{
							None
						}
					})
					.collect::<Vec<_>>();
				for ((r,count),n) in regs
				{
					v.push(
						Turn::Turn
						{
							name: name_you.clone(),
							source: r,
							target: n,
							count: count,
						}
					);
				}
				if v.len() <= 0
				{
					v.push(Turn::Noop);
				}
				let v = v.iter().map(|t|format!("{}",t)).collect::<Vec<_>>();
				println!("{}",v.join(","));
			},
		}
	}
}

<|endoftext|>


<commit_before>// PortAudio:
extern crate portaudio;
use portaudio as pa;

// DSP module
// TODO: remove all these "use" statements in favor of explicitly calling them in main.rs
pub mod dsp;
use dsp::sine_generator::SineGenerator;
use dsp::negate_signal::NegateSignal;
use dsp::add_signals::AddSignals;
use dsp::evaluatable::Evaluatable;

// Constants:
const CHANNELS: i32 = 2;
const NUM_SECONDS: i32 = 5;
const SAMPLE_RATE: f64 = 44100.0;
const FRAMES_PER_BUFFER: u32 = 64;

fn main() {
    let sine_generator1 = SineGenerator::new(44100.0, 400.0, 0.3);
    let sine_generator2 = SineGenerator::new(44100.0, 400.0, 0.3);
    let negated_sine_2 = NegateSignal::new(sine_generator2);

    //let mut add_vec = vec![sine_generator1, sine_generator2];

    let add_vec: Vec<Box<Evaluatable>> = vec![Box::new(sine_generator1), Box::new(negated_sine_2)];

    let add_signals = AddSignals::new(add_vec);
    run(add_signals).unwrap()
}

fn run<E: Evaluatable + 'static>(mut generator: E) -> Result<(), pa::Error> {
    println!("PortAudio Test: output sine wave. SR = {}, BufSize = {}", SAMPLE_RATE, FRAMES_PER_BUFFER);

    let pa = try!(pa::PortAudio::new());

    let mut settings = try!(pa.default_output_stream_settings(CHANNELS, SAMPLE_RATE, FRAMES_PER_BUFFER));
    settings.params.suggested_latency = 0.1;

    // This routine will be called by the PortAudio engine when audio is needed. It may called at
    // interrupt level on some machines so don't do anything that could mess up the system like
    // dynamic resource allocation or IO.
    let callback = move |pa::OutputStreamCallbackArgs { buffer, frames, .. }| {
        let mut idx = 0;
        for _ in 0..frames {
            let samples = generator.evaluate();
            buffer[idx]   = samples.0;
            buffer[idx+1] = samples.1;
            idx += 2;
        }
        pa::Continue
    };

    let mut stream = try!(pa.open_non_blocking_stream(settings, callback));

    try!(stream.start());

    println!("Play for {} seconds.", NUM_SECONDS);
    pa.sleep(NUM_SECONDS * 1_000);

    try!(stream.stop());
    try!(stream.close());

    println!("Test finished.");

    Ok(())
}<commit_msg>Clean up code a little in main.rs, add comments<commit_after>// TODO: #![deny(missing_docs)]

// PortAudio:
extern crate portaudio;
use portaudio as pa;

// DSP module
// TODO: remove all these "use" statements in favor of explicitly calling them in main.rs
pub mod dsp;
use dsp::sine_generator::SineGenerator;
use dsp::negate_signal::NegateSignal;
use dsp::add_signals::AddSignals;
use dsp::evaluatable::Evaluatable;

// Constants:
const NUM_CHANNELS: i32 = 2;
const NUM_SECONDS: i32 = 5;
const SAMPLE_RATE: f64 = 44100.0;
const FRAMES_PER_BUFFER: u32 = 64;
const BUFFER_SECONDS: f64 = 0.050;  // Buffer samples for 50ms -- reduces chances of underrun

fn main() {
    // Create input sound generators:
    let sine_generator1 = SineGenerator::new(44100.0, 400.0, 0.3);
    let sine_generator2 = SineGenerator::new(44100.0, 400.0, 0.3);

    // Negate one of the sine waves:
    let negated_sine_2 = NegateSignal::new(sine_generator2);

    // Add sound generators together -- result should be silence:
    let add_vec: Vec<Box<Evaluatable>> = vec![Box::new(sine_generator1), Box::new(negated_sine_2)];
    let add_signals = AddSignals::new(add_vec);

    // Play our resulting audio:
    run(add_signals).unwrap()
}

fn run<E: Evaluatable + 'static>(mut generator: E) -> Result<(), pa::Error> {
    // Fire up ye olde PortAudio:
    let pa = try!(pa::PortAudio::new());

    // Set up our settings - set a buffer amount to try to reduce underruns:
    let mut settings = try!(pa.default_output_stream_settings(NUM_CHANNELS, SAMPLE_RATE, FRAMES_PER_BUFFER));
    settings.params.suggested_latency = BUFFER_SECONDS;

    // This callback function will be called by PortAudio when it needs more audio samples.
    // It may be called at interrupt level on some machines, so don't do anything that could mess
    // up the system like dynamic resource allocation or I/O. (although doing so seems to be fine on
    // my machine...?)
    //
    // The job of this callback is to fill up the buffer that PortAudio tells us to fill up.
    // Each "frame" represents one sample for each channel that we have, so we need to put a total
    // of (NUM_CHANNELS * frames) samples into the buffer.
    // The samples are "interleaved" by default, so the structure of buffer looks like:
    // [ch0_sample0, ch1_sample0, ch0_sample1, ch1_sample1, ch0_sample2, ch1_sample2, ...]
    let callback = move |pa::OutputStreamCallbackArgs { buffer, frames, .. }| {
        let mut i = 0;
        for _ in 0..frames {
            let samples = generator.evaluate();
            buffer[i]   = samples.0;
            buffer[i+1] = samples.1;
            i += 2;
        }
        pa::Continue
    };

    // Now that we have the settings and the callback function set up, we can finally open the
    // stream, through which we will actually play audio:
    let mut stream = try!(pa.open_non_blocking_stream(settings, callback));

    // And now that we have the stream, we can start playing sounds!
    try!(stream.start());

    // We're using PortAudio in non-blocking mode, so execution will fall through immedately.
    // Let's sleep for NUM_SECONDS to let PortAudio play sounds for a bit.
    // Note that pa.sleep() will sleep for *at least* NUM_SECONDS, but probably more -- don't depend
    // on pa.sleep() for musical timings or anything like that.
    println!("Play for {} seconds.", NUM_SECONDS);
    pa.sleep(NUM_SECONDS * 1_000);

    // We're done playing, gracefully shut down the stream:
    try!(stream.stop());
    try!(stream.close());

    Ok(())
}<|endoftext|>