<commit_before><commit_msg>added older version-compatible rust implementation<commit_after>extern crate time;

use std::io::File;
use std::io::BufferedReader;
use time::precise_time_ns;

#[deriving(Clone, Show)]
struct Route{
  dest: i32,
  cost: i32
}

#[deriving(Clone, Show)]
struct Node {
  neighbours: Vec<Route>
}

fn read_places(num_nodes: &mut uint) ->Vec<Node>{
  let path = Path::new("agraph");
  let mut file = BufferedReader::new(File::open(&path));
  let lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();
  *num_nodes = from_str(lines[0].as_slice().trim()).expect("Error, first line of file should describe the amount of nodes");
  let mut nodes: Vec<Node> = Vec::from_fn(*num_nodes, |_| Node{neighbours: vec![]});
  for ln in lines.slice(1,lines.len()).iter(){
    let nums: Vec<&str> = ln.as_slice().split(' ').collect();
    if nums.len() < 3{
      break;
    }
    let node: uint = from_str(nums[0]).expect("Error: node id was not a uint");
    let neighbour: i32 = from_str(nums[1]).expect("Error: neighbour id was not an int");
    let cost: i32 = from_str(nums[2]).expect("Error: route cost was not an int");
    let mut newnode = nodes[node].clone();
    newnode.neighbours.push(Route{dest: neighbour, cost: cost});
    let mut newnodes = Vec::with_capacity(*num_nodes);
    for i in range(0u, *num_nodes){
      newnodes.push(if i == node{ newnode.clone()} else {nodes[i].clone()});
    }
    nodes = newnodes;
  }
  nodes
}

fn get_longest_path(nodes: &Vec<Node>, nodeID: i32, visited: *bool) -> i32{
  let uintID = nodeID.to_uint().expect("Error, something had a negative node id");
  unsafe{
    let newAddr: uint = (visited as uint) + (uintID as uint);
    let newAddrP: *mut bool = newAddr as *mut bool;
    *newAddrP = true;
  }
  let mut dist: i32;
  let mut max: i32 = 0;
  for neighbour in nodes[uintID].neighbours.iter(){
    let udest = neighbour.dest.to_uint().expect("Almost done..");
    let isVisited: bool;
    unsafe{
      let newAddr: uint = udest + (visited as uint);
      let newAddrP: *mut bool = newAddr as *mut bool;
      isVisited = *newAddrP
    }
    if !isVisited{
      dist = neighbour.cost + get_longest_path(nodes, neighbour.dest, visited);
      if dist > max{
	max = dist;
      }
    }
  }
  unsafe{
    let newAddr: uint = (visited as uint) + (uintID as uint);
    let newAddrP: *mut bool = newAddr as *mut bool;
    *newAddrP = false;
  }
  max
}

fn main(){
   let mut num_nodes = 0;
   let nodes = read_places(&mut num_nodes);
   let mut visited: Vec<bool> = Vec::from_fn(num_nodes, |_| false);
   let startTime = precise_time_ns();
   let path = get_longest_path(&nodes, 0, &visited[0] as *bool);
   let duration = (precise_time_ns() - startTime) / 1000000;
   println!("{} LANGUAGE Rust {}", path, duration);
}<|endoftext|>


<commit_before><commit_msg>Add some debug output<commit_after><|endoftext|>


<commit_before><commit_msg>Add FileLockEntry-getter in Mail struct<commit_after><|endoftext|>


<commit_before><commit_msg>increase RNG seed size<commit_after><|endoftext|>


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

use core::prelude::*;

use driver::session::Session;
use middle::resolve;
use middle::ty;
use middle::typeck;
use util::ppaux;

use core::dvec::DVec;
use core::option;
use std::oldmap::HashMap;
use syntax::ast::*;
use syntax::codemap;
use syntax::{visit, ast_util, ast_map};

pub fn check_crate(sess: Session,
                   crate: @crate,
                   ast_map: ast_map::map,
                   def_map: resolve::DefMap,
                   method_map: typeck::method_map,
                   tcx: ty::ctxt) {
    visit::visit_crate(*crate, false, visit::mk_vt(@visit::Visitor {
        visit_item: |a,b,c| check_item(sess, ast_map, def_map, a, b, c),
        visit_pat: check_pat,
        visit_expr: |a,b,c|
            check_expr(sess, def_map, method_map, tcx, a, b, c),
        .. *visit::default_visitor()
    }));
    sess.abort_if_errors();
}

pub fn check_item(sess: Session,
                  ast_map: ast_map::map,
                  def_map: resolve::DefMap,
                  it: @item,
                  &&_is_const: bool,
                  v: visit::vt<bool>) {
    match it.node {
      item_const(_, ex) => {
        (v.visit_expr)(ex, true, v);
        check_item_recursion(sess, ast_map, def_map, it);
      }
      item_enum(ref enum_definition, _) => {
        for (*enum_definition).variants.each |var| {
            do option::iter(&var.node.disr_expr) |ex| {
                (v.visit_expr)(*ex, true, v);
            }
        }
      }
      _ => visit::visit_item(it, false, v)
    }
}

pub fn check_pat(p: @pat, &&_is_const: bool, v: visit::vt<bool>) {
    fn is_str(e: @expr) -> bool {
        match e.node {
            expr_vstore(
                @expr { node: expr_lit(@codemap::spanned {
                    node: lit_str(_),
                    _}),
                       _ },
                expr_vstore_uniq
            ) => true,
            _ => false
        }
    }
    match p.node {
      // Let through plain ~-string literals here
      pat_lit(a) => if !is_str(a) { (v.visit_expr)(a, true, v); },
      pat_range(a, b) => {
        if !is_str(a) { (v.visit_expr)(a, true, v); }
        if !is_str(b) { (v.visit_expr)(b, true, v); }
      }
      _ => visit::visit_pat(p, false, v)
    }
}

pub fn check_expr(sess: Session,
                  def_map: resolve::DefMap,
                  method_map: typeck::method_map,
                  tcx: ty::ctxt,
                  e: @expr,
                  &&is_const: bool,
                  v: visit::vt<bool>) {
    if is_const {
        match e.node {
          expr_unary(box(_), _) | expr_unary(uniq(_), _) |
          expr_unary(deref, _) => {
            sess.span_err(e.span,
                          ~"disallowed operator in constant expression");
            return;
          }
          expr_lit(@codemap::spanned {node: lit_str(_), _}) => { }
          expr_binary(_, _, _) | expr_unary(_, _) => {
            if method_map.contains_key(&e.id) {
                sess.span_err(e.span, ~"user-defined operators are not \
                                       allowed in constant expressions");
            }
          }
          expr_lit(_) => (),
          expr_cast(_, _) => {
            let ety = ty::expr_ty(tcx, e);
            if !ty::type_is_numeric(ety) {
                sess.span_err(e.span, ~"can not cast to `" +
                              ppaux::ty_to_str(tcx, ety) +
                              ~"` in a constant expression");
            }
          }
          expr_path(pth) => {
            // NB: In the future you might wish to relax this slightly
            // to handle on-demand instantiation of functions via
            // foo::<bar> in a const. Currently that is only done on
            // a path in trans::callee that only works in block contexts.
            if pth.types.len() != 0 {
                sess.span_err(
                    e.span, ~"paths in constants may only refer to \
                              items without type parameters");
            }
            match def_map.find(&e.id) {
                Some(def_variant(_, _)) |
                Some(def_struct(_)) => { }

                Some(def_const(def_id)) |
                Some(def_fn(def_id, _)) => {
                if !ast_util::is_local(def_id) {
                    sess.span_err(
                        e.span, ~"paths in constants may only refer to \
                                 crate-local constants or functions");
                }
              }
              Some(def) => {
                debug!("(checking const) found bad def: %?", def);
                sess.span_err(
                    e.span,
                    fmt!("paths in constants may only refer to \
                          constants or functions"));
              }
              None => {
                sess.span_bug(e.span, ~"unbound path in const?!");
              }
            }
          }
          expr_call(callee, _, NoSugar) => {
            match def_map.find(&callee.id) {
                Some(def_struct(*)) => {}    // OK.
                Some(def_variant(*)) => {}    // OK.
                _ => {
                    sess.span_err(
                        e.span,
                        ~"function calls in constants are limited to \
                          struct and enum constructors");
                }
            }
          }
          expr_paren(e) => { check_expr(sess, def_map, method_map,
                                         tcx, e, is_const, v); }
          expr_vstore(_, expr_vstore_slice) |
          expr_vstore(_, expr_vstore_fixed(_)) |
          expr_vec(_, m_imm) |
          expr_addr_of(m_imm, _) |
          expr_field(*) |
          expr_index(*) |
          expr_tup(*) |
          expr_struct(*) |
          expr_rec(*) => { }
          expr_addr_of(*) => {
                sess.span_err(
                    e.span,
                    ~"borrowed pointers in constants may only refer to \
                      immutable values");
          }
          _ => {
            sess.span_err(e.span,
                          ~"constant contains unimplemented expression type");
            return;
          }
        }
    }
    match e.node {
      expr_lit(@codemap::spanned {node: lit_int(v, t), _}) => {
        if t != ty_char {
            if (v as u64) > ast_util::int_ty_max(
                if t == ty_i { sess.targ_cfg.int_type } else { t }) {
                sess.span_err(e.span, ~"literal out of range for its type");
            }
        }
      }
      expr_lit(@codemap::spanned {node: lit_uint(v, t), _}) => {
        if v > ast_util::uint_ty_max(
            if t == ty_u { sess.targ_cfg.uint_type } else { t }) {
            sess.span_err(e.span, ~"literal out of range for its type");
        }
      }
      _ => ()
    }
    visit::visit_expr(e, is_const, v);
}

