<commit_before>// ignore-cross-compile

// The general idea of this test is to enumerate all "interesting" expressions and check that
// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test:
//
// 1. The test focuses on expression nesting, because interactions between different expression
//    types are harder to test manually than single expression types in isolation.
//
// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x +
//    x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct
//    handling of an expression might depend on the expression's parent, but doesn't depend on its
//    siblings or any more distant ancestors.
//
// 3. The test only checks certain expression kinds. The assumption is that similar expression
//    types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer
//    and parser. So if all combinations of exprs involving `if` work correctly, then combinations
//    using `while`, `if let`, and so on will likely work as well.

#![feature(rustc_private)]

extern crate rustc_data_structures;
extern crate syntax;

use rustc_data_structures::thin_vec::ThinVec;
use syntax::ast::*;
use syntax::source_map::{Spanned, DUMMY_SP, FileName};
use syntax::source_map::FilePathMapping;
use syntax::mut_visit::{self, MutVisitor, visit_clobber};
use syntax::parse::{self, ParseSess};
use syntax::print::pprust;
use syntax::ptr::P;

fn parse_expr(ps: &ParseSess, src: &str) -> P<Expr> {
    let src_as_string = src.to_string();

    let mut p = parse::new_parser_from_source_str(ps,
                                                  FileName::Custom(src_as_string.clone()),
                                                  src_as_string);
    p.parse_expr().unwrap()
}

// Helper functions for building exprs
fn expr(kind: ExprKind) -> P<Expr> {
    P(Expr {
        id: DUMMY_NODE_ID,
        node: kind,
        span: DUMMY_SP,
        attrs: ThinVec::new(),
    })
}

fn make_x() -> P<Expr> {
    let seg = PathSegment::from_ident(Ident::from_str("x"));
    let path = Path { segments: vec![seg], span: DUMMY_SP };
    expr(ExprKind::Path(None, path))
}

/// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting"
/// combinations of expression nesting. For example, we explore combinations using `if`, but not
/// `while` or `match`, since those should print and parse in much the same way as `if`.
fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
    if depth == 0 {
        f(make_x());
        return;
    }

    let mut g = |e| f(expr(e));

    for kind in 0 .. 16 {
        match kind {
            0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))),
            1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
            2 => {
                let seg = PathSegment::from_ident(Ident::from_str("x"));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
                            seg.clone(), vec![e, make_x()])));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
                            seg.clone(), vec![make_x(), e])));
            },
            3 => {
                let op = Spanned { span: DUMMY_SP, node: BinOpKind::Add };
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
            },
            4 => {
                let op = Spanned { span: DUMMY_SP, node: BinOpKind::Mul };
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
            },
            5 => {
                let op = Spanned { span: DUMMY_SP, node: BinOpKind::Shl };
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
            },
            6 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
            },
            7 => {
                let block = P(Block {
                    stmts: Vec::new(),
                    id: DUMMY_NODE_ID,
                    rules: BlockCheckMode::Default,
                    span: DUMMY_SP,
                });
                iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
            },
            8 => {
                let decl = P(FnDecl {
                    inputs: vec![],
                    output: FunctionRetTy::Default(DUMMY_SP),
                    c_variadic: false,
                });
                iter_exprs(depth - 1, &mut |e| g(
                        ExprKind::Closure(CaptureBy::Value,
                                          IsAsync::NotAsync,
                                          Movability::Movable,
                                          decl.clone(),
                                          e,
                                          DUMMY_SP)));
            },
            9 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x())));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e)));
            },
            10 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f"))));
            },
            11 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
                            Some(e), Some(make_x()), RangeLimits::HalfOpen)));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
                            Some(make_x()), Some(e), RangeLimits::HalfOpen)));
            },
            12 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::AddrOf(Mutability::Immutable, e)));
            },
            13 => {
                g(ExprKind::Ret(None));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e))));
            },
            14 => {
                let path = Path::from_ident(Ident::from_str("S"));
                g(ExprKind::Struct(path, vec![], Some(make_x())));
            },
            15 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
            },
            _ => panic!("bad counter value in iter_exprs"),
        }
    }
}

// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed.

/// `MutVisitor` that removes all `ExprKind::Paren` nodes.
struct RemoveParens;

impl MutVisitor for RemoveParens {
    fn visit_expr(&mut self, e: &mut P<Expr>) {
        match e.node.clone() {
            ExprKind::Paren(inner) => *e = inner,
            _ => {}
        };
        mut_visit::noop_visit_expr(e, self);
    }
}

/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`.
struct AddParens;

impl MutVisitor for AddParens {
    fn visit_expr(&mut self, e: &mut P<Expr>) {
        mut_visit::noop_visit_expr(e, self);
        visit_clobber(e, |e| {
            P(Expr {
                id: DUMMY_NODE_ID,
                node: ExprKind::Paren(e),
                span: DUMMY_SP,
                attrs: ThinVec::new(),
            })
        });
    }
}

fn main() {
    syntax::with_default_globals(|| run());
}

fn run() {
    let ps = ParseSess::new(FilePathMapping::empty());

    iter_exprs(2, &mut |mut e| {
        // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,
        // modulo placement of `Paren` nodes.
        let printed = pprust::expr_to_string(&e);
        println!("printed: {}", printed);

        let mut parsed = parse_expr(&ps, &printed);

        // We want to know if `parsed` is structurally identical to `e`, ignoring trivial
        // differences like placement of `Paren`s or the exact ranges of node spans.
        // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s
        // everywhere we can, then pretty-print. This should give an unambiguous representation of
        // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't
        // relying on the correctness of the very thing we're testing.
        RemoveParens.visit_expr(&mut e);
        AddParens.visit_expr(&mut e);
        let text1 = pprust::expr_to_string(&e);
        RemoveParens.visit_expr(&mut parsed);
        AddParens.visit_expr(&mut parsed);
        let text2 = pprust::expr_to_string(&parsed);
        assert!(text1 == text2,
                "exprs are not equal:\n  e =      {:?}\n  parsed = {:?}",
                text1, text2);
    });
}
<commit_msg>let_chains: Add test cases to pprust-expr-roundtrip.<commit_after>// ignore-cross-compile

// The general idea of this test is to enumerate all "interesting" expressions and check that
// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test:
//
// 1. The test focuses on expression nesting, because interactions between different expression
//    types are harder to test manually than single expression types in isolation.
//
// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x +
//    x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct
//    handling of an expression might depend on the expression's parent, but doesn't depend on its
//    siblings or any more distant ancestors.
//
// 3. The test only checks certain expression kinds. The assumption is that similar expression
//    types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer
//    and parser. So if all combinations of exprs involving `if` work correctly, then combinations
//    using `while`, `if let`, and so on will likely work as well.

#![feature(rustc_private)]

extern crate rustc_data_structures;
extern crate syntax;

use rustc_data_structures::thin_vec::ThinVec;
use syntax::ast::*;
use syntax::source_map::{Spanned, DUMMY_SP, FileName};
use syntax::source_map::FilePathMapping;
use syntax::mut_visit::{self, MutVisitor, visit_clobber};
use syntax::parse::{self, ParseSess};
use syntax::print::pprust;
use syntax::ptr::P;

fn parse_expr(ps: &ParseSess, src: &str) -> P<Expr> {
    let src_as_string = src.to_string();

    let mut p = parse::new_parser_from_source_str(ps,
                                                  FileName::Custom(src_as_string.clone()),
                                                  src_as_string);
    p.parse_expr().unwrap()
}

// Helper functions for building exprs
fn expr(kind: ExprKind) -> P<Expr> {
    P(Expr {
        id: DUMMY_NODE_ID,
        node: kind,
        span: DUMMY_SP,
        attrs: ThinVec::new(),
    })
}

fn make_x() -> P<Expr> {
    let seg = PathSegment::from_ident(Ident::from_str("x"));
    let path = Path { segments: vec![seg], span: DUMMY_SP };
    expr(ExprKind::Path(None, path))
}

/// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting"
/// combinations of expression nesting. For example, we explore combinations using `if`, but not
/// `while` or `match`, since those should print and parse in much the same way as `if`.
fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
    if depth == 0 {
        f(make_x());
        return;
    }

    let mut g = |e| f(expr(e));

    for kind in 0..=19 {
        match kind {
            0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))),
            1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
            2 => {
                let seg = PathSegment::from_ident(Ident::from_str("x"));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
                            seg.clone(), vec![e, make_x()])));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
                            seg.clone(), vec![make_x(), e])));
            },
            3..=8 => {
                let op = Spanned {
                    span: DUMMY_SP,
                    node: match kind {
                        3 => BinOpKind::Add,
                        4 => BinOpKind::Mul,
                        5 => BinOpKind::Shl,
                        6 => BinOpKind::And,
                        7 => BinOpKind::Or,
                        8 => BinOpKind::Lt,
                        _ => unreachable!(),
                    }
                };
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
            },
            9 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
            },
            10 => {
                let block = P(Block {
                    stmts: Vec::new(),
                    id: DUMMY_NODE_ID,
                    rules: BlockCheckMode::Default,
                    span: DUMMY_SP,
                });
                iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
            },
            11 => {
                let decl = P(FnDecl {
                    inputs: vec![],
                    output: FunctionRetTy::Default(DUMMY_SP),
                    c_variadic: false,
                });
                iter_exprs(depth - 1, &mut |e| g(
                        ExprKind::Closure(CaptureBy::Value,
                                          IsAsync::NotAsync,
                                          Movability::Movable,
                                          decl.clone(),
                                          e,
                                          DUMMY_SP)));
            },
            12 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x())));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e)));
            },
            13 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f"))));
            },
            14 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
                            Some(e), Some(make_x()), RangeLimits::HalfOpen)));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
                            Some(make_x()), Some(e), RangeLimits::HalfOpen)));
            },
            15 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::AddrOf(Mutability::Immutable, e)));
            },
            16 => {
                g(ExprKind::Ret(None));
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e))));
            },
            17 => {
                let path = Path::from_ident(Ident::from_str("S"));
                g(ExprKind::Struct(path, vec![], Some(make_x())));
            },
            18 => {
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
            },
            19 => {
                let ps = vec![P(Pat {
                    id: DUMMY_NODE_ID,
                    node: PatKind::Wild,
                    span: DUMMY_SP,
                })];
                iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(ps.clone(), e)))
            },
            _ => panic!("bad counter value in iter_exprs"),
        }
    }
}

// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed.

/// `MutVisitor` that removes all `ExprKind::Paren` nodes.
struct RemoveParens;

impl MutVisitor for RemoveParens {
    fn visit_expr(&mut self, e: &mut P<Expr>) {
        match e.node.clone() {
            ExprKind::Paren(inner) => *e = inner,
            _ => {}
        };
        mut_visit::noop_visit_expr(e, self);
    }
}

/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`.
struct AddParens;

impl MutVisitor for AddParens {
    fn visit_expr(&mut self, e: &mut P<Expr>) {
        mut_visit::noop_visit_expr(e, self);
        visit_clobber(e, |e| {
            P(Expr {
                id: DUMMY_NODE_ID,
                node: ExprKind::Paren(e),
                span: DUMMY_SP,
                attrs: ThinVec::new(),
            })
        });
    }
}

fn main() {
    syntax::with_default_globals(|| run());
}

