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

use deriving;
use deriving::generic::*;
use deriving::generic::ty::*;

use syntax::ast::{MetaItem, Expr, Mutability};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;

pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut FnMut(Annotatable))
{

    let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
                          vec!(), true);

    let typaram = &*deriving::hygienic_type_parameter(item, "__H");

    let arg = Path::new_local(typaram);
    let hash_trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: path,
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            MethodDef {
                name: "hash",
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec![(typaram,
                                  vec![path_std!(cx, core::hash::Hasher)])],
                },
                explicit_self: borrowed_explicit_self(),
                args: vec!(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mutable))),
                ret_ty: nil_ty(),
                attributes: vec![],
                is_unsafe: false,
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    hash_substructure(a, b, c)
                }))
            }
        ),
        associated_types: Vec::new(),
    };

    hash_trait_def.expand(cx, mitem, item, push);
}

fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    let state_expr = match (substr.nonself_args.len(), substr.nonself_args.get(0)) {
        (1, Some(o_f)) => o_f,
        _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`")
    };
    let call_hash = |span, thing_expr| {
        let hash_path = {
            let strs = cx.std_path(&["hash", "Hash", "hash"]);

            cx.expr_path(cx.path_global(span, strs))
        };
        let ref_thing = cx.expr_addr_of(span, thing_expr);
        let expr = cx.expr_call(span, hash_path, vec!(ref_thing, state_expr.clone()));
        cx.stmt_expr(expr)
    };
    let mut stmts = Vec::new();

    let fields = match *substr.fields {
        Struct(_, ref fs) => fs,
        EnumMatching(index, variant, ref fs) => {
            // Determine the discriminant. We will feed this value to the byte
            // iteration function.
            let discriminant = match variant.node.disr_expr {
                Some(ref d) => d.clone(),
                None => cx.expr_usize(trait_span, index)
            };

            stmts.push(call_hash(trait_span, discriminant));

            fs
        }
        _ => cx.span_bug(trait_span, "impossible substructure in `derive(Hash)`")
    };

    for &FieldInfo { ref self_, span, .. } in fields {
        stmts.push(call_hash(span, self_.clone()));
    }

    cx.expr_block(cx.block(trait_span, stmts, None))
}
<commit_msg>fix #21714 by using discriminant_value in #[derive(Hash)]<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.

use deriving;
use deriving::generic::*;
use deriving::generic::ty::*;

use syntax::ast::{self, MetaItem, Expr, Mutability};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;

pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut FnMut(Annotatable))
{

    let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
                          vec!(), true);

    let typaram = &*deriving::hygienic_type_parameter(item, "__H");

    let arg = Path::new_local(typaram);
    let hash_trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: path,
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            MethodDef {
                name: "hash",
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec![(typaram,
                                  vec![path_std!(cx, core::hash::Hasher)])],
                },
                explicit_self: borrowed_explicit_self(),
                args: vec!(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mutable))),
                ret_ty: nil_ty(),
                attributes: vec![],
                is_unsafe: false,
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    hash_substructure(a, b, c)
                }))
            }
        ),
        associated_types: Vec::new(),
    };

    hash_trait_def.expand(cx, mitem, item, push);
}

fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    let state_expr = match (substr.nonself_args.len(), substr.nonself_args.get(0)) {
        (1, Some(o_f)) => o_f,
        _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`")
    };
    let call_hash = |span, thing_expr| {
        let hash_path = {
            let strs = cx.std_path(&["hash", "Hash", "hash"]);

            cx.expr_path(cx.path_global(span, strs))
        };
        let ref_thing = cx.expr_addr_of(span, thing_expr);
        let expr = cx.expr_call(span, hash_path, vec!(ref_thing, state_expr.clone()));
        cx.stmt_expr(expr)
    };
    let mut stmts = Vec::new();

    let fields = match *substr.fields {
        Struct(_, ref fs) => fs,
        EnumMatching(_, _, ref fs) => {
            let path = cx.std_path(&["intrinsics", "discriminant_value"]);
            let call = cx.expr_call_global(
                trait_span, path, vec![cx.expr_self(trait_span)]);
            let variant_value = cx.expr_block(P(ast::Block {
                stmts: vec![],
                expr: Some(call),
                id: ast::DUMMY_NODE_ID,
                rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
                span: trait_span }));

            stmts.push(call_hash(trait_span, variant_value));

            fs
        }
        _ => cx.span_bug(trait_span, "impossible substructure in `derive(Hash)`")
    };

    for &FieldInfo { ref self_, span, .. } in fields {
        stmts.push(call_hash(span, self_.clone()));
    }

    cx.expr_block(cx.block(trait_span, stmts, None))
}
<|endoftext|>


<commit_before><commit_msg>Added exceptions just in case somebody was being stupid<commit_after><|endoftext|>


<commit_before><commit_msg>Added E2E test<commit_after>#![cfg(all(test, feature = "test_e2e"))]
use azure_sdk_core::prelude::*;
use azure_sdk_storage_blob::prelude::*;
use azure_sdk_storage_core::prelude::*;
use futures::stream::StreamExt;

#[tokio::test]
async fn stream_list_blobs() {
    // First we retrieve the account name and master key from environment variables.
    let account =
        std::env::var("STORAGE_ACCOUNT").expect("Set env variable STORAGE_ACCOUNT first!");
    let master_key =
        std::env::var("STORAGE_MASTER_KEY").expect("Set env variable STORAGE_MASTER_KEY first!");

    let container_name = "streamlistblobs235xx752zdve";
    let client = Client::new(&account, &master_key).unwrap();

    let iv = client.list_containers().finalize().await.unwrap();

    if iv
        .incomplete_vector
        .iter()
        .find(|item| item.name == container_name)
        .is_some()
    {
        panic!("The specified container must not exists!");
    }

    // create the container
    client
        .create_container()
        .with_container_name(&container_name)
        .with_public_access(PublicAccess::None)
        .with_timeout(100)
        .finalize()
        .await
        .unwrap();

    // create 10 blobs
    for i in 0..10u8 {
        client
            .put_block_blob()
            .with_container_name(&container_name)
            .with_blob_name(&format!("blob{}.txt", i))
            .with_content_type("text/plain")
            .with_body("somedata".as_bytes())
            .finalize()
            .await
            .unwrap();
    }

    let mut stream = Box::pin(
        client
            .list_blobs()
            .with_max_results(3)
            .with_container_name(&container_name)
            .stream(),
    );

    let mut cnt = 0;
    while let Some(value) = stream.next().await {
        let len = value.unwrap().incomplete_vector.len();
        println!("received {} blobs", len);
        match cnt {
            0 | 1 | 2 => assert_eq!(len, 3),
            3 => assert_eq!(len, 1),
            _ => panic!("more than 10 entries??"),
        }
        cnt += 1;
    }

    client
        .delete_container()
        .with_container_name(&container_name)
        .finalize()
        .await
        .unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Test for #2288<commit_after>iface clam<A: copy> {
  fn chowder(y: A);
}
class foo<A: copy> : clam<A> {
  let x: A;
  new(b: A) { self.x = b; }
  fn chowder(y: A) {
  }
}

fn f<A: copy>(x: clam<A>, a: A) {
  x.chowder(a);
}

fn main() {

  let c = foo(42);
  let d: clam<int> = c as clam::<int>;
  f(d, c.x);
}
<|endoftext|>


<commit_before><commit_msg>auto merge of #12375 : FlaPer87/rust/issue-7660, r=cmr<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.

// Regresion test for issue 7660
// rvalue lifetime too short when equivalent `match` works

use std::hashmap::HashMap;

struct A(int, int);

pub fn main() {
    let mut m: HashMap<int, A> = HashMap::new();
    m.insert(1, A(0, 0));

    let A(ref _a, ref _b) = *m.get(&1);
    let (a, b) = match *m.get(&1) { A(ref _a, ref _b) => (_a, _b) };
}
<|endoftext|>


<commit_before><commit_msg>add simple test<commit_after><|endoftext|>


<commit_before>/*
Module: tuple
*/

// FIXME #1546: Would rather write fst<T, U>(+pair: (T, U)) -> T
fn first<T:copy, U:copy>(pair: (T, U)) -> T {
    let (t, _) = pair;
    ret t;
}

fn second<T:copy, U:copy>(pair: (T, U)) -> U {
    let (_, u) = pair;
    ret u;
}

fn swap<T:copy, U:copy>(pair: (T, U)) -> (U, T) {
    let (t, u) = pair;
    ret (u, t);
}

#[test]
fn test_tuple() {
    assert first((948, 4039.48)) == 948;
    assert second((34.5, "foo")) == "foo";
    assert swap(('a', 2)) == (2, 'a');
}

<commit_msg>libcore: Remove bogus FIXME from core::tuple<commit_after>/*
Module: tuple
*/

fn first<T:copy, U:copy>(pair: (T, U)) -> T {
    let (t, _) = pair;
    ret t;
}

fn second<T:copy, U:copy>(pair: (T, U)) -> U {
    let (_, u) = pair;
    ret u;
}

fn swap<T:copy, U:copy>(pair: (T, U)) -> (U, T) {
    let (t, u) = pair;
    ret (u, t);
}