// Make sure a const item doesn't recursively refer to itself
// FIXME: Should use the dependency graph when it's available (#1356)
pub fn check_item_recursion(sess: Session,
                            ast_map: ast_map::map,
                            def_map: resolve::DefMap,
                            it: @item) {
    type env = {
        root_it: @item,
        sess: Session,
        ast_map: ast_map::map,
        def_map: resolve::DefMap,
        idstack: @DVec<node_id>,
    };

    let env = {
        root_it: it,
        sess: sess,
        ast_map: ast_map,
        def_map: def_map,
        idstack: @DVec()
    };

    let visitor = visit::mk_vt(@visit::Visitor {
        visit_item: visit_item,
        visit_expr: visit_expr,
        .. *visit::default_visitor()
    });
    (visitor.visit_item)(it, env, visitor);

    fn visit_item(it: @item, &&env: env, v: visit::vt<env>) {
        if (*env.idstack).contains(&(it.id)) {
            env.sess.span_fatal(env.root_it.span, ~"recursive constant");
        }
        (*env.idstack).push(it.id);
        visit::visit_item(it, env, v);
        (*env.idstack).pop();
    }

    fn visit_expr(e: @expr, &&env: env, v: visit::vt<env>) {
        match e.node {
          expr_path(*) => {
            match env.def_map.find(&e.id) {
              Some(def_const(def_id)) => {
                match env.ast_map.get(&def_id.node) {
                  ast_map::node_item(it, _) => {
                    (v.visit_item)(it, env, v);
                  }
                  _ => fail!(~"const not bound to an item")
                }
              }
              _ => ()
            }
          }
          _ => ()
        }
        visit::visit_expr(e, env, v);
    }
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Remove DVec from check_const<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use driver::session::Session;
use middle::resolve;
use middle::ty;
use middle::typeck;
use util::ppaux;

use core::option;
use std::oldmap::HashMap;
use syntax::ast::*;
use syntax::codemap;
use syntax::{visit, ast_util, ast_map};

pub fn check_crate(sess: Session,
                   crate: @crate,
                   ast_map: ast_map::map,
                   def_map: resolve::DefMap,
                   method_map: typeck::method_map,
                   tcx: ty::ctxt) {
    visit::visit_crate(*crate, false, visit::mk_vt(@visit::Visitor {
        visit_item: |a,b,c| check_item(sess, ast_map, def_map, a, b, c),
        visit_pat: check_pat,
        visit_expr: |a,b,c|
            check_expr(sess, def_map, method_map, tcx, a, b, c),
        .. *visit::default_visitor()
    }));
    sess.abort_if_errors();
}

pub fn check_item(sess: Session,
                  ast_map: ast_map::map,
                  def_map: resolve::DefMap,
                  it: @item,
                  &&_is_const: bool,
                  v: visit::vt<bool>) {
    match it.node {
      item_const(_, ex) => {
        (v.visit_expr)(ex, true, v);
        check_item_recursion(sess, ast_map, def_map, it);
      }
      item_enum(ref enum_definition, _) => {
        for (*enum_definition).variants.each |var| {
            do option::iter(&var.node.disr_expr) |ex| {
                (v.visit_expr)(*ex, true, v);
            }
        }
      }
      _ => visit::visit_item(it, false, v)
    }
}

pub fn check_pat(p: @pat, &&_is_const: bool, v: visit::vt<bool>) {
    fn is_str(e: @expr) -> bool {
        match e.node {
            expr_vstore(
                @expr { node: expr_lit(@codemap::spanned {
                    node: lit_str(_),
                    _}),
                       _ },
                expr_vstore_uniq
            ) => true,
            _ => false
        }
    }
    match p.node {
      // Let through plain ~-string literals here
      pat_lit(a) => if !is_str(a) { (v.visit_expr)(a, true, v); },
      pat_range(a, b) => {
        if !is_str(a) { (v.visit_expr)(a, true, v); }
        if !is_str(b) { (v.visit_expr)(b, true, v); }
      }
      _ => visit::visit_pat(p, false, v)
    }
}

pub fn check_expr(sess: Session,
                  def_map: resolve::DefMap,
                  method_map: typeck::method_map,
                  tcx: ty::ctxt,
                  e: @expr,
                  &&is_const: bool,
                  v: visit::vt<bool>) {
    if is_const {
        match e.node {
          expr_unary(box(_), _) | expr_unary(uniq(_), _) |
          expr_unary(deref, _) => {
            sess.span_err(e.span,
                          ~"disallowed operator in constant expression");
            return;
          }
          expr_lit(@codemap::spanned {node: lit_str(_), _}) => { }
          expr_binary(_, _, _) | expr_unary(_, _) => {
            if method_map.contains_key(&e.id) {
                sess.span_err(e.span, ~"user-defined operators are not \
                                       allowed in constant expressions");
            }
          }
          expr_lit(_) => (),
          expr_cast(_, _) => {
            let ety = ty::expr_ty(tcx, e);
            if !ty::type_is_numeric(ety) {
                sess.span_err(e.span, ~"can not cast to `" +
                              ppaux::ty_to_str(tcx, ety) +
                              ~"` in a constant expression");
            }
          }
          expr_path(pth) => {
            // NB: In the future you might wish to relax this slightly
            // to handle on-demand instantiation of functions via
            // foo::<bar> in a const. Currently that is only done on
            // a path in trans::callee that only works in block contexts.
            if pth.types.len() != 0 {
                sess.span_err(
                    e.span, ~"paths in constants may only refer to \
                              items without type parameters");
            }
            match def_map.find(&e.id) {
                Some(def_variant(_, _)) |
                Some(def_struct(_)) => { }

                Some(def_const(def_id)) |
                Some(def_fn(def_id, _)) => {
                if !ast_util::is_local(def_id) {
                    sess.span_err(
                        e.span, ~"paths in constants may only refer to \
                                 crate-local constants or functions");
                }
              }
              Some(def) => {
                debug!("(checking const) found bad def: %?", def);
                sess.span_err(
                    e.span,
                    fmt!("paths in constants may only refer to \
                          constants or functions"));
              }
              None => {
                sess.span_bug(e.span, ~"unbound path in const?!");
              }
            }
          }
          expr_call(callee, _, NoSugar) => {
            match def_map.find(&callee.id) {
                Some(def_struct(*)) => {}    // OK.
                Some(def_variant(*)) => {}    // OK.
                _ => {
                    sess.span_err(
                        e.span,
                        ~"function calls in constants are limited to \
                          struct and enum constructors");
                }
            }
          }
          expr_paren(e) => { check_expr(sess, def_map, method_map,
                                         tcx, e, is_const, v); }
          expr_vstore(_, expr_vstore_slice) |
          expr_vstore(_, expr_vstore_fixed(_)) |
          expr_vec(_, m_imm) |
          expr_addr_of(m_imm, _) |
          expr_field(*) |
          expr_index(*) |
          expr_tup(*) |
          expr_struct(*) |
          expr_rec(*) => { }
          expr_addr_of(*) => {
                sess.span_err(
                    e.span,
                    ~"borrowed pointers in constants may only refer to \
                      immutable values");
          }
          _ => {
            sess.span_err(e.span,
                          ~"constant contains unimplemented expression type");
            return;
          }
        }
    }
    match e.node {
      expr_lit(@codemap::spanned {node: lit_int(v, t), _}) => {
        if t != ty_char {
            if (v as u64) > ast_util::int_ty_max(
                if t == ty_i { sess.targ_cfg.int_type } else { t }) {
                sess.span_err(e.span, ~"literal out of range for its type");
            }
        }
      }
      expr_lit(@codemap::spanned {node: lit_uint(v, t), _}) => {
        if v > ast_util::uint_ty_max(
            if t == ty_u { sess.targ_cfg.uint_type } else { t }) {
            sess.span_err(e.span, ~"literal out of range for its type");
        }
      }
      _ => ()
    }
    visit::visit_expr(e, is_const, v);
}

// Make sure a const item doesn't recursively refer to itself
// FIXME: Should use the dependency graph when it's available (#1356)
pub fn check_item_recursion(sess: Session,
                            ast_map: ast_map::map,
                            def_map: resolve::DefMap,
                            it: @item) {
    struct env {
        root_it: @item,
        sess: Session,
        ast_map: ast_map::map,
        def_map: resolve::DefMap,
        idstack: @mut ~[node_id]
    }

    let env = env {
        root_it: it,
        sess: sess,
        ast_map: ast_map,
        def_map: def_map,
        idstack: @mut ~[]
    };

    let visitor = visit::mk_vt(@visit::Visitor {
        visit_item: visit_item,
        visit_expr: visit_expr,
        .. *visit::default_visitor()
    });
    (visitor.visit_item)(it, env, visitor);

    fn visit_item(it: @item, &&env: env, v: visit::vt<env>) {
        if env.idstack.contains(&(it.id)) {
            env.sess.span_fatal(env.root_it.span, ~"recursive constant");
        }
        env.idstack.push(it.id);
        visit::visit_item(it, env, v);
        env.idstack.pop();
    }

    fn visit_expr(e: @expr, &&env: env, v: visit::vt<env>) {
        match e.node {
          expr_path(*) => {
            match env.def_map.find(&e.id) {
              Some(def_const(def_id)) => {
                match env.ast_map.get(&def_id.node) {
                  ast_map::node_item(it, _) => {
                    (v.visit_item)(it, env, v);
                  }
                  _ => fail!(~"const not bound to an item")
                }
              }
              _ => ()
            }
          }
          _ => ()
        }
        visit::visit_expr(e, env, v);
    }
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


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

use core::prelude::*;

use ast;
use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
use ast_util;
use codemap::{span, dummy_sp};
use diagnostic::span_handler;
use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
use parse::lexer::TokenAndSpan;

use core::option;
use core::vec;
use std;
use std::oldmap::HashMap;

enum tt_frame_up { /* to break a circularity */
    tt_frame_up(Option<tt_frame>)
}

/* FIXME #2811: figure out how to have a uniquely linked stack, and change to
   `~` */
///an unzipping of `token_tree`s
type tt_frame = @{
    readme: ~[ast::token_tree],
    mut idx: uint,
    dotdotdoted: bool,
    sep: Option<Token>,
    up: tt_frame_up,
};

pub type tt_reader = @tt_reader_;
pub type tt_reader_ = {
    sp_diag: span_handler,
    interner: @ident_interner,
    mut cur: tt_frame,
    /* for MBE-style macro transcription */
    interpolations: std::oldmap::HashMap<ident, @named_match>,
    mut repeat_idx: ~[uint],
    mut repeat_len: ~[uint],
    /* cached: */
    mut cur_tok: Token,
    mut cur_span: span
};

/** This can do Macro-By-Example transcription. On the other hand, if
 *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
 *  should) be none. */
pub fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner,
                     interp: Option<std::oldmap::HashMap<ident,@named_match>>,
                     src: ~[ast::token_tree])
                  -> tt_reader {
    let r = @{sp_diag: sp_diag, interner: itr,
              mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false,
                         sep: None, up: tt_frame_up(option::None)},
              interpolations: match interp { /* just a convienience */
                None => std::oldmap::HashMap(),
                Some(x) => x
              },
              mut repeat_idx: ~[],
              mut repeat_len: ~[],
              /* dummy values, never read: */
              mut cur_tok: EOF,
              mut cur_span: dummy_sp()
             };
    tt_next_token(r); /* get cur_tok and cur_span set up */
    return r;
}