fn run() {
    let ps = ParseSess::new(FilePathMapping::empty());

    iter_exprs(2, &mut |mut e| {
        // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,
        // modulo placement of `Paren` nodes.
        let printed = pprust::expr_to_string(&e);
        println!("printed: {}", printed);

        let mut parsed = parse_expr(&ps, &printed);

        // We want to know if `parsed` is structurally identical to `e`, ignoring trivial
        // differences like placement of `Paren`s or the exact ranges of node spans.
        // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s
        // everywhere we can, then pretty-print. This should give an unambiguous representation of
        // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't
        // relying on the correctness of the very thing we're testing.
        RemoveParens.visit_expr(&mut e);
        AddParens.visit_expr(&mut e);
        let text1 = pprust::expr_to_string(&e);
        RemoveParens.visit_expr(&mut parsed);
        AddParens.visit_expr(&mut parsed);
        let text2 = pprust::expr_to_string(&parsed);
        assert!(text1 == text2,
                "exprs are not equal:\n  e =      {:?}\n  parsed = {:?}",
                text1, text2);
    });
}
<|endoftext|>


<commit_before>use hyper::header::ContentType;
use hyper::server::Response;

use makeresponse::MakeResponse;

#[derive(Default)]
pub struct Favicon;

const FAVICON: &'static [u8] = include_bytes!("tin-can.png");

impl MakeResponse for Favicon {
    fn content_type(&self) -> ContentType {
        ContentType::png()
    }

    fn content(&self) -> &[u8] {
        FAVICON
    }
}
<commit_msg>Drop unused import<commit_after>use hyper::header::ContentType;

use makeresponse::MakeResponse;

#[derive(Default)]
pub struct Favicon;

const FAVICON: &'static [u8] = include_bytes!("tin-can.png");

impl MakeResponse for Favicon {
    fn content_type(&self) -> ContentType {
        ContentType::png()
    }

    fn content(&self) -> &[u8] {
        FAVICON
    }
}
<|endoftext|>


<commit_before>use std::cmp;

use grid_traits::GridDimensions;
use units::{ColumnIndex, ColumnLength, ColumnsCount, EdgesCount, NodesCount, RowIndex, RowLength,
            RowsCount};

#[derive(Debug, Copy, Clone)]
pub struct RectGridDimensions {
    row_width: RowLength,
    column_height: ColumnLength,
}

impl RectGridDimensions {
    pub fn new(row_width: RowLength, column_height: ColumnLength) -> RectGridDimensions {
        RectGridDimensions {
            row_width: row_width,
            column_height: column_height,
        }
    }
}

impl GridDimensions for RectGridDimensions {

    #[inline(always)]
    fn size(&self) -> NodesCount {
        NodesCount(self.row_width.0 * self.column_height.0)
    }

    #[inline(always)]
    fn rows(&self) -> RowsCount {
        RowsCount(self.column_height.0)
    }

    #[inline(always)]
    fn row_length(&self, _: Option<RowIndex>) -> Option<RowLength> {
        Some(self.row_width)
    }

    #[inline(always)]
    fn columns(&self) -> ColumnsCount {
        ColumnsCount(self.row_width.0)
    }

    #[inline(always)]
    fn column_length(&self, _: Option<ColumnIndex>) -> ColumnLength {
        self.column_height
    }

    fn graph_size(&self) -> (NodesCount, EdgesCount) {
        let cells_count = self.size();
        let edges_count_hint = 4 * cells_count.0 -
                               4 * cmp::max(self.row_width.0, self.column_height.0);
        (cells_count, EdgesCount(edges_count_hint))
    }
}
<commit_msg>Formatting.<commit_after>use std::cmp;

use grid_traits::GridDimensions;
use units::{ColumnIndex, ColumnLength, ColumnsCount, EdgesCount, NodesCount, RowIndex, RowLength,
            RowsCount};

#[derive(Debug, Copy, Clone)]
pub struct RectGridDimensions {
    row_width: RowLength,
    column_height: ColumnLength,
}

impl RectGridDimensions {
    pub fn new(row_width: RowLength, column_height: ColumnLength) -> RectGridDimensions {
        RectGridDimensions {
            row_width: row_width,
            column_height: column_height,
        }
    }
}

impl GridDimensions for RectGridDimensions {
    #[inline(always)]
    fn size(&self) -> NodesCount {
        NodesCount(self.row_width.0 * self.column_height.0)
    }

    #[inline(always)]
    fn rows(&self) -> RowsCount {
        RowsCount(self.column_height.0)
    }

    #[inline(always)]
    fn row_length(&self, _: Option<RowIndex>) -> Option<RowLength> {
        Some(self.row_width)
    }

    #[inline(always)]
    fn columns(&self) -> ColumnsCount {
        ColumnsCount(self.row_width.0)
    }

    #[inline(always)]
    fn column_length(&self, _: Option<ColumnIndex>) -> ColumnLength {
        self.column_height
    }

    fn graph_size(&self) -> (NodesCount, EdgesCount) {
        let cells_count = self.size();
        let edges_count_hint = 4 * cells_count.0 -
                               4 * cmp::max(self.row_width.0, self.column_height.0);
        (cells_count, EdgesCount(edges_count_hint))
    }
}
<|endoftext|>


<commit_before>use super::types::{ShardAndCommittee, ValidatorRecord, ChainConfig};
use super::TransitionError;
use super::shuffle;
use std::cmp::min;

type DelegatedSlot = Vec<ShardAndCommittee>;
type DelegatedCycle = Vec<DelegatedSlot>;

/*
 * Iterator for the honey_badger_split function
 */
struct Split<'a, T: 'a> {
    n: usize,
    current_pos: usize,
    list: &'a [T],
    list_length: usize
}

impl<'a,T> Iterator for Split<'a, T> {
    type Item = &'a [T];

    fn next(&mut self) -> Option<Self::Item> {
        self.current_pos +=1;
        if self.current_pos <= self.n {
            match self.list.get(self.list_length*(self.current_pos-1)/self.n..self.list_length*self.current_pos/self.n) {
                Some(v) => Some(v),
                None => unreachable!()
            }
        }
        else {
            None
        }
    }
}

/*
 * splits a slice into chunks of size n. All postive n values are applicable,
 * hence the honey_badger prefix.
 * Returns an iterator over the original list.
 */
trait SplitExt<T> {
    fn honey_badger_split(&self, n: usize) -> Split<T>;
}

impl<T> SplitExt<T> for [T] {

    fn honey_badger_split(&self, n: usize) -> Split<T> {
        Split {
            n: n,
            current_pos: 0,
            list: &self,
            list_length: self.len(),
        }
    }
}

/* Produce a vector of validators indicies where those validators start and end
 * dynasties are within the supplied `dynasty`.
*/
fn active_validator_indicies(
    dynasty: &u64,
    validators: &Vec<ValidatorRecord>)
    -> Vec<usize>
{
    validators.iter()
        .enumerate()
        .filter_map(|(i, validator)| {
            if (validator.start_dynasty >= *dynasty) &
                (validator.end_dynasty < *dynasty)
            {
                Some(i)
            } else {
                None
            }
        })
        .collect()
}

/*
 * Delegates active validators into slots for a given cycle, given a random seed.
 * Returns a vector or ShardAndComitte vectors representing the shards and committiees for
 * each slot.
 * References get_new_shuffling (ethereum 2.1 specification)
 */
pub fn delegate_validators(
    seed: &[u8],
    validators: &Vec<ValidatorRecord>,
    dynasty: &u64,
    crosslinking_shard_start: &u16,
    config: &ChainConfig)
    -> Result<DelegatedCycle, TransitionError>
{
    let shuffled_validator_indices = {
        let mut validator_indices = active_validator_indicies(dynasty, validators);
        match shuffle(seed, validator_indices) {
            Ok(shuffled) => shuffled,
            _ => return Err(TransitionError::InvalidInput(
                    String::from("Shuffle list length exceed.")))
        }
    };
    let shard_indices = (0_usize..config.shard_count as usize).into_iter().collect();
    let crosslinking_shard_start = *crosslinking_shard_start as usize;
    let cycle_length = config.cycle_length as usize;
    let min_committee_size = config.min_committee_size as usize;
    generate_cycle(
        &shuffled_validator_indices,
        &shard_indices,
        &crosslinking_shard_start,
        &cycle_length,
        &min_committee_size)
}

/*
 * Given the validator list, delegates the validators into slots and comittees for a given cycle.
 */