#[test]
fn test_tuple() {
    assert first((948, 4039.48)) == 948;
    assert second((34.5, "foo")) == "foo";
    assert swap(('a', 2)) == (2, 'a');
}

<|endoftext|>


<commit_before>// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

//! Operations on tuples

use cmp::{Eq, Ord};

pub trait CopyableTuple<T, U> {
    pure fn first() -> T;
    pure fn second() -> U;
    pure fn swap() -> (U, T);
}

impl<T: Copy, U: Copy> (T, U): CopyableTuple<T, U> {

    /// Return the first element of self
    pure fn first() -> T {
        let (t, _) = self;
        return t;
    }

    /// Return the second element of self
    pure fn second() -> U {
        let (_, u) = self;
        return u;
    }

    /// Return the results of swapping the two elements of self
    pure fn swap() -> (U, T) {
        let (t, u) = self;
        return (u, t);
    }

}

pub trait ImmutableTuple<T, U> {
    pure fn first_ref(&self) -> &self/T;
    pure fn second_ref(&self) -> &self/U;
}

impl<T, U> (T, U): ImmutableTuple<T, U> {
    pure fn first_ref(&self) -> &self/T {
        match *self {
            (ref t, _) => t,
        }
    }
    pure fn second_ref(&self) -> &self/U {
        match *self {
            (_, ref u) => u,
        }
    }
}

pub trait ExtendedTupleOps<A,B> {
    fn zip(&self) -> ~[(A, B)];
    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
}

impl<A: Copy, B: Copy> (&[A], &[B]): ExtendedTupleOps<A,B> {
    fn zip(&self) -> ~[(A, B)] {
        match *self {
            (ref a, ref b) => {
                vec::zip_slice(*a, *b)
            }
        }
    }

    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
        match *self {
            (ref a, ref b) => {
                vec::map2(*a, *b, f)
            }
        }
    }
}

impl<A: Copy, B: Copy> (~[A], ~[B]): ExtendedTupleOps<A,B> {

    fn zip(&self) -> ~[(A, B)] {
        match *self {
            (ref a, ref b) => {
                vec::zip_slice(*a, *b)
            }
        }
    }

    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
        match *self {
            (ref a, ref b) => {
                vec::map2(*a, *b, f)
            }
        }
    }
}

impl<A: Eq, B: Eq> (A, B) : Eq {
    pure fn eq(other: &(A, B)) -> bool {
        match self {
            (ref self_a, ref self_b) => match other {
                &(ref other_a, ref other_b) => {
                    (*self_a).eq(other_a) && (*self_b).eq(other_b)
                }
            }
        }
    }
    pure fn ne(other: &(A, B)) -> bool { !self.eq(other) }
}

impl<A: Ord, B: Ord> (A, B) : Ord {
    pure fn lt(other: &(A, B)) -> bool {
        match self {
            (ref self_a, ref self_b) => {
                match (*other) {
                    (ref other_a, ref other_b) => {
                        if (*self_a).lt(other_a) { return true; }
                        if (*other_a).lt(self_a) { return false; }
                        if (*self_b).lt(other_b) { return true; }
                        return false;
                    }
                }
            }
        }
    }
    pure fn le(other: &(A, B)) -> bool { !(*other).lt(&self) }
    pure fn ge(other: &(A, B)) -> bool { !self.lt(other) }
    pure fn gt(other: &(A, B)) -> bool { (*other).lt(&self)  }
}

impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
    pure fn eq(other: &(A, B, C)) -> bool {
        match self {
            (ref self_a, ref self_b, ref self_c) => match other {
                &(ref other_a, ref other_b, ref other_c) => {
                    (*self_a).eq(other_a) && (*self_b).eq(other_b)
                        && (*self_c).eq(other_c)
                }
            }
        }
    }
    pure fn ne(other: &(A, B, C)) -> bool { !self.eq(other) }
}

impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
    pure fn lt(other: &(A, B, C)) -> bool {
        match self {
            (ref self_a, ref self_b, ref self_c) => {
                match (*other) {
                    (ref other_a, ref other_b, ref other_c) => {
                        if (*self_a).lt(other_a) { return true; }
                        if (*other_a).lt(self_a) { return false; }
                        if (*self_b).lt(other_b) { return true; }
                        if (*other_b).lt(self_b) { return false; }
                        if (*self_c).lt(other_c) { return true; }
                        return false;
                    }
                }
            }
        }
    }
    pure fn le(other: &(A, B, C)) -> bool { !(*other).lt(&self) }
    pure fn ge(other: &(A, B, C)) -> bool { !self.lt(other) }
    pure fn gt(other: &(A, B, C)) -> bool { (*other).lt(&self)  }
}

#[test]
fn test_tuple_ref() {
    let (~"foo", ~"bar");
    assert x.first_ref() == &~"foo";
    assert x.second_ref() == &~"bar";
}

#[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_tuple() {
    assert (948, 4039.48).first() == 948;
    assert (34.5, ~"foo").second() == ~"foo";
    assert ('a', 2).swap() == (2, 'a');
}

<commit_msg>libcore Fix the tuple first_ref test<commit_after>// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

//! Operations on tuples

use cmp::{Eq, Ord};

pub trait CopyableTuple<T, U> {
    pure fn first() -> T;
    pure fn second() -> U;
    pure fn swap() -> (U, T);
}

impl<T: Copy, U: Copy> (T, U): CopyableTuple<T, U> {

    /// Return the first element of self
    pure fn first() -> T {
        let (t, _) = self;
        return t;
    }

    /// Return the second element of self
    pure fn second() -> U {
        let (_, u) = self;
        return u;
    }

    /// Return the results of swapping the two elements of self
    pure fn swap() -> (U, T) {
        let (t, u) = self;
        return (u, t);
    }

}

pub trait ImmutableTuple<T, U> {
    pure fn first_ref(&self) -> &self/T;
    pure fn second_ref(&self) -> &self/U;
}

impl<T, U> (T, U): ImmutableTuple<T, U> {
    pure fn first_ref(&self) -> &self/T {
        match *self {
            (ref t, _) => t,
        }
    }
    pure fn second_ref(&self) -> &self/U {
        match *self {
            (_, ref u) => u,
        }
    }
}

pub trait ExtendedTupleOps<A,B> {
    fn zip(&self) -> ~[(A, B)];
    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
}

impl<A: Copy, B: Copy> (&[A], &[B]): ExtendedTupleOps<A,B> {
    fn zip(&self) -> ~[(A, B)] {
        match *self {
            (ref a, ref b) => {
                vec::zip_slice(*a, *b)
            }
        }
    }

    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
        match *self {
            (ref a, ref b) => {
                vec::map2(*a, *b, f)
            }
        }
    }
}

impl<A: Copy, B: Copy> (~[A], ~[B]): ExtendedTupleOps<A,B> {

    fn zip(&self) -> ~[(A, B)] {
        match *self {
            (ref a, ref b) => {
                vec::zip_slice(*a, *b)
            }
        }
    }

    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
        match *self {
            (ref a, ref b) => {
                vec::map2(*a, *b, f)
            }
        }
    }
}

impl<A: Eq, B: Eq> (A, B) : Eq {
    pure fn eq(other: &(A, B)) -> bool {
        match self {
            (ref self_a, ref self_b) => match other {
                &(ref other_a, ref other_b) => {
                    (*self_a).eq(other_a) && (*self_b).eq(other_b)
                }
            }
        }
    }
    pure fn ne(other: &(A, B)) -> bool { !self.eq(other) }
}

impl<A: Ord, B: Ord> (A, B) : Ord {
    pure fn lt(other: &(A, B)) -> bool {
        match self {
            (ref self_a, ref self_b) => {
                match (*other) {
                    (ref other_a, ref other_b) => {
                        if (*self_a).lt(other_a) { return true; }
                        if (*other_a).lt(self_a) { return false; }
                        if (*self_b).lt(other_b) { return true; }
                        return false;
                    }
                }
            }
        }
    }
    pure fn le(other: &(A, B)) -> bool { !(*other).lt(&self) }
    pure fn ge(other: &(A, B)) -> bool { !self.lt(other) }
    pure fn gt(other: &(A, B)) -> bool { (*other).lt(&self)  }
}

impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
    pure fn eq(other: &(A, B, C)) -> bool {
        match self {
            (ref self_a, ref self_b, ref self_c) => match other {
                &(ref other_a, ref other_b, ref other_c) => {
                    (*self_a).eq(other_a) && (*self_b).eq(other_b)
                        && (*self_c).eq(other_c)
                }
            }
        }
    }
    pure fn ne(other: &(A, B, C)) -> bool { !self.eq(other) }
}

impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
    pure fn lt(other: &(A, B, C)) -> bool {
        match self {
            (ref self_a, ref self_b, ref self_c) => {
                match (*other) {
                    (ref other_a, ref other_b, ref other_c) => {
                        if (*self_a).lt(other_a) { return true; }
                        if (*other_a).lt(self_a) { return false; }
                        if (*self_b).lt(other_b) { return true; }
                        if (*other_b).lt(self_b) { return false; }
                        if (*self_c).lt(other_c) { return true; }
                        return false;
                    }
                }
            }
        }
    }
    pure fn le(other: &(A, B, C)) -> bool { !(*other).lt(&self) }
    pure fn ge(other: &(A, B, C)) -> bool { !self.lt(other) }
    pure fn gt(other: &(A, B, C)) -> bool { (*other).lt(&self)  }
}