pure fn dup_tt_frame(&&f: tt_frame) -> tt_frame {
    @{readme: f.readme, mut idx: f.idx, dotdotdoted: f.dotdotdoted,
      sep: f.sep, up: match f.up {
        tt_frame_up(Some(up_frame)) => {
          tt_frame_up(Some(dup_tt_frame(up_frame)))
        }
        tt_frame_up(none) => tt_frame_up(none)
      }
     }
}

pub pure fn dup_tt_reader(r: &tt_reader_) -> tt_reader {
    @{sp_diag: r.sp_diag, interner: r.interner,
      mut cur: dup_tt_frame(r.cur),
      interpolations: r.interpolations,
      mut repeat_idx: copy r.repeat_idx, mut repeat_len: copy r.repeat_len,
      mut cur_tok: r.cur_tok, mut cur_span: r.cur_span}
}

pure fn lookup_cur_matched_by_matched(r: &tt_reader_,
                                      start: @named_match) -> @named_match {
    pure fn red(+ad: @named_match, idx: &uint) -> @named_match {
        match *ad {
          matched_nonterminal(_) => {
            // end of the line; duplicate henceforth
            ad
          }
          matched_seq(ads, _) => ads[*idx]
        }
    }
    vec::foldl(start, r.repeat_idx, red)
}

fn lookup_cur_matched(r: &tt_reader_, name: ident) -> @named_match {
    lookup_cur_matched_by_matched(r, r.interpolations.get(&name))
}
enum lis {
    lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str)
}

fn lockstep_iter_size(t: token_tree, r: &tt_reader_) -> lis {
    fn lis_merge(lhs: lis, rhs: lis, r: &tt_reader_) -> lis {
        match lhs {
          lis_unconstrained => rhs,
          lis_contradiction(_) => lhs,
          lis_constraint(l_len, l_id) => match rhs {
            lis_unconstrained => lhs,
            lis_contradiction(_) => rhs,
            lis_constraint(r_len, _) if l_len == r_len => lhs,
            lis_constraint(r_len, r_id) => {
                let l_n = *r.interner.get(l_id);
                let r_n = *r.interner.get(r_id);
                lis_contradiction(fmt!("Inconsistent lockstep iteration: \
                                       '%s' has %u items, but '%s' has %u",
                                        l_n, l_len, r_n, r_len))
            }
          }
        }
    }
    match t {
      tt_delim(ref tts) | tt_seq(_, ref tts, _, _) => {
        vec::foldl(lis_unconstrained, (*tts), |lis, tt|
            lis_merge(lis, lockstep_iter_size(*tt, r), r))
      }
      tt_tok(*) => lis_unconstrained,
      tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) {
        matched_nonterminal(_) => lis_unconstrained,
        matched_seq(ads, _) => lis_constraint(ads.len(), name)
      }
    }
}

pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
    let ret_val = TokenAndSpan { tok: r.cur_tok, sp: r.cur_span };
    while r.cur.idx >= r.cur.readme.len() {
        /* done with this set; pop or repeat? */
        if ! r.cur.dotdotdoted
            || r.repeat_idx.last() == r.repeat_len.last() - 1 {

            match r.cur.up {
              tt_frame_up(None) => {
                r.cur_tok = EOF;
                return ret_val;
              }
              tt_frame_up(Some(tt_f)) => {
                if r.cur.dotdotdoted {
                    r.repeat_idx.pop();
                    r.repeat_len.pop();
                }

                r.cur = tt_f;
                r.cur.idx += 1u;
              }
            }

        } else { /* repeat */
            r.cur.idx = 0u;
            r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
            match r.cur.sep {
              Some(ref tk) => {
                r.cur_tok = (*tk); /* repeat same span, I guess */
                return ret_val;
              }
              None => ()
            }
        }
    }
    loop { /* because it's easiest, this handles `tt_delim` not starting
    with a `tt_tok`, even though it won't happen */
        match r.cur.readme[r.cur.idx] {
          tt_delim(ref tts) => {
            r.cur = @{readme: (*tts), mut idx: 0u, dotdotdoted: false,
                      sep: None, up: tt_frame_up(option::Some(r.cur)) };
            // if this could be 0-length, we'd need to potentially recur here
          }
          tt_tok(sp, ref tok) => {
            r.cur_span = sp; r.cur_tok = (*tok);
            r.cur.idx += 1u;
            return ret_val;
          }
          tt_seq(sp, ref tts, ref sep, zerok) => {
              match lockstep_iter_size(tt_seq(sp, (*tts), (*sep), zerok), r) {
                  lis_unconstrained => {
                      r.sp_diag.span_fatal(
                          sp, /* blame macro writer */
                          ~"attempted to repeat an expression containing no syntax \
                            variables matched as repeating at this depth");
                  }
                  lis_contradiction(ref msg) => {
                      /* FIXME #2887 blame macro invoker instead*/
                      r.sp_diag.span_fatal(sp, (*msg));
                  }
                  lis_constraint(len, _) => {
                      if len == 0 {
                          if !zerok {
                              r.sp_diag.span_fatal(sp, /* FIXME #2887 blame invoker
                              */
                                                   ~"this must repeat at least \
                                                     once");
                          }

                    r.cur.idx += 1u;
                    return tt_next_token(r);
                } else {
                    r.repeat_len.push(len);
                    r.repeat_idx.push(0u);
                    r.cur = @{
                        readme: (*tts),
                        mut idx: 0u,
                        dotdotdoted: true,
                        sep: (*sep),
                        up: tt_frame_up(option::Some(r.cur))
                    };
                }
              }
            }
          }
          // FIXME #2887: think about span stuff here
          tt_nonterminal(sp, ident) => {
            match *lookup_cur_matched(r, ident) {
              /* sidestep the interpolation tricks for ident because
              (a) idents can be in lots of places, so it'd be a pain
              (b) we actually can, since it's a token. */
              matched_nonterminal(nt_ident(sn,b)) => {
                r.cur_span = sp; r.cur_tok = IDENT(sn,b);
                r.cur.idx += 1u;
                return ret_val;
              }
              matched_nonterminal(ref other_whole_nt) => {
                r.cur_span = sp; r.cur_tok = INTERPOLATED((*other_whole_nt));
                r.cur.idx += 1u;
                return ret_val;
              }
              matched_seq(*) => {
                r.sp_diag.span_fatal(
                    copy r.cur_span, /* blame the macro writer */
                    fmt!("variable '%s' is still repeating at this depth",
                         *r.interner.get(ident)));
              }
            }
          }
        }
    }

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

use core::prelude::*;

use ast;
use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
use ast_util;
use codemap::{span, dummy_sp};
use diagnostic::span_handler;
use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
use parse::lexer::TokenAndSpan;

use core::option;
use core::vec;
use std;
use std::oldmap::HashMap;

enum tt_frame_up { /* to break a circularity */
    tt_frame_up(Option<tt_frame>)
}

/* FIXME #2811: figure out how to have a uniquely linked stack, and change to
   `~` */
///an unzipping of `token_tree`s
type tt_frame = @{
    readme: ~[ast::token_tree],
    mut idx: uint,
    dotdotdoted: bool,
    sep: Option<Token>,
    up: tt_frame_up,
};

pub type tt_reader = @tt_reader_;
pub type tt_reader_ = {
    sp_diag: span_handler,
    interner: @ident_interner,
    mut cur: tt_frame,
    /* for MBE-style macro transcription */
    interpolations: std::oldmap::HashMap<ident, @named_match>,
    mut repeat_idx: ~[uint],
    mut repeat_len: ~[uint],
    /* cached: */
    mut cur_tok: Token,
    mut cur_span: span
};

/** This can do Macro-By-Example transcription. On the other hand, if
 *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
 *  should) be none. */
pub fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner,
                     interp: Option<std::oldmap::HashMap<ident,@named_match>>,
                     src: ~[ast::token_tree])
                  -> tt_reader {
    let r = @{sp_diag: sp_diag, interner: itr,
              mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false,
                         sep: None, up: tt_frame_up(option::None)},
              interpolations: match interp { /* just a convienience */
                None => std::oldmap::HashMap(),
                Some(x) => x
              },
              mut repeat_idx: ~[],
              mut repeat_len: ~[],
              /* dummy values, never read: */
              mut cur_tok: EOF,
              mut cur_span: dummy_sp()
             };
    tt_next_token(r); /* get cur_tok and cur_span set up */
    return r;
}

