<commit_before>// Code that generates a test runner to run all the tests in a crate

import std::{option, vec, str};
import syntax::{ast, ast_util};
import syntax::ast_util::*;
//import syntax::ast_util::dummy_sp;
import syntax::fold;
import syntax::print::pprust;
import front::attr;

export modify_for_testing;

type node_id_gen = fn() -> ast::node_id;

type test = {path: [ast::ident], ignore: bool};

type test_ctxt =
    @{next_node_id: node_id_gen,
      mutable path: [ast::ident],
      mutable testfns: [test]};

// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
fn modify_for_testing(crate: @ast::crate) -> @ast::crate {

    // FIXME: This hackasaurus assumes that 200000 is a safe number to start
    // generating node_ids at (which is totally not the case). pauls is going
    // to land a patch that puts parse_sess into session, which will give us
    // access to the real next node_id.
    let next_node_id = @mutable 200000;
    let next_node_id_fn =
        bind fn (next_node_id: @mutable ast::node_id) -> ast::node_id {
                  let this_node_id = *next_node_id;
                  *next_node_id += 1;
                  ret this_node_id;
              }(next_node_id);

    let cx: test_ctxt =
        @{next_node_id: next_node_id_fn,
          mutable path: [],
          mutable testfns: []};

    let precursor =
        {fold_crate: bind fold_crate(cx, _, _),
         fold_item: bind fold_item(cx, _, _),
         fold_mod: bind fold_mod(cx, _, _) with *fold::default_ast_fold()};

    let fold = fold::make_fold(precursor);
    let res = @fold.fold_crate(*crate);
    ret res;
}

fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {

    // Remove any defined main function from the AST so it doesn't clash with
    // the one we're going to add.  FIXME: This is sloppy. Instead we should
    // have some mechanism to indicate to the translation pass which function
    // we want to be main.
    fn nomain(&&item: @ast::item) -> option::t<@ast::item> {
        alt item.node {
          ast::item_fn(f, _) {
            if item.ident == "main" {
                option::none
            } else { option::some(item) }
          }
          _ { option::some(item) }
        }
    }

    let mod_nomain =
        {view_items: m.view_items, items: vec::filter_map(nomain, m.items)};
    ret fold::noop_fold_mod(mod_nomain, fld);
}

fn fold_crate(cx: test_ctxt, c: ast::crate_, fld: fold::ast_fold) ->
   ast::crate_ {
    let folded = fold::noop_fold_crate(c, fld);

    // Add a special __test module to the crate that will contain code
    // generated for the test harness
    ret {module: add_test_module(cx, folded.module) with folded};
}

fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) ->
   @ast::item {

    cx.path += [i.ident];
    log #fmt["current path: %s", ast_util::path_name_i(cx.path)];

    if is_test_fn(i) {
        log "this is a test function";
        let test = {path: cx.path, ignore: is_ignored(i)};
        cx.testfns += [test];
        log #fmt["have %u test functions", vec::len(cx.testfns)];
    }

    let res = fold::noop_fold_item(i, fld);
    vec::pop(cx.path);
    ret res;
}

fn is_test_fn(i: @ast::item) -> bool {
    let has_test_attr =
        vec::len(attr::find_attrs_by_name(i.attrs, "test")) > 0u;

    fn has_test_signature(i: @ast::item) -> bool {
        alt i.node {
          ast::item_fn(f, tps) {
            let input_cnt = vec::len(f.decl.inputs);
            let no_output = f.decl.output.node == ast::ty_nil;
            let tparm_cnt = vec::len(tps);
            input_cnt == 0u && no_output && tparm_cnt == 0u
          }
          _ { false }
        }
    }

    ret has_test_attr && has_test_signature(i);
}

fn is_ignored(i: @ast::item) -> bool {
    attr::contains_name(attr::attr_metas(i.attrs), "ignore")
}

fn add_test_module(cx: test_ctxt, m: ast::_mod) -> ast::_mod {
    let testmod = mk_test_module(cx);
    ret {items: m.items + [testmod] with m};
}

/*

We're going to be building a module that looks more or less like:

mod __test {

  fn main(args: [str]) -> int {
    std::test::test_main(args, tests())
  }

  fn tests() -> [std::test::test_desc] {
    ... the list of tests in the crate ...
  }
}

*/

fn mk_test_module(cx: test_ctxt) -> @ast::item {
    // A function that generates a vector of test descriptors to feed to the
    // test runner
    let testsfn = mk_tests(cx);
    // The synthesized main function which will call the console test runner
    // with our list of tests
    let mainfn = mk_main(cx);
    let testmod: ast::_mod = {view_items: [], items: [mainfn, testsfn]};
    let item_ = ast::item_mod(testmod);
    let item: ast::item =
        {ident: "__test",
         attrs: [],
         id: cx.next_node_id(),
         node: item_,
         span: dummy_sp()};

    log #fmt["Synthetic test module:\n%s\n", pprust::item_to_str(@item)];

    ret @item;
}

fn nospan<@T>(t: T) -> ast::spanned<T> { ret {node: t, span: dummy_sp()}; }

fn mk_tests(cx: test_ctxt) -> @ast::item {
    let ret_ty = mk_test_desc_vec_ty(cx);

    let decl: ast::fn_decl =
        {inputs: [],
         output: ret_ty,
         purity: ast::impure_fn,
         il: ast::il_normal,
         cf: ast::return_val,
         constraints: []};
    let proto = ast::proto_fn;

    // The vector of test_descs for this crate
    let test_descs = mk_test_desc_vec(cx);

    let body_: ast::blk_ =
        default_block([], option::some(test_descs), cx.next_node_id());
    let body = nospan(body_);

    let fn_ = {decl: decl, proto: proto, body: body};

    let item_ = ast::item_fn(fn_, []);
    let item: ast::item =
        {ident: "tests",
         attrs: [],
         id: cx.next_node_id(),
         node: item_,
         span: dummy_sp()};
    ret @item;
}

fn empty_fn_ty() -> ast::ty {
    let proto = ast::proto_fn;
    let input_ty = [];
    let ret_ty = @nospan(ast::ty_nil);
    let cf = ast::return_val;
    let constrs = [];
    ret nospan(ast::ty_fn(proto, input_ty, ret_ty, cf, constrs));
}

// The ast::ty of [std::test::test_desc]
fn mk_test_desc_vec_ty(cx: test_ctxt) -> @ast::ty {
    let test_desc_ty_path: ast::path =
        nospan({global: false,
                idents: ["std", "test", "test_desc"],
                types: []});

    let test_desc_ty: ast::ty =
        nospan(ast::ty_path(test_desc_ty_path, cx.next_node_id()));

    let vec_mt: ast::mt = {ty: @test_desc_ty, mut: ast::imm};

    ret @nospan(ast::ty_vec(vec_mt));
}

fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr {
    log #fmt["building test vector from %u tests", vec::len(cx.testfns)];
    let descs = [];
    for test: test in cx.testfns {
        let test_ = test; // Satisfy alias analysis
        descs += [mk_test_desc_rec(cx, test_)];
    }

    ret @{id: cx.next_node_id(),
          node: ast::expr_vec(descs, ast::imm),
          span: dummy_sp()};
}

fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
    let path = test.path;

    log #fmt["encoding %s", ast_util::path_name_i(path)];

    let name_lit: ast::lit =
        nospan(ast::lit_str(ast_util::path_name_i(path)));
    let name_expr: ast::expr =
        {id: cx.next_node_id(),
         node: ast::expr_lit(@name_lit),
         span: dummy_sp()};

    let name_field: ast::field =
        nospan({mut: ast::imm, ident: "name", expr: @name_expr});

    let fn_path: ast::path = nospan({global: false, idents: path, types: []});

    let fn_expr: ast::expr =
        {id: cx.next_node_id(),
         node: ast::expr_path(fn_path),
         span: dummy_sp()};

    let fn_field: ast::field =
        nospan({mut: ast::imm, ident: "fn", expr: @fn_expr});

    let ignore_lit: ast::lit = nospan(ast::lit_bool(test.ignore));

    let ignore_expr: ast::expr =
        {id: cx.next_node_id(),
         node: ast::expr_lit(@ignore_lit),
         span: dummy_sp()};

    let ignore_field: ast::field =
        nospan({mut: ast::imm, ident: "ignore", expr: @ignore_expr});

    let desc_rec_: ast::expr_ =
        ast::expr_rec([name_field, fn_field, ignore_field], option::none);
    let desc_rec: ast::expr =
        {id: cx.next_node_id(), node: desc_rec_, span: dummy_sp()};
    ret @desc_rec;
}

fn mk_main(cx: test_ctxt) -> @ast::item {

    let args_mt: ast::mt = {ty: @nospan(ast::ty_str), mut: ast::imm};
    let args_ty: ast::ty = nospan(ast::ty_vec(args_mt));

    let args_arg: ast::arg =
        {mode: ast::by_val,
         ty: @args_ty,
         ident: "args",
         id: cx.next_node_id()};

    let ret_ty = nospan(ast::ty_nil);

    let decl: ast::fn_decl =
        {inputs: [args_arg],
         output: @ret_ty,
         purity: ast::impure_fn,
         il: ast::il_normal,
         cf: ast::return_val,
         constraints: []};
    let proto = ast::proto_fn;

    let test_main_call_expr = mk_test_main_call(cx);

    let body_: ast::blk_ =
        default_block([], option::some(test_main_call_expr),
                      cx.next_node_id());
    let body = {node: body_, span: dummy_sp()};

    let fn_ = {decl: decl, proto: proto, body: body};

    let item_ = ast::item_fn(fn_, []);
    let item: ast::item =
        {ident: "main",
         attrs: [],
         id: cx.next_node_id(),
         node: item_,
         span: dummy_sp()};
    ret @item;
}

fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {

    // Get the args passed to main so we can pass the to test_main
    let args_path: ast::path =
        nospan({global: false, idents: ["args"], types: []});

    let args_path_expr_: ast::expr_ = ast::expr_path(args_path);

    let args_path_expr: ast::expr =
        {id: cx.next_node_id(), node: args_path_expr_, span: dummy_sp()};

    // Call __test::test to generate the vector of test_descs
    let test_path: ast::path =
        nospan({global: false, idents: ["tests"], types: []});

    let test_path_expr_: ast::expr_ = ast::expr_path(test_path);

    let test_path_expr: ast::expr =
        {id: cx.next_node_id(), node: test_path_expr_, span: dummy_sp()};

    let test_call_expr_: ast::expr_ = ast::expr_call(@test_path_expr, []);

    let test_call_expr: ast::expr =
        {id: cx.next_node_id(), node: test_call_expr_, span: dummy_sp()};

    // Call std::test::test_main
    let test_main_path: ast::path =
        nospan({global: false,
                idents: ["std", "test", "test_main"],
                types: []});

    let test_main_path_expr_: ast::expr_ = ast::expr_path(test_main_path);

    let test_main_path_expr: ast::expr =
        {id: cx.next_node_id(), node: test_main_path_expr_, span: dummy_sp()};

    let test_main_call_expr_: ast::expr_ =
        ast::expr_call(@test_main_path_expr,
                       [@args_path_expr, @test_call_expr]);

    let test_main_call_expr: ast::expr =
        {id: cx.next_node_id(), node: test_main_call_expr_, span: dummy_sp()};

    ret @test_main_call_expr;
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>improve the span used in test generation<commit_after>// Code that generates a test runner to run all the tests in a crate

import std::{option, vec, str};
import syntax::{ast, ast_util};
import syntax::ast_util::*;
//import syntax::ast_util::dummy_sp;
import syntax::fold;
import syntax::print::pprust;
import syntax::codemap::span;
import front::attr;

export modify_for_testing;

type node_id_gen = fn() -> ast::node_id;

type test = {span: span, path: [ast::ident], ignore: bool};

type test_ctxt =
    @{next_node_id: node_id_gen,
      mutable path: [ast::ident],
      mutable testfns: [test]};

// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
fn modify_for_testing(crate: @ast::crate) -> @ast::crate {

    // FIXME: This hackasaurus assumes that 200000 is a safe number to start
    // generating node_ids at (which is totally not the case). pauls is going
    // to land a patch that puts parse_sess into session, which will give us
    // access to the real next node_id.
    let next_node_id = @mutable 200000;
    let next_node_id_fn =
        bind fn (next_node_id: @mutable ast::node_id) -> ast::node_id {
                  let this_node_id = *next_node_id;
                  *next_node_id += 1;
                  ret this_node_id;
              }(next_node_id);

    let cx: test_ctxt =
        @{next_node_id: next_node_id_fn,
          mutable path: [],
          mutable testfns: []};

    let precursor =
        {fold_crate: bind fold_crate(cx, _, _),
         fold_item: bind fold_item(cx, _, _),
         fold_mod: bind fold_mod(cx, _, _) with *fold::default_ast_fold()};

    let fold = fold::make_fold(precursor);
    let res = @fold.fold_crate(*crate);
    ret res;
}

fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {

    // Remove any defined main function from the AST so it doesn't clash with
    // the one we're going to add.  FIXME: This is sloppy. Instead we should
    // have some mechanism to indicate to the translation pass which function
    // we want to be main.
    fn nomain(&&item: @ast::item) -> option::t<@ast::item> {
        alt item.node {
          ast::item_fn(f, _) {
            if item.ident == "main" {
                option::none
            } else { option::some(item) }
          }
          _ { option::some(item) }
        }
    }

    let mod_nomain =
        {view_items: m.view_items, items: vec::filter_map(nomain, m.items)};
    ret fold::noop_fold_mod(mod_nomain, fld);
}

fn fold_crate(cx: test_ctxt, c: ast::crate_, fld: fold::ast_fold) ->
   ast::crate_ {
    let folded = fold::noop_fold_crate(c, fld);

    // Add a special __test module to the crate that will contain code
    // generated for the test harness
    ret {module: add_test_module(cx, folded.module) with folded};
}

fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) ->
   @ast::item {

    cx.path += [i.ident];
    log #fmt["current path: %s", ast_util::path_name_i(cx.path)];

    if is_test_fn(i) {
        log "this is a test function";
        let test = {span: i.span, path: cx.path, ignore: is_ignored(i)};
        cx.testfns += [test];
        log #fmt["have %u test functions", vec::len(cx.testfns)];
    }

    let res = fold::noop_fold_item(i, fld);
    vec::pop(cx.path);
    ret res;
}

fn is_test_fn(i: @ast::item) -> bool {
    let has_test_attr =
        vec::len(attr::find_attrs_by_name(i.attrs, "test")) > 0u;

    fn has_test_signature(i: @ast::item) -> bool {
        alt i.node {
          ast::item_fn(f, tps) {
            let input_cnt = vec::len(f.decl.inputs);
            let no_output = f.decl.output.node == ast::ty_nil;
            let tparm_cnt = vec::len(tps);
            input_cnt == 0u && no_output && tparm_cnt == 0u
          }
          _ { false }
        }
    }

    ret has_test_attr && has_test_signature(i);
}

fn is_ignored(i: @ast::item) -> bool {
    attr::contains_name(attr::attr_metas(i.attrs), "ignore")
}

fn add_test_module(cx: test_ctxt, m: ast::_mod) -> ast::_mod {
    let testmod = mk_test_module(cx);
    ret {items: m.items + [testmod] with m};
}

/*

We're going to be building a module that looks more or less like:

mod __test {

  fn main(args: [str]) -> int {
    std::test::test_main(args, tests())
  }

  fn tests() -> [std::test::test_desc] {
    ... the list of tests in the crate ...
  }
}

*/

fn mk_test_module(cx: test_ctxt) -> @ast::item {
    // A function that generates a vector of test descriptors to feed to the
    // test runner
    let testsfn = mk_tests(cx);
    // The synthesized main function which will call the console test runner
    // with our list of tests
    let mainfn = mk_main(cx);
    let testmod: ast::_mod = {view_items: [], items: [mainfn, testsfn]};
    let item_ = ast::item_mod(testmod);
    let item: ast::item =
        {ident: "__test",
         attrs: [],
         id: cx.next_node_id(),
         node: item_,
         span: dummy_sp()};

    log #fmt["Synthetic test module:\n%s\n", pprust::item_to_str(@item)];

    ret @item;
}

fn nospan<@T>(t: T) -> ast::spanned<T> { ret {node: t, span: dummy_sp()}; }

fn mk_tests(cx: test_ctxt) -> @ast::item {
    let ret_ty = mk_test_desc_vec_ty(cx);

    let decl: ast::fn_decl =
        {inputs: [],
         output: ret_ty,
         purity: ast::impure_fn,
         il: ast::il_normal,
         cf: ast::return_val,
         constraints: []};
    let proto = ast::proto_fn;

    // The vector of test_descs for this crate
    let test_descs = mk_test_desc_vec(cx);

    let body_: ast::blk_ =
        default_block([], option::some(test_descs), cx.next_node_id());
    let body = nospan(body_);

    let fn_ = {decl: decl, proto: proto, body: body};

    let item_ = ast::item_fn(fn_, []);
    let item: ast::item =
        {ident: "tests",
         attrs: [],
         id: cx.next_node_id(),
         node: item_,
         span: dummy_sp()};
    ret @item;
}

fn empty_fn_ty() -> ast::ty {
    let proto = ast::proto_fn;
    let input_ty = [];
    let ret_ty = @nospan(ast::ty_nil);
    let cf = ast::return_val;
    let constrs = [];
    ret nospan(ast::ty_fn(proto, input_ty, ret_ty, cf, constrs));
}

// The ast::ty of [std::test::test_desc]
fn mk_test_desc_vec_ty(cx: test_ctxt) -> @ast::ty {
    let test_desc_ty_path: ast::path =
        nospan({global: false,
                idents: ["std", "test", "test_desc"],
                types: []});

    let test_desc_ty: ast::ty =
        nospan(ast::ty_path(test_desc_ty_path, cx.next_node_id()));

    let vec_mt: ast::mt = {ty: @test_desc_ty, mut: ast::imm};

    ret @nospan(ast::ty_vec(vec_mt));
}

fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr {
    log #fmt["building test vector from %u tests", vec::len(cx.testfns)];
    let descs = [];
    for test: test in cx.testfns {
        let test_ = test; // Satisfy alias analysis
        descs += [mk_test_desc_rec(cx, test_)];
    }

    ret @{id: cx.next_node_id(),
          node: ast::expr_vec(descs, ast::imm),
          span: dummy_sp()};
}

fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
    let span = test.span;
    let path = test.path;

    log #fmt["encoding %s", ast_util::path_name_i(path)];

    let name_lit: ast::lit =
        nospan(ast::lit_str(ast_util::path_name_i(path)));
    let name_expr: ast::expr =
        {id: cx.next_node_id(),
         node: ast::expr_lit(@name_lit),
         span: span};

    let name_field: ast::field =
        nospan({mut: ast::imm, ident: "name", expr: @name_expr});

    let fn_path: ast::path = nospan({global: false, idents: path, types: []});

    let fn_expr: ast::expr =
        {id: cx.next_node_id(),
         node: ast::expr_path(fn_path),
         span: span};

    let fn_field: ast::field =
        nospan({mut: ast::imm, ident: "fn", expr: @fn_expr});

    let ignore_lit: ast::lit = nospan(ast::lit_bool(test.ignore));

    let ignore_expr: ast::expr =
        {id: cx.next_node_id(),
         node: ast::expr_lit(@ignore_lit),
         span: span};

    let ignore_field: ast::field =
        nospan({mut: ast::imm, ident: "ignore", expr: @ignore_expr});

    let desc_rec_: ast::expr_ =
        ast::expr_rec([name_field, fn_field, ignore_field], option::none);
    let desc_rec: ast::expr =
        {id: cx.next_node_id(), node: desc_rec_, span: span};
    ret @desc_rec;
}

fn mk_main(cx: test_ctxt) -> @ast::item {

    let args_mt: ast::mt = {ty: @nospan(ast::ty_str), mut: ast::imm};
    let args_ty: ast::ty = nospan(ast::ty_vec(args_mt));

    let args_arg: ast::arg =
        {mode: ast::by_val,
         ty: @args_ty,
         ident: "args",
         id: cx.next_node_id()};

    let ret_ty = nospan(ast::ty_nil);

    let decl: ast::fn_decl =
        {inputs: [args_arg],
         output: @ret_ty,
         purity: ast::impure_fn,
         il: ast::il_normal,
         cf: ast::return_val,
         constraints: []};
    let proto = ast::proto_fn;

    let test_main_call_expr = mk_test_main_call(cx);

    let body_: ast::blk_ =
        default_block([], option::some(test_main_call_expr),
                      cx.next_node_id());
    let body = {node: body_, span: dummy_sp()};

    let fn_ = {decl: decl, proto: proto, body: body};

    let item_ = ast::item_fn(fn_, []);
    let item: ast::item =
        {ident: "main",
         attrs: [],
         id: cx.next_node_id(),
         node: item_,
         span: dummy_sp()};
    ret @item;
}

fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {

    // Get the args passed to main so we can pass the to test_main
    let args_path: ast::path =
        nospan({global: false, idents: ["args"], types: []});

    let args_path_expr_: ast::expr_ = ast::expr_path(args_path);

    let args_path_expr: ast::expr =
        {id: cx.next_node_id(), node: args_path_expr_, span: dummy_sp()};

    // Call __test::test to generate the vector of test_descs
    let test_path: ast::path =
        nospan({global: false, idents: ["tests"], types: []});

    let test_path_expr_: ast::expr_ = ast::expr_path(test_path);

    let test_path_expr: ast::expr =
        {id: cx.next_node_id(), node: test_path_expr_, span: dummy_sp()};

    let test_call_expr_: ast::expr_ = ast::expr_call(@test_path_expr, []);

    let test_call_expr: ast::expr =
        {id: cx.next_node_id(), node: test_call_expr_, span: dummy_sp()};

    // Call std::test::test_main
    let test_main_path: ast::path =
        nospan({global: false,
                idents: ["std", "test", "test_main"],
                types: []});

    let test_main_path_expr_: ast::expr_ = ast::expr_path(test_main_path);

    let test_main_path_expr: ast::expr =
        {id: cx.next_node_id(), node: test_main_path_expr_, span: dummy_sp()};

    let test_main_call_expr_: ast::expr_ =
        ast::expr_call(@test_main_path_expr,
                       [@args_path_expr, @test_call_expr]);

    let test_main_call_expr: ast::expr =
        {id: cx.next_node_id(), node: test_main_call_expr_, span: dummy_sp()};

    ret @test_main_call_expr;
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>[No-auto] bin/core/gps: Fix Clippy warnings<commit_after><|endoftext|>


<commit_before><commit_msg>Adapt for new StoreId API<commit_after><|endoftext|>


<commit_before><commit_msg>Remove let binding for unit value<commit_after><|endoftext|>


<commit_before><commit_msg>ninedof example<commit_after>#![no_std]

use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;

libtock_core::stack_size! {0x800}

#[libtock::main]
async fn main() -> TockResult<()> {
    let mut drivers = libtock::retrieve_drivers()?;

    let mut timer_driver = drivers.timer.create_timer_driver();
    let timer_driver = timer_driver.activate()?;
    drivers.console.create_console();

    loop {
        println!("Mag:   {}\n", drivers.ninedof.read_magnetometer()?);
        println!("Accel: {}\n", drivers.ninedof.read_acceleration()?);
        println!("Gyro:  {}\n", drivers.ninedof.read_gyroscope()?);
        timer_driver.sleep(Duration::from_ms(500)).await?;
    }
}
<|endoftext|>


<commit_before><commit_msg>Rename all variables that had uppercase characters in their names to use lowercase instead<commit_after><|endoftext|>


<commit_before>//! The Credentials provider to read from a task's IAM Role.

use std::error::Error;
use futures::{Async, Future, Poll};
use futures::future::err;
use hyper::{Client, Uri, Request, Method};
//use hyper::error::UriError;
use hyper::header::Authorization;
use hyper::client::HttpConnector;
use tokio_core::reactor::Handle;

use {AwsCredentials, CredentialsError, ProvideAwsCredentials,
     make_request, parse_credentials_from_aws_service, non_empty_env_var};

// The following constants are documented in AWS' ECS developers guide,
// see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html.
const AWS_CREDENTIALS_PROVIDER_IP: &'static str = "169.254.170.2";
const AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: &str = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
// I have not yet found any official documentation from AWS concerning the following two
// environment variables, but they are used by the Java, Go, JavaScript and the Python SDKs.
const AWS_CONTAINER_CREDENTIALS_FULL_URI: &str = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
const AWS_CONTAINER_AUTHORIZATION_TOKEN: &str = "AWS_CONTAINER_AUTHORIZATION_TOKEN";

/// Provides AWS credentials from a task's IAM role.
///
/// As described in Amazon's
/// [ECS developers guide](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html),
/// Containers started as part of Tasks using IAM Roles for Tasks will be provided with a relative
/// URL stored in the environment variable ```AWS_CONTAINER_CREDENTIALS_RELATIVE_URI```, which will
/// be used to obtain the AWS credentials. If that environment variable is not set, rusoto will use
/// the URL set in environment variable ```AWS_CONTAINER_CREDENTIALS_FULL_URI``` to obtain AWS
/// credentials and will (optionally) also set the ```Authorization``` header to the value of
/// environment variable ```AWS_CONTAINER_AUTHORIZATION_TOKEN```.
///
#[derive(Clone, Debug)]
pub struct ContainerProvider {
    client: Client<HttpConnector>
}

impl ContainerProvider {
    /// Create a new provider with the given handle.
    pub fn new(handle: &Handle) -> Self {
        let client = Client::configure().build(handle);
        ContainerProvider { client: client }
    }
}

/// Future returned from `ContainerProvider`.
pub struct ContainerProviderFuture {
    inner: Box<Future<Item=String, Error=CredentialsError>>
}

impl Future for ContainerProviderFuture {
    type Item = AwsCredentials;
    type Error = CredentialsError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let resp = try_ready!(self.inner.poll());
        let creds = parse_credentials_from_aws_service(&resp)?;
        Ok(Async::Ready(creds))
    }
}

impl ProvideAwsCredentials for ContainerProvider {
    type Future = ContainerProviderFuture;

    fn credentials(&self) -> Self::Future {
        let inner = match credentials_from_container(&self.client) {
            Ok(future) => future,
            Err(e) => Box::new(err(e))
        };
        ContainerProviderFuture { inner: inner }
    }
}

/// Grabs the Credentials from the AWS Container Credentials Provider. (169.254.170.2).
fn credentials_from_container(client: &Client<HttpConnector>) -> Result<Box<Future<Item=String, Error=CredentialsError>>, CredentialsError> {
    Ok(make_request(client, request_from_env_vars()?))
}

fn request_from_env_vars() -> Result<Request, CredentialsError> {
    let relative_uri = non_empty_env_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI).map(
        |path| format!("http://{}{}", AWS_CREDENTIALS_PROVIDER_IP, path)
    );
    match relative_uri {
        Some(ref uri) => new_request(uri, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI),
        None => match non_empty_env_var(AWS_CONTAINER_CREDENTIALS_FULL_URI) {
            Some(ref uri) => {
                let mut request = new_request(uri, AWS_CONTAINER_CREDENTIALS_FULL_URI)?;
                let token = non_empty_env_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
                token.map(|t| request.headers_mut().set(Authorization(t)));
                Ok(request)
            },
            None => Err(CredentialsError::new(
                format!("Neither environment variable '{}' nor '{}' is set", AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI),
            ))
        }
    }
}

fn new_request(uri: &str, env_var_name: &str) -> Result<Request, CredentialsError> {
    uri.parse::<Uri>().map(
            |uri| Request::new(Method::Get, uri)
        ).or_else(|error| Err(
             CredentialsError::new(
                 format!("Error while parsing URI '{}' derived from environment variable '{}': {}",
                         uri, env_var_name, error.description())
             )
        )
    )
}