#[test]
fn test_tuple_ref() {
    let x = (~"foo", ~"bar");
    assert x.first_ref() == &~"foo";
    assert x.second_ref() == &~"bar";
}

#[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_tuple() {
    assert (948, 4039.48).first() == 948;
    assert (34.5, ~"foo").second() == ~"foo";
    assert ('a', 2).swap() == (2, 'a');
}

<|endoftext|>


<commit_before><commit_msg>Rect area as method<commit_after><|endoftext|>


<commit_before>// Copyright 2012-2013 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.

/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match msg {
    Some(m) => m,
    None => ~"default message"
};
~~~

*/

use cmp::{Eq,Ord};
use ops::Add;
use kinds::Copy;
use util;
use num::Zero;
use iterator::Iterator;
use str::StrSlice;
use clone::DeepClone;

#[cfg(test)] use str;
#[cfg(test)] use iterator::IteratorUtil;

/// The option type
#[deriving(Clone, DeepClone, Eq)]
pub enum Option<T> {
    None,
    Some(T),
}

impl<T:Ord> Ord for Option<T> {
    fn lt(&self, other: &Option<T>) -> bool {
        match (self, other) {
            (&None, &None) => false,
            (&None, &Some(_)) => true,
            (&Some(_), &None) => false,
            (&Some(ref a), &Some(ref b)) => *a < *b
        }
    }

    fn le(&self, other: &Option<T>) -> bool {
        match (self, other) {
            (&None, &None) => true,
            (&None, &Some(_)) => true,
            (&Some(_), &None) => false,
            (&Some(ref a), &Some(ref b)) => *a <= *b
        }
    }

    fn ge(&self, other: &Option<T>) -> bool {
        !(self < other)
    }

    fn gt(&self, other: &Option<T>) -> bool {
        !(self <= other)
    }
}

impl<T: Copy+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
    #[inline]
    fn add(&self, other: &Option<T>) -> Option<T> {
        match (&*self, &*other) {
            (&None, &None) => None,
            (_, &None) => copy *self,
            (&None, _) => copy *other,
            (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
        }
    }
}

impl<T> Option<T> {
    /// Return an iterator over the possibly contained value
    #[inline]
    pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
        match *self {
            Some(ref x) => OptionIterator{opt: Some(x)},
            None => OptionIterator{opt: None}
        }
    }

    /// Return a mutable iterator over the possibly contained value
    #[inline]
    pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
        match *self {
            Some(ref mut x) => OptionMutIterator{opt: Some(x)},
            None => OptionMutIterator{opt: None}
        }
    }

    /// Returns true if the option equals `none`
    #[inline]
    pub fn is_none(&self) -> bool {
        match *self { None => true, Some(_) => false }
    }

    /// Returns true if the option contains some value
    #[inline]
    pub fn is_some(&self) -> bool { !self.is_none() }

    /// Update an optional value by optionally running its content through a
    /// function that returns an option.
    #[inline]
    pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
        match self {
            Some(t) => f(t),
            None => None
        }
    }

    /// Returns the leftmost Some() value, or None if both are None.
    #[inline]
    pub fn or(self, optb: Option<T>) -> Option<T> {
        match self {
            Some(opta) => Some(opta),
            _ => optb
        }
    }

    /// Update an optional value by optionally running its content by reference
    /// through a function that returns an option.
    #[inline]
    pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
                            -> Option<U> {
        match *self {
            Some(ref x) => f(x),
            None => None
        }
    }

    /// Filters an optional value using given function.
    #[inline(always)]
    pub fn filtered<'a>(self, f: &fn(t: &'a T) -> bool) -> Option<T> {
        match self {
            Some(x) => if(f(&x)) {Some(x)} else {None},
            None => None
        }
    }

    /// Maps a `some` value from one type to another by reference
    #[inline]
    pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
        match *self { Some(ref x) => Some(f(x)), None => None }
    }

    /// As `map`, but consumes the option and gives `f` ownership to avoid
    /// copying.
    #[inline]
    pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
        match self { None => None, Some(v) => Some(f(v)) }
    }

    /// Applies a function to the contained value or returns a default
    #[inline]
    pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
        match *self { None => def, Some(ref t) => f(t) }
    }

    /// As `map_default`, but consumes the option and gives `f`
    /// ownership to avoid copying.
    #[inline]
    pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
        match self { None => def, Some(v) => f(v) }
    }

    /// Apply a function to the contained value or do nothing
    pub fn mutate(&mut self, f: &fn(T) -> T) {
        if self.is_some() {
            *self = Some(f(self.swap_unwrap()));
        }
    }

    /// Apply a function to the contained value or set it to a default
    pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
        if self.is_some() {
            *self = Some(f(self.swap_unwrap()));
        } else {
            *self = Some(def);
        }
    }

    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline]
    pub fn get_ref<'a>(&'a self) -> &'a T {
        match *self {
          Some(ref x) => x,
          None => fail!("option::get_ref none")
        }
    }

    /**
    Gets a mutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline]
    pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
        match *self {
          Some(ref mut x) => x,
          None => fail!("option::get_mut_ref none")
        }
    }

    #[inline]
    pub fn unwrap(self) -> T {
        /*!
        Moves a value out of an option type and returns it.

        Useful primarily for getting strings, vectors and unique pointers out
        of option types without copying them.

        # Failure

        Fails if the value equals `None`.

        # Safety note

        In general, because this function may fail, its use is discouraged.
        Instead, prefer to use pattern matching and handle the `None`
        case explicitly.
         */
        match self {
          Some(x) => x,
          None => fail!("option::unwrap none")
        }
    }

    /**
     * The option dance. Moves a value out of an option type and returns it,
     * replacing the original with `None`.
     *
     * # Failure
     *
     * Fails if the value equals `None`.
     */
    #[inline]
    pub fn swap_unwrap(&mut self) -> T {
        if self.is_none() { fail!("option::swap_unwrap none") }
        util::replace(self, None).unwrap()
    }

    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline]
    pub fn expect(self, reason: &str) -> T {
        match self {
          Some(val) => val,
          None => fail!(reason.to_owned()),
        }
    }
}

impl<T:Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    #[inline]
    pub fn get(self) -> T {
        match self {
          Some(x) => return x,
          None => fail!("option::get none")
        }
    }

    /// Returns the contained value or a default
    #[inline]
    pub fn get_or_default(self, def: T) -> T {
        match self { Some(x) => x, None => def }
    }

    /// Applies a function zero or more times until the result is none.
    #[inline]
    pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
        let mut opt = self;
        while opt.is_some() {
            opt = blk(opt.unwrap());
        }
    }
}

impl<T:Copy + Zero> Option<T> {
    /// Returns the contained value or zero (for this type)
    #[inline]
    pub fn get_or_zero(self) -> T {
        match self {
            Some(x) => x,
            None => Zero::zero()
        }
    }
}

impl<T> Zero for Option<T> {
    fn zero() -> Option<T> { None }
    fn is_zero(&self) -> bool { self.is_none() }
}

/// Immutable iterator over an `Option<A>`
pub struct OptionIterator<'self, A> {
    priv opt: Option<&'self A>
}

impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
    fn next(&mut self) -> Option<&'self A> {
        util::replace(&mut self.opt, None)
    }
}

/// Mutable iterator over an `Option<A>`
pub struct OptionMutIterator<'self, A> {
    priv opt: Option<&'self mut A>
}

impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
    fn next(&mut self) -> Option<&'self mut A> {
        util::replace(&mut self.opt, None)
    }
}

#[test]
fn test_unwrap_ptr() {
    unsafe {
        let x = ~0;
        let addr_x: *int = ::cast::transmute(&*x);
        let opt = Some(x);
        let y = opt.unwrap();
        let addr_y: *int = ::cast::transmute(&*y);
        assert_eq!(addr_x, addr_y);
    }
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(x);
    let y = opt.unwrap();
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert_eq!(addr_x, addr_y);
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
    }

    #[unsafe_destructor]
    impl ::ops::Drop for R {
       fn drop(&self) { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(x);
        let _y = opt.unwrap();
    }
    assert_eq!(*i, 1);
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    for x.iter().advance |_x| {
        y2 = y.swap_unwrap();
    }
    assert_eq!(y2, 5);
    assert!(y.is_none());
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable);
    let _y2 = y.swap_unwrap();
    let _y3 = y.swap_unwrap();
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert_eq!(i, 11);
}

#[test]
fn test_get_or_zero() {
    let some_stuff = Some(42);
    assert_eq!(some_stuff.get_or_zero(), 42);
    let no_stuff: Option<int> = None;
    assert_eq!(no_stuff.get_or_zero(), 0);
}

#[test]
fn test_filtered() {
    let some_stuff = Some(42);
    let modified_stuff = some_stuff.filtered(|&x| {x < 10});
    assert_eq!(some_stuff.get(), 42);
    assert!(modified_stuff.is_none());
}
<commit_msg>auto merge of #7497 : alexcrichton/rust/issue-7394, r=huonw<commit_after>// Copyright 2012-2013 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.