pure fn dup_tt_frame(&&f: tt_frame) -> tt_frame {
    @{readme: f.readme, mut idx: f.idx, dotdotdoted: f.dotdotdoted,
      sep: f.sep, up: match f.up {
        tt_frame_up(Some(up_frame)) => {
          tt_frame_up(Some(dup_tt_frame(up_frame)))
        }
        tt_frame_up(none) => tt_frame_up(none)
      }
     }
}

pub pure fn dup_tt_reader(r: &tt_reader_) -> tt_reader {
    @{sp_diag: r.sp_diag, interner: r.interner,
      mut cur: dup_tt_frame(r.cur),
      interpolations: r.interpolations,
      mut repeat_idx: copy r.repeat_idx, mut repeat_len: copy r.repeat_len,
      mut cur_tok: r.cur_tok, mut cur_span: r.cur_span}
}

pure fn lookup_cur_matched_by_matched(r: &tt_reader_,
                                      start: @named_match) -> @named_match {
    pure fn red(+ad: @named_match, idx: &uint) -> @named_match {
        match *ad {
          matched_nonterminal(_) => {
            // end of the line; duplicate henceforth
            ad
          }
          matched_seq(ads, _) => ads[*idx]
        }
    }
    vec::foldl(start, r.repeat_idx, red)
}

fn lookup_cur_matched(r: &tt_reader_, name: ident) -> @named_match {
    lookup_cur_matched_by_matched(r, r.interpolations.get(&name))
}
enum lis {
    lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str)
}

fn lockstep_iter_size(t: token_tree, r: &tt_reader_) -> lis {
    fn lis_merge(lhs: lis, rhs: lis, r: &tt_reader_) -> lis {
        match lhs {
          lis_unconstrained => rhs,
          lis_contradiction(_) => lhs,
          lis_constraint(l_len, l_id) => match rhs {
            lis_unconstrained => lhs,
            lis_contradiction(_) => rhs,
            lis_constraint(r_len, _) if l_len == r_len => lhs,
            lis_constraint(r_len, r_id) => {
                let l_n = *r.interner.get(l_id);
                let r_n = *r.interner.get(r_id);
                lis_contradiction(fmt!("Inconsistent lockstep iteration: \
                                       '%s' has %u items, but '%s' has %u",
                                        l_n, l_len, r_n, r_len))
            }
          }
        }
    }
    match t {
      tt_delim(ref tts) | tt_seq(_, ref tts, _, _) => {
        vec::foldl(lis_unconstrained, (*tts), |lis, tt|
            lis_merge(lis, lockstep_iter_size(*tt, r), r))
      }
      tt_tok(*) => lis_unconstrained,
      tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) {
        matched_nonterminal(_) => lis_unconstrained,
        matched_seq(ads, _) => lis_constraint(ads.len(), name)
      }
    }
}

pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
    let ret_val = TokenAndSpan { tok: r.cur_tok, sp: r.cur_span };
    while r.cur.idx >= r.cur.readme.len() {
        /* done with this set; pop or repeat? */
        if ! r.cur.dotdotdoted
            || r.repeat_idx.last() == r.repeat_len.last() - 1 {

            match r.cur.up {
              tt_frame_up(None) => {
                r.cur_tok = EOF;
                return ret_val;
              }
              tt_frame_up(Some(tt_f)) => {
                if r.cur.dotdotdoted {
                    r.repeat_idx.pop();
                    r.repeat_len.pop();
                }

                r.cur = tt_f;
                r.cur.idx += 1u;
              }
            }

        } else { /* repeat */
            r.cur.idx = 0u;
            r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
            match r.cur.sep {
              Some(ref tk) => {
                r.cur_tok = (*tk); /* repeat same span, I guess */
                return ret_val;
              }
              None => ()
            }
        }
    }
    loop { /* because it's easiest, this handles `tt_delim` not starting
    with a `tt_tok`, even though it won't happen */
        match r.cur.readme[r.cur.idx] {
          tt_delim(ref tts) => {
            r.cur = @{readme: (*tts), mut idx: 0u, dotdotdoted: false,
                      sep: None, up: tt_frame_up(option::Some(r.cur)) };
            // if this could be 0-length, we'd need to potentially recur here
          }
          tt_tok(sp, ref tok) => {
            r.cur_span = sp; r.cur_tok = (*tok);
            r.cur.idx += 1u;
            return ret_val;
          }
          tt_seq(sp, ref tts, ref sep, zerok) => {
              match lockstep_iter_size(tt_seq(sp, (*tts), (*sep), zerok), r) {
                lis_unconstrained => {
                  r.sp_diag.span_fatal(
                    sp, /* blame macro writer */
                      ~"attempted to repeat an expression \
                        containing no syntax \
                        variables matched as repeating at this depth");
                  }
                  lis_contradiction(ref msg) => {
                      /* FIXME #2887 blame macro invoker instead*/
                      r.sp_diag.span_fatal(sp, (*msg));
                  }
                  lis_constraint(len, _) => {
                    if len == 0 {
                      if !zerok {
                        r.sp_diag.span_fatal(sp, /* FIXME #2887 blame invoker
                        */
                                             ~"this must repeat at least \
                                               once");
                          }

                    r.cur.idx += 1u;
                    return tt_next_token(r);
                } else {
                    r.repeat_len.push(len);
                    r.repeat_idx.push(0u);
                    r.cur = @{
                        readme: (*tts),
                        mut idx: 0u,
                        dotdotdoted: true,
                        sep: (*sep),
                        up: tt_frame_up(option::Some(r.cur))
                    };
                }
              }
            }
          }
          // FIXME #2887: think about span stuff here
          tt_nonterminal(sp, ident) => {
            match *lookup_cur_matched(r, ident) {
              /* sidestep the interpolation tricks for ident because
              (a) idents can be in lots of places, so it'd be a pain
              (b) we actually can, since it's a token. */
              matched_nonterminal(nt_ident(sn,b)) => {
                r.cur_span = sp; r.cur_tok = IDENT(sn,b);
                r.cur.idx += 1u;
                return ret_val;
              }
              matched_nonterminal(ref other_whole_nt) => {
                r.cur_span = sp; r.cur_tok = INTERPOLATED((*other_whole_nt));
                r.cur.idx += 1u;
                return ret_val;
              }
              matched_seq(*) => {
                r.sp_diag.span_fatal(
                    copy r.cur_span, /* blame the macro writer */
                    fmt!("variable '%s' is still repeating at this depth",
                         *r.interner.get(ident)));
              }
            }
          }
        }
    }

}
<|endoftext|>


<commit_before>export Msg, Prefetch, GetImage, Exit;
export ImageResponseMsg, ImageReady, ImageNotReady;
export ImageCacheTask;
export image_cache_task;

import image::base::{Image, load_from_memory, test_image_bin};
import std::net::url::url;
import util::url::{make_url, UrlMap, url_map};
import comm::{chan, port};
import task::spawn_listener;
import resource::resource_task;
import resource_task::ResourceTask;
import core::arc::arc;
import clone_arc = core::arc::clone;

enum Msg {
    Prefetch(url),
    GetImage(url, chan<ImageResponseMsg>),
    Exit
}

enum ImageResponseMsg {
    ImageReady(arc<~Image>),
    ImageNotReady
}

type ImageCacheTask = chan<Msg>;

fn image_cache_task(resource_task: ResourceTask) -> ImageCacheTask {
    do spawn_listener |from_client| {
        ImageCache {
            resource_task: resource_task,
            from_client: from_client,
            prefetch_map: url_map(),
            image_map: url_map()
        }.run();
    }
}

struct ImageCache {
    resource_task: ResourceTask;
    from_client: port<Msg>;
    prefetch_map: UrlMap<@PrefetchData>;
    image_map: UrlMap<@arc<~Image>>;
}

struct PrefetchData {
    response_port: port<resource_task::ProgressMsg>;
    mut data: ~[u8];
}

impl ImageCache {

    fn run() {

        loop {
            match self.from_client.recv() {
              Prefetch(url) => self.prefetch(url),
              GetImage(url, response) => self.get_image(url, response),
              Exit => break
            }
        }
    }

    /*priv*/ fn prefetch(url: url) {
        if self.image_map.contains_key(url) {
            // We've already decoded this image
            return
        }

        if self.prefetch_map.contains_key(url) {
            // We're already waiting for this image
            return
        }
        let response_port = port();
        self.resource_task.send(resource_task::Load(url, response_port.chan()));

        let prefetch_data = @PrefetchData {
            response_port: response_port,
            data: ~[]
        };

        self.prefetch_map.insert(url, prefetch_data);
    }

    /*priv*/ fn get_image(url: url, response: chan<ImageResponseMsg>) {
        match self.image_map.find(url) {
          some(image) => {
            response.send(ImageReady(clone_arc(image)));
            return
          }
          none => ()
        }

        match self.prefetch_map.find(url) {
          some(prefetch_data) => {

            let mut image_sent = false;

            while prefetch_data.response_port.peek() {
                match prefetch_data.response_port.recv() {
                  resource_task::Payload(data) => {
                    prefetch_data.data += data;
                  }
                  resource_task::Done(result::ok(*)) => {
                    // We've got the entire image binary
                    let mut data = ~[];
                    data <-> prefetch_data.data;
                    // FIXME: Need to do this in parallel
                    let image = @arc(~load_from_memory(data));
                    response.send(ImageReady(clone_arc(image)));
                    self.prefetch_map.remove(url);
                    self.image_map.insert(url, image);
                    image_sent = true;
                    break;
                  }
                  resource_task::Done(result::err(*)) => {
                    // FIXME: need to actually report the failed image load
                    self.prefetch_map.remove(url);
                    break;
                  }
                }
            }

            if !image_sent {
                response.send(ImageNotReady);
            }
          }
          none => fail ~"got a request for image data without prefetch"
        }
    }
}