#[cfg(test)]
mod tests {
    use std::env;
    use std::sync::{Mutex, MutexGuard};
    use hyper::header::Authorization;
    use hyper::header::Bearer;
    use super::*;

    // cargo runs tests in parallel, which leads to race conditions when changing
    // environment variables. Therefore we use a global mutex for all tests which
    // rely on environment variables.
    lazy_static! {
        static ref ENV_MUTEX: Mutex<()> = Mutex::new(());
    }

    // As failed (panic) tests will poisen the global mutex, we use a helper which
    // recovers from poisoned mutex.
    fn lock<'a, T>(mutex: &'a Mutex<T>) -> MutexGuard<'a, T> {
        match mutex.lock() {
            Ok(guard) => guard,
            Err(poisoned) => poisoned.into_inner(),
        }
    }

    #[test]
    fn request_from_relative_uri() {
        let path = "/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::set_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, path);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, "dummy");
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "dummy");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().path(), path);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), false);
    }

    #[test]
    fn error_from_missing_env_vars() {
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        let result = request_from_env_vars();
        assert!(result.is_err());
    }

    #[test]
    fn error_from_empty_env_vars() {
        let _guard = lock(&ENV_MUTEX);
        env::set_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, "");
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, "");
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_err());
    }

    #[test]
    fn request_from_full_uri_with_token() {
        let url = "http://localhost/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, url);
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "dummy");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().to_string(), url);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), true);
    }

    #[test]
    fn request_from_full_uri_without_token() {
        let url = "http://localhost/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, url);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().to_string(), url);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), false);
    }

    #[test]
    fn request_from_full_uri_with_empty_token() {
        let url = "http://localhost/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, url);
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().to_string(), url);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), false);
    }
}
<commit_msg>Remove useless line<commit_after>//! The Credentials provider to read from a task's IAM Role.

use std::error::Error;
use futures::{Async, Future, Poll};
use futures::future::err;
use hyper::{Client, Uri, Request, Method};
use hyper::header::Authorization;
use hyper::client::HttpConnector;
use tokio_core::reactor::Handle;

use {AwsCredentials, CredentialsError, ProvideAwsCredentials,
     make_request, parse_credentials_from_aws_service, non_empty_env_var};

// The following constants are documented in AWS' ECS developers guide,
// see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html.
const AWS_CREDENTIALS_PROVIDER_IP: &'static str = "169.254.170.2";
const AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: &str = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
// I have not yet found any official documentation from AWS concerning the following two
// environment variables, but they are used by the Java, Go, JavaScript and the Python SDKs.
const AWS_CONTAINER_CREDENTIALS_FULL_URI: &str = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
const AWS_CONTAINER_AUTHORIZATION_TOKEN: &str = "AWS_CONTAINER_AUTHORIZATION_TOKEN";

/// Provides AWS credentials from a task's IAM role.
///
/// As described in Amazon's
/// [ECS developers guide](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html),
/// Containers started as part of Tasks using IAM Roles for Tasks will be provided with a relative
/// URL stored in the environment variable ```AWS_CONTAINER_CREDENTIALS_RELATIVE_URI```, which will
/// be used to obtain the AWS credentials. If that environment variable is not set, rusoto will use
/// the URL set in environment variable ```AWS_CONTAINER_CREDENTIALS_FULL_URI``` to obtain AWS
/// credentials and will (optionally) also set the ```Authorization``` header to the value of
/// environment variable ```AWS_CONTAINER_AUTHORIZATION_TOKEN```.
///
#[derive(Clone, Debug)]
pub struct ContainerProvider {
    client: Client<HttpConnector>
}

impl ContainerProvider {
    /// Create a new provider with the given handle.
    pub fn new(handle: &Handle) -> Self {
        let client = Client::configure().build(handle);
        ContainerProvider { client: client }
    }
}

/// Future returned from `ContainerProvider`.
pub struct ContainerProviderFuture {
    inner: Box<Future<Item=String, Error=CredentialsError>>
}

impl Future for ContainerProviderFuture {
    type Item = AwsCredentials;
    type Error = CredentialsError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let resp = try_ready!(self.inner.poll());
        let creds = parse_credentials_from_aws_service(&resp)?;
        Ok(Async::Ready(creds))
    }
}

impl ProvideAwsCredentials for ContainerProvider {
    type Future = ContainerProviderFuture;

    fn credentials(&self) -> Self::Future {
        let inner = match credentials_from_container(&self.client) {
            Ok(future) => future,
            Err(e) => Box::new(err(e))
        };
        ContainerProviderFuture { inner: inner }
    }
}

/// Grabs the Credentials from the AWS Container Credentials Provider. (169.254.170.2).
fn credentials_from_container(client: &Client<HttpConnector>) -> Result<Box<Future<Item=String, Error=CredentialsError>>, CredentialsError> {
    Ok(make_request(client, request_from_env_vars()?))
}

fn request_from_env_vars() -> Result<Request, CredentialsError> {
    let relative_uri = non_empty_env_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI).map(
        |path| format!("http://{}{}", AWS_CREDENTIALS_PROVIDER_IP, path)
    );
    match relative_uri {
        Some(ref uri) => new_request(uri, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI),
        None => match non_empty_env_var(AWS_CONTAINER_CREDENTIALS_FULL_URI) {
            Some(ref uri) => {
                let mut request = new_request(uri, AWS_CONTAINER_CREDENTIALS_FULL_URI)?;
                let token = non_empty_env_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
                token.map(|t| request.headers_mut().set(Authorization(t)));
                Ok(request)
            },
            None => Err(CredentialsError::new(
                format!("Neither environment variable '{}' nor '{}' is set", AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI),
            ))
        }
    }
}

fn new_request(uri: &str, env_var_name: &str) -> Result<Request, CredentialsError> {
    uri.parse::<Uri>().map(
            |uri| Request::new(Method::Get, uri)
        ).or_else(|error| Err(
             CredentialsError::new(
                 format!("Error while parsing URI '{}' derived from environment variable '{}': {}",
                         uri, env_var_name, error.description())
             )
        )
    )
}

#[cfg(test)]
mod tests {
    use std::env;
    use std::sync::{Mutex, MutexGuard};
    use hyper::header::Authorization;
    use hyper::header::Bearer;
    use super::*;

    // cargo runs tests in parallel, which leads to race conditions when changing
    // environment variables. Therefore we use a global mutex for all tests which
    // rely on environment variables.
    lazy_static! {
        static ref ENV_MUTEX: Mutex<()> = Mutex::new(());
    }