/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match msg {
    Some(m) => m,
    None => ~"default message"
};
~~~

*/

use cmp::{Eq,Ord};
use ops::Add;
use kinds::Copy;
use util;
use num::Zero;
use iterator::Iterator;
use str::StrSlice;
use clone::DeepClone;

#[cfg(test)] use str;
#[cfg(test)] use iterator::IteratorUtil;

/// The option type
#[deriving(Clone, DeepClone, Eq)]
pub enum Option<T> {
    None,
    Some(T),
}

impl<T:Ord> Ord for Option<T> {
    fn lt(&self, other: &Option<T>) -> bool {
        match (self, other) {
            (&None, &None) => false,
            (&None, &Some(_)) => true,
            (&Some(_), &None) => false,
            (&Some(ref a), &Some(ref b)) => *a < *b
        }
    }

    fn le(&self, other: &Option<T>) -> bool {
        match (self, other) {
            (&None, &None) => true,
            (&None, &Some(_)) => true,
            (&Some(_), &None) => false,
            (&Some(ref a), &Some(ref b)) => *a <= *b
        }
    }

    fn ge(&self, other: &Option<T>) -> bool {
        !(self < other)
    }

    fn gt(&self, other: &Option<T>) -> bool {
        !(self <= other)
    }
}

impl<T: Copy+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
    #[inline]
    fn add(&self, other: &Option<T>) -> Option<T> {
        match (&*self, &*other) {
            (&None, &None) => None,
            (_, &None) => copy *self,
            (&None, _) => copy *other,
            (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
        }
    }
}

impl<T> Option<T> {
    /// Return an iterator over the possibly contained value
    #[inline]
    pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
        match *self {
            Some(ref x) => OptionIterator{opt: Some(x)},
            None => OptionIterator{opt: None}
        }
    }

    /// Return a mutable iterator over the possibly contained value
    #[inline]
    pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
        match *self {
            Some(ref mut x) => OptionMutIterator{opt: Some(x)},
            None => OptionMutIterator{opt: None}
        }
    }

    /// Returns true if the option equals `none`
    #[inline]
    pub fn is_none(&self) -> bool {
        match *self { None => true, Some(_) => false }
    }

    /// Returns true if the option contains some value
    #[inline]
    pub fn is_some(&self) -> bool { !self.is_none() }

    /// Update an optional value by optionally running its content through a
    /// function that returns an option.
    #[inline]
    pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
        match self {
            Some(t) => f(t),
            None => None
        }
    }

    /// Returns the leftmost Some() value, or None if both are None.
    #[inline]
    pub fn or(self, optb: Option<T>) -> Option<T> {
        match self {
            Some(opta) => Some(opta),
            _ => optb
        }
    }

    /// Update an optional value by optionally running its content by reference
    /// through a function that returns an option.
    #[inline]
    pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
                            -> Option<U> {
        match *self {
            Some(ref x) => f(x),
            None => None
        }
    }

    /// Filters an optional value using given function.
    #[inline(always)]
    pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option<T> {
        match self {
            Some(x) => if(f(&x)) {Some(x)} else {None},
            None => None
        }
    }

    /// Maps a `some` value from one type to another by reference
    #[inline]
    pub fn map<'a, U>(&'a self, f: &fn(&'a T) -> U) -> Option<U> {
        match *self { Some(ref x) => Some(f(x)), None => None }
    }

    /// Maps a `some` value from one type to another by a mutable reference
    #[inline]
    pub fn map_mut<'a, U>(&'a mut self, f: &fn(&'a mut T) -> U) -> Option<U> {
        match *self { Some(ref mut x) => Some(f(x)), None => None }
    }

    /// As `map`, but consumes the option and gives `f` ownership to avoid
    /// copying.
    #[inline]
    pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
        match self { None => None, Some(v) => Some(f(v)) }
    }

    /// Applies a function to the contained value or returns a default
    #[inline]
    pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
        match *self { None => def, Some(ref t) => f(t) }
    }

    /// As `map_default`, but consumes the option and gives `f`
    /// ownership to avoid copying.
    #[inline]
    pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
        match self { None => def, Some(v) => f(v) }
    }

    /// Apply a function to the contained value or do nothing
    pub fn mutate(&mut self, f: &fn(T) -> T) {
        if self.is_some() {
            *self = Some(f(self.swap_unwrap()));
        }
    }

    /// Apply a function to the contained value or set it to a default
    pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
        if self.is_some() {
            *self = Some(f(self.swap_unwrap()));
        } else {
            *self = Some(def);
        }
    }

    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline]
    pub fn get_ref<'a>(&'a self) -> &'a T {
        match *self {
          Some(ref x) => x,
          None => fail!("option::get_ref none")
        }
    }

    /**
    Gets a mutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline]
    pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
        match *self {
          Some(ref mut x) => x,
          None => fail!("option::get_mut_ref none")
        }
    }

    #[inline]
    pub fn unwrap(self) -> T {
        /*!
        Moves a value out of an option type and returns it.

        Useful primarily for getting strings, vectors and unique pointers out
        of option types without copying them.

        # Failure

        Fails if the value equals `None`.

        # Safety note

        In general, because this function may fail, its use is discouraged.
        Instead, prefer to use pattern matching and handle the `None`
        case explicitly.
         */
        match self {
          Some(x) => x,
          None => fail!("option::unwrap none")
        }
    }

    /**
     * The option dance. Moves a value out of an option type and returns it,
     * replacing the original with `None`.
     *
     * # Failure
     *
     * Fails if the value equals `None`.
     */
    #[inline]
    pub fn swap_unwrap(&mut self) -> T {
        if self.is_none() { fail!("option::swap_unwrap none") }
        util::replace(self, None).unwrap()
    }

    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline]
    pub fn expect(self, reason: &str) -> T {
        match self {
          Some(val) => val,
          None => fail!(reason.to_owned()),
        }
    }
}

impl<T:Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    #[inline]
    pub fn get(self) -> T {
        match self {
          Some(x) => return x,
          None => fail!("option::get none")
        }
    }

    /// Returns the contained value or a default
    #[inline]
    pub fn get_or_default(self, def: T) -> T {
        match self { Some(x) => x, None => def }
    }

    /// Applies a function zero or more times until the result is none.
    #[inline]
    pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
        let mut opt = self;
        while opt.is_some() {
            opt = blk(opt.unwrap());
        }
    }
}

impl<T:Copy + Zero> Option<T> {
    /// Returns the contained value or zero (for this type)
    #[inline]
    pub fn get_or_zero(self) -> T {
        match self {
            Some(x) => x,
            None => Zero::zero()
        }
    }
}

impl<T> Zero for Option<T> {
    fn zero() -> Option<T> { None }
    fn is_zero(&self) -> bool { self.is_none() }
}

/// Immutable iterator over an `Option<A>`
pub struct OptionIterator<'self, A> {
    priv opt: Option<&'self A>
}

impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
    fn next(&mut self) -> Option<&'self A> {
        util::replace(&mut self.opt, None)
    }
}

/// Mutable iterator over an `Option<A>`
pub struct OptionMutIterator<'self, A> {
    priv opt: Option<&'self mut A>
}

impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
    fn next(&mut self) -> Option<&'self mut A> {
        util::replace(&mut self.opt, None)
    }
}

#[test]
fn test_unwrap_ptr() {
    unsafe {
        let x = ~0;
        let addr_x: *int = ::cast::transmute(&*x);
        let opt = Some(x);
        let y = opt.unwrap();
        let addr_y: *int = ::cast::transmute(&*y);
        assert_eq!(addr_x, addr_y);
    }
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(x);
    let y = opt.unwrap();
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert_eq!(addr_x, addr_y);
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
    }

    #[unsafe_destructor]
    impl ::ops::Drop for R {
       fn drop(&self) { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(x);
        let _y = opt.unwrap();
    }
    assert_eq!(*i, 1);
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    for x.iter().advance |_x| {
        y2 = y.swap_unwrap();
    }
    assert_eq!(y2, 5);
    assert!(y.is_none());
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable);
    let _y2 = y.swap_unwrap();
    let _y3 = y.swap_unwrap();
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert_eq!(i, 11);
}

#[test]
fn test_get_or_zero() {
    let some_stuff = Some(42);
    assert_eq!(some_stuff.get_or_zero(), 42);
    let no_stuff: Option<int> = None;
    assert_eq!(no_stuff.get_or_zero(), 0);
}

#[test]
fn test_filtered() {
    let some_stuff = Some(42);
    let modified_stuff = some_stuff.filtered(|&x| {x < 10});
    assert_eq!(some_stuff.get(), 42);
    assert!(modified_stuff.is_none());
}
<|endoftext|>


<commit_before>// Copyright 2012-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.

//! Signaling success or failure states (`Result` type)

use clone::Clone;
use cmp::Eq;
use iter::{Iterator, FromIterator};
use option::{None, Option, Some};

/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Show)]
#[must_use]
pub enum Result<T, E> {
    /// Contains the success value
    Ok(T),

    /// Contains the error value
    Err(E)
}

/////////////////////////////////////////////////////////////////////////////
// Type implementation
/////////////////////////////////////////////////////////////////////////////