#[test]
fn should_exit_on_request() {

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Exit => break,
              _ => ()
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
#[should_fail]
fn should_fail_if_unprefetched_image_is_requested() {

    let mock_resource_task = do spawn_listener |from_client| {
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    let request = port();
    image_cache_task.send(GetImage(url, request.chan()));
    request.recv();
}

#[test]
fn should_request_url_from_resource_task_on_prefetch() {
    let url_requested = port();
    let url_requested_chan = url_requested.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(url, _) => url_requested_chan.send(()),
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));
    url_requested.recv();
    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_not_request_url_from_resource_task_on_multiple_prefetches() {
    let url_requested = port();
    let url_requested_chan = url_requested.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(url, _) => url_requested_chan.send(()),
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));
    image_cache_task.send(Prefetch(url));
    url_requested.recv();
    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
    assert !url_requested.peek()
}

#[test]
fn should_return_image_not_ready_if_data_has_not_arrived() {
    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Exit => break,
              _ => ()
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));
    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    assert response_port.recv() == ImageNotReady;
    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_return_decoded_image_data_if_data_has_arrived() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                response.send(resource_task::Done(result::ok(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    match response_port.recv() {
      ImageReady(_) => (),
      _ => fail
    }

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_return_decoded_image_data_for_multiple_requests() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                response.send(resource_task::Done(result::ok(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    for iter::repeat(2) {
        let response_port = port();
        image_cache_task.send(GetImage(url, response_port.chan()));
        match response_port.recv() {
          ImageReady(_) => (),
          _ => fail
        }
    }

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_not_request_image_from_resource_task_if_image_is_already_available() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let resource_task_exited = port();
    let resource_task_exited_chan = resource_task_exited.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                response.send(resource_task::Done(result::ok(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => {
                resource_task_exited_chan.send(());
                break
              }
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    match response_port.recv() {
      ImageReady(_) => (),
      _ => fail
    }

    image_cache_task.send(Prefetch(url));

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    response_port.recv();

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);

    resource_task_exited.recv();

    // Our resource task should not have received another request for the image
    // because it's already cached
    assert !image_bin_sent.peek();
}

#[test]
fn should_return_not_ready_if_image_bin_cannot_be_fetched() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                // ERROR fetching image
                response.send(resource_task::Done(result::err(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    match response_port.recv() {
      ImageNotReady => (),
      _ => fail
    }

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}
<commit_msg>Decode images in parallel<commit_after>export Msg, Prefetch, GetImage, Exit;
export ImageResponseMsg, ImageReady, ImageNotReady;
export ImageCacheTask;
export image_cache_task;

import image::base::{Image, load_from_memory, test_image_bin};
import std::net::url::url;
import util::url::{make_url, UrlMap, url_map};
import comm::{chan, port};
import task::{spawn, spawn_listener};
import resource::resource_task;
import resource_task::ResourceTask;
import core::arc::arc;
import clone_arc = core::arc::clone;

enum Msg {
    Prefetch(url),
    GetImage(url, chan<ImageResponseMsg>),
    StoreImage(url, arc<~Image>),
    Exit
}

enum ImageResponseMsg {
    ImageReady(arc<~Image>),
    ImageNotReady
}

type ImageCacheTask = chan<Msg>;

fn image_cache_task(resource_task: ResourceTask) -> ImageCacheTask {
    do spawn_listener |from_client| {
        ImageCache {
            resource_task: resource_task,
            from_client: from_client,
            prefetch_map: url_map(),
            future_image_map: url_map(),
            image_map: url_map()
        }.run();
    }
}

struct ImageCache {
    resource_task: ResourceTask;
    from_client: port<Msg>;
    prefetch_map: UrlMap<@PrefetchData>;
    future_image_map: UrlMap<@FutureData>;
    image_map: UrlMap<@arc<~Image>>;
}

struct PrefetchData {
    response_port: port<resource_task::ProgressMsg>;
    mut data: ~[u8];
}

struct FutureData {
    mut waiters: ~[chan<ImageResponseMsg>];
}

impl ImageCache {

    fn run() {

        loop {
            match self.from_client.recv() {
              Prefetch(url) => self.prefetch(url),
              GetImage(url, response) => self.get_image(url, response),
              StoreImage(url, image) => self.store_image(url, &image),
              Exit => break
            }
        }
    }

    /*priv*/ fn prefetch(url: url) {
        if self.image_map.contains_key(url) {
            // We've already decoded this image
            return
        }

        if self.future_image_map.contains_key(url) {
            // We've already begun decoding this image
            return
        }

        if self.prefetch_map.contains_key(url) {
            // We're already waiting for this image
            return
        }

        let response_port = port();
        self.resource_task.send(resource_task::Load(url, response_port.chan()));

        let prefetch_data = @PrefetchData {
            response_port: response_port,
            data: ~[]
        };

        self.prefetch_map.insert(url, prefetch_data);
    }

    /*priv*/ fn get_image(url: url, response: chan<ImageResponseMsg>) {
        match self.image_map.find(url) {
          some(image) => {
            response.send(ImageReady(clone_arc(image)));
            return
          }
          none => ()
        }

        match self.future_image_map.find(url) {
          some(future_data) => {
            // We've started decoding this image but haven't recieved it back yet.
            // Put this client on the wait list
            vec::push(future_data.waiters, response);
            return
          }
          none => ()
        }

        match self.prefetch_map.find(url) {
          some(prefetch_data) => {

            let mut image_sent = false;

            while prefetch_data.response_port.peek() {
                match prefetch_data.response_port.recv() {
                  resource_task::Payload(data) => {
                    prefetch_data.data += data;
                  }
                  resource_task::Done(result::ok(*)) => {
                    // We've got the entire image binary
                    let mut data = ~[];
                    data <-> prefetch_data.data;
                    let data <- data; // freeze for capture

                    let to_cache = self.from_client.chan();

                    do spawn {
                        let image = arc(~load_from_memory(data));
                        // Send the image to the original requester
                        response.send(ImageReady(clone_arc(&image)));
                        to_cache.send(StoreImage(url, clone_arc(&image)));
                    }

                    let future_data = @FutureData {
                        waiters: ~[]
                    };

                    self.prefetch_map.remove(url);
                    self.future_image_map.insert(url, future_data);

                    image_sent = true;
                    break;
                  }
                  resource_task::Done(result::err(*)) => {
                    // FIXME: need to actually report the failed image load
                    self.prefetch_map.remove(url);
                    break;
                  }
                }
            }

            if !image_sent {
                response.send(ImageNotReady);
            }
          }
          none => fail ~"got a request for image data without prefetch"
        }
    }

    /*priv*/ fn store_image(url: url, image: &arc<~Image>) {
        match self.future_image_map.find(url) {
          some(future_data) => {

            let mut waiters = ~[];
            waiters <-> future_data.waiters;

            // Send the image to all those who requested it while
            // it was being decoded
            for waiters.each |waiter| {
                waiter.send(ImageReady(clone_arc(image)))
            }
            self.image_map.insert(url, @clone_arc(image));
            self.future_image_map.remove(url);
          }
          none => fail ~"storing an image that isn't in the future map"
        }
    }
}

#[test]
fn should_exit_on_request() {

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Exit => break,
              _ => ()
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
#[should_fail]
fn should_fail_if_unprefetched_image_is_requested() {

    let mock_resource_task = do spawn_listener |from_client| {
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    let request = port();
    image_cache_task.send(GetImage(url, request.chan()));
    request.recv();
}

#[test]
fn should_request_url_from_resource_task_on_prefetch() {
    let url_requested = port();
    let url_requested_chan = url_requested.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(url, _) => url_requested_chan.send(()),
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));
    url_requested.recv();
    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_not_request_url_from_resource_task_on_multiple_prefetches() {
    let url_requested = port();
    let url_requested_chan = url_requested.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(url, _) => url_requested_chan.send(()),
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));
    image_cache_task.send(Prefetch(url));
    url_requested.recv();
    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
    assert !url_requested.peek()
}

#[test]
fn should_return_image_not_ready_if_data_has_not_arrived() {
    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Exit => break,
              _ => ()
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));
    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    assert response_port.recv() == ImageNotReady;
    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_return_decoded_image_data_if_data_has_arrived() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                response.send(resource_task::Done(result::ok(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    match response_port.recv() {
      ImageReady(_) => (),
      _ => fail
    }

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_return_decoded_image_data_for_multiple_requests() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                response.send(resource_task::Done(result::ok(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    for iter::repeat(2) {
        let response_port = port();
        image_cache_task.send(GetImage(url, response_port.chan()));
        match response_port.recv() {
          ImageReady(_) => (),
          _ => fail
        }
    }

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}

#[test]
fn should_not_request_image_from_resource_task_if_image_is_already_available() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let resource_task_exited = port();
    let resource_task_exited_chan = resource_task_exited.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                response.send(resource_task::Done(result::ok(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => {
                resource_task_exited_chan.send(());
                break
              }
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    match response_port.recv() {
      ImageReady(_) => (),
      _ => fail
    }

    image_cache_task.send(Prefetch(url));

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    response_port.recv();

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);

    resource_task_exited.recv();

    // Our resource task should not have received another request for the image
    // because it's already cached
    assert !image_bin_sent.peek();
}

#[test]
fn should_return_not_ready_if_image_bin_cannot_be_fetched() {

    let image_bin_sent = port();
    let image_bin_sent_chan = image_bin_sent.chan();

    let mock_resource_task = do spawn_listener |from_client| {

        // infer me
        let from_client: port<resource_task::ControlMsg> = from_client;

        loop {
            match from_client.recv() {
              resource_task::Load(_, response) => {
                response.send(resource_task::Payload(test_image_bin()));
                // ERROR fetching image
                response.send(resource_task::Done(result::err(())));
                image_bin_sent_chan.send(());
              }
              resource_task::Exit => break
            }
        }
    };

    let image_cache_task = image_cache_task(mock_resource_task);
    let url = make_url(~"file", none);

    image_cache_task.send(Prefetch(url));

    // Wait until our mock resource task has sent the image to the image cache
    image_bin_sent.recv();

    let response_port = port();
    image_cache_task.send(GetImage(url, response_port.chan()));
    match response_port.recv() {
      ImageNotReady => (),
      _ => fail
    }

    image_cache_task.send(Exit);
    mock_resource_task.send(resource_task::Exit);
}
<|endoftext|>


<commit_before><commit_msg>test: Add test for #1763<commit_after>// Issue #1763 - infer types correctly
// error-pattern:explicit failure

type actor<T> = {
    unused: bool
};

fn act2<T>() -> actor<T> {
    fail;
}

fn main() {
    let a: actor<int> = act2();
}
<|endoftext|>


<commit_before><commit_msg>test: Add test for issue #1460<commit_after>
fn main() {
    {|i| if i == 1 { }};
}<|endoftext|>


<commit_before><commit_msg>ignore revoke error<commit_after><|endoftext|>


<commit_before><commit_msg>Add debugging output in test via logger<commit_after><|endoftext|>


<commit_before><commit_msg>musl: opt for dynamic linking for arm arch<commit_after><|endoftext|>


<commit_before><commit_msg>Return print<commit_after><|endoftext|>


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

// compile-pass
// only-x86_64
// no-prefer-dynamic
// compile-flags: -Ctarget-feature=+avx -Clto

fn main() {}<|endoftext|>


<commit_before><commit_msg>use u32 suffixes<commit_after><|endoftext|>


<commit_before>#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(not(feature = "unstable"), deny(warnings))]

//! Types for loading and managing AWS access credentials for API requests.

extern crate chrono;
extern crate reqwest;
extern crate regex;
extern crate serde_json;

pub use environment::EnvironmentProvider;
pub use container::ContainerProvider;
pub use instance_metadata::InstanceMetadataProvider;
pub use profile::ProfileProvider;

mod container;
mod environment;
mod instance_metadata;
mod profile;

use std::fmt;
use std::error::Error;
use std::io::Error as IoError;
use std::sync::Mutex;
use std::cell::RefCell;

use chrono::{Duration, UTC, DateTime, ParseError};
use serde_json::Value;

/// AWS API access credentials, including access key, secret key, token (for IAM profiles), and
/// expiration timestamp.
#[derive(Clone, Debug)]
pub struct AwsCredentials {
    key: String,
    secret: String,
    token: Option<String>,
    expires_at: DateTime<UTC>
}

impl AwsCredentials {
    /// Create a new `AwsCredentials` from a key ID, secret key, optional access token, and expiry
    /// time.
    pub fn new<K, S>(key:K, secret:S, token:Option<String>, expires_at:DateTime<UTC>)
    -> AwsCredentials where K:Into<String>, S:Into<String> {
        AwsCredentials {
            key: key.into(),
            secret: secret.into(),
            token: token,
            expires_at: expires_at,
        }
    }

    /// Get a reference to the access key ID.
    pub fn aws_access_key_id(&self) -> &str {
        &self.key
    }

    /// Get a reference to the secret access key.
    pub fn aws_secret_access_key(&self) -> &str {
        &self.secret
    }

    /// Get a reference to the expiry time.
    pub fn expires_at(&self) -> &DateTime<UTC> {
        &self.expires_at
    }

    /// Get a reference to the access token.
    pub fn token(&self) -> &Option<String> {
        &self.token
    }

    /// Determine whether or not the credentials are expired.
    fn credentials_are_expired(&self) -> bool {
        // This is a rough hack to hopefully avoid someone requesting creds then sitting on them
        // before issuing the request:
        self.expires_at < UTC::now() + Duration::seconds(20)
    }
}

#[derive(Debug, PartialEq)]
pub struct CredentialsError {
    pub message: String
}

impl CredentialsError {
    fn new(message: &str) -> CredentialsError {
        CredentialsError {
            message: message.to_string()
        }
    }
}

impl fmt::Display for CredentialsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl Error for CredentialsError {
    fn description(&self) -> &str {
        &self.message
    }
}

impl From<ParseError> for CredentialsError {
    fn from(err: ParseError) -> CredentialsError {
        CredentialsError::new(err.description())
    }
}

impl From<IoError> for CredentialsError {
    fn from(err: IoError) -> CredentialsError {
        CredentialsError::new(err.description())
    }
}

/// A trait for types that produce `AwsCredentials`.
pub trait ProvideAwsCredentials {
    /// Produce a new `AwsCredentials`.
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError>;
}

/// Wrapper for `ProvideAwsCredentials` that caches the credentials returned by the
/// wrapped provider.  Each time the credentials are accessed, they are checked to see if
/// they have expired, in which case they are retrieved from the wrapped provider again.
#[derive(Debug)]
pub struct BaseAutoRefreshingProvider<P, T> {
    credentials_provider: P,
    cached_credentials: T
}

/// Threadsafe `AutoRefreshingProvider` that locks cached credentials with a `Mutex`
pub type AutoRefreshingProviderSync<P> = BaseAutoRefreshingProvider<P, Mutex<AwsCredentials>>;

impl <P: ProvideAwsCredentials> AutoRefreshingProviderSync<P> {
    pub fn with_mutex(provider: P) -> Result<AutoRefreshingProviderSync<P>, CredentialsError> {
        let creds = try!(provider.credentials());
        Ok(BaseAutoRefreshingProvider {
            credentials_provider: provider,
            cached_credentials: Mutex::new(creds)
        })
    }
}

impl <P: ProvideAwsCredentials> ProvideAwsCredentials for BaseAutoRefreshingProvider<P, Mutex<AwsCredentials>> {
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {
        let mut creds = self.cached_credentials.lock().expect("Failed to lock the cached credentials Mutex");
        if creds.credentials_are_expired() {
            *creds = try!(self.credentials_provider.credentials());
        }
        Ok(creds.clone())
    }
}

/// `!Sync` `AutoRefreshingProvider` that caches credentials in a `RefCell`
pub type AutoRefreshingProvider<P> = BaseAutoRefreshingProvider<P, RefCell<AwsCredentials>>;

impl <P: ProvideAwsCredentials> AutoRefreshingProvider<P> {
    pub fn with_refcell(provider: P) -> Result<AutoRefreshingProvider<P>, CredentialsError> {
        let creds = try!(provider.credentials());
        Ok(BaseAutoRefreshingProvider {
            credentials_provider: provider,
            cached_credentials: RefCell::new(creds)
        })
    }
}

impl <P: ProvideAwsCredentials> ProvideAwsCredentials for BaseAutoRefreshingProvider<P, RefCell<AwsCredentials>> {
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {

        let mut creds = self.cached_credentials.borrow_mut();

        if creds.credentials_are_expired() {
            *creds = try!(self.credentials_provider.credentials());
        }

        Ok(creds.clone())
    }
}

/// The credentials provider you probably want to use if you don't require Sync for your AWS services.
/// Wraps a `ChainProvider` in an `AutoRefreshingProvider` that uses a `RefCell` to cache credentials
///
/// The underlying `ChainProvider` checks multiple sources for credentials, and the `AutoRefreshingProvider`
/// refreshes the credentials automatically when they expire.  The `RefCell` allows this caching to happen
/// without the overhead of a `Mutex`, but is `!Sync`.
///
/// For a `Sync` implementation of the same, see `DefaultCredentialsProviderSync`
pub type DefaultCredentialsProvider = AutoRefreshingProvider<ChainProvider>;

impl DefaultCredentialsProvider {
    pub fn new() -> Result<DefaultCredentialsProvider, CredentialsError> {
        Ok(try!(AutoRefreshingProvider::with_refcell(ChainProvider::new())))
    }
}

/// The credentials provider you probably want to use if you do require Sync for your AWS services.
/// Wraps a `ChainProvider` in an `AutoRefreshingProvider` that uses a `Mutex` to lock credentials in a
/// threadsafe manner.
///
/// The underlying `ChainProvider` checks multiple sources for credentials, and the `AutoRefreshingProvider`
/// refreshes the credentials automatically when they expire.  The `Mutex` allows this caching to happen
/// in a Sync manner, incurring the overhead of a Mutex when credentials expire and need to be refreshed.
///
/// For a `!Sync` implementation of the same, see `DefaultCredentialsProvider`
pub type DefaultCredentialsProviderSync = AutoRefreshingProviderSync<ChainProvider>;

impl DefaultCredentialsProviderSync {
    pub fn new() -> Result<DefaultCredentialsProviderSync, CredentialsError> {
        Ok(try!(AutoRefreshingProviderSync::with_mutex(ChainProvider::new())))
    }
}

/// Provides AWS credentials from multiple possible sources using a priority order.
///
/// The following sources are checked in order for credentials when calling `credentials`:
///
/// 1. Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
/// 2. AWS credentials file. Usually located at `~/.aws/credentials`.
/// 3. IAM instance profile. Will only work if running on an EC2 instance with an instance profile/role.
///
/// If the sources are exhausted without finding credentials, an error is returned.
#[derive(Debug, Default, Clone)]
pub struct ChainProvider {
    profile_provider: Option<ProfileProvider>,
}

impl ProvideAwsCredentials for ChainProvider {
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {

    EnvironmentProvider.credentials()
        .or_else(|_| {
            match self.profile_provider {
                Some(ref provider) => provider.credentials(),
                None => Err(CredentialsError::new(""))
            }
        })
        .or_else(|_| ContainerProvider.credentials())
        .or_else(|_| InstanceMetadataProvider.credentials())
        .or_else(|_| Err(CredentialsError::new("Couldn't find AWS credentials in environment, credentials file, or IAM role.")))
    }
}

impl ChainProvider {
    /// Create a new `ChainProvider` using a `ProfileProvider` with the default settings.
    pub fn new() -> ChainProvider {
        ChainProvider {
            profile_provider: ProfileProvider::new().ok(),
        }
    }

    /// Create a new `ChainProvider` using the provided `ProfileProvider`.
    pub fn with_profile_provider(profile_provider: ProfileProvider)
    -> ChainProvider {
        ChainProvider {
            profile_provider: Some(profile_provider),
        }
    }
}

fn in_ten_minutes() -> DateTime<UTC> {
    UTC::now() + Duration::seconds(600)
}

fn extract_string_value_from_json(json_object: &Value, key: &str) -> Result<String, CredentialsError> {
    match json_object.get(key) {
        Some(v) => Ok(v.as_str().expect(&format!("{} value was not a string", key)).to_owned()),
        None => Err(CredentialsError::new(&format!("Couldn't find {} in response.", key))),
    }
}

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

    #[test]
    fn credential_chain_explicit_profile_provider() {
        let profile_provider = ProfileProvider::with_configuration(
            "tests/sample-data/multiple_profile_credentials",
            "foo",
        );

        let chain = ChainProvider::with_profile_provider(profile_provider);

        let credentials = chain.credentials().expect(
            "Failed to get credentials from default provider chain with manual profile",
        );

        assert_eq!(credentials.aws_access_key_id(), "foo_access_key");
        assert_eq!(credentials.aws_secret_access_key(), "foo_secret_key");
    }
}
<commit_msg>Remove use of feature flag in credentials that we don't use any more.<commit_after>#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]

//! Types for loading and managing AWS access credentials for API requests.

extern crate chrono;
extern crate reqwest;
extern crate regex;
extern crate serde_json;

pub use environment::EnvironmentProvider;
pub use container::ContainerProvider;
pub use instance_metadata::InstanceMetadataProvider;
pub use profile::ProfileProvider;

mod container;
mod environment;
mod instance_metadata;
mod profile;

use std::fmt;
use std::error::Error;
use std::io::Error as IoError;
use std::sync::Mutex;
use std::cell::RefCell;

use chrono::{Duration, UTC, DateTime, ParseError};
use serde_json::Value;

/// AWS API access credentials, including access key, secret key, token (for IAM profiles), and
/// expiration timestamp.
#[derive(Clone, Debug)]
pub struct AwsCredentials {
    key: String,
    secret: String,
    token: Option<String>,
    expires_at: DateTime<UTC>
}

impl AwsCredentials {
    /// Create a new `AwsCredentials` from a key ID, secret key, optional access token, and expiry
    /// time.
    pub fn new<K, S>(key:K, secret:S, token:Option<String>, expires_at:DateTime<UTC>)
    -> AwsCredentials where K:Into<String>, S:Into<String> {
        AwsCredentials {
            key: key.into(),
            secret: secret.into(),
            token: token,
            expires_at: expires_at,
        }
    }

    /// Get a reference to the access key ID.
    pub fn aws_access_key_id(&self) -> &str {
        &self.key
    }

    /// Get a reference to the secret access key.
    pub fn aws_secret_access_key(&self) -> &str {
        &self.secret
    }

    /// Get a reference to the expiry time.
    pub fn expires_at(&self) -> &DateTime<UTC> {
        &self.expires_at
    }

    /// Get a reference to the access token.
    pub fn token(&self) -> &Option<String> {
        &self.token
    }

    /// Determine whether or not the credentials are expired.
    fn credentials_are_expired(&self) -> bool {
        // This is a rough hack to hopefully avoid someone requesting creds then sitting on them
        // before issuing the request:
        self.expires_at < UTC::now() + Duration::seconds(20)
    }
}

#[derive(Debug, PartialEq)]
pub struct CredentialsError {
    pub message: String
}

impl CredentialsError {
    fn new(message: &str) -> CredentialsError {
        CredentialsError {
            message: message.to_string()
        }
    }
}

impl fmt::Display for CredentialsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl Error for CredentialsError {
    fn description(&self) -> &str {
        &self.message
    }
}

impl From<ParseError> for CredentialsError {
    fn from(err: ParseError) -> CredentialsError {
        CredentialsError::new(err.description())
    }
}

impl From<IoError> for CredentialsError {
    fn from(err: IoError) -> CredentialsError {
        CredentialsError::new(err.description())
    }
}

/// A trait for types that produce `AwsCredentials`.
pub trait ProvideAwsCredentials {
    /// Produce a new `AwsCredentials`.
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError>;
}

/// Wrapper for `ProvideAwsCredentials` that caches the credentials returned by the
/// wrapped provider.  Each time the credentials are accessed, they are checked to see if
/// they have expired, in which case they are retrieved from the wrapped provider again.
#[derive(Debug)]
pub struct BaseAutoRefreshingProvider<P, T> {
    credentials_provider: P,
    cached_credentials: T
}

/// Threadsafe `AutoRefreshingProvider` that locks cached credentials with a `Mutex`
pub type AutoRefreshingProviderSync<P> = BaseAutoRefreshingProvider<P, Mutex<AwsCredentials>>;

impl <P: ProvideAwsCredentials> AutoRefreshingProviderSync<P> {
    pub fn with_mutex(provider: P) -> Result<AutoRefreshingProviderSync<P>, CredentialsError> {
        let creds = try!(provider.credentials());
        Ok(BaseAutoRefreshingProvider {
            credentials_provider: provider,
            cached_credentials: Mutex::new(creds)
        })
    }
}

impl <P: ProvideAwsCredentials> ProvideAwsCredentials for BaseAutoRefreshingProvider<P, Mutex<AwsCredentials>> {
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {
        let mut creds = self.cached_credentials.lock().expect("Failed to lock the cached credentials Mutex");
        if creds.credentials_are_expired() {
            *creds = try!(self.credentials_provider.credentials());
        }
        Ok(creds.clone())
    }
}

/// `!Sync` `AutoRefreshingProvider` that caches credentials in a `RefCell`
pub type AutoRefreshingProvider<P> = BaseAutoRefreshingProvider<P, RefCell<AwsCredentials>>;

impl <P: ProvideAwsCredentials> AutoRefreshingProvider<P> {
    pub fn with_refcell(provider: P) -> Result<AutoRefreshingProvider<P>, CredentialsError> {
        let creds = try!(provider.credentials());
        Ok(BaseAutoRefreshingProvider {
            credentials_provider: provider,
            cached_credentials: RefCell::new(creds)
        })
    }
}

impl <P: ProvideAwsCredentials> ProvideAwsCredentials for BaseAutoRefreshingProvider<P, RefCell<AwsCredentials>> {
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {

        let mut creds = self.cached_credentials.borrow_mut();

        if creds.credentials_are_expired() {
            *creds = try!(self.credentials_provider.credentials());
        }

        Ok(creds.clone())
    }
}

/// The credentials provider you probably want to use if you don't require Sync for your AWS services.
/// Wraps a `ChainProvider` in an `AutoRefreshingProvider` that uses a `RefCell` to cache credentials
///
/// The underlying `ChainProvider` checks multiple sources for credentials, and the `AutoRefreshingProvider`
/// refreshes the credentials automatically when they expire.  The `RefCell` allows this caching to happen
/// without the overhead of a `Mutex`, but is `!Sync`.
///
/// For a `Sync` implementation of the same, see `DefaultCredentialsProviderSync`
pub type DefaultCredentialsProvider = AutoRefreshingProvider<ChainProvider>;

impl DefaultCredentialsProvider {
    pub fn new() -> Result<DefaultCredentialsProvider, CredentialsError> {
        Ok(try!(AutoRefreshingProvider::with_refcell(ChainProvider::new())))
    }
}

/// The credentials provider you probably want to use if you do require Sync for your AWS services.
/// Wraps a `ChainProvider` in an `AutoRefreshingProvider` that uses a `Mutex` to lock credentials in a
/// threadsafe manner.
///
/// The underlying `ChainProvider` checks multiple sources for credentials, and the `AutoRefreshingProvider`
/// refreshes the credentials automatically when they expire.  The `Mutex` allows this caching to happen
/// in a Sync manner, incurring the overhead of a Mutex when credentials expire and need to be refreshed.
///
/// For a `!Sync` implementation of the same, see `DefaultCredentialsProvider`
pub type DefaultCredentialsProviderSync = AutoRefreshingProviderSync<ChainProvider>;

impl DefaultCredentialsProviderSync {
    pub fn new() -> Result<DefaultCredentialsProviderSync, CredentialsError> {
        Ok(try!(AutoRefreshingProviderSync::with_mutex(ChainProvider::new())))
    }
}

/// Provides AWS credentials from multiple possible sources using a priority order.
///
/// The following sources are checked in order for credentials when calling `credentials`:
///
/// 1. Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
/// 2. AWS credentials file. Usually located at `~/.aws/credentials`.
/// 3. IAM instance profile. Will only work if running on an EC2 instance with an instance profile/role.
///
/// If the sources are exhausted without finding credentials, an error is returned.
#[derive(Debug, Default, Clone)]
pub struct ChainProvider {
    profile_provider: Option<ProfileProvider>,
}

impl ProvideAwsCredentials for ChainProvider {
    fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {

    EnvironmentProvider.credentials()
        .or_else(|_| {
            match self.profile_provider {
                Some(ref provider) => provider.credentials(),
                None => Err(CredentialsError::new(""))
            }
        })
        .or_else(|_| ContainerProvider.credentials())
        .or_else(|_| InstanceMetadataProvider.credentials())
        .or_else(|_| Err(CredentialsError::new("Couldn't find AWS credentials in environment, credentials file, or IAM role.")))
    }
}

impl ChainProvider {
    /// Create a new `ChainProvider` using a `ProfileProvider` with the default settings.
    pub fn new() -> ChainProvider {
        ChainProvider {
            profile_provider: ProfileProvider::new().ok(),
        }
    }

    /// Create a new `ChainProvider` using the provided `ProfileProvider`.
    pub fn with_profile_provider(profile_provider: ProfileProvider)
    -> ChainProvider {
        ChainProvider {
            profile_provider: Some(profile_provider),
        }
    }
}

fn in_ten_minutes() -> DateTime<UTC> {
    UTC::now() + Duration::seconds(600)
}

fn extract_string_value_from_json(json_object: &Value, key: &str) -> Result<String, CredentialsError> {
    match json_object.get(key) {
        Some(v) => Ok(v.as_str().expect(&format!("{} value was not a string", key)).to_owned()),
        None => Err(CredentialsError::new(&format!("Couldn't find {} in response.", key))),
    }
}

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

    #[test]
    fn credential_chain_explicit_profile_provider() {
        let profile_provider = ProfileProvider::with_configuration(
            "tests/sample-data/multiple_profile_credentials",
            "foo",
        );

        let chain = ChainProvider::with_profile_provider(profile_provider);

        let credentials = chain.credentials().expect(
            "Failed to get credentials from default provider chain with manual profile",
        );

        assert_eq!(credentials.aws_access_key_id(), "foo_access_key");
        assert_eq!(credentials.aws_secret_access_key(), "foo_secret_key");
    }
}
<|endoftext|>


<commit_before><commit_msg>Minor touchups to variables prog<commit_after><|endoftext|>


<commit_before><commit_msg>Add example for parse and eval R code from string<commit_after>extern crate libc;
extern crate libr;
use std::ptr;
use std::env;
use std::ffi::{CStr, CString};

use libr::ffi::internals::*;
use libr::ffi::embedded::{self, Rf_endEmbeddedR, Rf_initEmbeddedR};
use libr::ffi::ext::parse::{ParseStatus, R_ParseVector};

fn main() {
    if let Err(_) = env::var("R_HOME") {
        panic!("Rembedded test need R_HOME be setted");
    }

    let mut s = Box::new(vec![CString::new("R").unwrap().into_raw(),
                              CString::new("--quiet").unwrap().into_raw(),
                              CString::new("--no-save").unwrap().into_raw()]);
    unsafe {
        embedded::Rf_initEmbeddedR(s.len() as i32, s.as_mut_ptr());
        // Plot
        let mut status = ParseStatus::PARSE_OK;
        let mut had_error: libc::c_int = 0;
        let mut tmp = Rf_protect(Rf_mkString(CString::new("{pdf(\"03-plot.pdf\"); plot(1:10, pch=\"+\"); print(1:10)}").unwrap().into_raw()));
        let mut e = Rf_protect(R_ParseVector(tmp, 1, &mut status, R_NilValue));
        Rf_PrintValue(e);
        R_tryEval(VECTOR_ELT(e,0), R_GlobalEnv, &mut had_error);
        Rf_unprotect(2);
        embedded::Rf_endEmbeddedR(0);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a super simple example with a moving rectangle<commit_after>extern crate ggez;
use ggez::conf;
use ggez::event;
use ggez::{GameResult, Context};
use ggez::graphics;
use ggez::graphics::{Color, DrawMode, Point};
use std::time::Duration;

struct MainState {
    pos_x: f32,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let s = MainState { pos_x: 0.0 };
        Ok(s)
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        self.pos_x = self.pos_x % 800.0 + 1.0;
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);
        graphics::circle(ctx, DrawMode::Fill, Point { x: self.pos_x, y: 380.0 }, 100.0, 32)?;
        graphics::present(ctx);
        Ok(())
    }
}

pub fn main() {
    let c = conf::Conf::new();
    let ctx = &mut Context::load_from_conf("super_simple", "ggez", c).unwrap();
    let state = &mut MainState::new(ctx).unwrap();
    event::run(ctx, state).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>layout<commit_after><|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2456<commit_after>// https://leetcode.com/problems/most-popular-video-creator/
pub fn most_popular_creator(
    creators: Vec<String>,
    ids: Vec<String>,
    views: Vec<i32>,
) -> Vec<Vec<String>> {
    todo!()
}

fn main() {
    println!(
        "{:?}",
        most_popular_creator(
            vec![
                "alice".to_string(),
                "bob".to_string(),
                "alice".to_string(),
                "chris".to_string()
            ],
            vec![
                "one".to_string(),
                "two".to_string(),
                "three".to_string(),
                "four".to_string()
            ],
            vec![5, 10, 5, 4]
        )
    ); // [["alice","one"],["bob","two"]]
    println!(
        "{:?}",
        most_popular_creator(
            vec![
                "alice".to_string(),
                "alice".to_string(),
                "alice".to_string()
            ],
            vec!["a".to_string(), "b".to_string(), "c".to_string(),],
            vec![1, 2, 2]
        )
    ); // [["alice","b"]]
}
<|endoftext|>


<commit_before><commit_msg>a test program for auto-completion ui<commit_after>extern crate libc;
extern crate rustbox;
extern crate time;
extern crate tiny;

use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::mem;

use tiny::tui::{TUI, TUIRet, MsgTarget};

fn loop_() -> Option<String> {
    let mut tui = TUI::new();
    tui.new_server_tab("debug");

    writeln!(tui, "Loading word list for auto-completion ...").unwrap();
    tui.draw();

    {
        let mut contents = String::new();
        let mut file = File::open("/usr/share/dict/american").unwrap();
        file.read_to_string(&mut contents).unwrap();
        for word in contents.lines() {
            tui.add_nick(word, None, &MsgTarget::Server { serv_name: "debug" });
        }
    }

    writeln!(tui, "Done.").unwrap();
    tui.draw();

    let mut fd_set : libc::fd_set = unsafe { mem::zeroed() };
    unsafe { libc::FD_SET(0, &mut fd_set); }
    let nfds = 1; // stdin + 1

    loop {
        tui.draw();

        let mut fd_set_ = fd_set.clone();
        let ret = unsafe {
            libc::select(nfds,
                         &mut fd_set_,           // read fds
                         std::ptr::null_mut(),   // write fds
                         std::ptr::null_mut(),   // error fds
                         std::ptr::null_mut())   // timeval
        };

        if unsafe { ret == -1 || libc::FD_ISSET(0, &mut fd_set_) } {
            match tui.keypressed_peek() {
                TUIRet::Input { msg, .. } => {
                    tui.add_msg(&msg.into_iter().collect::<String>(),
                                &time::now(),
                                &MsgTarget::Server { serv_name: "debug" });
                },
                TUIRet::Abort => {
                    return None;
                },
                _ => {}
            }
        }
    }
}

fn main() {
    loop_().map(|err| println!("{}", err));
}
<|endoftext|>


<commit_before><commit_msg>Add benchmark/example for Tails.<commit_after>extern crate test;
extern crate simd;
extern crate simdty;

use simdty::*;
use simd::*;

#[bench]
fn simd_(b: &mut test::Bencher) {
    let v = (0..10000).map(|i| i as f64).collect::<Vec<_>>();

    // sum a f64 vector as i32's, via SIMD.
    b.iter(|| {
        let Tails {start,middle,end}: Tails<_, f64x2> = test::black_box(&v[]).convert();
        let mut ret = i32x4(0, 0, 0, 0);
        for elem in middle.iter() {
            ret = ret + elem.convert();
        }
        let leftovers = start.iter().chain(end.iter()).fold(0, |a, b| a + *b as i32);

        ret.0 + ret.1 + leftovers
    })
}
#[bench]
fn nonsimd(b: &mut test::Bencher) {
    let v = (0..10000).map(|i| i as f64).collect::<Vec<f64>>();

    b.iter(|| test::black_box(&v[]).iter().fold(0, |a, b| a + *b as i32))
}
<|endoftext|>


<commit_before><commit_msg>Working now! ...<commit_after><|endoftext|>


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

fn main() {
    let foo = "bar";
    let x = foo("baz");
    //~^ ERROR: expected function, found `&str`
}

fn foo(file: &str) -> bool {
    true
}
<|endoftext|>


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

// compile-flags: -Z parse-only

struct Struct {
    a: usize,
} //~ ERROR expected item, found ';'
//~| NOTE consider removing the semicolon

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add rust merge sort<commit_after>fn merge(v: &mut Vec<i32>, start: usize, mid: usize, end: usize) {
    let mut com1 = start;
    let mut com2 = mid+1;
    let mut com_aux = 0;
    let mut v_aux = vec![0; end-start+1];
    while com1 <= mid && com2 <= end {
        if v[com1] < v[com2] {
            v_aux[com_aux] = v[com1];
            com1 += 1;
        } else {
            v_aux[com_aux] = v[com2];
            com2 += 1;
        }
        com_aux += 1;
    }
    while com1 <= mid {
        v_aux[com_aux] = v[com1];
        com1 += 1;
        com_aux += 1;
    }
    while com2 <= end {
        v_aux[com_aux] = v[com2];
        com2 += 1;
        com_aux += 1;
    }
    for i in start..(end+1) {
        v[i] = v_aux[i - start];
    }
}
fn merge_sort(v: &mut Vec<i32>, start: usize, end: usize) {
    if start < end {
        let mid = (start+end) / 2;
        merge_sort(v, start, mid);
        merge_sort(v, mid+1, end);
        merge(v, start, mid, end);
    }
}
fn main() {
    let mut v = vec![8, 4, 6, 3, 2, 6, 9];
    println!("{:?}", v);
    let end = v.len()-1;
    merge_sort(&mut v, 0, end);
    println!("{:?}", v);
}
<|endoftext|>


<commit_before><commit_msg>add tests<commit_after>#![feature(plugin)]
#![plugin(clippy)]

#![deny(clippy, clippy_pedantic)]
fn main() {
    let _: Vec<_> = vec![5; 6].into_iter() //~ERROR called `filter(p).map(q)` on an Iterator
                              .filter(|&x| x == 0)
                              .map(|x| x * 2)
                              .collect();

    let _: Vec<_> = vec![5i8; 6].into_iter() //~ERROR called `filter(p).flat_map(q)` on an Iterator
                                .filter(|&x| x == 0)
                                .flat_map(|x| x.checked_mul(2))
                                .collect();
}
<|endoftext|>