    // As failed (panic) tests will poisen the global mutex, we use a helper which
    // recovers from poisoned mutex.
    fn lock<'a, T>(mutex: &'a Mutex<T>) -> MutexGuard<'a, T> {
        match mutex.lock() {
            Ok(guard) => guard,
            Err(poisoned) => poisoned.into_inner(),
        }
    }

    #[test]
    fn request_from_relative_uri() {
        let path = "/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::set_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, path);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, "dummy");
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "dummy");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().path(), path);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), false);
    }

    #[test]
    fn error_from_missing_env_vars() {
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        let result = request_from_env_vars();
        assert!(result.is_err());
    }

    #[test]
    fn error_from_empty_env_vars() {
        let _guard = lock(&ENV_MUTEX);
        env::set_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, "");
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, "");
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_err());
    }

    #[test]
    fn request_from_full_uri_with_token() {
        let url = "http://localhost/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, url);
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "dummy");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().to_string(), url);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), true);
    }

    #[test]
    fn request_from_full_uri_without_token() {
        let url = "http://localhost/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, url);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().to_string(), url);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), false);
    }

    #[test]
    fn request_from_full_uri_with_empty_token() {
        let url = "http://localhost/xxx";
        let _guard = lock(&ENV_MUTEX);
        env::remove_var(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
        env::set_var(AWS_CONTAINER_CREDENTIALS_FULL_URI, url);
        env::set_var(AWS_CONTAINER_AUTHORIZATION_TOKEN, "");
        let result = request_from_env_vars();
        env::remove_var(AWS_CONTAINER_CREDENTIALS_FULL_URI);
        env::remove_var(AWS_CONTAINER_AUTHORIZATION_TOKEN);
        assert!(result.is_ok());
        let request = result.ok().unwrap();
        assert_eq!(request.uri().to_string(), url);
        assert_eq!(request.headers().has::<Authorization<Bearer>>(), false);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a regression test for unevaluated const in rustdoc<commit_after>// ignore-tidy-linelength

#![feature(const_generics)]

#![crate_name = "foo"]

use std::ops::Add;

// @has foo/struct.Simd.html '//pre[@class="rust struct"]' 'pub struct Simd<T, const WIDTH: usize>'
pub struct Simd<T, const WIDTH: usize> {
    inner: T,
}

// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add<Simd<u8, 16>> for Simd<u8, 16>'
impl Add for Simd<u8, 16> {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Self { inner: 0 }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add benchmark for feature map construction.<commit_after>#![feature(test)]

extern crate conllx;

extern crate test;

use test::{Bencher, black_box};

use conllx::Features;

static FEATURES: &'static [&'static str] = &[
    "cat:regular+noun|case:nominative|number:plural",
    "cat:article|definite:true|case:nominative|number:singular|gender:feminine",
    "cat:proper+name|case:nominative|number:singular|gender:feminine",
    "cat:regular+noun|case:nominative|number:singular|case:neuter",
    "cat:symbol|cat:punctuation",
];

#[bench]
pub fn bench_as_map(b: &mut Bencher) {
    b.iter(|| for f_str in FEATURES {
        let features = Features::from_string(*f_str);
        black_box(features.as_map());
        black_box(features.as_map());
        black_box(features.as_map());
        black_box(features.as_map());
    });
}
<|endoftext|>


<commit_before><commit_msg>Fixed stack overflow of recursive functions.<commit_after><|endoftext|>


<commit_before><commit_msg>Rename the macro to a shorter name<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for #68532<commit_after><|endoftext|>


<commit_before><commit_msg>Add PieceField struct<commit_after>use std::mem;

pub struct PieceField {
    len: usize,
    data: Box<[u8]>
}

impl PieceField {
    fn new(len: usize) -> PieceField {
        let mut size = len/8;
        if len % 8 != 0 {
            size += 1;
        }

        PieceField {
            len: len,
            data: vec![0; size].into_boxed_slice(),
        }
    }

    fn has_piece(&self, pos: usize) -> Option<bool> {
        if pos >= self.len {
            return None;
        } else {
            let block_pos = pos/8;
            let index = pos % 8;
            let block = self.data[block_pos];
            Some(((block >> index) & 1) == 1)
        }
    }

    fn set_piece(&mut self, pos: usize) {
        if pos < self.len {
            let block_pos = pos/8;
            let index = pos % 8;
            let block = self.data[block_pos];
            self.data[block_pos] = block | (1 << index);
        }
    }
}

fn test_create() {
    let pf = PieceField::new(10);
    assert!(pf.len == 10);
    assert!(pf.data.len() == 2)
}

fn test_has() {
    let pf = PieceField::new(10);
    let res = pf.has_piece(9);
    assert!(res.is_some());
    assert!(res.unwrap() == false);
}

fn test_set() {
    let mut pf = PieceField::new(10);

    let res = pf.has_piece(9);
    assert!(res.is_some());
    assert!(res.unwrap() == false);

    pf.set_piece(9);

    let res = pf.has_piece(9);
    assert!(res.is_some());
    assert!(res.unwrap() == true);
}
<|endoftext|>


<commit_before>#![crate_name = "split"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Akira Hayakawa <ruby.wktk@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::io;
use std::num::Int;
use std::char;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "split";
static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> int {
    let opts = [
        getopts::optopt("a", "suffix-length", "use suffixes of length N (default 2)", "N"),
        getopts::optopt("b", "bytes", "put SIZE bytes per output file", "SIZE"),
        getopts::optopt("C", "line-bytes", "put at most SIZE bytes of lines per output file", "SIZE"),
        getopts::optflag("d", "numeric-suffixes", "use numeric suffixes instead of alphabetic"),
        getopts::optopt("l", "lines", "put NUMBER lines per output file", "NUMBER"),
        getopts::optflag("", "verbose", "print a diagnostic just before each output file is opened"),
        getopts::optflag("h", "help", "display help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f)
    };

    if matches.opt_present("h") {
        println!("{} v{}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [OPTION]... [INPUT [PREFIX]]", NAME);
        println!("");
        io::print(getopts::usage("Output fixed-size pieces of INPUT to PREFIXaa, PREFIX ab, ...; default size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is -, read standard input." , &opts).as_slice());
        return 0;
    }

    if matches.opt_present("V") {
        println!("{} v{}", NAME, VERSION);
        return 0;
    }

    let mut settings = Settings {
        prefix: "".to_string(),
        numeric_suffix: false,
        suffix_length: 0,
        input: "".to_string(),
        strategy: "".to_string(),
        strategy_param: "".to_string(),
        verbose: false,
    };

    settings.numeric_suffix = if matches.opt_present("d") { true } else { false };

    settings.suffix_length = match matches.opt_str("a") {
        Some(n) => match from_str(n.as_slice()) {
            Some(m) => m,
            None => crash!(1, "cannot parse num")
        },
        None => 2
    };

    settings.verbose = if matches.opt_present("verbose") { true } else { false };

    settings.strategy = "l".to_string();
    settings.strategy_param = "1000".to_string();
    let strategies = vec!["b", "C", "l"];
    for e in strategies.iter() {
        match matches.opt_str(*e) {
            Some(a) => {
                if settings.strategy.as_slice() == "l" {
                    settings.strategy = e.to_string();
                    settings.strategy_param = a;
                } else {
                    crash!(1, "{}: cannot split in more than one way", NAME)
                }
            },
            None => {}
        }
    }

    let mut v = matches.free.iter();
    let (input, prefix) = match (v.next(), v.next()) {
        (Some(a), None) => (a.to_string(), "x".to_string()),
        (Some(a), Some(b)) => (a.to_string(), b.to_string()),
        (None, _) => ("-".to_string(), "x".to_string()),
    };
    settings.input = input;
    settings.prefix = prefix;

    split(&settings)
}

struct Settings {
    prefix: String,
    numeric_suffix: bool,
    suffix_length: uint,
    input: String,
    strategy: String,
    strategy_param: String,
    verbose: bool,
}

struct SplitControl {
    current_line: String, // Don't touch
    request_new_file: bool, // Splitter implementation requests new file
}

trait Splitter {
    // Factory pattern
    fn new(_hint: Option<Self>, &Settings) -> Box<Splitter>;

    // Consume the current_line and return the consumed string
    fn consume(&mut self, &mut SplitControl) -> String;
}

struct LineSplitter {
    saved_lines_to_write: uint,
    lines_to_write: uint,
}

impl Splitter for LineSplitter {
    fn new(_: Option<LineSplitter>, settings: &Settings) -> Box<Splitter> {
        let n = match from_str(settings.strategy_param.as_slice()) {
            Some(a) => a,
            _ => crash!(1, "invalid number of lines")
        };
        box LineSplitter {
            saved_lines_to_write: n,
            lines_to_write: n,
        } as Box<Splitter>
    }

    fn consume(&mut self, control: &mut SplitControl) -> String {
        self.lines_to_write -= 1;
        if self.lines_to_write == 0 {
            self.lines_to_write = self.saved_lines_to_write;
            control.request_new_file = true;
        }
        control.current_line.clone()
    }
}

struct ByteSplitter {
    saved_bytes_to_write: uint,
    bytes_to_write: uint,
}

impl Splitter for ByteSplitter {
    fn new(_: Option<ByteSplitter>, settings: &Settings) -> Box<Splitter> {
        let n = match from_str(settings.strategy_param.as_slice()) {
            Some(a) => a,
            _ => crash!(1, "invalid number of lines")
        };
        box ByteSplitter {
            saved_bytes_to_write: n,
            bytes_to_write: n,
        } as Box<Splitter>
    }

    fn consume(&mut self, control: &mut SplitControl) -> String {
        let line = control.current_line.clone();
        let n = std::cmp::min(line.as_slice().char_len(), self.bytes_to_write);
        self.bytes_to_write -= n;
        if n == 0 {
            self.bytes_to_write = self.saved_bytes_to_write;
            control.request_new_file = true;
        }
        line.as_slice().slice(0, n).to_string()
    }
}

// (1, 3) -> "aab"
fn str_prefix(i: uint, width: uint) -> String {
    let mut c = "".to_string();
    let mut n = i;
    let mut w = width;
    while w > 0 {
        w -= 1;
        let div = Int::pow(26 as uint, w);
        let r = n / div;
        n -= r * div;
        c.push(char::from_u32((r as u32) + 97).unwrap());
    }
    c
}

// (1, 3) -> "001"
fn num_prefix(i: uint, width: uint) -> String {
    let mut c = "".to_string();
    let mut n = i;
    let mut w = width;
    while w > 0 {
        w -= 1;
        let div = Int::pow(10 as uint, w);
        let r = n / div;
        n -= r * div;
        c.push(char::from_digit(r, 10).unwrap());
    }
    c
}

fn split(settings: &Settings) -> int {
    let mut reader = io::BufferedReader::new(
        if settings.input.as_slice() == "-" {
            box io::stdio::stdin_raw() as Box<Reader>
        } else {
            let r = match io::File::open(&Path::new(settings.input.clone())) {
                Ok(a) => a,
                Err(_) => crash!(1, "cannot open '{}' for reading: No such file or directory", settings.input)
            };
            box r as Box<Reader>
        }
    );

    let mut splitter: Box<Splitter> =
        match settings.strategy.as_slice() {
            "l" => Splitter::new(None::<LineSplitter>, settings),
            "b" => Splitter::new(None::<ByteSplitter>, settings),
            a @ _ => crash!(1, "strategy {} not supported", a)
        };

    let mut control = SplitControl {
        current_line: "".to_string(), // Request new line
        request_new_file: true, // Request new file
    };

    let mut writer = io::BufferedWriter::new(box io::stdio::stdout_raw() as Box<Writer>);
    let mut fileno = 0;
    loop {
        if control.current_line.as_slice().char_len() == 0 {
            match reader.read_line() {
                Ok(a) => { control.current_line = a; }
                Err(_) =>  { break; }
            }
        }

        if control.request_new_file {
            let mut filename = settings.prefix.to_string();
            filename.push_str(if settings.numeric_suffix {
                num_prefix(fileno, settings.suffix_length)
            } else {
                str_prefix(fileno, settings.suffix_length)
            }.as_slice());

            if fileno != 0 {
                crash_if_err!(1, writer.flush());
            }
            fileno += 1;
            writer = io::BufferedWriter::new(box io::File::open_mode(&Path::new(filename.as_slice()), io::Open, io::Write) as Box<Writer>);
            control.request_new_file = false;
        }

        let consumed = splitter.consume(&mut control);
        crash_if_err!(1, writer.write_str(consumed.as_slice()));

        let advance = consumed.as_slice().char_len();
        let clone = control.current_line.clone();
        let sl = clone.as_slice();
        control.current_line = sl.slice(advance, sl.char_len()).to_string();
    }
    0
}
<commit_msg>Added SIZE multiplier suffixes.<commit_after>#![crate_name = "split"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Akira Hayakawa <ruby.wktk@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::io;
use std::num::Int;
use std::char;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "split";
static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> int {
    let opts = [
        getopts::optopt("a", "suffix-length", "use suffixes of length N (default 2)", "N"),
        getopts::optopt("b", "bytes", "put SIZE bytes per output file", "SIZE"),
        getopts::optopt("C", "line-bytes", "put at most SIZE bytes of lines per output file", "SIZE"),
        getopts::optflag("d", "numeric-suffixes", "use numeric suffixes instead of alphabetic"),
        getopts::optopt("l", "lines", "put NUMBER lines per output file", "NUMBER"),
        getopts::optflag("", "verbose", "print a diagnostic just before each output file is opened"),
        getopts::optflag("h", "help", "display help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f)
    };

    if matches.opt_present("h") {
        println!("{} v{}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [OPTION]... [INPUT [PREFIX]]", NAME);
        println!("");
        io::print(getopts::usage("Output fixed-size pieces of INPUT to PREFIXaa, PREFIX ab, ...; default size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is -, read standard input." , &opts).as_slice());
        println!("");
        println!("SIZE may have a multiplier suffix: b for 512, k for 1K, m for 1 Meg.");
        return 0;
    }

    if matches.opt_present("V") {
        println!("{} v{}", NAME, VERSION);
        return 0;
    }

    let mut settings = Settings {
        prefix: "".to_string(),
        numeric_suffix: false,
        suffix_length: 0,
        input: "".to_string(),
        strategy: "".to_string(),
        strategy_param: "".to_string(),
        verbose: false,
    };

    settings.numeric_suffix = if matches.opt_present("d") { true } else { false };

    settings.suffix_length = match matches.opt_str("a") {
        Some(n) => match from_str(n.as_slice()) {
            Some(m) => m,
            None => crash!(1, "cannot parse num")
        },
        None => 2
    };

    settings.verbose = if matches.opt_present("verbose") { true } else { false };

    settings.strategy = "l".to_string();
    settings.strategy_param = "1000".to_string();
    let strategies = vec!["b", "C", "l"];
    for e in strategies.iter() {
        match matches.opt_str(*e) {
            Some(a) => {
                if settings.strategy.as_slice() == "l" {
                    settings.strategy = e.to_string();
                    settings.strategy_param = a;
                } else {
                    crash!(1, "{}: cannot split in more than one way", NAME)
                }
            },
            None => {}
        }
    }

    let mut v = matches.free.iter();
    let (input, prefix) = match (v.next(), v.next()) {
        (Some(a), None) => (a.to_string(), "x".to_string()),
        (Some(a), Some(b)) => (a.to_string(), b.to_string()),
        (None, _) => ("-".to_string(), "x".to_string()),
    };
    settings.input = input;
    settings.prefix = prefix;

    split(&settings)
}

struct Settings {
    prefix: String,
    numeric_suffix: bool,
    suffix_length: uint,
    input: String,
    strategy: String,
    strategy_param: String,
    verbose: bool,
}

struct SplitControl {
    current_line: String, // Don't touch
    request_new_file: bool, // Splitter implementation requests new file
}

trait Splitter {
    // Factory pattern
    fn new(_hint: Option<Self>, &Settings) -> Box<Splitter>;

    // Consume the current_line and return the consumed string
    fn consume(&mut self, &mut SplitControl) -> String;
}

struct LineSplitter {
    saved_lines_to_write: uint,
    lines_to_write: uint,
}

impl Splitter for LineSplitter {
    fn new(_: Option<LineSplitter>, settings: &Settings) -> Box<Splitter> {
        let n = match from_str(settings.strategy_param.as_slice()) {
            Some(a) => a,
            _ => crash!(1, "invalid number of lines")
        };
        box LineSplitter {
            saved_lines_to_write: n,
            lines_to_write: n,
        } as Box<Splitter>
    }

    fn consume(&mut self, control: &mut SplitControl) -> String {
        self.lines_to_write -= 1;
        if self.lines_to_write == 0 {
            self.lines_to_write = self.saved_lines_to_write;
            control.request_new_file = true;
        }
        control.current_line.clone()
    }
}

struct ByteSplitter {
    saved_bytes_to_write: uint,
    bytes_to_write: uint,
}

impl Splitter for ByteSplitter {
    fn new(_: Option<ByteSplitter>, settings: &Settings) -> Box<Splitter> {
        let mut strategy_param : Vec<char> = settings.strategy_param.chars().collect();
        let suffix = strategy_param.pop().unwrap();
        let multiplier = match suffix {
            '0'...'9' => 1u,
            'b' => 512u,
            'k' => 1024u,
            'm' => 1024u * 1024u,
            _ => crash!(1, "invalid number of bytes")
        };
        let n = if suffix.is_alphabetic() {
            match String::from_chars(strategy_param.as_slice()).as_slice().parse::<uint>() {
                Some(a) => a,
                _ => crash!(1, "invalid number of bytes")
            }
        } else {
            match settings.strategy_param.as_slice().parse::<uint>() {
                Some(a) => a,
                _ => crash!(1, "invalid number of bytes")
            }
        };
        box ByteSplitter {
            saved_bytes_to_write: n * multiplier,
            bytes_to_write: n * multiplier,
        } as Box<Splitter>
    }

    fn consume(&mut self, control: &mut SplitControl) -> String {
        let line = control.current_line.clone();
        let n = std::cmp::min(line.as_slice().char_len(), self.bytes_to_write);
        self.bytes_to_write -= n;
        if n == 0 {
            self.bytes_to_write = self.saved_bytes_to_write;
            control.request_new_file = true;
        }
        line.as_slice().slice(0, n).to_string()
    }
}

// (1, 3) -> "aab"
fn str_prefix(i: uint, width: uint) -> String {
    let mut c = "".to_string();
    let mut n = i;
    let mut w = width;
    while w > 0 {
        w -= 1;
        let div = Int::pow(26 as uint, w);
        let r = n / div;
        n -= r * div;
        c.push(char::from_u32((r as u32) + 97).unwrap());
    }
    c
}

// (1, 3) -> "001"
fn num_prefix(i: uint, width: uint) -> String {
    let mut c = "".to_string();
    let mut n = i;
    let mut w = width;
    while w > 0 {
        w -= 1;
        let div = Int::pow(10 as uint, w);
        let r = n / div;
        n -= r * div;
        c.push(char::from_digit(r, 10).unwrap());
    }
    c
}

fn split(settings: &Settings) -> int {
    let mut reader = io::BufferedReader::new(
        if settings.input.as_slice() == "-" {
            box io::stdio::stdin_raw() as Box<Reader>
        } else {
            let r = match io::File::open(&Path::new(settings.input.clone())) {
                Ok(a) => a,
                Err(_) => crash!(1, "cannot open '{}' for reading: No such file or directory", settings.input)
            };
            box r as Box<Reader>
        }
    );

    let mut splitter: Box<Splitter> =
        match settings.strategy.as_slice() {
            "l" => Splitter::new(None::<LineSplitter>, settings),
            "b" => Splitter::new(None::<ByteSplitter>, settings),
            a @ _ => crash!(1, "strategy {} not supported", a)
        };

    let mut control = SplitControl {
        current_line: "".to_string(), // Request new line
        request_new_file: true, // Request new file
    };

    let mut writer = io::BufferedWriter::new(box io::stdio::stdout_raw() as Box<Writer>);
    let mut fileno = 0;
    loop {
        if control.current_line.as_slice().char_len() == 0 {
            match reader.read_line() {
                Ok(a) => { control.current_line = a; }
                Err(_) =>  { break; }
            }
        }

        if control.request_new_file {
            let mut filename = settings.prefix.to_string();
            filename.push_str(if settings.numeric_suffix {
                num_prefix(fileno, settings.suffix_length)
            } else {
                str_prefix(fileno, settings.suffix_length)
            }.as_slice());

            if fileno != 0 {
                crash_if_err!(1, writer.flush());
            }
            fileno += 1;
            writer = io::BufferedWriter::new(box io::File::open_mode(&Path::new(filename.as_slice()), io::Open, io::Write) as Box<Writer>);
            control.request_new_file = false;
        }

        let consumed = splitter.consume(&mut control);
        crash_if_err!(1, writer.write_str(consumed.as_slice()));

        let advance = consumed.as_slice().char_len();
        let clone = control.current_line.clone();
        let sl = clone.as_slice();
        control.current_line = sl.slice(advance, sl.char_len()).to_string();
    }
    0
}
<|endoftext|>


<commit_before><commit_msg>Add some regression tests<commit_after>#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![warn(unused_results)]

#![feature(plugin)]
#![plugin(power_assert)]

use std::thread;

#[derive(Debug)]
struct Foo {
    val: u32
}

#[derive(Debug)]
struct Bar {
    val: u32,
    foo: Foo
}

fn run_panic_test<F>(f: F) -> String
    where F: FnOnce(), F: Send + 'static
{
    thread::spawn(f).join().unwrap_err().downcast_ref::<String>().unwrap().clone()
}

#[test]
fn test_member_access() {
    assert_eq!(run_panic_test(|| {
        let bar = Bar { val: 3, foo: Foo { val: 2 }};
        power_assert!(bar.val == bar.foo.val);
    }), "assertion failed: bar.val == bar.foo.val
power_assert!(bar.val == bar.foo.val)
              |   |   |  |   |   |
              |   3   |  |   |   2
              |       |  |   Foo { val: 2 }
              |       |  Bar { val: 3, foo: Foo { val: 2 } }
              |       false
              Bar { val: 3, foo: Foo { val: 2 } }
");

    assert_eq!(run_panic_test(|| {
        let bar = Bar { val: 3, foo: Foo { val: 2 }};
        power_assert_eq!(bar.val, bar.foo.val);
    }), "assertion failed: `(left == right)` (left: `3`, right: `2`)
power_assert_eq!(bar.val, bar.foo.val)
left: bar.val
      |   |
      |   3
      Bar { val: 3, foo: Foo { val: 2 } }
right: bar.foo.val
       |   |   |
       |   |   2
       |   Foo { val: 2 }
       Bar { val: 3, foo: Foo { val: 2 } }
");
}
<|endoftext|>


<commit_before><commit_msg>Chore(sync): log sid of ignored files<commit_after><|endoftext|>


<commit_before><commit_msg>add Route53 Domains integration tests<commit_after>#![cfg(feature = "route53domains")]

extern crate rusoto;

use rusoto::route53domains::{Route53DomainsClient, ListOperationsRequest};
use rusoto::{DefaultCredentialsProvider, Region};

#[test]
fn should_list_operations() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = Route53DomainsClient::new(credentials, Region::UsEast1);

    let request = ListOperationsRequest::default();

    match client.list_operations(&request) {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}<|endoftext|>


<commit_before><commit_msg>Add char literal and lifetime parsing in tokenizer. Move identifier parsing code to a new function. Reformat error converting code. Add more tests.<commit_after><|endoftext|>


<commit_before><commit_msg>fixing Die trait topic line in documentation<commit_after><|endoftext|>


<commit_before><commit_msg>Handle train lengths.<commit_after><|endoftext|>


<commit_before><commit_msg>started something?<commit_after><|endoftext|>


<commit_before><commit_msg>Improve docs on node module.<commit_after><|endoftext|>


<commit_before><commit_msg>Basic quad grid implementation<commit_after>pub type Coordinate = [i32; 2];

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

pub struct Grid {
    cell_size: [::Float; 2],
}

impl Grid {
    pub fn new(size: ::Float) -> Grid {
        Grid {
            cell_size: [size, size],
        }
    }
}

impl ::Grid for Grid {
    type Coordinate = Coordinate;
    type Direction = Direction;

    fn get_cell_center(&self, c: Coordinate) -> ::Point {
        [(c[0] as f32 + 0.5) * self.cell_size[0],
         (c[1] as f32 + 0.5) * self.cell_size[1],
         0.0]
    }

    fn get_coordinate(&self, p: &::Point) -> Coordinate {
        [(p[0] / self.cell_size[0]) as i32,
         (p[1] / self.cell_size[1]) as i32]
    }

    fn get_neighbour(&self, c: Coordinate, d: Direction) -> Coordinate {
        match d {
            Direction::North => [c[0], c[1]+1],
            Direction::East  => [c[0]+1, c[1]],
            Direction::South => [c[0], c[1]-1],
            Direction::West  => [c[0]-1, c[1]],
        }
    }

    fn fold_neighbours<U, F: Fn(U, Coordinate, Direction) -> U>(&self, _: Coordinate, _: F, u: U) -> U {
        u //TODO
    }

    fn fold_in_radius<U, F: Fn(U, Coordinate) -> U>(&self, _: Coordinate, _: ::Float, _: F, u: U) -> U {
        u //TODO
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix: Allocating of buffer does not work as expected with Vec::with_capacity()<commit_after><|endoftext|>


<commit_before><commit_msg>Initialise installation.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Don't strobe d-pad<commit_after><|endoftext|>


<commit_before>// -*- rust -*-

/*
Module: bool

Classic Boolean logic reified as ADT
*/

export t;
export not, and, or, xor, implies;
export eq, ne, is_true, is_false;
export from_str, to_str, all_values, to_bit;

/*
Type: t

The type of boolean logic values
*/
type t = bool;

/* Function: not

Negation/Inverse
*/
pure fn not(v: t) -> t { !v }

/* Function: and

Conjunction
*/
pure fn and(a: t, b: t) -> t { a && b }

/* Function: or

Disjunction
*/
pure fn or(a: t, b: t) -> t { a || b }

/*
Function: xor

Exclusive or, i.e. `or(and(a, not(b)), and(not(a), b))`
*/
pure fn xor(a: t, b: t) -> t { (a && !b) || (!a && b) }

/*
Function: implies

Implication in the logic, i.e. from `a` follows `b`
*/
pure fn implies(a: t, b: t) -> t { !a || b }

/*
Predicate: eq

Returns:

true if truth values `a` and `b` are indistinguishable in the logic
*/
pure fn eq(a: t, b: t) -> bool { a == b }

/*
Predicate: ne

Returns:

true if truth values `a` and `b` are distinguishable in the logic
*/
pure fn ne(a: t, b: t) -> bool { a != b }

/*
Predicate: is_true

Returns:

true if `v` represents truth in the logic
*/
pure fn is_true(v: t) -> bool { v }

/*
Predicate: is_false

Returns:

true if `v` represents falsehood in the logic
*/
pure fn is_false(v: t) -> bool { !v }

/*
Function: from_str

Parse logic value from `s`
*/
pure fn from_str(s: str) -> t {
    alt s {
      "true" { true }
      "false" { false }
    }
}

/*
Function: to_str

Convert `v` into a string
*/
pure fn to_str(v: t) -> str { if v { "true" } else { "false" } }

/*
Function: all_values

Iterates over all truth values by passing them to `blk`
in an unspecified order
*/
fn all_values(blk: block(v: t)) {
    blk(true);
    blk(false);
}

/*
Function: to_bit

Returns:

An u8 whose first bit is set if `if_true(v)` holds
*/
pure fn to_bit(v: t) -> u8 { if v { 1u8 } else { 0u8 } }

// 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>Change doc comments to rustdoc in bool.rs<commit_after>// -*- rust -*-

#[doc = "Classic Boolean logic reified as ADT"];

export t;
export not, and, or, xor, implies;
export eq, ne, is_true, is_false;
export from_str, to_str, all_values, to_bit;

#[doc = "The type of boolean logic values"]
type t = bool;

#[doc(
  brief = "Negation/Inverse",
  args(v = "Value to Negate/Invert"),
  return = "Negated/Inverted Value"
)]
pure fn not(v: t) -> t { !v }

#[doc(
  brief = "Conjunction",
  args(a = "value `a`",
       b = "value `b`"),
  return = "`a` AND `b`"
)]
pure fn and(a: t, b: t) -> t { a && b }

#[doc(
  brief = "Disjunction",
  args(a = "value `a`",
       b = "value `b`"),
  return = "`a` OR `b`"
)]
pure fn or(a: t, b: t) -> t { a || b }

#[doc(
  brief = "Exclusive or, i.e. `or(and(a, not(b)), and(not(a), b))`",
  args(a = "value `a`",
       b = "value `b`"),
  return = "`a` XOR `b`"
)]
pure fn xor(a: t, b: t) -> t { (a && !b) || (!a && b) }