impl<T, E> Result<T, E> {
    /////////////////////////////////////////////////////////////////////////
    // Querying the contained values
    /////////////////////////////////////////////////////////////////////////

    /// Returns true if the result is `Ok`
    #[inline]
    pub fn is_ok(&self) -> bool {
        match *self {
            Ok(_) => true,
            Err(_) => false
        }
    }

    /// Returns true if the result is `Err`
    #[inline]
    pub fn is_err(&self) -> bool {
        !self.is_ok()
    }

    /////////////////////////////////////////////////////////////////////////
    // Adapter for each variant
    /////////////////////////////////////////////////////////////////////////

    /// Convert from `Result<T, E>` to `Option<T>`
    #[inline]
    pub fn ok(self) -> Option<T> {
        match self {
            Ok(x)  => Some(x),
            Err(_) => None,
        }
    }

    /// Convert from `Result<T, E>` to `Option<E>`
    #[inline]
    pub fn err(self) -> Option<E> {
        match self {
            Ok(_)  => None,
            Err(x) => Some(x),
        }
    }

    /////////////////////////////////////////////////////////////////////////
    // Adapter for working with references
    /////////////////////////////////////////////////////////////////////////

    /// Convert from `Result<T, E>` to `Result<&T, &E>`
    #[inline]
    pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
        match *self {
            Ok(ref x) => Ok(x),
            Err(ref x) => Err(x),
        }
    }

    /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
    #[inline]
    pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
        match *self {
            Ok(ref mut x) => Ok(x),
            Err(ref mut x) => Err(x),
        }
    }

    /////////////////////////////////////////////////////////////////////////
    // Transforming contained values
    /////////////////////////////////////////////////////////////////////////

    /// Maps a `Result<T, E>` to `Result<U, E>` by applying a function to an
    /// contained `Ok` value, leaving an `Err` value untouched.
    ///
    /// This function can be used to compose the results of two functions.
    ///
    /// Example:
    ///
    ///     let res = read_file(file).map(|buf| {
    ///         parse_bytes(buf)
    ///     })
    #[inline]
    pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
        match self {
          Ok(t) => Ok(op(t)),
          Err(e) => Err(e)
        }
    }

    /// Maps a `Result<T, E>` to `Result<T, F>` by applying a function to an
    /// contained `Err` value, leaving an `Ok` value untouched.
    ///
    /// This function can be used to pass through a successful result while handling
    /// an error.
    #[inline]
    pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
        match self {
          Ok(t) => Ok(t),
          Err(e) => Err(op(e))
        }
    }

    ////////////////////////////////////////////////////////////////////////
    // Boolean operations on the values, eager and lazy
    /////////////////////////////////////////////////////////////////////////

    /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
    #[inline]
    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
        match self {
            Ok(_) => res,
            Err(e) => Err(e),
        }
    }

    /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
    ///
    /// This function can be used for control flow based on result values
    #[inline]
    pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
        match self {
            Ok(t) => op(t),
            Err(e) => Err(e),
        }
    }

    /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
    #[inline]
    pub fn or(self, res: Result<T, E>) -> Result<T, E> {
        match self {
            Ok(_) => self,
            Err(_) => res,
        }
    }

    /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
    ///
    /// This function can be used for control flow based on result values
    #[inline]
    pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
        match self {
            Ok(t) => Ok(t),
            Err(e) => op(e),
        }
    }

    /////////////////////////////////////////////////////////////////////////
    // Common special cases
    /////////////////////////////////////////////////////////////////////////

    /// Unwraps a result, yielding the content of an `Ok`.
    /// Fails if the value is an `Err`.
    #[inline]
    pub fn unwrap(self) -> T {
        match self {
            Ok(t) => t,
            Err(_) => fail!("called `Result::unwrap()` on an `Err` value")
        }
    }

    /// Unwraps a result, yielding the content of an `Err`.
    /// Fails if the value is an `Ok`.
    #[inline]
    pub fn unwrap_err(self) -> E {
        match self {
            Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"),
            Err(e) => e
        }
    }
}

/////////////////////////////////////////////////////////////////////////////
// Free functions
/////////////////////////////////////////////////////////////////////////////

/// Takes each element in the `Iterator`: if it is an `Err`, no further
/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
/// vector containing the values of each `Result` is returned.
///
/// Here is an example which increments every integer in a vector,
/// checking for overflow:
///
///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
///         if x == uint::MAX { return Err("overflow"); }
///         else { return Ok(x+1u); }
///     }
///     let v = [1u, 2, 3];
///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
///     assert!(res == Ok(~[2u, 3, 4]));
#[inline]
pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> {
    // FIXME(#11084): This should be twice as fast once this bug is closed.
    let mut iter = iter.scan(None, |state, x| {
        match x {
            Ok(x) => Some(x),
            Err(err) => {
                *state = Some(err);
                None
            }
        }
    });

    let v: V = FromIterator::from_iter(iter.by_ref());

    match iter.state {
        Some(err) => Err(err),
        None => Ok(v),
    }
}

/// Perform a fold operation over the result values from an iterator.
///
/// If an `Err` is encountered, it is immediately returned.
/// Otherwise, the folded value is returned.
#[inline]
pub fn fold<T,
            V,
            E,
            Iter: Iterator<Result<T, E>>>(
            mut iterator: Iter,
            mut init: V,
            f: |V, T| -> V)
            -> Result<V, E> {
    for t in iterator {
        match t {
            Ok(v) => init = f(init, v),
            Err(u) => return Err(u)
        }
    }
    Ok(init)
}

/// Perform a trivial fold operation over the result values
/// from an iterator.
///
/// If an `Err` is encountered, it is immediately returned.
/// Otherwise, a simple `Ok(())` is returned.
#[inline]
pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
    fold(iterator, (), |_, _| ())
}

/////////////////////////////////////////////////////////////////////////////
// Tests
/////////////////////////////////////////////////////////////////////////////

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

    use iter::range;

    pub fn op1() -> Result<int, ~str> { Ok(666) }
    pub fn op2() -> Result<int, ~str> { Err(~"sadface") }

    #[test]
    pub fn test_and() {
        assert_eq!(op1().and(Ok(667)).unwrap(), 667);
        assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad");

        assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
        assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface");
    }

    #[test]
    pub fn test_and_then() {
        assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
        assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");

        assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
        assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
    }

    #[test]
    pub fn test_or() {
        assert_eq!(op1().or(Ok(667)).unwrap(), 666);
        assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);

        assert_eq!(op2().or(Ok(667)).unwrap(), 667);
        assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
    }

    #[test]
    pub fn test_or_else() {
        assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
        assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);

        assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
        assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
    }

    #[test]
    pub fn test_impl_map() {
        assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab"));
        assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a"));
    }

    #[test]
    pub fn test_impl_map_err() {
        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a"));
        assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab"));
    }

    #[test]
    fn test_collect() {
        let v: Result<~[int], ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0)));
        assert_eq!(v, Ok(~[]));

        let v: Result<~[int], ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x)));
        assert_eq!(v, Ok(~[0, 1, 2]));

        let v: Result<~[int], int> = collect(range(0, 3)
                                             .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
        assert_eq!(v, Err(2));

        // test that it does not take more elements than it needs
        let functions = [|| Ok(()), || Err(1), || fail!()];

        let v: Result<~[()], int> = collect(functions.iter().map(|f| (*f)()));
        assert_eq!(v, Err(1));
    }

    #[test]
    fn test_fold() {
        assert_eq!(fold_(range(0, 0)
                        .map(|_| Ok::<(), ()>(()))),
                   Ok(()));
        assert_eq!(fold(range(0, 3)
                        .map(|x| Ok::<int, ()>(x)),
                        0, |a, b| a + b),
                   Ok(3));
        assert_eq!(fold_(range(0, 3)
                        .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
                   Err(2));

        // test that it does not take more elements than it needs
        let functions = [|| Ok(()), || Err(1), || fail!()];

        assert_eq!(fold_(functions.iter()
                        .map(|f| (*f)())),
                   Err(1));
    }

    #[test]
    pub fn test_to_str() {
        let ok: Result<int, ~str> = Ok(100);
        let err: Result<int, ~str> = Err(~"Err");

        assert_eq!(ok.to_str(), ~"Ok(100)");
        assert_eq!(err.to_str(), ~"Err(Err)");
    }

    #[test]
    pub fn test_fmt_default() {
        let ok: Result<int, ~str> = Ok(100);
        let err: Result<int, ~str> = Err(~"Err");

        assert_eq!(format!("{}", ok), ~"Ok(100)");
        assert_eq!(format!("{}", err), ~"Err(Err)");
    }
}
<commit_msg>auto merge of #13475 : Ryman/rust/result_unwrap_or_else, r=brson<commit_after>// Copyright 2012-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.

//! Signaling success or failure states (`Result` type)

use clone::Clone;
use cmp::Eq;
use iter::{Iterator, FromIterator};
use option::{None, Option, Some};

/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Show)]
#[must_use]
pub enum Result<T, E> {
    /// Contains the success value
    Ok(T),

    /// Contains the error value
    Err(E)
}