fn generate_cycle(
    validator_indices: &Vec<usize>,
    shard_indices: &Vec<usize>,
    crosslinking_shard_start: &usize,
    cycle_length: &usize,
    min_committee_size: &usize)
    -> Result<DelegatedCycle, TransitionError>
{

    let validator_count = validator_indices.len();
    let shard_count = shard_indices.len();

    if shard_count / cycle_length == 0 {
	    return Err(TransitionError::InvalidInput(String::from("Number of
					    shards needs to be greater than
					    cycle length")));

    }

    let (committees_per_slot, slots_per_committee) = {
        if validator_count >= cycle_length * min_committee_size {
            let committees_per_slot = min(validator_count / cycle_length /
			    (min_committee_size * 2) + 1, shard_count /
			    cycle_length);
            let slots_per_committee = 1;
            (committees_per_slot, slots_per_committee)
        } else {
            let committees_per_slot = 1;
            let mut slots_per_committee = 1;
            while (validator_count * slots_per_committee < cycle_length * min_committee_size) &
                (slots_per_committee < *cycle_length) {
                slots_per_committee = slots_per_committee * 2;
            }
            (committees_per_slot, slots_per_committee)
        }
    };

    let cycle = validator_indices.honey_badger_split(*cycle_length)
        .enumerate()
        .map(|(i, slot_indices)| {
            let shard_id_start = crosslinking_shard_start + i * committees_per_slot / slots_per_committee;
            return slot_indices.honey_badger_split(committees_per_slot)
                .enumerate()
                .map(|(j, shard_indices)| {
                    return ShardAndCommittee{
                        shard_id: ((shard_id_start + j) % shard_count) as u16,
                        committee: shard_indices.to_vec(),
                    }
                })
                .collect()
        })
        .collect();
    Ok(cycle)
}

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

    fn generate_cycle_helper(
        validator_count: &usize,
        shard_count: &usize,
        crosslinking_shard_start: &usize,
        cycle_length: &usize,
        min_committee_size: &usize)
        -> (Vec<usize>, Vec<usize>, Result<DelegatedCycle, TransitionError>)
    {
        let validator_indices = (0_usize..*validator_count).into_iter().collect();
        let shard_indices = (0_usize..*shard_count).into_iter().collect();
        let result = generate_cycle(
            &validator_indices,
            &shard_indices,
            &crosslinking_shard_start,
            &cycle_length,
            &min_committee_size);
        (validator_indices, shard_indices, result)
    }

    #[allow(dead_code)]
    fn print_cycle(cycle: &DelegatedCycle) {
        cycle.iter()
            .enumerate()
            .for_each(|(i, slot)| {
                println!("slot {:?}", &i);
                slot.iter()
                    .enumerate()
                    .for_each(|(i, sac)| {
                        println!("#{:?}\tshard_id={}\tcommittee.len()={}",
                            &i, &sac.shard_id, &sac.committee.len())
                    })
            });
    }

    fn flatten_validators(cycle: &DelegatedCycle)
        -> Vec<usize>
    {
        let mut flattened = vec![];
        for slot in cycle.iter() {
            for sac in slot.iter() {
                for validator in sac.committee.iter() {
                    flattened.push(*validator);
                }
            }
        }
        flattened
    }

    fn flatten_and_dedup_shards(cycle: &DelegatedCycle)
        -> Vec<usize>
    {
        let mut flattened = vec![];
        for slot in cycle.iter() {
            for sac in slot.iter() {
                flattened.push(sac.shard_id as usize);
            }
        }
        flattened.dedup();
        flattened
    }

    fn flatten_shards_in_slots(cycle: &DelegatedCycle)
        -> Vec<Vec<usize>>
    {
        let mut shards_in_slots: Vec<Vec<usize>> = vec![];
        for slot in cycle.iter() {
            let mut shards: Vec<usize> = vec![];
            for sac in slot.iter() {
                shards.push(sac.shard_id as usize);
            }
            shards_in_slots.push(shards);
        }
        shards_in_slots
    }

    #[test]
    fn test_generate_cycle() {
        let validator_count: usize = 100;
        let shard_count: usize = 10;
        let crosslinking_shard_start: usize = 0;
        let cycle_length: usize = 20;
        let min_committee_size: usize = 10;
        let (validators, shards, result) = generate_cycle_helper(
            &validator_count,
            &shard_count,
            &crosslinking_shard_start,
            &cycle_length,
            &min_committee_size);
        let cycle = result.unwrap();

        let assigned_validators = flatten_validators(&cycle);
        let assigned_shards = flatten_and_dedup_shards(&cycle);
        let shards_in_slots = flatten_shards_in_slots(&cycle);
        assert_eq!(assigned_validators, validators, "Validator assignment incorrect");
        assert_eq!(assigned_shards, shards, "Shard assignment incorrect");

        let expected_shards_in_slots: Vec<Vec<usize>> = vec![
            vec![0], vec![0],   // Each line is 2 slots..
            vec![1], vec![1],
            vec![2], vec![2],
            vec![3], vec![3],
            vec![4], vec![4],
            vec![5], vec![5],
            vec![6], vec![6],
            vec![7], vec![7],
            vec![8], vec![8],
            vec![9], vec![9],
        ];
        // assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots));
        assert_eq!(expected_shards_in_slots, shards_in_slots, "Shard assignment incorrect.")
    }

    #[test]
    // Check that the committees per slot is upper bounded by shard count
    fn test_generate_cycle_committees_bounded() {
        let validator_count: usize = 1001;
        let shard_count: usize = 15;
        let crosslinking_shard_start: usize = 0;
        let cycle_length: usize = 10;
        let min_committee_size: usize = 10;
        let (validators, shards, result) = generate_cycle_helper(
            &validator_count,
            &shard_count,
            &crosslinking_shard_start,
            &cycle_length,
            &min_committee_size);
        let cycle = result.unwrap();
        print_cycle(&cycle);
        let assigned_validators = flatten_validators(&cycle);
        let assigned_shards = flatten_and_dedup_shards(&cycle);
        let shards_in_slots = flatten_shards_in_slots(&cycle);
        assert_eq!(assigned_validators, validators, "Validator assignment incorrect");
        assert_eq!(assigned_shards, shards, "Shard assignment incorrect");

        let expected_shards_in_slots: Vec<Vec<usize>> = vec![
            vec![0], vec![0],   // Each line is 2 slots..
            vec![1], vec![1],
            vec![2], vec![2],
            vec![3], vec![3],
            vec![4], vec![4],
            vec![5], vec![5],
            vec![6], vec![6],
            vec![7], vec![7],
            vec![8], vec![8],
            vec![9], vec![9],
        ];
        // assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots));
        assert_eq!(expected_shards_in_slots, shards_in_slots, "Shard assignment incorrect.")
    }
}
<commit_msg>Corrects cycle tests<commit_after>use super::types::{ShardAndCommittee, ValidatorRecord, ChainConfig};
use super::TransitionError;
use super::shuffle;
use std::cmp::min;

type DelegatedSlot = Vec<ShardAndCommittee>;
type DelegatedCycle = Vec<DelegatedSlot>;

/*
 * Iterator for the honey_badger_split function
 */
struct Split<'a, T: 'a> {
    n: usize,
    current_pos: usize,
    list: &'a [T],
    list_length: usize
}

impl<'a,T> Iterator for Split<'a, T> {
    type Item = &'a [T];

    fn next(&mut self) -> Option<Self::Item> {
        self.current_pos +=1;
        if self.current_pos <= self.n {
            match self.list.get(self.list_length*(self.current_pos-1)/self.n..self.list_length*self.current_pos/self.n) {
                Some(v) => Some(v),
                None => unreachable!()
            }
        }
        else {
            None
        }
    }
}

/*
 * splits a slice into chunks of size n. All postive n values are applicable,
 * hence the honey_badger prefix.
 * Returns an iterator over the original list.
 */
trait SplitExt<T> {
    fn honey_badger_split(&self, n: usize) -> Split<T>;
}

impl<T> SplitExt<T> for [T] {

    fn honey_badger_split(&self, n: usize) -> Split<T> {
        Split {
            n: n,
            current_pos: 0,
            list: &self,
            list_length: self.len(),
        }
    }
}

/* Produce a vector of validators indicies where those validators start and end
 * dynasties are within the supplied `dynasty`.
*/
fn active_validator_indicies(
    dynasty: &u64,
    validators: &Vec<ValidatorRecord>)
    -> Vec<usize>
{
    validators.iter()
        .enumerate()
        .filter_map(|(i, validator)| {
            if (validator.start_dynasty >= *dynasty) &
                (validator.end_dynasty < *dynasty)
            {
                Some(i)
            } else {
                None
            }
        })
        .collect()
}

/*
 * Delegates active validators into slots for a given cycle, given a random seed.
 * Returns a vector or ShardAndComitte vectors representing the shards and committiees for
 * each slot.
 * References get_new_shuffling (ethereum 2.1 specification)
 */
pub fn delegate_validators(
    seed: &[u8],
    validators: &Vec<ValidatorRecord>,
    dynasty: &u64,
    crosslinking_shard_start: &u16,
    config: &ChainConfig)
    -> Result<DelegatedCycle, TransitionError>
{
    let shuffled_validator_indices = {
        let mut validator_indices = active_validator_indicies(dynasty, validators);
        match shuffle(seed, validator_indices) {
            Ok(shuffled) => shuffled,
            _ => return Err(TransitionError::InvalidInput(
                    String::from("Shuffle list length exceed.")))
        }
    };
    let shard_indices = (0_usize..config.shard_count as usize).into_iter().collect();
    let crosslinking_shard_start = *crosslinking_shard_start as usize;
    let cycle_length = config.cycle_length as usize;
    let min_committee_size = config.min_committee_size as usize;
    generate_cycle(
        &shuffled_validator_indices,
        &shard_indices,
        &crosslinking_shard_start,
        &cycle_length,
        &min_committee_size)
}

/*
 * Given the validator list, delegates the validators into slots and comittees for a given cycle.
 */
fn generate_cycle(
    validator_indices: &Vec<usize>,
    shard_indices: &Vec<usize>,
    crosslinking_shard_start: &usize,
    cycle_length: &usize,
    min_committee_size: &usize)
    -> Result<DelegatedCycle, TransitionError>
{

    let validator_count = validator_indices.len();
    let shard_count = shard_indices.len();

    if shard_count / cycle_length == 0 {
	    return Err(TransitionError::InvalidInput(String::from("Number of
					    shards needs to be greater than
					    cycle length")));

    }

    let (committees_per_slot, slots_per_committee) = {
        if validator_count >= cycle_length * min_committee_size {
            let committees_per_slot = min(validator_count / cycle_length /
			    (min_committee_size * 2) + 1, shard_count /
			    cycle_length);
            let slots_per_committee = 1;
            (committees_per_slot, slots_per_committee)
        } else {
            let committees_per_slot = 1;
            let mut slots_per_committee = 1;
            while (validator_count * slots_per_committee < cycle_length * min_committee_size) &
                (slots_per_committee < *cycle_length) {
                slots_per_committee = slots_per_committee * 2;
            }
            (committees_per_slot, slots_per_committee)
        }
    };

    let cycle = validator_indices.honey_badger_split(*cycle_length)
        .enumerate()
        .map(|(i, slot_indices)| {
            let shard_id_start = crosslinking_shard_start + i * committees_per_slot / slots_per_committee;
            return slot_indices.honey_badger_split(committees_per_slot)
                .enumerate()
                .map(|(j, shard_indices)| {
                    return ShardAndCommittee{
                        shard_id: ((shard_id_start + j) % shard_count) as u16,
                        committee: shard_indices.to_vec(),
                    }
                })
                .collect()
        })
        .collect();
    Ok(cycle)
}

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

    fn generate_cycle_helper(
        validator_count: &usize,
        shard_count: &usize,
        crosslinking_shard_start: &usize,
        cycle_length: &usize,
        min_committee_size: &usize)
        -> (Vec<usize>, Vec<usize>, Result<DelegatedCycle, TransitionError>)
    {
        let validator_indices = (0_usize..*validator_count).into_iter().collect();
        let shard_indices = (0_usize..*shard_count).into_iter().collect();
        let result = generate_cycle(
            &validator_indices,
            &shard_indices,
            &crosslinking_shard_start,
            &cycle_length,
            &min_committee_size);
        (validator_indices, shard_indices, result)
    }

    #[allow(dead_code)]
    fn print_cycle(cycle: &DelegatedCycle) {
        cycle.iter()
            .enumerate()
            .for_each(|(i, slot)| {
                println!("slot {:?}", &i);
                slot.iter()
                    .enumerate()
                    .for_each(|(i, sac)| {
                        println!("#{:?}\tshard_id={}\tcommittee.len()={}",
                            &i, &sac.shard_id, &sac.committee.len())
                    })
            });
    }

    fn flatten_validators(cycle: &DelegatedCycle)
        -> Vec<usize>
    {
        let mut flattened = vec![];
        for slot in cycle.iter() {
            for sac in slot.iter() {
                for validator in sac.committee.iter() {
                    flattened.push(*validator);
                }
            }
        }
        flattened
    }

    fn flatten_and_dedup_shards(cycle: &DelegatedCycle)
        -> Vec<usize>
    {
        let mut flattened = vec![];
        for slot in cycle.iter() {
            for sac in slot.iter() {
                flattened.push(sac.shard_id as usize);
            }
        }
        flattened.dedup();
        flattened
    }

    fn flatten_shards_in_slots(cycle: &DelegatedCycle)
        -> Vec<Vec<usize>>
    {
        let mut shards_in_slots: Vec<Vec<usize>> = vec![];
        for slot in cycle.iter() {
            let mut shards: Vec<usize> = vec![];
            for sac in slot.iter() {
                shards.push(sac.shard_id as usize);
            }
            shards_in_slots.push(shards);
        }
        shards_in_slots
    }

    // TODO: Improve these tests to check committee lengths
    #[test]
    fn test_generate_cycle() {
        let validator_count: usize = 100;
        let shard_count: usize = 20;
        let crosslinking_shard_start: usize = 0;
        let cycle_length: usize = 20;
        let min_committee_size: usize = 10;
        let (validators, shards, result) = generate_cycle_helper(
            &validator_count,
            &shard_count,
            &crosslinking_shard_start,
            &cycle_length,
            &min_committee_size);
        let cycle = result.unwrap();

        let assigned_validators = flatten_validators(&cycle);
        let assigned_shards = flatten_and_dedup_shards(&cycle);
        let shards_in_slots = flatten_shards_in_slots(&cycle);
        let expected_shards = shards.get(0..10).unwrap();
        assert_eq!(assigned_validators, validators, "Validator assignment incorrect");
        assert_eq!(assigned_shards, expected_shards, "Shard assignment incorrect");

        let expected_shards_in_slots: Vec<Vec<usize>> = vec![
            vec![0], vec![0],   // Each line is 2 slots..
            vec![1], vec![1],
            vec![2], vec![2],
            vec![3], vec![3],
            vec![4], vec![4],
            vec![5], vec![5],
            vec![6], vec![6],
            vec![7], vec![7],
            vec![8], vec![8],
            vec![9], vec![9],
        ];
        // assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots));
        assert_eq!(expected_shards_in_slots, shards_in_slots, "Shard assignment incorrect.")
    }

    #[test]
    // Check that the committees per slot is upper bounded by shard count
    fn test_generate_cycle_committees_bounded() {
        let validator_count: usize = 523;
        let shard_count: usize = 31;
        let crosslinking_shard_start: usize = 0;
        let cycle_length: usize = 11;
        let min_committee_size: usize = 5;
        let (validators, shards, result) = generate_cycle_helper(
            &validator_count,
            &shard_count,
            &crosslinking_shard_start,
            &cycle_length,
            &min_committee_size);
        let cycle = result.unwrap();
        let assigned_validators = flatten_validators(&cycle);
        let assigned_shards = flatten_and_dedup_shards(&cycle);
        let shards_in_slots = flatten_shards_in_slots(&cycle);
        let expected_shards = shards.get(0..22).unwrap();
        let expected_shards_in_slots: Vec<Vec<usize>> =
            (0_usize..11_usize) .map(|x| vec![2*x,2*x+1]).collect();
        assert_eq!(assigned_validators, validators, "Validator assignment incorrect");
        assert_eq!(assigned_shards, expected_shards, "Shard assignment incorrect");
        // assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots));
        assert_eq!(expected_shards_in_slots, shards_in_slots, "Shard assignment incorrect.")
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Handle_a_signal

extern crate libc;
extern crate time;

#[cfg(unix)]
fn main() {
    use std::mem;
    use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
    use std::thread;
    use std::time::Duration;
    use libc::SIGINT;
    // The time between ticks of our counter.
    let duration = Duration::from_secs(1) / 2;
    // "SIGINT received" global variable.
    static mut GOT_SIGINT: AtomicBool = ATOMIC_BOOL_INIT;
    unsafe {
        // Initially, "SIGINT received" is false.
        GOT_SIGINT.store(false, Ordering::Release);
        // Interrupt handler that handles the SIGINT signal
        unsafe fn handle_sigint() {
            // It is dangerous to perform any system calls in interrupts, so just set the atomic
            // "SIGINT received" global to true when it arrives.
            GOT_SIGINT.store(true, Ordering::Release);
        }
        // Make handle_sigint the signal handler for SIGINT.
        libc::signal(SIGINT, mem::transmute(handle_sigint));
    }
    // Get the start time...
    let start = time::precise_time_ns();
    // Integer counter
    let mut i = 0u32;
    // Every `duration`...
    loop {
        thread::sleep(duration);
        // Break if SIGINT was handled
        if unsafe { GOT_SIGINT.load(Ordering::Acquire) } {
            break;
        }
        // Otherwise, increment and display the integer and continue the loop.
        i += 1;
        println!("{}", i);
    }
    // Get the end time.
    let end = time::precise_time_ns();
    // Compute the difference
    let diff = Duration::from_millis((end - start) / 1000000);
    // Print the difference and exit
    println!("Program has run for {} seconds", diff.as_secs());
}

#[cfg(not(unix))]
fn main() {
    println!("Not supported on this platform");
}
<commit_msg>fix zero-sized fn warning (#513)<commit_after>// http://rosettacode.org/wiki/Handle_a_signal

extern crate libc;
extern crate time;

#[cfg(unix)]
fn main() {
    use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
    use std::thread;
    use std::time::Duration;

    use libc::{SIGINT, sighandler_t};

    // The time between ticks of our counter.
    let duration = Duration::from_secs(1) / 2;

    // "SIGINT received" global variable.
    static mut GOT_SIGINT: AtomicBool = ATOMIC_BOOL_INIT;

    unsafe {
        // Initially, "SIGINT received" is false.
        GOT_SIGINT.store(false, Ordering::Release);
        // Interrupt handler that handles the SIGINT signal
        unsafe fn handle_sigint() {
            // It is dangerous to perform any system calls in interrupts, so just set the atomic
            // "SIGINT received" global to true when it arrives.
            GOT_SIGINT.store(true, Ordering::Release);
        }
        // Make handle_sigint the signal handler for SIGINT.
        libc::signal(SIGINT, handle_sigint as sighandler_t);
    }

    // Get the start time...
    let start = time::precise_time_ns();

    // Integer counter
    let mut i = 0u32;

    // Every `duration`...
    loop {
        thread::sleep(duration);

        // Break if SIGINT was handled
        if unsafe { GOT_SIGINT.load(Ordering::Acquire) } {
            break;
        }

        // Otherwise, increment and display the integer and continue the loop.
        i += 1;
        println!("{}", i);
    }

    // Get the end time.
    let end = time::precise_time_ns();

    // Compute the difference
    let diff = Duration::from_millis((end - start) / 1000000);

    // Print the difference and exit
    println!("Program has run for {} seconds", diff.as_secs());
}

#[cfg(not(unix))]
fn main() {
    println!("Not supported on this platform");
}
<|endoftext|>


<commit_before>use num::traits::Float;

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::ops::{Add, Sub, Mul};
use std::path::Path;

#[derive(Debug, Copy, Clone)]
pub struct Vec2D<T> {
    pub x: T,
    pub y: T,
}

impl<T> Add<Vec2D<T>> for Vec2D<T> where T: Add<T, Output = T> {
    type Output = Vec2D<T>;

    fn add(self, other: Vec2D<T>) -> Vec2D<T> {
        Vec2D { x: self.x + other.x, y: self.y + other.y }
    }
}

impl<T> Sub<Vec2D<T>> for Vec2D<T> where T: Sub<T, Output = T> {
    type Output = Vec2D<T>;

    fn sub(self, other: Vec2D<T>) -> Vec2D<T> {
        Vec2D { x: self.x - other.x, y: self.y - other.y }
    }
}

#[derive(Debug, Copy, Clone)]
pub struct Vec3D<T> {
    pub x: T,
    pub y: T,
    pub z: T,
}

impl<T> Add<Vec3D<T>> for Vec3D<T> where T: Add<T, Output = T> {
    type Output = Vec3D<T>;

    fn add(self, other: Vec3D<T>) -> Vec3D<T> {
        Vec3D { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z }
    }
}

impl<T> Sub<Vec3D<T>> for Vec3D<T> where T: Sub<T, Output = T> {
    type Output = Vec3D<T>;

    fn sub(self, other: Vec3D<T>) -> Vec3D<T> {
        Vec3D { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z }
    }
}

impl<T> Mul<Vec3D<T>> for Vec3D<T> where T: Mul<T, Output = T> + Add<T, Output = T> {
    type Output = T;

    fn mul(self, other: Vec3D<T>) -> T {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
}

impl<T> Vec3D<T> where T: Mul<T, Output = T> + Sub<T, Output = T> + Copy {
    pub fn cross(self, other: Vec3D<T>) -> Vec3D<T> {
        Vec3D {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x
        }
    }
}

impl<T> Vec3D<T> where T: PartialOrd {
    pub fn min_bound(&mut self, v: Vec3D<T>) -> &mut Self {
        if v.x < self.x { self.x = v.x; }
        if v.y < self.y { self.y = v.y; }
        if v.z < self.z { self.z = v.z; }
        self
    }

    pub fn max_bound(&mut self, v: Vec3D<T>) -> &mut Self {
        if v.x > self.x { self.x = v.x; }
        if v.y > self.y { self.y = v.y; }
        if v.z > self.z { self.z = v.z; }
        self
    }
}

impl<T> Vec3D<T> where T: Float {
    pub fn normalized(self) -> Vec3D<T> {
        let l = (self * self).sqrt();

        if l == T::zero() {
            self
        } else {
            Vec3D {
                x: self.x / l,
                y: self.y / l,
                z: self.z / l
            }
        }
    }
}

impl Vec3Df {
    pub fn to_i32(self) -> Vec3Di {
        Vec3Di { x: self.x as i32, y: self.y as i32, z: self.z as i32 }
    }

    pub fn scale(self, s: f64) -> Self {
        Vec3Df { x: self.x * s, y: self.y * s, z: self.z * s }
    }
}

pub type Vec2Di = Vec2D<i32>;
pub type Vec2Du = Vec2D<u32>;
pub type Vec2Df = Vec2D<f64>;

pub type Vec3Di = Vec3D<i32>;
pub type Vec3Du = Vec3D<u32>;
pub type Vec3Df = Vec3D<f64>;

#[derive(Debug)]
pub struct Model {
    pub verts: Vec<Vec3Df>,
    pub faces: Vec<Vec<usize>>,
}

#[derive(Debug)]
struct Facet {
    pub v: usize,
    pub t: usize,
    pub n: usize,
}

fn parse_facet_obj(str: &str) -> Facet {
    let idx: Vec<&str> = str.split('/').collect();

    if idx.len() == 1 {
        Facet { v: idx[0].parse::<usize>().unwrap(), t: 0, n: 0 }
    } else if idx.len() >= 3 {
        Facet {
            v: idx[0].parse::<usize>().unwrap(),
            t: if idx[1] == "" {0} else {idx[1].parse::<usize>().unwrap()},
            n: idx[2].parse::<usize>().unwrap()
        }
    } else {
        Facet { v: 0, t: 0, n: 0 }
    }
}

pub fn load_model_obj<P>(path: P) -> Result<Model, io::Error> where P: AsRef<Path> {
    let f = match File::open(&path) {
        Err(why)    => return Err(why),
        Ok(f)       => f,
    };

    let reader = BufReader::new(&f);
    let mut vs = Vec::new();
    let mut fs = Vec::new();

    for line in reader.lines().filter_map(|res| res.ok()) {
        let v: Vec<&str> = line.split(' ').collect();

        if v.len() >= 4 && v[0] == "v" {
            let coords: Vec<f64> = v.tail().iter().map(|s| s.trim()).filter_map(
                |s| if s == "" {None} else {Some(s.parse::<f64>().unwrap())}
                ).collect();

            if coords.len() >= 3 {
                vs.push(Vec3Df { x: coords[0], y: coords[1], z: coords[2] });
            }
        } else if v.len() >= 4 && v[0] == "f" {
            // TODO: add error handling (0 vertex -> Result<Facet>)
            let verts: Vec<usize> = v.tail().iter().map(|s| s.trim()).filter_map(
                |s| if s == "" {None} else {Some(parse_facet_obj(s).v - 1)}
                ).collect();

            if verts.len() >= 2 {
                fs.push(verts);
            }
        }
    }

    Ok(Model { verts: vs, faces: fs })
}
<commit_msg>try to use &self<commit_after>use num::traits::Float;

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::ops::{Add, Sub, Mul};
use std::path::Path;

#[derive(Debug, Copy, Clone)]
pub struct Vec2D<T> {
    pub x: T,
    pub y: T,
}

impl<T> Add<Vec2D<T>> for Vec2D<T> where T: Add<T, Output = T> {
    type Output = Vec2D<T>;

    fn add(self, other: Vec2D<T>) -> Vec2D<T> {
        Vec2D { x: self.x + other.x, y: self.y + other.y }
    }
}

impl<T> Sub<Vec2D<T>> for Vec2D<T> where T: Sub<T, Output = T> {
    type Output = Vec2D<T>;

    fn sub(self, other: Vec2D<T>) -> Vec2D<T> {
        Vec2D { x: self.x - other.x, y: self.y - other.y }
    }
}

#[derive(Debug, Copy, Clone)]
pub struct Vec3D<T> {
    pub x: T,
    pub y: T,
    pub z: T,
}

impl<T> Add<Vec3D<T>> for Vec3D<T> where T: Add<T, Output = T> {
    type Output = Vec3D<T>;

    fn add(self, other: Vec3D<T>) -> Vec3D<T> {
        Vec3D { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z }
    }
}

impl<T> Sub<Vec3D<T>> for Vec3D<T> where T: Sub<T, Output = T> {
    type Output = Vec3D<T>;

    fn sub(self, other: Vec3D<T>) -> Vec3D<T> {
        Vec3D { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z }
    }
}

impl<T> Mul<Vec3D<T>> for Vec3D<T> where T: Mul<T, Output = T> + Add<T, Output = T> {
    type Output = T;

    fn mul(self, other: Vec3D<T>) -> T {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
}

impl<T> Vec3D<T> where T: Mul<T, Output = T> + Sub<T, Output = T> + Copy {
    pub fn cross(&self, other: Vec3D<T>) -> Vec3D<T> {
        Vec3D {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x
        }
    }
}

impl<T> Vec3D<T> where T: PartialOrd {
    pub fn min_bound(&mut self, v: Vec3D<T>) -> &mut Self {
        if v.x < self.x { self.x = v.x; }
        if v.y < self.y { self.y = v.y; }
        if v.z < self.z { self.z = v.z; }
        self
    }

    pub fn max_bound(&mut self, v: Vec3D<T>) -> &mut Self {
        if v.x > self.x { self.x = v.x; }
        if v.y > self.y { self.y = v.y; }
        if v.z > self.z { self.z = v.z; }
        self
    }
}

impl<T> Vec3D<T> where T: Float {
    pub fn normalized(self) -> Vec3D<T> {
        let l = (self * self).sqrt();

        if l == T::zero() {
            self
        } else {
            Vec3D {
                x: self.x / l,
                y: self.y / l,
                z: self.z / l
            }
        }
    }
}

impl Vec3Df {
    pub fn to_i32(&self) -> Vec3Di {
        Vec3Di { x: self.x as i32, y: self.y as i32, z: self.z as i32 }
    }

    pub fn scale(&self, s: f64) -> Self {
        Vec3Df { x: self.x * s, y: self.y * s, z: self.z * s }
    }
}

pub type Vec2Di = Vec2D<i32>;
pub type Vec2Du = Vec2D<u32>;
pub type Vec2Df = Vec2D<f64>;

pub type Vec3Di = Vec3D<i32>;
pub type Vec3Du = Vec3D<u32>;
pub type Vec3Df = Vec3D<f64>;

#[derive(Debug)]
pub struct Model {
    pub verts: Vec<Vec3Df>,
    pub faces: Vec<Vec<usize>>,
}

#[derive(Debug)]
struct Facet {
    pub v: usize,
    pub t: usize,
    pub n: usize,
}

fn parse_facet_obj(str: &str) -> Facet {
    let idx: Vec<&str> = str.split('/').collect();

    if idx.len() == 1 {
        Facet { v: idx[0].parse::<usize>().unwrap(), t: 0, n: 0 }
    } else if idx.len() >= 3 {
        Facet {
            v: idx[0].parse::<usize>().unwrap(),
            t: if idx[1] == "" {0} else {idx[1].parse::<usize>().unwrap()},
            n: idx[2].parse::<usize>().unwrap()
        }
    } else {
        Facet { v: 0, t: 0, n: 0 }
    }
}

pub fn load_model_obj<P>(path: P) -> Result<Model, io::Error> where P: AsRef<Path> {
    let f = match File::open(&path) {
        Err(why)    => return Err(why),
        Ok(f)       => f,
    };

    let reader = BufReader::new(&f);
    let mut vs = Vec::new();
    let mut fs = Vec::new();

    for line in reader.lines().filter_map(|res| res.ok()) {
        let v: Vec<&str> = line.split(' ').collect();

        if v.len() >= 4 && v[0] == "v" {
            let coords: Vec<f64> = v.tail().iter().map(|s| s.trim()).filter_map(
                |s| if s == "" {None} else {Some(s.parse::<f64>().unwrap())}
                ).collect();

            if coords.len() >= 3 {
                vs.push(Vec3Df { x: coords[0], y: coords[1], z: coords[2] });
            }
        } else if v.len() >= 4 && v[0] == "f" {
            // TODO: add error handling (0 vertex -> Result<Facet>)
            let verts: Vec<usize> = v.tail().iter().map(|s| s.trim()).filter_map(
                |s| if s == "" {None} else {Some(parse_facet_obj(s).v - 1)}
                ).collect();

            if verts.len() >= 2 {
                fs.push(verts);
            }
        }
    }

    Ok(Model { verts: vs, faces: fs })
}
<|endoftext|>


<commit_before>//! Handlers
//!  - Endpoint handlers
//!
use std::io::{self, Read, Write};
use std::path::PathBuf;
use std::fs;
use std::env;
use std::time;
use std::fmt;

use reqwest;
use url::Url;
use iron::prelude::*;
use iron::{self, status, modifiers};
use router::Router;
use params::Params;
use mime;

use errors::*;

lazy_static! {
    static ref STATIC_ROOT: PathBuf = {
        let mut root = env::current_dir().expect("Failed to get the current directory");
        root.push("static/badges");
        root
    };
    static ref SVG: mime::Mime = "image/svg+xml".parse().unwrap();
}

/// Badge type represents a `crate` badge or a generic customizable `label` badge
enum Badge {
    Crate,
    Label,
}
impl fmt::Display for Badge {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Badge::*;
        match *self {
            Crate => write!(f, "crate"),
            Label => write!(f, "label"),
        }
    }
}

type UrlParams = Vec<(String, String)>;

/// Downloads a fresh badge from shields.io and saves it to `badge_path`
/// Returns the contents of the downloaded file.
///
/// Errors:
///     * Url parse errors from generating a new shields.io url with querystring
///     * Network errors from reqwest
///     * Io errors from copying badge content or writing it to file
fn fetch_badge(badge_type: &Badge, badge_path: PathBuf, name: &str, params: &UrlParams) -> Result<Vec<u8>> {
    println!("[LOG]: fetching fresh badge ({}) -> {:?}", badge_type, badge_path);
    let url = match *badge_type {
        Badge::Crate => format!("https://img.shields.io/crates/v/{krate}.svg", krate=name),
        Badge::Label => format!("https://img.shields.io/badge/{info}.svg", info=name),
    };
    let url = Url::parse_with_params(&url, params)?;

    let mut client = reqwest::Client::new()?;
    client.timeout(time::Duration::new(3, 0));
    let mut resp = client.get(url.as_str())
        .form(params)
        .send()?;

    let mut bytes = Vec::new();
    io::copy(&mut resp, &mut bytes)?;

    let mut file = fs::File::create(badge_path)?;
    file.write_all(&bytes)?;

    Ok(bytes)
}

/// Returns bytes of the requested badge
/// Tries to find a cached file, falls back to fetching a fresh badge from shields.io
///
/// Errors:
///     * Io/Url/Reqwest errors from `fetch_badge`
fn get_badge(badge_type: &Badge, name: &str, params: &UrlParams) -> Result<Vec<u8>> {
    // key for the cache
    let badge_key = params.iter().fold(String::from(name), |mut s, &(ref k, ref v)| {
        s.push('_');
        s.push_str(k);
        s.push('_');
        s.push_str(v);
        s
    });

    let filename = format!("{}__{}.svg", badge_type, badge_key);
    let mut badge_path = PathBuf::from(&*STATIC_ROOT);
    badge_path.push(filename);

    fs::File::open(&badge_path).and_then(|mut file| {
        let mut bytes = Vec::new();
        file.read_to_end(&mut bytes)?;
        Ok(bytes)
    }).or_else(|_| {
        // cached file is missing
        fetch_badge(badge_type, badge_path, name, params)
    })
}

/// Returns the contents of a request badge defined by its `badge_type`, `name`,
/// and modifying `params`
/// If something goes wrong when loading/fetching bytes, redirect to shields.io
fn badge_or_redirect(badge_type: &Badge, name: &str, req: &mut Request) -> IronResult<Response> {
    let params = req.get_ref::<Params>().unwrap()
        .to_strict_map::<String>().unwrap();
    let params: UrlParams = params.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect();

    match get_badge(badge_type, name, &params) {
        Err(_) => {
            // Failed to fetch a cached or fresh version, redirect to shields.io
            let url = match *badge_type {
                Badge::Crate => format!("https://img.shields.io/crates/v/{krate}.svg?label={krate}", krate=name),
                Badge::Label => format!("https://img.shields.io/badge/{info}.svg?style=social", info=name),
            };
            let url = Url::parse(&url).unwrap();
            let url = iron::Url::from_generic_url(url).unwrap();
            Ok(Response::with((status::Found, modifiers::Redirect(url))))
        }
        Ok(bytes) => {
            Ok(Response::with((SVG.clone(), status::Ok, bytes)))
        }
    }

}

/// handle `/crate/:cratename` requests
pub fn krate(req: &mut Request) -> IronResult<Response> {
    // the `:cratename` token should exist or the router messed up
    let crate_name = {
        let crate_name = req.extensions.get::<Router>().unwrap().find("cratename");
        match crate_name {
            Some(name) => name.to_string(),
            None => unreachable!(),
        }
    };
    badge_or_redirect(&Badge::Crate, &crate_name, req)
}

/// handle `/badge/:badgeinfo` requests
pub fn badge(req: &mut Request) -> IronResult<Response> {
    // the `:badgeinfo` token should exist or the router messed up
    let badge_info = {
        let badge_info = req.extensions.get::<Router>().unwrap().find("badgeinfo");
        match badge_info {
            Some(name) => name.to_string(),
            None => unreachable!(),
        }
    };
    badge_or_redirect(&Badge::Label, &badge_info, req)
}

<commit_msg>Allow for URL's to contain the shields.io ".svg" part<commit_after>//! Handlers
//!  - Endpoint handlers
//!
use std::io::{self, Read, Write};
use std::path::PathBuf;
use std::fs;
use std::env;
use std::time;
use std::fmt;

use reqwest;
use url::Url;
use iron::prelude::*;
use iron::{self, status, modifiers};
use router::Router;
use params::Params;
use mime;

use errors::*;

lazy_static! {
    static ref STATIC_ROOT: PathBuf = {
        let mut root = env::current_dir().expect("Failed to get the current directory");
        root.push("static/badges");
        root
    };
    static ref SVG: mime::Mime = "image/svg+xml".parse().unwrap();
}

/// Badge type represents a `crate` badge or a generic customizable `label` badge
enum Badge {
    Crate,
    Label,
}
impl fmt::Display for Badge {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Badge::*;
        match *self {
            Crate => write!(f, "crate"),
            Label => write!(f, "label"),
        }
    }
}

type UrlParams = Vec<(String, String)>;

/// Downloads a fresh badge from shields.io and saves it to `badge_path`
/// Returns the contents of the downloaded file.
///
/// Errors:
///     * Url parse errors from generating a new shields.io url with querystring
///     * Network errors from reqwest
///     * Io errors from copying badge content or writing it to file
fn fetch_badge(badge_type: &Badge, badge_path: PathBuf, name: &str, params: &UrlParams) -> Result<Vec<u8>> {
    println!("[LOG]: fetching fresh badge ({}) -> {:?}", badge_type, badge_path);
    let url = match *badge_type {
        Badge::Crate => format!("https://img.shields.io/crates/v/{krate}.svg", krate=name),
        Badge::Label => format!("https://img.shields.io/badge/{info}.svg", info=name),
    };
    let url = Url::parse_with_params(&url, params)?;

    let mut client = reqwest::Client::new()?;
    client.timeout(time::Duration::new(3, 0));
    let mut resp = client.get(url.as_str())
        .form(params)
        .send()?;

    let mut bytes = Vec::new();
    io::copy(&mut resp, &mut bytes)?;

    let mut file = fs::File::create(badge_path)?;
    file.write_all(&bytes)?;

    Ok(bytes)
}

/// Returns bytes of the requested badge
/// Tries to find a cached file, falls back to fetching a fresh badge from shields.io
///
/// Errors:
///     * Io/Url/Reqwest errors from `fetch_badge`
fn get_badge(badge_type: &Badge, name: &str, params: &UrlParams) -> Result<Vec<u8>> {
    // key for the cache
    let badge_key = params.iter().fold(String::from(name), |mut s, &(ref k, ref v)| {
        s.push('_');
        s.push_str(k);
        s.push('_');
        s.push_str(v);
        s
    });

    let filename = format!("{}__{}.svg", badge_type, badge_key);
    let mut badge_path = PathBuf::from(&*STATIC_ROOT);
    badge_path.push(filename);

    fs::File::open(&badge_path).and_then(|mut file| {
        let mut bytes = Vec::new();
        file.read_to_end(&mut bytes)?;
        Ok(bytes)
    }).or_else(|_| {
        // cached file is missing
        fetch_badge(badge_type, badge_path, name, params)
    })
}

/// Returns the contents of a request badge defined by its `badge_type`, `name`,
/// and modifying `params`
/// If something goes wrong when loading/fetching bytes, redirect to shields.io
fn badge_or_redirect(badge_type: &Badge, name: &str, req: &mut Request) -> IronResult<Response> {
    let params = req.get_ref::<Params>().unwrap()
        .to_strict_map::<String>().unwrap();
    let params: UrlParams = params.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect();

    let name = match name.find(".") {
        Some(n) => &name[..n],
        None => name,
    };

    match get_badge(badge_type, name, &params) {
        Err(_) => {
            // Failed to fetch a cached or fresh version, redirect to shields.io
            let url = match *badge_type {
                Badge::Crate => format!("https://img.shields.io/crates/v/{krate}.svg?label={krate}", krate=name),
                Badge::Label => format!("https://img.shields.io/badge/{info}.svg?style=social", info=name),
            };
            let url = Url::parse(&url).unwrap();
            let url = iron::Url::from_generic_url(url).unwrap();
            Ok(Response::with((status::Found, modifiers::Redirect(url))))
        }
        Ok(bytes) => {
            Ok(Response::with((SVG.clone(), status::Ok, bytes)))
        }
    }

}

/// handle `/crate/:cratename` requests
pub fn krate(req: &mut Request) -> IronResult<Response> {
    // the `:cratename` token should exist or the router messed up
    let crate_name = {
        let crate_name = req.extensions.get::<Router>().unwrap().find("cratename");
        match crate_name {
            Some(name) => name.to_string(),
            None => unreachable!(),
        }
    };
    badge_or_redirect(&Badge::Crate, &crate_name, req)
}

/// handle `/badge/:badgeinfo` requests
pub fn badge(req: &mut Request) -> IronResult<Response> {
    // the `:badgeinfo` token should exist or the router messed up
    let badge_info = {
        let badge_info = req.extensions.get::<Router>().unwrap().find("badgeinfo");
        match badge_info {
            Some(name) => name.to_string(),
            None => unreachable!(),
        }
    };
    badge_or_redirect(&Badge::Label, &badge_info, req)
}

<|endoftext|>


<commit_before>use std::marker::PhantomData;

use middle;

pub mod types;
use self::types::*;

macro_rules! declare_cif {
    ( $typename:ident $( $param:ident )*) => {
        pub struct $typename<$( $param, )* R> {
            untyped: middle::Cif,
            _marker: PhantomData<fn($( $param, )*) -> R>,
        }

        impl<$( $param, )* R> $typename<$( $param, )* R> {
            #[allow(non_snake_case)]
            pub fn new($( $param: Type<$param>, )* result: Type<R>) -> Self {
                let cif = middle::Cif::new(vec![$( $param.into_untyped() ),*],
                                           result.into_untyped());
                $typename { untyped: cif, _marker: PhantomData }
            }
        }
    }
}

declare_cif!(Cif0);
declare_cif!(Cif1 A);
declare_cif!(Cif2 A B);
declare_cif!(Cif3 A B C);
declare_cif!(Cif4 A B C D);
declare_cif!(Cif5 A B C D E);
declare_cif!(Cif6 A B C D E F);
declare_cif!(Cif7 A B C D E F G);
declare_cif!(Cif8 A B C D E F G H);
declare_cif!(Cif9 A B C D E F G H I);
declare_cif!(Cif10 A B C D E F G H I J);

macro_rules! declare_callback {
    ( $typename:ident $( $param:ident )* ) => {
        pub type $typename<U, $( $param, )* R>
            = extern "C" fn(cif:      &::low::ffi_cif,
                            result:   &mut R,
                            args:     &($( &$param, )*),
                            userdata: &U);
    }
}

declare_callback!( Callback0 );
declare_callback!( Callback1 A );
declare_callback!( Callback2 A B );
declare_callback!( Callback3 A B C );
declare_callback!( Callback4 A B C D );
declare_callback!( Callback5 A B C D E );
declare_callback!( Callback6 A B C D E F );
declare_callback!( Callback7 A B C D E F G );
declare_callback!( Callback8 A B C D E F G H );
declare_callback!( Callback9 A B C D E F G H I );
declare_callback!( Callback10 A B C D E F G H I J );

macro_rules! declare_callback_mut {
    ( $typename:ident $( $param:ident )* ) => {
        pub type $typename<U, $( $param, )* R>
            = extern "C" fn(cif:      &::low::ffi_cif,
                            result:   &mut R,
                            args:     &($( &$param, )*),
                            userdata: &mut U);
    }
}

declare_callback_mut!( CallbackMut0 );
declare_callback_mut!( CallbackMut1 A );
declare_callback_mut!( CallbackMut2 A B );
declare_callback_mut!( CallbackMut3 A B C );
declare_callback_mut!( CallbackMut4 A B C D );
declare_callback_mut!( CallbackMut5 A B C D E );
declare_callback_mut!( CallbackMut6 A B C D E F );
declare_callback_mut!( CallbackMut7 A B C D E F G );
declare_callback_mut!( CallbackMut8 A B C D E F G H );
declare_callback_mut!( CallbackMut9 A B C D E F G H I );
declare_callback_mut!( CallbackMut10 A B C D E F G H I J );

macro_rules! declare_closure {
    ( $closure:ident $cif:ident $callback:ident $( $param:ident )*) => {
        pub struct $closure<'a, $( $param, )* R> {
            untyped: middle::Closure<'a>,
            _marker: PhantomData<fn($( $param, )*) -> R>,
        }

        impl<'a, $( $param, )* R> $closure<'a, $( $param, )* R> {
            pub fn from_parts<U>(cif: $cif<$( $param, )* R>,
                                 callback: $callback<U, $( $param, )* R>,
                                 userdata: &'a U) -> Self
            {
                let callback: middle::Callback<U, R>
                    = unsafe { ::std::mem::transmute(callback) };
                let closure
                    = middle::Closure::new(cif.untyped,
                                           callback,
                                           userdata);
                $closure {
                    untyped: closure,
                    _marker: PhantomData,
                }
            }

            pub fn code_ptr(&self) -> &extern "C" fn($( $param, )*) -> R {
                unsafe {
                    ::std::mem::transmute(self.untyped.code_ptr())
                }
            }
        }

        impl<'a, $( $param: Copy, )* R> $closure<'a, $( $param, )* R> {
            pub fn new<Callback>(cif: $cif<$( $param, )* R>,
                                 callback: &'a Callback) -> Self
                where Callback: Fn($( $param, )*) -> R + 'a
            {
                Self::from_parts(cif,
                                 Self::static_callback,
                                 callback)
            }

            #[allow(non_snake_case)]
            extern "C" fn static_callback<Callback>
                (_cif:     &::low::ffi_cif,
                 result:   &mut R,
                 &($( &$param, )*):
                           &($( &$param, )*),
                 userdata: &Callback)
              where Callback: Fn($( $param, )*) -> R + 'a
            {
                *result = userdata($( $param, )*);
            }
        }

        impl<'a, $($param: Copy + FfiType,)* R: FfiType>
            $closure<'a, $($param,)* R>
        {
            pub fn wrap<Callback>(callback: &'a Callback) -> Self
                where Callback: Fn($( $param, )*) -> R + 'a
            {
                let cif = $cif::new($( $param::get_type(), )* R::get_type());
                Self::new(cif, callback)
            }
        }
    }
}

declare_closure!(Closure0 Cif0 Callback0);
declare_closure!(Closure1 Cif1 Callback1 A);
declare_closure!(Closure2 Cif2 Callback2 A B);
declare_closure!(Closure3 Cif3 Callback3 A B C);
declare_closure!(Closure4 Cif4 Callback4 A B C D);
declare_closure!(Closure5 Cif5 Callback5 A B C D E);
declare_closure!(Closure6 Cif6 Callback6 A B C D E F);
declare_closure!(Closure7 Cif7 Callback7 A B C D E F G);
declare_closure!(Closure8 Cif8 Callback8 A B C D E F G H);
declare_closure!(Closure9 Cif9 Callback9 A B C D E F G H I);
declare_closure!(Closure10 Cif10 Callback10 A B C D E F G H I J);

macro_rules! declare_closure_mut {
    ( $closure:ident $cif:ident $callback:ident $( $param:ident )*) => {
        pub struct $closure<'a, $( $param, )* R> {
            untyped: middle::Closure<'a>,
            _marker: PhantomData<fn($( $param, )*) -> R>,
        }

        impl<'a, $( $param, )* R> $closure<'a, $( $param, )* R> {
            pub fn from_parts<U>(cif: $cif<$( $param, )* R>,
                                 callback: $callback<U, $( $param, )* R>,
                                 userdata: &'a mut U) -> Self
            {
                let callback: middle::Callback<U, R>
                    = unsafe { ::std::mem::transmute(callback) };
                let closure
                    = middle::Closure::new(cif.untyped,
                                           callback,
                                           userdata);
                $closure {
                    untyped: closure,
                    _marker: PhantomData,
                }
            }

            pub fn code_ptr(&self) -> &extern "C" fn($( $param, )*) -> R {
                unsafe {
                    ::std::mem::transmute(self.untyped.code_ptr())
                }
            }
        }

        impl<'a, $( $param: Copy, )* R> $closure<'a, $( $param, )* R> {
            pub fn new<Callback>(cif: $cif<$( $param, )* R>,
                                 callback: &'a mut Callback) -> Self
                where Callback: FnMut($( $param, )*) -> R + 'a
            {
                Self::from_parts(cif,
                                 Self::static_callback,
                                 callback)
            }

            #[allow(non_snake_case)]
            extern "C" fn static_callback<Callback>
                (_cif:     &::low::ffi_cif,
                 result:   &mut R,
                 &($( &$param, )*):
                           &($( &$param, )*),
                 userdata: &mut Callback)
              where Callback: FnMut($( $param, )*) -> R + 'a
            {
                *result = userdata($( $param, )*);
            }
        }

        impl<'a, $($param: Copy + FfiType,)* R: FfiType>
            $closure<'a, $($param,)* R>
        {
            pub fn wrap<Callback>(callback: &'a mut Callback) -> Self
                where Callback: FnMut($( $param, )*) -> R + 'a
            {
                let cif = $cif::new($( $param::get_type(), )* R::get_type());
                Self::new(cif, callback)
            }
        }
    }
}

declare_closure_mut!(ClosureMut0 Cif0 CallbackMut0);
declare_closure_mut!(ClosureMut1 Cif1 CallbackMut1 A);
declare_closure_mut!(ClosureMut2 Cif2 CallbackMut2 A B);
declare_closure_mut!(ClosureMut3 Cif3 CallbackMut3 A B C);
declare_closure_mut!(ClosureMut4 Cif4 CallbackMut4 A B C D);
declare_closure_mut!(ClosureMut5 Cif5 CallbackMut5 A B C D E);
declare_closure_mut!(ClosureMut6 Cif6 CallbackMut6 A B C D E F);
declare_closure_mut!(ClosureMut7 Cif7 CallbackMut7 A B C D E F G);
declare_closure_mut!(ClosureMut8 Cif8 CallbackMut8 A B C D E F G H);
declare_closure_mut!(ClosureMut9 Cif9 CallbackMut9 A B C D E F G H I);
declare_closure_mut!(ClosureMut10 Cif10 CallbackMut10 A B C D E F G H I J);

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

    #[test]
    fn new() {
        let x: u64 = 1;
        let f = |y: u64, z: u64| x + y + z;

        let type_   = u64::get_type();
        let cif     = Cif2::new(type_.clone(), type_.clone(), type_.clone());
        let closure = Closure2::new(cif, &f);

        assert_eq!(12, closure.code_ptr()(5, 6));
    }

    #[test]
    fn new_mut() {
        let mut x: u64 = 0;
        let mut f = |y: u64| { x += y; x };

        let type_   = u64::get_type();
        let cif     = Cif1::new(type_.clone(), type_.clone());
        let closure = ClosureMut1::new(cif, &mut f);

        let counter = closure.code_ptr();

        assert_eq!(5, counter(5));
        assert_eq!(6, counter(1));
        assert_eq!(8, counter(2));
    }

    #[test]
    fn wrap() {
        let x: u64 = 1;
        let f = |y: u64, z: u64| x + y + z;

        let closure = Closure2::wrap(&f);

        assert_eq!(12, closure.code_ptr()(5, 6));
    }
}
<commit_msg>Renamed Closure(Mut)N new to new_with_cif and wrap to new.<commit_after>use std::marker::PhantomData;

use middle;

pub mod types;
use self::types::*;

macro_rules! declare_cif {
    ( $typename:ident $( $param:ident )*) => {
        pub struct $typename<$( $param, )* R> {
            untyped: middle::Cif,
            _marker: PhantomData<fn($( $param, )*) -> R>,
        }

        impl<$( $param, )* R> $typename<$( $param, )* R> {
            #[allow(non_snake_case)]
            pub fn new($( $param: Type<$param>, )* result: Type<R>) -> Self {
                let cif = middle::Cif::new(vec![$( $param.into_untyped() ),*],
                                           result.into_untyped());
                $typename { untyped: cif, _marker: PhantomData }
            }
        }
    }
}

declare_cif!(Cif0);
declare_cif!(Cif1 A);
declare_cif!(Cif2 A B);
declare_cif!(Cif3 A B C);
declare_cif!(Cif4 A B C D);
declare_cif!(Cif5 A B C D E);
declare_cif!(Cif6 A B C D E F);
declare_cif!(Cif7 A B C D E F G);
declare_cif!(Cif8 A B C D E F G H);
declare_cif!(Cif9 A B C D E F G H I);
declare_cif!(Cif10 A B C D E F G H I J);

macro_rules! declare_callback {
    ( $typename:ident $( $param:ident )* ) => {
        pub type $typename<U, $( $param, )* R>
            = extern "C" fn(cif:      &::low::ffi_cif,
                            result:   &mut R,
                            args:     &($( &$param, )*),
                            userdata: &U);
    }
}

declare_callback!( Callback0 );
declare_callback!( Callback1 A );
declare_callback!( Callback2 A B );
declare_callback!( Callback3 A B C );
declare_callback!( Callback4 A B C D );
declare_callback!( Callback5 A B C D E );
declare_callback!( Callback6 A B C D E F );
declare_callback!( Callback7 A B C D E F G );
declare_callback!( Callback8 A B C D E F G H );
declare_callback!( Callback9 A B C D E F G H I );
declare_callback!( Callback10 A B C D E F G H I J );

macro_rules! declare_callback_mut {
    ( $typename:ident $( $param:ident )* ) => {
        pub type $typename<U, $( $param, )* R>
            = extern "C" fn(cif:      &::low::ffi_cif,
                            result:   &mut R,
                            args:     &($( &$param, )*),
                            userdata: &mut U);
    }
}

declare_callback_mut!( CallbackMut0 );
declare_callback_mut!( CallbackMut1 A );
declare_callback_mut!( CallbackMut2 A B );
declare_callback_mut!( CallbackMut3 A B C );
declare_callback_mut!( CallbackMut4 A B C D );
declare_callback_mut!( CallbackMut5 A B C D E );
declare_callback_mut!( CallbackMut6 A B C D E F );
declare_callback_mut!( CallbackMut7 A B C D E F G );
declare_callback_mut!( CallbackMut8 A B C D E F G H );
declare_callback_mut!( CallbackMut9 A B C D E F G H I );
declare_callback_mut!( CallbackMut10 A B C D E F G H I J );

macro_rules! declare_closure {
    ( $closure:ident $cif:ident $callback:ident $( $param:ident )*) => {
        pub struct $closure<'a, $( $param, )* R> {
            untyped: middle::Closure<'a>,
            _marker: PhantomData<fn($( $param, )*) -> R>,
        }

        impl<'a, $( $param, )* R> $closure<'a, $( $param, )* R> {
            pub fn from_parts<U>(cif: $cif<$( $param, )* R>,
                                 callback: $callback<U, $( $param, )* R>,
                                 userdata: &'a U) -> Self
            {
                let callback: middle::Callback<U, R>
                    = unsafe { ::std::mem::transmute(callback) };
                let closure
                    = middle::Closure::new(cif.untyped,
                                           callback,
                                           userdata);
                $closure {
                    untyped: closure,
                    _marker: PhantomData,
                }
            }

            pub fn code_ptr(&self) -> &extern "C" fn($( $param, )*) -> R {
                unsafe {
                    ::std::mem::transmute(self.untyped.code_ptr())
                }
            }
        }

        impl<'a, $( $param: Copy, )* R> $closure<'a, $( $param, )* R> {
            pub fn new_with_cif<Callback>(cif: $cif<$( $param, )* R>,
                                          callback: &'a Callback) -> Self
                where Callback: Fn($( $param, )*) -> R + 'a
            {
                Self::from_parts(cif,
                                 Self::static_callback,
                                 callback)
            }

            #[allow(non_snake_case)]
            extern "C" fn static_callback<Callback>
                (_cif:     &::low::ffi_cif,
                 result:   &mut R,
                 &($( &$param, )*):
                           &($( &$param, )*),
                 userdata: &Callback)
              where Callback: Fn($( $param, )*) -> R + 'a
            {
                *result = userdata($( $param, )*);
            }
        }

        impl<'a, $($param: Copy + FfiType,)* R: FfiType>
            $closure<'a, $($param,)* R>
        {
            pub fn new<Callback>(callback: &'a Callback) -> Self
                where Callback: Fn($( $param, )*) -> R + 'a
            {
                let cif = $cif::new($( $param::get_type(), )* R::get_type());
                Self::new_with_cif(cif, callback)
            }
        }
    }
}

declare_closure!(Closure0 Cif0 Callback0);
declare_closure!(Closure1 Cif1 Callback1 A);
declare_closure!(Closure2 Cif2 Callback2 A B);
declare_closure!(Closure3 Cif3 Callback3 A B C);
declare_closure!(Closure4 Cif4 Callback4 A B C D);
declare_closure!(Closure5 Cif5 Callback5 A B C D E);
declare_closure!(Closure6 Cif6 Callback6 A B C D E F);
declare_closure!(Closure7 Cif7 Callback7 A B C D E F G);
declare_closure!(Closure8 Cif8 Callback8 A B C D E F G H);
declare_closure!(Closure9 Cif9 Callback9 A B C D E F G H I);
declare_closure!(Closure10 Cif10 Callback10 A B C D E F G H I J);

macro_rules! declare_closure_mut {
    ( $closure:ident $cif:ident $callback:ident $( $param:ident )*) => {
        pub struct $closure<'a, $( $param, )* R> {
            untyped: middle::Closure<'a>,
            _marker: PhantomData<fn($( $param, )*) -> R>,
        }

        impl<'a, $( $param, )* R> $closure<'a, $( $param, )* R> {
            pub fn from_parts<U>(cif: $cif<$( $param, )* R>,
                                 callback: $callback<U, $( $param, )* R>,
                                 userdata: &'a mut U) -> Self
            {
                let callback: middle::Callback<U, R>
                    = unsafe { ::std::mem::transmute(callback) };
                let closure
                    = middle::Closure::new(cif.untyped,
                                           callback,
                                           userdata);
                $closure {
                    untyped: closure,
                    _marker: PhantomData,
                }
            }

            pub fn code_ptr(&self) -> &extern "C" fn($( $param, )*) -> R {
                unsafe {
                    ::std::mem::transmute(self.untyped.code_ptr())
                }
            }
        }

        impl<'a, $( $param: Copy, )* R> $closure<'a, $( $param, )* R> {
            pub fn new_with_cif<Callback>(cif: $cif<$( $param, )* R>,
                                          callback: &'a mut Callback) -> Self
                where Callback: FnMut($( $param, )*) -> R + 'a
            {
                Self::from_parts(cif,
                                 Self::static_callback,
                                 callback)
            }

            #[allow(non_snake_case)]
            extern "C" fn static_callback<Callback>
                (_cif:     &::low::ffi_cif,
                 result:   &mut R,
                 &($( &$param, )*):
                           &($( &$param, )*),
                 userdata: &mut Callback)
              where Callback: FnMut($( $param, )*) -> R + 'a
            {
                *result = userdata($( $param, )*);
            }
        }

        impl<'a, $($param: Copy + FfiType,)* R: FfiType>
            $closure<'a, $($param,)* R>
        {
            pub fn new<Callback>(callback: &'a mut Callback) -> Self
                where Callback: FnMut($( $param, )*) -> R + 'a
            {
                let cif = $cif::new($( $param::get_type(), )* R::get_type());
                Self::new_with_cif(cif, callback)
            }
        }
    }
}

declare_closure_mut!(ClosureMut0 Cif0 CallbackMut0);
declare_closure_mut!(ClosureMut1 Cif1 CallbackMut1 A);
declare_closure_mut!(ClosureMut2 Cif2 CallbackMut2 A B);
declare_closure_mut!(ClosureMut3 Cif3 CallbackMut3 A B C);
declare_closure_mut!(ClosureMut4 Cif4 CallbackMut4 A B C D);
declare_closure_mut!(ClosureMut5 Cif5 CallbackMut5 A B C D E);
declare_closure_mut!(ClosureMut6 Cif6 CallbackMut6 A B C D E F);
declare_closure_mut!(ClosureMut7 Cif7 CallbackMut7 A B C D E F G);
declare_closure_mut!(ClosureMut8 Cif8 CallbackMut8 A B C D E F G H);
declare_closure_mut!(ClosureMut9 Cif9 CallbackMut9 A B C D E F G H I);
declare_closure_mut!(ClosureMut10 Cif10 CallbackMut10 A B C D E F G H I J);

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

    #[test]
    fn new_with_cif() {
        let x: u64 = 1;
        let f = |y: u64, z: u64| x + y + z;

        let type_   = u64::get_type();
        let cif     = Cif2::new(type_.clone(), type_.clone(), type_.clone());
        let closure = Closure2::new_with_cif(cif, &f);

        assert_eq!(12, closure.code_ptr()(5, 6));
    }

    #[test]
    fn new_with_cif_mut() {
        let mut x: u64 = 0;
        let mut f = |y: u64| { x += y; x };

        let type_   = u64::get_type();
        let cif     = Cif1::new(type_.clone(), type_.clone());
        let closure = ClosureMut1::new_with_cif(cif, &mut f);

        let counter = closure.code_ptr();

        assert_eq!(5, counter(5));
        assert_eq!(6, counter(1));
        assert_eq!(8, counter(2));
    }

    #[test]
    fn new() {
        let x: u64 = 1;
        let f = |y: u64, z: u64| x + y + z;

        let closure = Closure2::new(&f);

        assert_eq!(12, closure.code_ptr()(5, 6));
    }
}
<|endoftext|>


<commit_before>use decoders::Image;
use imageops::OpBuffer;
use std::cmp;

pub fn demosaic_and_scale(img: &Image, minwidth: usize, minheight: usize) -> OpBuffer {
  // Calculate the resulting width/height and top-left corner after crops
  let width = (img.width as i64 - img.crops[1] - img.crops[3]) as usize;
  let height = (img.height as i64 - img.crops[0] - img.crops[2]) as usize;
  let x = img.crops[3] as usize;
  let y = img.crops[0] as usize;

  let (scale, nwidth, nheight) = if minwidth == 0 || minheight == 0 {
    (0.0, width, height)
  } else {
    // Do the calculations manually to avoid off-by-one errors from floating point rounding
    let xscale = (width as f32) / (minwidth as f32);
    let yscale = (height as f32) / (minheight as f32);
    if yscale > xscale {
      (yscale, ((width as f32)/yscale) as usize, minheight)
    } else {
      (xscale, minwidth, ((height as f32)/xscale) as usize)
    }
  };

  let minscale = match img.cfa.width() {
    2  => 2.0,  // RGGB/RGBE bayer
    6  => 3.0,  // x-trans is 6 wide but has all colors in every 3x3 block
    12 => 12.0, // some crazy sensor I haven't actually encountered, use full block
    _  => 2.0,  // default
  };

  if scale < minscale {
    full(img, x, y, width, height)
  } else {
    scaled(img, x, y, width, height, nwidth, nheight)
  }
}

pub fn full(img: &Image, xs: usize, ys: usize, width: usize, height: usize) -> OpBuffer {
  let mut out = OpBuffer::new(width, height, 4);
  let crop_cfa = img.cfa.shift(xs, ys);

  // First we set the colors we already have
  out.mutate_lines(&(|line: &mut [f32], row| {
    for (col, (pixout, pixin)) in line.chunks_mut(4).zip(img.data[img.width*(row+ys)+xs..].chunks(1)).enumerate() {
      let color = crop_cfa.color_at(row, col);
      pixout[color] = pixin[0] as f32;
    }
  }));

  // Now we go around the image setting the unset colors to the average of the
  // surrounding pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..width {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [u32; 4] = [0; 4];
      let color = crop_cfa.color_at(row, col);

      for y in (cmp::max(0,(row as isize)-1) as usize) .. cmp::min(height, row+2) {
        for x in (cmp::max(0,(col as isize)-1) as usize) .. cmp::min(width, col+2) {
          let c = crop_cfa.color_at(y, x);
          if c != color {
            sums[c] += img.data[(y+ys)*img.width+(x+xs)] as f32;
            counts[c] += 1;
          }
        }
      }

      for c in 0..4 {
        if c != color && counts[c] > 0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}

pub fn scaled(img: &Image, xs: usize, ys: usize, width: usize, height: usize, nwidth: usize, nheight: usize) -> OpBuffer {
  let mut out = OpBuffer::new(nwidth, nheight, 4);
  let crop_cfa = img.cfa.shift(xs, ys);

  let rowskip = (width as f32) / (nwidth as f32);
  let colskip = (height as f32) / (nheight as f32);

  // Go around the image averaging blocks of pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..nwidth {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [f32; 4] = [0.0;4];

      let fromrow = ((row as f32)*rowskip).floor() as usize;
      let torow = cmp::min(height, (((row+1) as f32)*rowskip).ceil() as usize);
      for y in fromrow..torow {
        let fromcol = ((col as f32)*colskip).floor() as usize;
        let tocol = cmp::min(width, (((col+1) as f32)*colskip).ceil() as usize);
        for x in fromcol..tocol {
          let c = crop_cfa.color_at(y, x);
          sums[c] += img.data[(y+ys)*img.width+(x+xs)] as f32;
          counts[c] += 1.0;
        }
      }

      for c in 0..4 {
        if counts[c] > 0.0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}
<commit_msg>demosaic: properly weighing for fractional scale<commit_after>use decoders::Image;
use imageops::OpBuffer;
use std::cmp;

pub fn demosaic_and_scale(img: &Image, minwidth: usize, minheight: usize) -> OpBuffer {
  // Calculate the resulting width/height and top-left corner after crops
  let width = (img.width as i64 - img.crops[1] - img.crops[3]) as usize;
  let height = (img.height as i64 - img.crops[0] - img.crops[2]) as usize;
  let x = img.crops[3] as usize;
  let y = img.crops[0] as usize;

  let (scale, nwidth, nheight) = if minwidth == 0 || minheight == 0 {
    (0.0, width, height)
  } else {
    // Do the calculations manually to avoid off-by-one errors from floating point rounding
    let xscale = (width as f32) / (minwidth as f32);
    let yscale = (height as f32) / (minheight as f32);
    if yscale > xscale {
      (yscale, ((width as f32)/yscale) as usize, minheight)
    } else {
      (xscale, minwidth, ((height as f32)/xscale) as usize)
    }
  };

  let minscale = match img.cfa.width() {
    2  => 2.0,  // RGGB/RGBE bayer
    6  => 3.0,  // x-trans is 6 wide but has all colors in every 3x3 block
    12 => 12.0, // some crazy sensor I haven't actually encountered, use full block
    _  => 2.0,  // default
  };

  if scale < minscale {
    full(img, x, y, width, height)
  } else {
    scaled(img, x, y, width, height, nwidth, nheight)
  }
}

pub fn full(img: &Image, xs: usize, ys: usize, width: usize, height: usize) -> OpBuffer {
  let mut out = OpBuffer::new(width, height, 4);
  let crop_cfa = img.cfa.shift(xs, ys);

  // First we set the colors we already have
  out.mutate_lines(&(|line: &mut [f32], row| {
    for (col, (pixout, pixin)) in line.chunks_mut(4).zip(img.data[img.width*(row+ys)+xs..].chunks(1)).enumerate() {
      let color = crop_cfa.color_at(row, col);
      pixout[color] = pixin[0] as f32;
    }
  }));

  // Now we go around the image setting the unset colors to the average of the
  // surrounding pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..width {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [u32; 4] = [0; 4];
      let color = crop_cfa.color_at(row, col);

      for y in (cmp::max(0,(row as isize)-1) as usize) .. cmp::min(height, row+2) {
        for x in (cmp::max(0,(col as isize)-1) as usize) .. cmp::min(width, col+2) {
          let c = crop_cfa.color_at(y, x);
          if c != color {
            sums[c] += img.data[(y+ys)*img.width+(x+xs)] as f32;
            counts[c] += 1;
          }
        }
      }

      for c in 0..4 {
        if c != color && counts[c] > 0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}

fn calc_skips(idx: usize, skip: f32) -> (usize, usize, f32, f32) {
  let from = (idx as f32)*skip;
  let fromback = from.floor();
  let fromfactor = 1.0 - (from-fromback).fract();

  let to = ((idx+1) as f32)*skip;
  let toforward = to.ceil();
  let tofactor = (toforward-to).fract();

  (fromback as usize, toforward as usize, fromfactor, tofactor)
}

pub fn scaled(img: &Image, xs: usize, ys: usize, width: usize, height: usize, nwidth: usize, nheight: usize) -> OpBuffer {
  let mut out = OpBuffer::new(nwidth, nheight, 4);
  let crop_cfa = img.cfa.shift(xs, ys);

  let rowskip = (width as f32) / (nwidth as f32);
  let colskip = (height as f32) / (nheight as f32);

  // Go around the image averaging blocks of pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..nwidth {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [f32; 4] = [0.0;4];
      let (fromrow, torow, topfactor, bottomfactor) = calc_skips(row, rowskip);
      for y in fromrow..torow {
        let (fromcol, tocol, leftfactor, rightfactor) = calc_skips(col, colskip);
        for x in fromcol..tocol {
          let factor = {
            (if y == fromrow {topfactor} else if y == torow {bottomfactor} else {1.0}) *
            (if x == fromcol {leftfactor} else if x == tocol {rightfactor} else {1.0})
          };

          let c = crop_cfa.color_at(y, x);
          sums[c] += (img.data[(y+ys)*img.width+(x+xs)] as f32) * factor;
          counts[c] += factor;
        }
      }

      for c in 0..4 {
        if counts[c] > 0.0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}
<|endoftext|>