#[doc(
  brief = "Implication in the logic, i.e. from `a` follows `b`",
  args(a = "value `a`",
       b = "value `b`"),
  return = "`a` IMPLIES `b`"
)]
pure fn implies(a: t, b: t) -> t { !a || b }

#[doc(
  brief = "true if truth values `a` and `b` are indistinguishable in the logic",
  args(a = "value `a`",
       b = "value `b`"),
  return = "`a` == `b`"
)]
pure fn eq(a: t, b: t) -> bool { a == b }

#[doc(
  brief = "true if truth values `a` and `b` are distinguishable in the logic",
  args(a = "value `a`",
       b = "value `b`"),
  return = "`a` != `b`"
)]
pure fn ne(a: t, b: t) -> bool { a != b }

#[doc(
  brief = "true if `v` represents truth in the logic",
  args(v = "value `v`"),
  return = "bool(`v`)"
)]
pure fn is_true(v: t) -> bool { v }

#[doc(
  brief = "true if `v` represents falsehood in the logic",
  args(v = "value `v`"),
  return = "bool(!`v`)"
)]
pure fn is_false(v: t) -> bool { !v }

#[doc(
  brief = "Parse logic value from `s`",
  args(v = "string value `s`"),
  return = "true if `s` equals \"true\", else false"
)]
pure fn from_str(s: str) -> t {
    alt s {
      "true" { true }
      "false" { false }
    }
}