/////////////////////////////////////////////////////////////////////////////
// Type implementation
/////////////////////////////////////////////////////////////////////////////

impl<T, E> Result<T, E> {
    /////////////////////////////////////////////////////////////////////////
    // Querying the contained values
    /////////////////////////////////////////////////////////////////////////

    /// Returns true if the result is `Ok`
    #[inline]
    pub fn is_ok(&self) -> bool {
        match *self {
            Ok(_) => true,
            Err(_) => false
        }
    }

    /// Returns true if the result is `Err`
    #[inline]
    pub fn is_err(&self) -> bool {
        !self.is_ok()
    }

    /////////////////////////////////////////////////////////////////////////
    // Adapter for each variant
    /////////////////////////////////////////////////////////////////////////

    /// Convert from `Result<T, E>` to `Option<T>`
    #[inline]
    pub fn ok(self) -> Option<T> {
        match self {
            Ok(x)  => Some(x),
            Err(_) => None,
        }
    }

    /// Convert from `Result<T, E>` to `Option<E>`
    #[inline]
    pub fn err(self) -> Option<E> {
        match self {
            Ok(_)  => None,
            Err(x) => Some(x),
        }
    }

    /////////////////////////////////////////////////////////////////////////
    // Adapter for working with references
    /////////////////////////////////////////////////////////////////////////

    /// Convert from `Result<T, E>` to `Result<&T, &E>`
    #[inline]
    pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
        match *self {
            Ok(ref x) => Ok(x),
            Err(ref x) => Err(x),
        }
    }

    /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
    #[inline]
    pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
        match *self {
            Ok(ref mut x) => Ok(x),
            Err(ref mut x) => Err(x),
        }
    }

    /////////////////////////////////////////////////////////////////////////
    // Transforming contained values
    /////////////////////////////////////////////////////////////////////////

    /// Maps a `Result<T, E>` to `Result<U, E>` by applying a function to an
    /// contained `Ok` value, leaving an `Err` value untouched.
    ///
    /// This function can be used to compose the results of two functions.
    ///
    /// Example:
    ///
    ///     let res = read_file(file).map(|buf| {
    ///         parse_bytes(buf)
    ///     })
    #[inline]
    pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
        match self {
          Ok(t) => Ok(op(t)),
          Err(e) => Err(e)
        }
    }

    /// Maps a `Result<T, E>` to `Result<T, F>` by applying a function to an
    /// contained `Err` value, leaving an `Ok` value untouched.
    ///
    /// This function can be used to pass through a successful result while handling
    /// an error.
    #[inline]
    pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
        match self {
          Ok(t) => Ok(t),
          Err(e) => Err(op(e))
        }
    }

    ////////////////////////////////////////////////////////////////////////
    // Boolean operations on the values, eager and lazy
    /////////////////////////////////////////////////////////////////////////

    /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
    #[inline]
    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
        match self {
            Ok(_) => res,
            Err(e) => Err(e),
        }
    }

    /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
    ///
    /// This function can be used for control flow based on result values
    #[inline]
    pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
        match self {
            Ok(t) => op(t),
            Err(e) => Err(e),
        }
    }

    /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
    #[inline]
    pub fn or(self, res: Result<T, E>) -> Result<T, E> {
        match self {
            Ok(_) => self,
            Err(_) => res,
        }
    }

    /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
    ///
    /// This function can be used for control flow based on result values
    #[inline]
    pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
        match self {
            Ok(t) => Ok(t),
            Err(e) => op(e),
        }
    }

    /////////////////////////////////////////////////////////////////////////
    // Common special cases
    /////////////////////////////////////////////////////////////////////////

    /// Unwraps a result, yielding the content of an `Ok`.
    /// Fails if the value is an `Err`.
    #[inline]
    pub fn unwrap(self) -> T {
        match self {
            Ok(t) => t,
            Err(_) => fail!("called `Result::unwrap()` on an `Err` value")
        }
    }

    /// Unwraps a result, yielding the content of an `Ok`.
    /// Else it returns `optb`.
    #[inline]
    pub fn unwrap_or(self, optb: T) -> T {
        match self {
            Ok(t) => t,
            Err(_) => optb
        }
    }

    /// Unwraps a result, yielding the content of an `Ok`.
    /// If the value is an `Err` then it calls `op` with its value.
    #[inline]
    pub fn unwrap_or_handle(self, op: |E| -> T) -> T {
        match self {
            Ok(t) => t,
            Err(e) => op(e)
        }
    }

    /// Unwraps a result, yielding the content of an `Err`.
    /// Fails if the value is an `Ok`.
    #[inline]
    pub fn unwrap_err(self) -> E {
        match self {
            Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"),
            Err(e) => e
        }
    }
}

/////////////////////////////////////////////////////////////////////////////
// Free functions
/////////////////////////////////////////////////////////////////////////////

/// Takes each element in the `Iterator`: if it is an `Err`, no further
/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
/// vector containing the values of each `Result` is returned.
///
/// Here is an example which increments every integer in a vector,
/// checking for overflow:
///
///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
///         if x == uint::MAX { return Err("overflow"); }
///         else { return Ok(x+1u); }
///     }
///     let v = [1u, 2, 3];
///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
///     assert!(res == Ok(~[2u, 3, 4]));
#[inline]
pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> {
    // FIXME(#11084): This should be twice as fast once this bug is closed.
    let mut iter = iter.scan(None, |state, x| {
        match x {
            Ok(x) => Some(x),
            Err(err) => {
                *state = Some(err);
                None
            }
        }
    });

    let v: V = FromIterator::from_iter(iter.by_ref());

    match iter.state {
        Some(err) => Err(err),
        None => Ok(v),
    }
}

/// Perform a fold operation over the result values from an iterator.
///
/// If an `Err` is encountered, it is immediately returned.
/// Otherwise, the folded value is returned.
#[inline]
pub fn fold<T,
            V,
            E,
            Iter: Iterator<Result<T, E>>>(
            mut iterator: Iter,
            mut init: V,
            f: |V, T| -> V)
            -> Result<V, E> {
    for t in iterator {
        match t {
            Ok(v) => init = f(init, v),
            Err(u) => return Err(u)
        }
    }
    Ok(init)
}

/// Perform a trivial fold operation over the result values
/// from an iterator.
///
/// If an `Err` is encountered, it is immediately returned.
/// Otherwise, a simple `Ok(())` is returned.
#[inline]
pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
    fold(iterator, (), |_, _| ())
}

/////////////////////////////////////////////////////////////////////////////
// Tests
/////////////////////////////////////////////////////////////////////////////

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

    use iter::range;

    pub fn op1() -> Result<int, ~str> { Ok(666) }
    pub fn op2() -> Result<int, ~str> { Err(~"sadface") }

    #[test]
    pub fn test_and() {
        assert_eq!(op1().and(Ok(667)).unwrap(), 667);
        assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad");

        assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
        assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface");
    }

    #[test]
    pub fn test_and_then() {
        assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
        assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");

        assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
        assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
    }

    #[test]
    pub fn test_or() {
        assert_eq!(op1().or(Ok(667)).unwrap(), 666);
        assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);

        assert_eq!(op2().or(Ok(667)).unwrap(), 667);
        assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
    }

    #[test]
    pub fn test_or_else() {
        assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
        assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);

        assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
        assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
    }

    #[test]
    pub fn test_impl_map() {
        assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab"));
        assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a"));
    }

    #[test]
    pub fn test_impl_map_err() {
        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a"));
        assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab"));
    }

    #[test]
    fn test_collect() {
        let v: Result<~[int], ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0)));
        assert_eq!(v, Ok(~[]));

        let v: Result<~[int], ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x)));
        assert_eq!(v, Ok(~[0, 1, 2]));

        let v: Result<~[int], int> = collect(range(0, 3)
                                             .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
        assert_eq!(v, Err(2));

        // test that it does not take more elements than it needs
        let functions = [|| Ok(()), || Err(1), || fail!()];

        let v: Result<~[()], int> = collect(functions.iter().map(|f| (*f)()));
        assert_eq!(v, Err(1));
    }

    #[test]
    fn test_fold() {
        assert_eq!(fold_(range(0, 0)
                        .map(|_| Ok::<(), ()>(()))),
                   Ok(()));
        assert_eq!(fold(range(0, 3)
                        .map(|x| Ok::<int, ()>(x)),
                        0, |a, b| a + b),
                   Ok(3));
        assert_eq!(fold_(range(0, 3)
                        .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
                   Err(2));

        // test that it does not take more elements than it needs
        let functions = [|| Ok(()), || Err(1), || fail!()];

        assert_eq!(fold_(functions.iter()
                        .map(|f| (*f)())),
                   Err(1));
    }

    #[test]
    pub fn test_to_str() {
        let ok: Result<int, ~str> = Ok(100);
        let err: Result<int, ~str> = Err(~"Err");

        assert_eq!(ok.to_str(), ~"Ok(100)");
        assert_eq!(err.to_str(), ~"Err(Err)");
    }

    #[test]
    pub fn test_fmt_default() {
        let ok: Result<int, ~str> = Ok(100);
        let err: Result<int, ~str> = Err(~"Err");

        assert_eq!(format!("{}", ok), ~"Ok(100)");
        assert_eq!(format!("{}", err), ~"Err(Err)");
    }

    #[test]
    pub fn test_unwrap_or() {
        let ok: Result<int, ~str> = Ok(100);
        let ok_err: Result<int, ~str> = Err(~"Err");

        assert_eq!(ok.unwrap_or(50), 100);
        assert_eq!(ok_err.unwrap_or(50), 50);
    }

    #[test]
    pub fn test_unwrap_or_else() {
        fn handler(msg: ~str) -> int {
            if msg == ~"I got this." {
                50
            } else {
                fail!("BadBad")
            }
        }

        let ok: Result<int, ~str> = Ok(100);
        let ok_err: Result<int, ~str> = Err(~"I got this.");

        assert_eq!(ok.unwrap_or_handle(handler), 100);
        assert_eq!(ok_err.unwrap_or_handle(handler), 50);
    }

    #[test]
    #[should_fail]
    pub fn test_unwrap_or_else_failure() {
        fn handler(msg: ~str) -> int {
            if msg == ~"I got this." {
                50
            } else {
                fail!("BadBad")
            }
        }

        let bad_err: Result<int, ~str> = Err(~"Unrecoverable mess.");
        let _ : int = bad_err.unwrap_or_handle(handler);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

/*! The Rust Runtime, including the task scheduler and I/O

The `rt` module provides the private runtime infrastructure necessary
to support core language features like the exchange and local heap,
the garbage collector, logging, local data and unwinding. It also
implements the default task scheduler and task model. Initialization
routines are provided for setting up runtime resources in common
configurations, including that used by `rustc` when generating
executables.

It is intended that the features provided by `rt` can be factored in a
way such that the core library can be built with different 'profiles'
for different use cases, e.g. excluding the task scheduler. A number
of runtime features though are critical to the functioning of the
language and an implementation must be provided regardless of the
execution environment.

Of foremost importance is the global exchange heap, in the module
`global_heap`. Very little practical Rust code can be written without
access to the global heap. Unlike most of `rt` the global heap is
truly a global resource and generally operates independently of the
rest of the runtime.

All other runtime features are task-local, including the local heap,
the garbage collector, local storage, logging and the stack unwinder.

The relationship between `rt` and the rest of the core library is
not entirely clear yet and some modules will be moving into or
out of `rt` as development proceeds.

Several modules in `core` are clients of `rt`:

* `core::task` - The user-facing interface to the Rust task model.
* `core::task::local_data` - The interface to local data.
* `core::gc` - The garbage collector.
* `core::unstable::lang` - Miscellaneous lang items, some of which rely on `core::rt`.
* `core::condition` - Uses local data.
* `core::cleanup` - Local heap destruction.
* `core::io` - In the future `core::io` will use an `rt` implementation.
* `core::logging`
* `core::pipes`
* `core::comm`
* `core::stackwalk`

*/

#[doc(hidden)];
#[deny(unused_imports)];
#[deny(unused_mut)];
#[deny(unused_variable)];

use cell::Cell;
use clone::Clone;
use container::Container;
use from_str::FromStr;
use iterator::IteratorUtil;
use option::{Some, None};
use os;
use ptr::RawPtr;
use uint;
use rt::sched::{Scheduler, Coroutine, Shutdown};
use rt::sleeper_list::SleeperList;
use rt::task::Task;
use rt::thread::Thread;
use rt::work_queue::WorkQueue;
use rt::uv::uvio::UvEventLoop;
use vec::{OwnedVector, MutableVector};

/// The global (exchange) heap.
pub mod global_heap;

/// Implementations of language-critical runtime features like @.
pub mod task;

/// The coroutine task scheduler, built on the `io` event loop.
mod sched;

/// Synchronous I/O.
#[path = "io/mod.rs"]
pub mod io;

/// The EventLoop and internal synchronous I/O interface.
mod rtio;

/// libuv and default rtio implementation.
#[path = "uv/mod.rs"]
pub mod uv;

/// The Local trait for types that are accessible via thread-local
/// or task-local storage.
pub mod local;

/// A parallel work-stealing deque.
mod work_queue;

/// A parallel queue.
mod message_queue;

/// A parallel data structure for tracking sleeping schedulers.
mod sleeper_list;

/// Stack segments and caching.
mod stack;

/// CPU context swapping.
mod context;

/// Bindings to system threading libraries.
mod thread;

/// The runtime configuration, read from environment variables
pub mod env;

/// The local, managed heap
mod local_heap;

/// The Logger trait and implementations
pub mod logging;

/// Tools for testing the runtime
pub mod test;

/// Reference counting
pub mod rc;

/// A simple single-threaded channel type for passing buffered data between
/// scheduler and task context
pub mod tube;

/// Simple reimplementation of core::comm
pub mod comm;

// FIXME #5248 shouldn't be pub
/// The runtime needs to be able to put a pointer into thread-local storage.
pub mod local_ptr;

// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
/// Bindings to pthread/windows thread-local storage.
pub mod thread_local_storage;

/// A concurrent data structure with which parent tasks wait on child tasks.
pub mod join_latch;

pub mod metrics;

// FIXME #5248 shouldn't be pub
/// Just stuff
pub mod util;

/// Set up a default runtime configuration, given compiler-supplied arguments.
///
/// This is invoked by the `start` _language item_ (unstable::lang) to
/// run a Rust executable.
///
/// # Arguments
///
/// * `argc` & `argv` - The argument vector. On Unix this information is used
///   by os::args.
/// * `crate_map` - Runtime information about the executing crate, mostly for logging
///
/// # Return value
///
/// The return value is used as the process return code. 0 on success, 101 on error.
pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {

    init(crate_map);
    run(main);
    cleanup();

    return 0;
}

/// One-time runtime initialization. Currently all this does is set up logging
/// based on the RUST_LOG environment variable.
pub fn init(crate_map: *u8) {
    logging::init(crate_map);
}

pub fn cleanup() {
    global_heap::cleanup();
}

pub fn run(main: ~fn()) {
    let nthreads = match os::getenv("RUST_THREADS") {
        Some(nstr) => FromStr::from_str(nstr).get(),
        None => unsafe {
            // Using more threads than cores in test code
            // to force the OS to preempt them frequently.
            // Assuming that this help stress test concurrent types.
            util::num_cpus() * 2
        }
    };

    let sleepers = SleeperList::new();
    let work_queue = WorkQueue::new();

    let mut handles = ~[];
    let mut scheds = ~[];

    for uint::range(0, nthreads) |_| {
        let loop_ = ~UvEventLoop::new();
        let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
        let handle = sched.make_handle();

        handles.push(handle);
        scheds.push(sched);
    }

    let main_cell = Cell::new(main);
    let handles = Cell::new(handles);
    let mut new_task = ~Task::new_root();
    let on_exit: ~fn(bool) = |exit_status| {

        let mut handles = handles.take();
        // Tell schedulers to exit
        for handles.mut_iter().advance |handle| {
            handle.send(Shutdown);
        }

        rtassert!(exit_status);
    };
    new_task.on_exit = Some(on_exit);
    let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool,
                                          new_task, main_cell.take());
    scheds[0].enqueue_task(main_task);

    let mut threads = ~[];

    while !scheds.is_empty() {
        let sched = scheds.pop();
        let sched_cell = Cell::new(sched);
        let thread = do Thread::start {
            let sched = sched_cell.take();
            sched.run();
        };

        threads.push(thread);
    }

    // Wait for schedulers
    let _threads = threads;
}

/// Possible contexts in which Rust code may be executing.
/// Different runtime services are available depending on context.
/// Mostly used for determining if we're using the new scheduler
/// or the old scheduler.
#[deriving(Eq)]
pub enum RuntimeContext {
    // Only the exchange heap is available
    GlobalContext,
    // The scheduler may be accessed
    SchedulerContext,
    // Full task services, e.g. local heap, unwinding
    TaskContext,
    // Running in an old-style task
    OldTaskContext
}

/// Determine the current RuntimeContext
pub fn context() -> RuntimeContext {

    use task::rt::rust_task;
    use self::local::Local;
    use self::sched::Scheduler;

    // XXX: Hitting TLS twice to check if the scheduler exists
    // then to check for the task is not good for perf
    if unsafe { rust_try_get_task().is_not_null() } {
        return OldTaskContext;
    } else {
        if Local::exists::<Scheduler>() {
            let context = Cell::new_empty();
            do Local::borrow::<Scheduler, ()> |sched| {
                if sched.in_task_context() {
                    context.put_back(TaskContext);
                } else {
                    context.put_back(SchedulerContext);
                }
            }
            return context.take();
        } else {
            return GlobalContext;
        }
    }

    pub extern {
        #[rust_stack]
        fn rust_try_get_task() -> *rust_task;
    }
}

#[test]
fn test_context() {
    use unstable::run_in_bare_thread;
    use self::sched::{Scheduler, Coroutine};
    use rt::local::Local;
    use rt::test::new_test_uv_sched;

    assert_eq!(context(), OldTaskContext);
    do run_in_bare_thread {
        assert_eq!(context(), GlobalContext);
        let mut sched = ~new_test_uv_sched();
        let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
            assert_eq!(context(), TaskContext);
            let sched = Local::take::<Scheduler>();
            do sched.deschedule_running_task_and_then() |sched, task| {
                assert_eq!(context(), SchedulerContext);
                sched.enqueue_task(task);
            }
        };
        sched.enqueue_task(task);
        sched.run();
    }
}
<commit_msg>std::rt: Set the process exit code<commit_after>// Copyright 2013 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.