#[doc(
  brief = "Convert `v` into a string",
  args(v = "truth value `v`"),
  return = "\"true\" if value `v` is true, else \"false\""
)]
pure fn to_str(v: t) -> str { if v { "true" } else { "false" } }

#[doc(
  brief = "Iterates over all truth values by passing them to `blk` in an unspecified order",
  args(v = "block value `v`"),
  return = "Undefined return value"
)]
fn all_values(blk: block(v: t)) {
    blk(true);
    blk(false);
}

#[doc(
  brief = "converts truth value to an 8 bit byte",
  args(v = "value `v`"),
  return = "returns byte with value 1 if `v` has truth value of true, else 0"
)]
pure fn to_bit(v: t) -> u8 { if v { 1u8 } else { 0u8 } }

// 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 2014 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.

//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail (via
//! `Display`) and cause chain information:
//!
//! ```
//! use std::fmt::Display;
//!
//! trait Error: Display {
//!     fn description(&self) -> &str;
//!
//!     fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The `cause` method is generally used when errors cross "abstraction
//! boundaries", i.e.  when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.

#![stable(feature = "rust1", since = "1.0.0")]

// A note about crates and the facade:
//
// Originally, the `Error` trait was defined in libcore, and the impls
// were scattered about. However, coherence objected to this
// arrangement, because to create the blanket impls for `Box` required
// knowing that `&str: !Error`, and we have no means to deal with that
// sort of conflict just now. Therefore, for the time being, we have
// moved the `Error` trait into libstd. As we evolve a sol'n to the
// coherence challenge (e.g., specialization, neg impls, etc) we can
// reconsider what crate these items belong in.