/*! The Rust Runtime, including the task scheduler and I/O

The `rt` module provides the private runtime infrastructure necessary
to support core language features like the exchange and local heap,
the garbage collector, logging, local data and unwinding. It also
implements the default task scheduler and task model. Initialization
routines are provided for setting up runtime resources in common
configurations, including that used by `rustc` when generating
executables.

It is intended that the features provided by `rt` can be factored in a
way such that the core library can be built with different 'profiles'
for different use cases, e.g. excluding the task scheduler. A number
of runtime features though are critical to the functioning of the
language and an implementation must be provided regardless of the
execution environment.

Of foremost importance is the global exchange heap, in the module
`global_heap`. Very little practical Rust code can be written without
access to the global heap. Unlike most of `rt` the global heap is
truly a global resource and generally operates independently of the
rest of the runtime.

All other runtime features are task-local, including the local heap,
the garbage collector, local storage, logging and the stack unwinder.

The relationship between `rt` and the rest of the core library is
not entirely clear yet and some modules will be moving into or
out of `rt` as development proceeds.

Several modules in `core` are clients of `rt`:

* `core::task` - The user-facing interface to the Rust task model.
* `core::task::local_data` - The interface to local data.
* `core::gc` - The garbage collector.
* `core::unstable::lang` - Miscellaneous lang items, some of which rely on `core::rt`.
* `core::condition` - Uses local data.
* `core::cleanup` - Local heap destruction.
* `core::io` - In the future `core::io` will use an `rt` implementation.
* `core::logging`
* `core::pipes`
* `core::comm`
* `core::stackwalk`

*/

#[doc(hidden)];
#[deny(unused_imports)];
#[deny(unused_mut)];
#[deny(unused_variable)];

use cell::Cell;
use clone::Clone;
use container::Container;
use from_str::FromStr;
use iterator::IteratorUtil;
use option::{Some, None};
use os;
use ptr::RawPtr;
use uint;
use rt::sched::{Scheduler, Coroutine, Shutdown};
use rt::sleeper_list::SleeperList;
use rt::task::Task;
use rt::thread::Thread;
use rt::work_queue::WorkQueue;
use rt::uv::uvio::UvEventLoop;
use unstable::atomics::{AtomicInt, SeqCst};
use unstable::sync::UnsafeAtomicRcBox;
use vec::{OwnedVector, MutableVector};

/// The global (exchange) heap.
pub mod global_heap;

/// Implementations of language-critical runtime features like @.
pub mod task;

/// The coroutine task scheduler, built on the `io` event loop.
mod sched;

/// Synchronous I/O.
#[path = "io/mod.rs"]
pub mod io;

/// The EventLoop and internal synchronous I/O interface.
mod rtio;

/// libuv and default rtio implementation.
#[path = "uv/mod.rs"]
pub mod uv;

/// The Local trait for types that are accessible via thread-local
/// or task-local storage.
pub mod local;

/// A parallel work-stealing deque.
mod work_queue;

/// A parallel queue.
mod message_queue;

/// A parallel data structure for tracking sleeping schedulers.
mod sleeper_list;

/// Stack segments and caching.
mod stack;

/// CPU context swapping.
mod context;

/// Bindings to system threading libraries.
mod thread;

/// The runtime configuration, read from environment variables
pub mod env;

/// The local, managed heap
mod local_heap;

/// The Logger trait and implementations
pub mod logging;

/// Tools for testing the runtime
pub mod test;

/// Reference counting
pub mod rc;

/// A simple single-threaded channel type for passing buffered data between
/// scheduler and task context
pub mod tube;

/// Simple reimplementation of core::comm
pub mod comm;

// FIXME #5248 shouldn't be pub
/// The runtime needs to be able to put a pointer into thread-local storage.
pub mod local_ptr;

// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
/// Bindings to pthread/windows thread-local storage.
pub mod thread_local_storage;

/// A concurrent data structure with which parent tasks wait on child tasks.
pub mod join_latch;

pub mod metrics;

// FIXME #5248 shouldn't be pub
/// Just stuff
pub mod util;

/// Set up a default runtime configuration, given compiler-supplied arguments.
///
/// This is invoked by the `start` _language item_ (unstable::lang) to
/// run a Rust executable.
///
/// # Arguments
///
/// * `argc` & `argv` - The argument vector. On Unix this information is used
///   by os::args.
/// * `crate_map` - Runtime information about the executing crate, mostly for logging
///
/// # Return value
///
/// The return value is used as the process return code. 0 on success, 101 on error.
pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {

    init(crate_map);
    let exit_code = run(main);
    cleanup();

    return exit_code;
}

/// One-time runtime initialization. Currently all this does is set up logging
/// based on the RUST_LOG environment variable.
pub fn init(crate_map: *u8) {
    logging::init(crate_map);
}

pub fn cleanup() {
    global_heap::cleanup();
}

pub fn run(main: ~fn()) -> int {
    static DEFAULT_ERROR_CODE: int = 101;

    let nthreads = match os::getenv("RUST_THREADS") {
        Some(nstr) => FromStr::from_str(nstr).get(),
        None => unsafe {
            // Using more threads than cores in test code
            // to force the OS to preempt them frequently.
            // Assuming that this help stress test concurrent types.
            util::num_cpus() * 2
        }
    };

    let sleepers = SleeperList::new();
    let work_queue = WorkQueue::new();

    let mut handles = ~[];
    let mut scheds = ~[];

    for uint::range(0, nthreads) |_| {
        let loop_ = ~UvEventLoop::new();
        let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
        let handle = sched.make_handle();

        handles.push(handle);
        scheds.push(sched);
    }

    let exit_code = UnsafeAtomicRcBox::new(AtomicInt::new(0));
    let exit_code_clone = exit_code.clone();

    let main_cell = Cell::new(main);
    let handles = Cell::new(handles);
    let mut new_task = ~Task::new_root();
    let on_exit: ~fn(bool) = |exit_success| {

        let mut handles = handles.take();
        // Tell schedulers to exit
        for handles.mut_iter().advance |handle| {
            handle.send(Shutdown);
        }

        unsafe {
            let exit_code = if exit_success { 0 } else { DEFAULT_ERROR_CODE };
            (*exit_code_clone.get()).store(exit_code, SeqCst);
        }
    };
    new_task.on_exit = Some(on_exit);
    let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool,
                                          new_task, main_cell.take());
    scheds[0].enqueue_task(main_task);

    let mut threads = ~[];

    while !scheds.is_empty() {
        let sched = scheds.pop();
        let sched_cell = Cell::new(sched);
        let thread = do Thread::start {
            let sched = sched_cell.take();
            sched.run();
        };

        threads.push(thread);
    }

    // Wait for schedulers
    let _threads = threads;

    unsafe {
        (*exit_code.get()).load(SeqCst)
    }
}

/// Possible contexts in which Rust code may be executing.
/// Different runtime services are available depending on context.
/// Mostly used for determining if we're using the new scheduler
/// or the old scheduler.
#[deriving(Eq)]
pub enum RuntimeContext {
    // Only the exchange heap is available
    GlobalContext,
    // The scheduler may be accessed
    SchedulerContext,
    // Full task services, e.g. local heap, unwinding
    TaskContext,
    // Running in an old-style task
    OldTaskContext
}

/// Determine the current RuntimeContext
pub fn context() -> RuntimeContext {

    use task::rt::rust_task;
    use self::local::Local;
    use self::sched::Scheduler;

    // XXX: Hitting TLS twice to check if the scheduler exists
    // then to check for the task is not good for perf
    if unsafe { rust_try_get_task().is_not_null() } {
        return OldTaskContext;
    } else {
        if Local::exists::<Scheduler>() {
            let context = Cell::new_empty();
            do Local::borrow::<Scheduler, ()> |sched| {
                if sched.in_task_context() {
                    context.put_back(TaskContext);
                } else {
                    context.put_back(SchedulerContext);
                }
            }
            return context.take();
        } else {
            return GlobalContext;
        }
    }

    pub extern {
        #[rust_stack]
        fn rust_try_get_task() -> *rust_task;
    }
}

#[test]
fn test_context() {
    use unstable::run_in_bare_thread;
    use self::sched::{Scheduler, Coroutine};
    use rt::local::Local;
    use rt::test::new_test_uv_sched;

    assert_eq!(context(), OldTaskContext);
    do run_in_bare_thread {
        assert_eq!(context(), GlobalContext);
        let mut sched = ~new_test_uv_sched();
        let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
            assert_eq!(context(), TaskContext);
            let sched = Local::take::<Scheduler>();
            do sched.deschedule_running_task_and_then() |sched, task| {
                assert_eq!(context(), SchedulerContext);
                sched.enqueue_task(task);
            }
        };
        sched.enqueue_task(task);
        sched.run();
    }
}
<|endoftext|>