use any::TypeId;
use boxed::Box;
use convert::From;
use fmt::{self, Debug, Display};
use marker::{Send, Sync, Reflect};
use mem::transmute;
use num;
use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err};
use raw::TraitObject;
use str;
use string::{self, String};

/// Base functionality for all errors in Rust.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display + Reflect {
    /// A short description of the error.
    ///
    /// The description should not contain newlines or sentence-ending
    /// punctuation, to facilitate embedding in larger user-facing
    /// strings.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn description(&self) -> &str;

    /// The lower-level cause of this error, if any.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn cause(&self) -> Option<&Error> { None }

    /// Get the `TypeId` of `self`
    #[doc(hidden)]
    #[unstable(feature = "error_type_id",
               reason = "unclear whether to commit to this public implementation detail",
               issue = "27745")]
    fn type_id(&self) -> TypeId where Self: 'static {
        TypeId::of::<Self>()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
    fn from(err: E) -> Box<Error + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
    fn from(err: E) -> Box<Error + Send + Sync + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<Error + Send + Sync> {
    fn from(err: String) -> Box<Error + Send + Sync> {
        #[derive(Debug)]
        struct StringError(String);

        impl Error for StringError {
            fn description(&self) -> &str { &self.0 }
        }

        impl Display for StringError {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                Display::fmt(&self.0, f)
            }
        }

        Box::new(StringError(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl From<String> for Box<Error> {
    fn from(str_err: String) -> Box<Error> {
        let err1: Box<Error + Send + Sync> = From::from(str_err);
        let err2: Box<Error> = err1;
        err2
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
    fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
        From::from(String::from(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl<'a> From<&'a str> for Box<Error> {
    fn from(err: &'a str) -> Box<Error> {
        From::from(String::from(err))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::ParseBoolError {
    fn description(&self) -> &str { "failed to parse bool" }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error {
    fn description(&self) -> &str {
        "invalid utf-8: corrupt contents"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseIntError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseFloatError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf8Error {
    fn description(&self) -> &str {
        "invalid utf-8"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf16Error {
    fn description(&self) -> &str {
        "invalid utf-16"
    }
}

#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError {
    fn description(&self) -> &str {
        match *self {}
    }
}

// copied from any.rs
impl Error + 'static {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Error + 'static + Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error + 'static + Send + Sync {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let raw = Box::into_raw(self);
                let to: TraitObject =
                    transmute::<*mut Error, TraitObject>(raw);

                // Extract the data pointer
                Ok(Box::from_raw(to.data as *mut T))
            }
        } else {
            Err(self)
        }
    }
}

impl Error + Send {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Error + Send>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send marker
            transmute::<Box<Error>, Box<Error + Send>>(s)
        })
    }
}

impl Error + Send + Sync {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Self>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send+Sync marker
            transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
        })
    }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;
    use super::Error;
    use fmt;

    #[derive(Debug, PartialEq)]
    struct A;
    #[derive(Debug, PartialEq)]
    struct B;

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

    impl Error for A {
        fn description(&self) -> &str { "A-desc" }
    }
    impl Error for B {
        fn description(&self) -> &str { "A-desc" }
    }

    #[test]
    fn downcasting() {
        let mut a = A;
        let mut a = &mut a as &mut (Error + 'static);
        assert_eq!(a.downcast_ref::<A>(), Some(&A));
        assert_eq!(a.downcast_ref::<B>(), None);
        assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
        assert_eq!(a.downcast_mut::<B>(), None);

        let a: Box<Error> = Box::new(A);
        match a.downcast::<B>() {
            Ok(..) => panic!("expected error"),
            Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
        }
    }
}
<commit_msg>Auto merge of #30796 - GuillaumeGomez:impl_box_error, r=alexcrichton<commit_after>// Copyright 2014 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.

//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail (via
//! `Display`) and cause chain information:
//!
//! ```
//! use std::fmt::Display;
//!
//! trait Error: Display {
//!     fn description(&self) -> &str;
//!
//!     fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The `cause` method is generally used when errors cross "abstraction
//! boundaries", i.e.  when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.

#![stable(feature = "rust1", since = "1.0.0")]

// A note about crates and the facade:
//
// Originally, the `Error` trait was defined in libcore, and the impls
// were scattered about. However, coherence objected to this
// arrangement, because to create the blanket impls for `Box` required
// knowing that `&str: !Error`, and we have no means to deal with that
// sort of conflict just now. Therefore, for the time being, we have
// moved the `Error` trait into libstd. As we evolve a sol'n to the
// coherence challenge (e.g., specialization, neg impls, etc) we can
// reconsider what crate these items belong in.

use any::TypeId;
use boxed::Box;
use convert::From;
use fmt::{self, Debug, Display};
use marker::{Send, Sync, Reflect};
use mem::transmute;
use num;
use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err};
use raw::TraitObject;
use str;
use string::{self, String};

/// Base functionality for all errors in Rust.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display + Reflect {
    /// A short description of the error.
    ///
    /// The description should not contain newlines or sentence-ending
    /// punctuation, to facilitate embedding in larger user-facing
    /// strings.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn description(&self) -> &str;

    /// The lower-level cause of this error, if any.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn cause(&self) -> Option<&Error> { None }

    /// Get the `TypeId` of `self`
    #[doc(hidden)]
    #[unstable(feature = "error_type_id",
               reason = "unclear whether to commit to this public implementation detail",
               issue = "27745")]
    fn type_id(&self) -> TypeId where Self: 'static {
        TypeId::of::<Self>()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
    fn from(err: E) -> Box<Error + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
    fn from(err: E) -> Box<Error + Send + Sync + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<Error + Send + Sync> {
    fn from(err: String) -> Box<Error + Send + Sync> {
        #[derive(Debug)]
        struct StringError(String);

        impl Error for StringError {
            fn description(&self) -> &str { &self.0 }
        }

        impl Display for StringError {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                Display::fmt(&self.0, f)
            }
        }

        Box::new(StringError(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl From<String> for Box<Error> {
    fn from(str_err: String) -> Box<Error> {
        let err1: Box<Error + Send + Sync> = From::from(str_err);
        let err2: Box<Error> = err1;
        err2
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
    fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
        From::from(String::from(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl<'a> From<&'a str> for Box<Error> {
    fn from(err: &'a str) -> Box<Error> {
        From::from(String::from(err))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::ParseBoolError {
    fn description(&self) -> &str { "failed to parse bool" }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error {
    fn description(&self) -> &str {
        "invalid utf-8: corrupt contents"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseIntError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseFloatError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf8Error {
    fn description(&self) -> &str {
        "invalid utf-8"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf16Error {
    fn description(&self) -> &str {
        "invalid utf-16"
    }
}

#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError {
    fn description(&self) -> &str {
        match *self {}
    }
}

#[stable(feature = "box_error", since = "1.7.0")]
impl<T: Error> Error for Box<T> {
    fn description(&self) -> &str {
        Error::description(&**self)
    }

    fn cause(&self) -> Option<&Error> {
        Error::cause(&**self)
    }
}

// copied from any.rs
impl Error + 'static {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Error + 'static + Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error + 'static + Send + Sync {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let raw = Box::into_raw(self);
                let to: TraitObject =
                    transmute::<*mut Error, TraitObject>(raw);

                // Extract the data pointer
                Ok(Box::from_raw(to.data as *mut T))
            }
        } else {
            Err(self)
        }
    }
}

impl Error + Send {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Error + Send>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send marker
            transmute::<Box<Error>, Box<Error + Send>>(s)
        })
    }
}

impl Error + Send + Sync {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Self>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send+Sync marker
            transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
        })
    }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;
    use super::Error;
    use fmt;

    #[derive(Debug, PartialEq)]
    struct A;
    #[derive(Debug, PartialEq)]
    struct B;

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

    impl Error for A {
        fn description(&self) -> &str { "A-desc" }
    }
    impl Error for B {
        fn description(&self) -> &str { "A-desc" }
    }

    #[test]
    fn downcasting() {
        let mut a = A;
        let mut a = &mut a as &mut (Error + 'static);
        assert_eq!(a.downcast_ref::<A>(), Some(&A));
        assert_eq!(a.downcast_ref::<B>(), None);
        assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
        assert_eq!(a.downcast_mut::<B>(), None);

        let a: Box<Error> = Box::new(A);
        match a.downcast::<B>() {
            Ok(..) => panic!("expected error"),
            Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>got rid of the unused impl<commit_after><|endoftext|>