<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::sync::Arc;
use std::rc::Rc;
use std::cell::RefCell;
use std::borrow::Cow;
use std::string::String;
use std::path::{Path, PathBuf};
use dbus::{Connection, NameFlag};
use dbus::tree::{Factory, Tree, Property, MethodFn, MethodErr};
use dbus::MessageItem;
use dbus;
use dbus::Message;
use dbus::tree::MethodResult;

use dbus_consts::*;
use engine::Engine;

use types::{StratisResult, StratisError};

#[derive(Debug, Clone)]
pub struct DbusContext<'a> {
    name_prop: Arc<Property<MethodFn<'a>>>,
    pub remaining_prop: Arc<Property<MethodFn<'a>>>,
    pub total_prop: Arc<Property<MethodFn<'a>>>,
    pub status_prop: Arc<Property<MethodFn<'a>>>,
    pub running_status_prop: Arc<Property<MethodFn<'a>>>,
    pub block_devices_prop: Arc<Property<MethodFn<'a>>>,
}

impl<'a> DbusContext<'a> {
    pub fn update_one(prop: &Arc<Property<MethodFn<'a>>>, m: MessageItem) -> StratisResult<()> {
        match prop.set_value(m) {
            Ok(_) => Ok(()), // TODO: return signals
            Err(()) => Err(StratisError::Dbus(dbus::Error::new_custom(
                "UpdateError", "Could not update property with value"))),
        }
    }
}

fn listpools(m: &Message) -> MethodResult {

    m.method_return().append2("pool1", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool2", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool3", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool4", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool5", StratisErrorEnum::STRATIS_OK as i32);
    Ok(vec![m.method_return()])
}

fn createpool(m: &Message, engine: Rc<RefCell<Engine>>) -> MethodResult {

    let mut items = m.get_items();
    if items.len() < 1 {
        return Err(MethodErr::no_arg());
    }

    let raid_level: u16 = try!(items.pop()
        .ok_or_else(MethodErr::no_arg)
        .and_then(|i| {
            i.inner()
                .map_err(|_| MethodErr::invalid_arg(&i))
        }));

    let devs = match try!(items.pop().ok_or_else(MethodErr::no_arg)) {
        MessageItem::Array(x, _) => x,
        x => return Err(MethodErr::invalid_arg(&x)),
    };

    // Get the name of the pool from the parameters
    let name = try!(items.pop()
        .ok_or_else(MethodErr::no_arg)
        .and_then(|i| {
            i.inner::<&str>()
                .map_err(|_| MethodErr::invalid_arg(&i))
                .map(|i| i.to_owned())
        }));

    // TODO: figure out how to convert devs to &[], or should
    // we be using PathBuf like Foryo does?
    let result = engine.borrow().create_pool(&name, &[], raid_level);

    Ok(vec![m.method_return().append3("/dbus/newpool/path", 0, "Ok")])
}

fn destroypool(m: &Message) -> MethodResult {

    Ok(vec![m.method_return().append3("/dbus/pool/path", 0, "Ok")])
}

fn getpoolobjectpath(m: &Message) -> MethodResult {

    Ok(vec![m.method_return().append3("/dbus/pool/path", 0, "Ok")])
}

fn getvolumeobjectpath(m: &Message) -> MethodResult {
    Ok(vec![m.method_return().append3("/dbus/volume/path", 0, "Ok")])
}

fn getdevobjectpath(m: &Message) -> MethodResult {
    Ok(vec![m.method_return().append3("/dbus/dev/path", 0, "Ok")])
}

fn getcacheobjectpath(m: &Message) -> MethodResult {
    Ok(vec![m.method_return().append3("/dbus/cache/path", 0, "Ok")])
}

fn geterrorcodes(m: &Message) -> MethodResult {
    let mut msg_vec = Vec::new();

    for error in StratisErrorEnum::iterator() {

        let entry = vec![MessageItem::Str(format!("{}", error)),
                         MessageItem::UInt16(StratisErrorEnum::get_error_int(error)),
                         MessageItem::Str(String::from(StratisErrorEnum::get_error_string(error)))];

        msg_vec.push(MessageItem::Struct(entry));

    }

    let item_array = MessageItem::Array(msg_vec, Cow::Borrowed("(sqs)"));

    Ok(vec![m.method_return().append1(item_array)])

}

fn getraidlevels(m: &Message) -> MethodResult {

    let mut msg_vec = Vec::new();

    for raid_type in StratisRaidType::iterator() {

        let entry = vec![MessageItem::Str(format!("{}", raid_type)),
                 MessageItem::UInt16(StratisRaidType::get_error_int(raid_type)),
                 MessageItem::Str(String::from(StratisRaidType::get_error_string(raid_type)))];

        let item = MessageItem::Struct(entry);

        msg_vec.push(item);

    }

    let item_array = MessageItem::Array(msg_vec, Cow::Borrowed("(sqs)"));

    Ok(vec![m.method_return().append1(item_array)])
}

fn getdevtypes(m: &Message) -> MethodResult {
    let mut items = m.get_items();
    if items.len() < 1 {
        return Err(MethodErr::no_arg());
    }

    let _name = try!(items.pop()
        .ok_or_else(MethodErr::no_arg)
        .and_then(|i| {
            i.inner::<&str>()
                .map_err(|_| MethodErr::invalid_arg(&i))
                .map(|i| i.to_owned())
        }));

    println!("method called");

    Ok(vec![m.method_return()])
}

pub fn get_base_tree<'a>(c: &'a Connection,
                         engine: Rc<RefCell<Engine>>)
                         -> StratisResult<Tree<MethodFn<'a>>> {
    c.register_name(STRATIS_BASE_SERVICE, NameFlag::ReplaceExisting as u32).unwrap();

    let f = Factory::new_fn();

    let base_tree = f.tree();

    let listpools_method = f.method(LIST_POOLS, move |m, _, _| listpools(m))
        .out_arg(("pool_names", "as"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let createpool_method = f.method(CREATE_POOL, move |m, _, _| createpool(m, engine.clone()))
        .in_arg(("pool_name", "s"))
        .in_arg(("dev_list", "as"))
        .in_arg(("raid_type", "q"))
        .out_arg(("object_path", "s"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let destroypool_method = f.method(DESTROY_POOL, move |m, _, _| destroypool(m))
        .in_arg(("pool_name", "s"))
        .out_arg(("object_path", "o"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let getpoolobjectpath_method =
        f.method(GET_POOL_OBJECT_PATH, move |m, _, _| getpoolobjectpath(m))
            .in_arg(("pool_name", "s"))
            .out_arg(("object_path", "o"))
            .out_arg(("return_code", "q"))
            .out_arg(("return_string", "s"));

    let getvolumeobjectpath_method = f.method(GET_VOLUME_OBJECT_PATH,
                move |m, _, _| getvolumeobjectpath(m))
        .in_arg(("pool_name", "s"))
        .in_arg(("volume_name", "s"))
        .out_arg(("object_path", "o"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let getdevobjectpath_method = f.method(GET_DEV_OBJECT_PATH, move |m, _, _| getdevobjectpath(m))
        .in_arg(("dev_name", "s"))
        .out_arg(("object_path", "o"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let getcacheobjectpath_method =
        f.method(GET_CACHE_OBJECT_PATH, move |m, _, _| getcacheobjectpath(m))
            .in_arg(("cache_dev_name", "s"))
            .out_arg(("object_path", "o"))
            .out_arg(("return_code", "q"))
            .out_arg(("return_string", "s"));

    let geterrorcodes_method = f.method(GET_ERROR_CODES, move |m, _, _| geterrorcodes(m))
        .out_arg(("error_codes", "a(sqs)"));

    let getraidlevels_method = f.method(GET_RAID_LEVELS, move |m, _, _| getraidlevels(m))
        .out_arg(("error_codes", "a(sqs)"));

    let getdevtypes_method = f.method(GET_DEV_TYPES, move |m, _, _| getdevtypes(m));

    let obj_path = f.object_path(STRATIS_BASE_PATH)
        .introspectable()
        .add(f.interface(STRATIS_MANAGER_INTERFACE)
            .add_m(listpools_method)
            .add_m(createpool_method)
            .add_m(destroypool_method)
            .add_m(getpoolobjectpath_method)
            .add_m(getvolumeobjectpath_method)
            .add_m(getdevobjectpath_method)
            .add_m(getcacheobjectpath_method)
            .add_m(geterrorcodes_method)
            .add_m(getraidlevels_method)
            .add_m(getdevtypes_method));

    let base_tree = base_tree.add(obj_path);
    try!(base_tree.set_registered(c, true));

    Ok(base_tree)
}
<commit_msg>Alphabetize use directives.<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::borrow::Cow;
use std::cell::RefCell;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::string::String;
use std::sync::Arc;

use dbus;

use dbus::Connection;
use dbus::Message;
use dbus::MessageItem;
use dbus::NameFlag;

use dbus::tree::Factory;
use dbus::tree::MethodErr;
use dbus::tree::MethodFn;
use dbus::tree::MethodResult;
use dbus::tree::Property;
use dbus::tree::Tree;

use dbus_consts::*;

use engine::Engine;

use types::{StratisResult, StratisError};

#[derive(Debug, Clone)]
pub struct DbusContext<'a> {
    name_prop: Arc<Property<MethodFn<'a>>>,
    pub remaining_prop: Arc<Property<MethodFn<'a>>>,
    pub total_prop: Arc<Property<MethodFn<'a>>>,
    pub status_prop: Arc<Property<MethodFn<'a>>>,
    pub running_status_prop: Arc<Property<MethodFn<'a>>>,
    pub block_devices_prop: Arc<Property<MethodFn<'a>>>,
}

impl<'a> DbusContext<'a> {
    pub fn update_one(prop: &Arc<Property<MethodFn<'a>>>, m: MessageItem) -> StratisResult<()> {
        match prop.set_value(m) {
            Ok(_) => Ok(()), // TODO: return signals
            Err(()) => Err(StratisError::Dbus(dbus::Error::new_custom(
                "UpdateError", "Could not update property with value"))),
        }
    }
}

fn listpools(m: &Message) -> MethodResult {

    m.method_return().append2("pool1", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool2", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool3", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool4", StratisErrorEnum::STRATIS_OK as i32);
    m.method_return().append2("pool5", StratisErrorEnum::STRATIS_OK as i32);
    Ok(vec![m.method_return()])
}

fn createpool(m: &Message, engine: Rc<RefCell<Engine>>) -> MethodResult {

    let mut items = m.get_items();
    if items.len() < 1 {
        return Err(MethodErr::no_arg());
    }

    let raid_level: u16 = try!(items.pop()
        .ok_or_else(MethodErr::no_arg)
        .and_then(|i| {
            i.inner()
                .map_err(|_| MethodErr::invalid_arg(&i))
        }));

    let devs = match try!(items.pop().ok_or_else(MethodErr::no_arg)) {
        MessageItem::Array(x, _) => x,
        x => return Err(MethodErr::invalid_arg(&x)),
    };

    // Get the name of the pool from the parameters
    let name = try!(items.pop()
        .ok_or_else(MethodErr::no_arg)
        .and_then(|i| {
            i.inner::<&str>()
                .map_err(|_| MethodErr::invalid_arg(&i))
                .map(|i| i.to_owned())
        }));

    // TODO: figure out how to convert devs to &[], or should
    // we be using PathBuf like Foryo does?
    let result = engine.borrow().create_pool(&name, &[], raid_level);

    Ok(vec![m.method_return().append3("/dbus/newpool/path", 0, "Ok")])
}

fn destroypool(m: &Message) -> MethodResult {

    Ok(vec![m.method_return().append3("/dbus/pool/path", 0, "Ok")])
}

fn getpoolobjectpath(m: &Message) -> MethodResult {

    Ok(vec![m.method_return().append3("/dbus/pool/path", 0, "Ok")])
}

fn getvolumeobjectpath(m: &Message) -> MethodResult {
    Ok(vec![m.method_return().append3("/dbus/volume/path", 0, "Ok")])
}

fn getdevobjectpath(m: &Message) -> MethodResult {
    Ok(vec![m.method_return().append3("/dbus/dev/path", 0, "Ok")])
}

fn getcacheobjectpath(m: &Message) -> MethodResult {
    Ok(vec![m.method_return().append3("/dbus/cache/path", 0, "Ok")])
}

fn geterrorcodes(m: &Message) -> MethodResult {
    let mut msg_vec = Vec::new();

    for error in StratisErrorEnum::iterator() {

        let entry = vec![MessageItem::Str(format!("{}", error)),
                         MessageItem::UInt16(StratisErrorEnum::get_error_int(error)),
                         MessageItem::Str(String::from(StratisErrorEnum::get_error_string(error)))];

        msg_vec.push(MessageItem::Struct(entry));

    }

    let item_array = MessageItem::Array(msg_vec, Cow::Borrowed("(sqs)"));

    Ok(vec![m.method_return().append1(item_array)])

}

fn getraidlevels(m: &Message) -> MethodResult {

    let mut msg_vec = Vec::new();

    for raid_type in StratisRaidType::iterator() {

        let entry = vec![MessageItem::Str(format!("{}", raid_type)),
                 MessageItem::UInt16(StratisRaidType::get_error_int(raid_type)),
                 MessageItem::Str(String::from(StratisRaidType::get_error_string(raid_type)))];

        let item = MessageItem::Struct(entry);

        msg_vec.push(item);

    }

    let item_array = MessageItem::Array(msg_vec, Cow::Borrowed("(sqs)"));

    Ok(vec![m.method_return().append1(item_array)])
}

fn getdevtypes(m: &Message) -> MethodResult {
    let mut items = m.get_items();
    if items.len() < 1 {
        return Err(MethodErr::no_arg());
    }

    let _name = try!(items.pop()
        .ok_or_else(MethodErr::no_arg)
        .and_then(|i| {
            i.inner::<&str>()
                .map_err(|_| MethodErr::invalid_arg(&i))
                .map(|i| i.to_owned())
        }));

    println!("method called");

    Ok(vec![m.method_return()])
}

pub fn get_base_tree<'a>(c: &'a Connection,
                         engine: Rc<RefCell<Engine>>)
                         -> StratisResult<Tree<MethodFn<'a>>> {
    c.register_name(STRATIS_BASE_SERVICE, NameFlag::ReplaceExisting as u32).unwrap();

    let f = Factory::new_fn();

    let base_tree = f.tree();

    let listpools_method = f.method(LIST_POOLS, move |m, _, _| listpools(m))
        .out_arg(("pool_names", "as"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let createpool_method = f.method(CREATE_POOL, move |m, _, _| createpool(m, engine.clone()))
        .in_arg(("pool_name", "s"))
        .in_arg(("dev_list", "as"))
        .in_arg(("raid_type", "q"))
        .out_arg(("object_path", "s"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let destroypool_method = f.method(DESTROY_POOL, move |m, _, _| destroypool(m))
        .in_arg(("pool_name", "s"))
        .out_arg(("object_path", "o"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let getpoolobjectpath_method =
        f.method(GET_POOL_OBJECT_PATH, move |m, _, _| getpoolobjectpath(m))
            .in_arg(("pool_name", "s"))
            .out_arg(("object_path", "o"))
            .out_arg(("return_code", "q"))
            .out_arg(("return_string", "s"));

    let getvolumeobjectpath_method = f.method(GET_VOLUME_OBJECT_PATH,
                move |m, _, _| getvolumeobjectpath(m))
        .in_arg(("pool_name", "s"))
        .in_arg(("volume_name", "s"))
        .out_arg(("object_path", "o"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let getdevobjectpath_method = f.method(GET_DEV_OBJECT_PATH, move |m, _, _| getdevobjectpath(m))
        .in_arg(("dev_name", "s"))
        .out_arg(("object_path", "o"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let getcacheobjectpath_method =
        f.method(GET_CACHE_OBJECT_PATH, move |m, _, _| getcacheobjectpath(m))
            .in_arg(("cache_dev_name", "s"))
            .out_arg(("object_path", "o"))
            .out_arg(("return_code", "q"))
            .out_arg(("return_string", "s"));

    let geterrorcodes_method = f.method(GET_ERROR_CODES, move |m, _, _| geterrorcodes(m))
        .out_arg(("error_codes", "a(sqs)"));

    let getraidlevels_method = f.method(GET_RAID_LEVELS, move |m, _, _| getraidlevels(m))
        .out_arg(("error_codes", "a(sqs)"));

    let getdevtypes_method = f.method(GET_DEV_TYPES, move |m, _, _| getdevtypes(m));

    let obj_path = f.object_path(STRATIS_BASE_PATH)
        .introspectable()
        .add(f.interface(STRATIS_MANAGER_INTERFACE)
            .add_m(listpools_method)
            .add_m(createpool_method)
            .add_m(destroypool_method)
            .add_m(getpoolobjectpath_method)
            .add_m(getvolumeobjectpath_method)
            .add_m(getdevobjectpath_method)
            .add_m(getcacheobjectpath_method)
            .add_m(geterrorcodes_method)
            .add_m(getraidlevels_method)
            .add_m(getdevtypes_method));

    let base_tree = base_tree.add(obj_path);
    try!(base_tree.set_registered(c, true));

    Ok(base_tree)
}
<|endoftext|>


<commit_before><commit_msg>basic document module with Document struct and impl<commit_after>pub struct Document;

impl Document {
    pub fn new(path: &Path) {
        println!("Creating Document from path {}", path.as_str().unwrap());
    }
}
<|endoftext|>


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

impl Undefined {}
//~^ ERROR use of undeclared type name `Undefined`

fn main() {}
<|endoftext|>


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

// Regression test for issue #28586

pub trait Foo {}
impl Foo for [u8; usize::BYTES] {} //~ ERROR E0250

fn main() { }
<|endoftext|>


<commit_before>// xfail-stage0

mod test_single_attr_outer {

    #[attr = "val"]
    const int x = 10;

    #[attr = "val"]
    fn f() {}

    #[attr = "val"]
    mod mod1 {
    }

    #[attr = "val"]
    native "rust" mod rustrt { }

    #[attr = "val"]
    type t = obj { };

    #[attr = "val"]
    obj o() { }
}

mod test_multi_attr_outer {

    #[attr1 = "val"]
    #[attr2 = "val"]
    const int x = 10;

    #[attr1 = "val"]
    #[attr2 = "val"]
    fn f() {}

    #[attr1 = "val"]
    #[attr2 = "val"]
    mod mod1 {
    }

    #[attr1 = "val"]
    #[attr2 = "val"]
    native "rust" mod rustrt { }

    #[attr1 = "val"]
    #[attr2 = "val"]
    type t = obj { };

    #[attr1 = "val"]
    #[attr2 = "val"]
    obj o() { }
}

mod test_stmt_single_attr_outer {

    fn f() {

        #[attr = "val"]
        const int x = 10;

        #[attr = "val"]
        fn f() {}

        /* FIXME: Issue #493
        #[attr = "val"]
        mod mod1 {
        }

        #[attr = "val"]
        native "rust" mod rustrt {
        }
        */

        #[attr = "val"]
        type t = obj { };

        #[attr = "val"]
        obj o() { }

    }
}

mod test_stmt_multi_attr_outer {

    fn f() {

        #[attr1 = "val"]
        #[attr2 = "val"]
        const int x = 10;

        #[attr1 = "val"]
        #[attr2 = "val"]
        fn f() {}

        /* FIXME: Issue #493
        #[attr1 = "val"]
        #[attr2 = "val"]
        mod mod1 {
        }

        #[attr1 = "val"]
        #[attr2 = "val"]
        native "rust" mod rustrt {
        }
        */

        #[attr1 = "val"]
        #[attr2 = "val"]
        type t = obj { };

        #[attr1 = "val"]
        #[attr2 = "val"]
        obj o() { }

    }
}

mod test_attr_inner {

    mod m {
        // This is an attribute of mod m
        #[attr = "val"];
    }
}

mod test_attr_inner_then_outer {

    mod m {
        // This is an attribute of mod m
        #[attr = "val"];
        // This is an attribute of fn f
        #[attr = "val"]
        fn f() {
        }
    }
}

mod test_attr_inner_then_outer_multi {
    mod m {
        // This is an attribute of mod m
        #[attr1 = "val"];
        #[attr2 = "val"];
        // This is an attribute of fn f
        #[attr1 = "val"]
        #[attr2 = "val"]
        fn f() {
        }
    }
}

fn main() {
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>test: Add a test for outer attributes on the first module in a file<commit_after>// xfail-stage0

// These are are attributes of the following mod
#[attr1 = "val"]
#[attr2 = "val"]
mod test_first_item_in_file_mod {
}

mod test_single_attr_outer {

    #[attr = "val"]
    const int x = 10;

    #[attr = "val"]
    fn f() {}

    #[attr = "val"]
    mod mod1 {
    }

    #[attr = "val"]
    native "rust" mod rustrt { }

    #[attr = "val"]
    type t = obj { };

    #[attr = "val"]
    obj o() { }
}

mod test_multi_attr_outer {

    #[attr1 = "val"]
    #[attr2 = "val"]
    const int x = 10;

    #[attr1 = "val"]
    #[attr2 = "val"]
    fn f() {}

    #[attr1 = "val"]
    #[attr2 = "val"]
    mod mod1 {
    }

    #[attr1 = "val"]
    #[attr2 = "val"]
    native "rust" mod rustrt { }

    #[attr1 = "val"]
    #[attr2 = "val"]
    type t = obj { };

    #[attr1 = "val"]
    #[attr2 = "val"]
    obj o() { }
}

mod test_stmt_single_attr_outer {

    fn f() {

        #[attr = "val"]
        const int x = 10;

        #[attr = "val"]
        fn f() {}

        /* FIXME: Issue #493
        #[attr = "val"]
        mod mod1 {
        }

        #[attr = "val"]
        native "rust" mod rustrt {
        }
        */

        #[attr = "val"]
        type t = obj { };

        #[attr = "val"]
        obj o() { }

    }
}

mod test_stmt_multi_attr_outer {

    fn f() {

        #[attr1 = "val"]
        #[attr2 = "val"]
        const int x = 10;

        #[attr1 = "val"]
        #[attr2 = "val"]
        fn f() {}

        /* FIXME: Issue #493
        #[attr1 = "val"]
        #[attr2 = "val"]
        mod mod1 {
        }

        #[attr1 = "val"]
        #[attr2 = "val"]
        native "rust" mod rustrt {
        }
        */

        #[attr1 = "val"]
        #[attr2 = "val"]
        type t = obj { };

        #[attr1 = "val"]
        #[attr2 = "val"]
        obj o() { }

    }
}

mod test_attr_inner {

    mod m {
        // This is an attribute of mod m
        #[attr = "val"];
    }
}

mod test_attr_inner_then_outer {

    mod m {
        // This is an attribute of mod m
        #[attr = "val"];
        // This is an attribute of fn f
        #[attr = "val"]
        fn f() {
        }
    }
}

mod test_attr_inner_then_outer_multi {
    mod m {
        // This is an attribute of mod m
        #[attr1 = "val"];
        #[attr2 = "val"];
        // This is an attribute of fn f
        #[attr1 = "val"]
        #[attr2 = "val"]
        fn f() {
        }
    }
}

fn main() {
}

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


<commit_before><commit_msg>[No-auto] lib/domain/todo: Fix Clippy warnings<commit_after><|endoftext|>


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

//! Vertex attribute types.
//!
//! Nothing interesting here for users.

#![allow(missing_doc)]

pub type Count = u8;    // only value 1 to 4 are supported
pub type Offset = u32;  // can point in the middle of the buffer
pub type Stride = u8;   // I don't believe HW supports more

#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum SignFlag {
    Signed,
    Unsigned,
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum IntSubType {
    IntRaw,         // un-processed integer
    IntNormalized,  // normalized either to [0,1] or [-1,1] depending on the sign flag
    IntAsFloat,     // converted to float on the fly by the hardware
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum IntSize {
    U8,
    U16,
    U32,
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum FloatSubType {
    FloatDefault,    // 32-bit
    FloatPrecision,  // 64-bit
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum FloatSize {
    F16,
    F32,
    F64,
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
pub enum Type {
    Int(IntSubType, IntSize, SignFlag),
    Float(FloatSubType, FloatSize),
    Special,
}

impl Type {
    pub fn is_compatible(&self, bt: super::shade::BaseType) -> Result<(), ()> {
        use super::shade as s;
        match (*self, bt) {
            (Int(IntRaw, _, _), s::BaseI32) => Ok(()),
            (Int(IntRaw, _, Unsigned), s::BaseU32) => Ok(()),
            (Int(IntRaw, _, _), _) => Err(()),
            (Int(_, _, _), s::BaseF32) => Ok(()),
            (Int(_, _, _), _) => Err(()),
            (Float(_, _), s::BaseF32) => Ok(()),
            (Float(FloatPrecision, F64), s::BaseF64) => Ok(()),
            (Float(_, _), _) => Err(()),
            (_, s::BaseF64) => Err(()),
            (_, s::BaseBool) => Err(()),
            _ => Err(()),
        }
    }
}
<commit_msg>Added comments to our device attributes<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Vertex attribute types.

#![allow(missing_doc)]

/// Number of elements per attribute, only 1 to 4 are supported
pub type Count = u8;
/// Offset of an attribute from the start of the buffer, in bytes
pub type Offset = u32;
/// Offset between attribute values, in bytes
pub type Stride = u8;
/// The number of instances between each subsequent attribute value
pub type InstanceRate = u8;

/// Signness of the attribute
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum SignFlag {
    Signed,
    Unsigned,
}

/// How integer values are interpreted for the shader
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum IntSubType {
    IntRaw,         // un-processed integer
    IntNormalized,  // normalized either to [0,1] or [-1,1] depending on the sign flag
    IntAsFloat,     // converted to float on the fly by the hardware
}

/// Size of an integer attribute, in bits
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum IntSize {
    U8,
    U16,
    U32,
}

/// Type of a floating-point attribute on the shader side.
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum FloatSubType {
    FloatDefault,    // 32-bit
    FloatPrecision,  // 64-bit
}

/// Size of a floating point attribute, in bits
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
#[repr(u8)]
pub enum FloatSize {
    F16,
    F32,
    F64,
}

/// Type of an attribute
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Show)]
pub enum Type {
    Int(IntSubType, IntSize, SignFlag),
    Float(FloatSubType, FloatSize),
    Special,
}

impl Type {
    /// Check if the attribute is compatible with a particular shader type
    pub fn is_compatible(&self, bt: super::shade::BaseType) -> Result<(), ()> {
        use super::shade as s;
        match (*self, bt) {
            (Int(IntRaw, _, _), s::BaseI32) => Ok(()),
            (Int(IntRaw, _, Unsigned), s::BaseU32) => Ok(()),
            (Int(IntRaw, _, _), _) => Err(()),
            (Int(_, _, _), s::BaseF32) => Ok(()),
            (Int(_, _, _), _) => Err(()),
            (Float(_, _), s::BaseF32) => Ok(()),
            (Float(FloatPrecision, F64), s::BaseF64) => Ok(()),
            (Float(_, _), _) => Err(()),
            (_, s::BaseF64) => Err(()),
            (_, s::BaseBool) => Err(()),
            _ => Err(()),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Slightly modify even more stats text<commit_after><|endoftext|>


<commit_before><commit_msg>epoll_ctl returns Result<()>, not result<something><commit_after><|endoftext|>


<commit_before>use std::intrinsics::TypeId;

use input;

use {
    RenderArgs,
    RenderEvent,
    UpdateArgs,
    UpdateEvent,
    GenericEvent,
};
use Event::{ Render, Update, Input };
use ptr::Ptr;
use events::EventMap;

/// Adds render and update events to input events
#[deriving(Clone, PartialEq, Show)]
pub enum Event<I = input::Input> {
    /// Render graphics.
    Render(RenderArgs),
    /// Update the state of the application.
    Update(UpdateArgs),
    /// Input event.
    Input(I),
}

impl<I> EventMap<I> for Event<I> {
    fn render(args: RenderArgs) -> Event<I> { Render(args) }
    fn update(args: UpdateArgs) -> Event<I> { Update(args) }
    fn input(args: I) -> Event<I> { Input(args) }
}

impl<I: GenericEvent> GenericEvent for Event<I> {
    #[inline(always)]
    fn from_event(event_trait_id: TypeId, ev: &Ptr) -> Option<Event<I>> {
        let update = TypeId::of::<Box<UpdateEvent>>();
        let render = TypeId::of::<Box<RenderEvent>>();
        match event_trait_id {
            x if x == update => {
                Some(Update(ev.expect::<UpdateArgs>().clone()))
            }
            x if x == render => {
                Some(Render(ev.expect::<RenderArgs>().clone()))
            }
            _ => {
                let input: Option<I> = GenericEvent::from_event(
                    event_trait_id, ev
                );
                match input {
                    Some(input) => Some(Input(input)),
                    None => None
                }
            }
        }
    }

    #[inline(always)]
    fn with_event<U>(&self, event_trait_id: TypeId, f: |&Ptr| -> U) -> Option<U> {
        let update = TypeId::of::<Box<UpdateEvent>>();
        let render = TypeId::of::<Box<RenderEvent>>();
        match event_trait_id {
            x if x == update => {
                match *self {
                    Update(ref args) => Some(Ptr::with_ref(args, |ptr| f(ptr))),
                    _ => None
                }
            }
            x if x == render => {
                match *self {
                    Render(ref args) => Some(Ptr::with_ref(args, |ptr| f(ptr))),
                    _ => None
                }
            }
            _ => {
                match *self {
                    Input(ref input) => input.with_event(event_trait_id, f),
                    _ => None
                }
            }
        }
    }
}

#[test]
fn test_event() {
    use assert_event_trait;
    use MouseCursorEvent;

    // Update.
    let ref e = UpdateEvent::from_update_args(&UpdateArgs { dt: 1.0 }).unwrap();
    assert_event_trait::<Event, Box<UpdateEvent>>(e);

    // Render.
    let ref e = RenderEvent::from_render_args(
        &RenderArgs { ext_dt: 1.0, width: 0, height: 0 }
    ).unwrap();
    assert_event_trait::<Event, Box<RenderEvent>>(e);

    let ref e = MouseCursorEvent::from_xy(1.0, 0.0).unwrap();
    assert_event_trait::<Event, Box<MouseCursorEvent>>(e);
}
<commit_msg>Upgrade to latest Rust<commit_after>use std::intrinsics::TypeId;

use input;

use {
    RenderArgs,
    RenderEvent,
    UpdateArgs,
    UpdateEvent,
    GenericEvent,
};
use Event::{ Render, Update, Input };
use ptr::Ptr;
use events::EventMap;

/// Adds render and update events to input events
#[derive(Clone, PartialEq, Show)]
pub enum Event<I = input::Input> {
    /// Render graphics.
    Render(RenderArgs),
    /// Update the state of the application.
    Update(UpdateArgs),
    /// Input event.
    Input(I),
}

impl<I> EventMap<I> for Event<I> {
    fn render(args: RenderArgs) -> Event<I> { Render(args) }
    fn update(args: UpdateArgs) -> Event<I> { Update(args) }
    fn input(args: I) -> Event<I> { Input(args) }
}

impl<I: GenericEvent> GenericEvent for Event<I> {
    #[inline(always)]
    fn from_event(event_trait_id: TypeId, ev: &Ptr) -> Option<Event<I>> {
        let update = TypeId::of::<Box<UpdateEvent>>();
        let render = TypeId::of::<Box<RenderEvent>>();
        match event_trait_id {
            x if x == update => {
                Some(Update(ev.expect::<UpdateArgs>().clone()))
            }
            x if x == render => {
                Some(Render(ev.expect::<RenderArgs>().clone()))
            }
            _ => {
                let input: Option<I> = GenericEvent::from_event(
                    event_trait_id, ev
                );
                match input {
                    Some(input) => Some(Input(input)),
                    None => None
                }
            }
        }
    }

    #[inline(always)]
    fn with_event<U>(&self, event_trait_id: TypeId, f: |&Ptr| -> U) -> Option<U> {
        let update = TypeId::of::<Box<UpdateEvent>>();
        let render = TypeId::of::<Box<RenderEvent>>();
        match event_trait_id {
            x if x == update => {
                match *self {
                    Update(ref args) => Some(Ptr::with_ref(args, |ptr| f(ptr))),
                    _ => None
                }
            }
            x if x == render => {
                match *self {
                    Render(ref args) => Some(Ptr::with_ref(args, |ptr| f(ptr))),
                    _ => None
                }
            }
            _ => {
                match *self {
                    Input(ref input) => input.with_event(event_trait_id, f),
                    _ => None
                }
            }
        }
    }
}

#[test]
fn test_event() {
    use assert_event_trait;
    use MouseCursorEvent;

    // Update.
    let ref e = UpdateEvent::from_update_args(&UpdateArgs { dt: 1.0 }).unwrap();
    assert_event_trait::<Event, Box<UpdateEvent>>(e);

    // Render.
    let ref e = RenderEvent::from_render_args(
        &RenderArgs { ext_dt: 1.0, width: 0, height: 0 }
    ).unwrap();
    assert_event_trait::<Event, Box<RenderEvent>>(e);

    let ref e = MouseCursorEvent::from_xy(1.0, 0.0).unwrap();
    assert_event_trait::<Event, Box<MouseCursorEvent>>(e);
}
<|endoftext|>


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

//! Standard library macros
//!
//! This modules contains a set of macros which are exported from the standard
//! library. Each macro is available for use when linking against the standard
//! library.

#![unstable(feature = "std_misc")]

/// The entry point for panic of Rust tasks.
///
/// This macro is used to inject panic into a Rust task, causing the task to
/// unwind and panic entirely. Each task's panic can be reaped as the
/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
/// the value which is transmitted.
///
/// The multi-argument form of this macro panics with a string and has the
/// `format!` syntax for building a string.
///
/// # Examples
///
/// ```should_fail
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!(4); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! panic {
    () => ({
        panic!("explicit panic")
    });
    ($msg:expr) => ({
        $crate::rt::begin_unwind($msg, {
            // static requires less code at runtime, more constant data
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
    ($fmt:expr, $($arg:tt)+) => ({
        $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), {
            // The leading _'s are to avoid dead code warnings if this is
            // used inside a dead function. Just `#[allow(dead_code)]` is
            // insufficient, since the user may have
            // `#[forbid(dead_code)]` and which cannot be overridden.
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
}

/// Macro for printing to the standard output.
///
/// Equivalent to the `println!` macro except that a newline is not printed at
/// the end of the message.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! print {
    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
}

/// Macro for printing to the standard output.
///
/// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information.
///
/// # Examples
///
/// ```
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! println {
    ($fmt:expr) => (print!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}

/// Helper macro for unwrapping `Result` values while returning early with an
/// error if the value of the expression is `Err`. For more information, see
/// `std::io`.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            return $crate::result::Result::Err($crate::error::FromError::from_error(err))
        }
    })
}

/// A macro to select an event from a number of receivers.
///
/// This macro is used to wait for the first event to occur on a number of
/// receivers. It places no restrictions on the types of receivers given to
/// this macro, this can be viewed as a heterogeneous select.
///
/// # Examples
///
/// ```
/// use std::thread;
/// use std::sync::mpsc;
///
/// // two placeholder functions for now
/// fn long_running_task() {}
/// fn calculate_the_answer() -> u32 { 42 }
///
/// let (tx1, rx1) = mpsc::channel();
/// let (tx2, rx2) = mpsc::channel();
///
/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
///
/// select! (
///     _ = rx1.recv() => println!("the long running task finished first"),
///     answer = rx2.recv() => {
///         println!("the answer was: {}", answer.unwrap());
///     }
/// )
/// ```
///
/// For more information about select, see the `std::sync::mpsc::Select` structure.
#[macro_export]
#[unstable(feature = "std_misc")]
macro_rules! select {
    (
        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
    ) => ({
        use $crate::sync::mpsc::Select;
        let sel = Select::new();
        $( let mut $rx = sel.handle(&$rx); )+
        unsafe {
            $( $rx.add(); )+
        }
        let ret = sel.wait();
        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
        { unreachable!() }
    })
}

// When testing the standard library, we link to the liblog crate to get the
// logging macros. In doing so, the liblog crate was linked against the real
// version of libstd, and uses a different std::fmt module than the test crate
// uses. To get around this difference, we redefine the log!() macro here to be
// just a dumb version of what it should be.
#[cfg(test)]
macro_rules! log {
    ($lvl:expr, $($args:tt)*) => (
        if log_enabled!($lvl) { println!($($args)*) }
    )
}

/// Built-in macros to the compiler itself.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(dox)]
pub mod builtin {
    /// The core macro for formatted string creation & output.
    ///
    /// This macro produces a value of type `fmt::Arguments`. This value can be
    /// passed to the functions in `std::fmt` for performing useful functions.
    /// All other formatting macros (`format!`, `write!`, `println!`, etc) are
    /// proxied through this one.
    ///
    /// For more information, see the documentation in `std::fmt`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::fmt;
    ///
    /// let s = fmt::format(format_args!("hello {}", "world"));
    /// assert_eq!(s, format!("hello {}", "world"));
    ///
    /// ```
    #[macro_export]
    macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
        /* compiler built-in */
    }) }

    /// Inspect an environment variable at compile time.
    ///
    /// This macro will expand to the value of the named environment variable at
    /// compile time, yielding an expression of type `&'static str`.
    ///
    /// If the environment variable is not defined, then a compilation error
    /// will be emitted.  To not emit a compile error, use the `option_env!`
    /// macro instead.
    ///
    /// # Examples
    ///
    /// ```
    /// let path: &'static str = env!("PATH");
    /// println!("the $PATH variable at the time of compiling was: {}", path);
    /// ```
    #[macro_export]
    macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Optionally inspect an environment variable at compile time.
    ///
    /// If the named environment variable is present at compile time, this will
    /// expand into an expression of type `Option<&'static str>` whose value is
    /// `Some` of the value of the environment variable. If the environment
    /// variable is not present, then this will expand to `None`.
    ///
    /// A compile time error is never emitted when using this macro regardless
    /// of whether the environment variable is present or not.
    ///
    /// # Examples
    ///
    /// ```
    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
    /// println!("the secret key might be: {:?}", key);
    /// ```
    #[macro_export]
    macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Concatenate identifiers into one identifier.
    ///
    /// This macro takes any number of comma-separated identifiers, and
    /// concatenates them all into one, yielding an expression which is a new
    /// identifier. Note that hygiene makes it such that this macro cannot
    /// capture local variables, and macros are only allowed in item,
    /// statement or expression position, meaning this macro may be difficult to
    /// use in some situations.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(concat_idents)]
    ///
    /// # fn main() {
    /// fn foobar() -> u32 { 23 }
    ///
    /// let f = concat_idents!(foo, bar);
    /// println!("{}", f());
    /// # }
    /// ```
    #[macro_export]
    macro_rules! concat_idents {
        ($($e:ident),*) => ({ /* compiler built-in */ })
    }

    /// Concatenates literals into a static string slice.
    ///
    /// This macro takes any number of comma-separated literals, yielding an
    /// expression of type `&'static str` which represents all of the literals
    /// concatenated left-to-right.
    ///
    /// Integer and floating point literals are stringified in order to be
    /// concatenated.
    ///
    /// # Examples
    ///
    /// ```
    /// let s = concat!("test", 10, 'b', true);
    /// assert_eq!(s, "test10btrue");
    /// ```
    #[macro_export]
    macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }

    /// A macro which expands to the line number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned line is not
    /// the invocation of the `line!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `line!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_line = line!();
    /// println!("defined on line: {}", current_line);
    /// ```
    #[macro_export]
    macro_rules! line { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the column number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned column is not
    /// the invocation of the `column!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `column!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_col = column!();
    /// println!("defined on column: {}", current_col);
    /// ```
    #[macro_export]
    macro_rules! column { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the file name from which it was invoked.
    ///
    /// The expanded expression has type `&'static str`, and the returned file
    /// is not the invocation of the `file!()` macro itself, but rather the
    /// first macro invocation leading up to the invocation of the `file!()`
    /// macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let this_file = file!();
    /// println!("defined in file: {}", this_file);
    /// ```
    #[macro_export]
    macro_rules! file { () => ({ /* compiler built-in */ }) }

    /// A macro which stringifies its argument.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// stringification of all the tokens passed to the macro. No restrictions
    /// are placed on the syntax of the macro invocation itself.
    ///
    /// # Examples
    ///
    /// ```
    /// let one_plus_one = stringify!(1 + 1);
    /// assert_eq!(one_plus_one, "1 + 1");
    /// ```
    #[macro_export]
    macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }

    /// Includes a utf8-encoded file as a string.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// contents of the filename specified. The file is located relative to the
    /// current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_str!("secret-key.ascii");
    /// ```
    #[macro_export]
    macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Includes a file as a byte slice.
    ///
    /// This macro will yield an expression of type `&'static [u8]` which is
    /// the contents of the filename specified. The file is located relative to
    /// the current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_bytes!("secret-key.bin");
    /// ```
    #[macro_export]
    macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Expands to a string that represents the current module path.
    ///
    /// The current module path can be thought of as the hierarchy of modules
    /// leading back up to the crate root. The first component of the path
    /// returned is the name of the crate currently being compiled.
    ///
    /// # Examples
    ///
    /// ```
    /// mod test {
    ///     pub fn foo() {
    ///         assert!(module_path!().ends_with("test"));
    ///     }
    /// }
    ///
    /// test::foo();
    /// ```
    #[macro_export]
    macro_rules! module_path { () => ({ /* compiler built-in */ }) }

    /// Boolean evaluation of configuration flags.
    ///
    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
    /// boolean expression evaluation of configuration flags. This frequently
    /// leads to less duplicated code.
    ///
    /// The syntax given to this macro is the same syntax as the `cfg`
    /// attribute.
    ///
    /// # Examples
    ///
    /// ```
    /// let my_directory = if cfg!(windows) {
    ///     "windows-specific-directory"
    /// } else {
    ///     "unix-directory"
    /// };
    /// ```
    #[macro_export]
    macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }

    /// Parse the current given file as an expression.
    ///
    /// This is generally a bad idea, because it's going to behave unhygenically.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// fn foo() {
    ///     include!("/path/to/a/file")
    /// }
    /// ```
    #[macro_export]
    macro_rules! include { ($cfg:tt) => ({ /* compiler built-in */ }) }
}
<commit_msg>rollup merge of #23615: steveklabnik/gh23540<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.

//! Standard library macros
//!
//! This modules contains a set of macros which are exported from the standard
//! library. Each macro is available for use when linking against the standard
//! library.

#![unstable(feature = "std_misc")]

/// The entry point for panic of Rust tasks.
///
/// This macro is used to inject panic into a Rust task, causing the task to
/// unwind and panic entirely. Each task's panic can be reaped as the
/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
/// the value which is transmitted.
///
/// The multi-argument form of this macro panics with a string and has the
/// `format!` syntax for building a string.
///
/// # Examples
///
/// ```should_fail
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!(4); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! panic {
    () => ({
        panic!("explicit panic")
    });
    ($msg:expr) => ({
        $crate::rt::begin_unwind($msg, {
            // static requires less code at runtime, more constant data
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
    ($fmt:expr, $($arg:tt)+) => ({
        $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), {
            // The leading _'s are to avoid dead code warnings if this is
            // used inside a dead function. Just `#[allow(dead_code)]` is
            // insufficient, since the user may have
            // `#[forbid(dead_code)]` and which cannot be overridden.
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
}

/// Macro for printing to the standard output.
///
/// Equivalent to the `println!` macro except that a newline is not printed at
/// the end of the message.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! print {
    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
}

/// Macro for printing to the standard output.
///
/// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information.
///
/// # Examples
///
/// ```
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! println {
    ($fmt:expr) => (print!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}

/// Helper macro for unwrapping `Result` values while returning early with an
/// error if the value of the expression is `Err`.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            return $crate::result::Result::Err($crate::error::FromError::from_error(err))
        }
    })
}

/// A macro to select an event from a number of receivers.
///
/// This macro is used to wait for the first event to occur on a number of
/// receivers. It places no restrictions on the types of receivers given to
/// this macro, this can be viewed as a heterogeneous select.
///
/// # Examples
///
/// ```
/// use std::thread;
/// use std::sync::mpsc;
///
/// // two placeholder functions for now
/// fn long_running_task() {}
/// fn calculate_the_answer() -> u32 { 42 }
///
/// let (tx1, rx1) = mpsc::channel();
/// let (tx2, rx2) = mpsc::channel();
///
/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
///
/// select! (
///     _ = rx1.recv() => println!("the long running task finished first"),
///     answer = rx2.recv() => {
///         println!("the answer was: {}", answer.unwrap());
///     }
/// )
/// ```
///
/// For more information about select, see the `std::sync::mpsc::Select` structure.
#[macro_export]
#[unstable(feature = "std_misc")]
macro_rules! select {
    (
        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
    ) => ({
        use $crate::sync::mpsc::Select;
        let sel = Select::new();
        $( let mut $rx = sel.handle(&$rx); )+
        unsafe {
            $( $rx.add(); )+
        }
        let ret = sel.wait();
        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
        { unreachable!() }
    })
}

// When testing the standard library, we link to the liblog crate to get the
// logging macros. In doing so, the liblog crate was linked against the real
// version of libstd, and uses a different std::fmt module than the test crate
// uses. To get around this difference, we redefine the log!() macro here to be
// just a dumb version of what it should be.
#[cfg(test)]
macro_rules! log {
    ($lvl:expr, $($args:tt)*) => (
        if log_enabled!($lvl) { println!($($args)*) }
    )
}

/// Built-in macros to the compiler itself.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(dox)]
pub mod builtin {
    /// The core macro for formatted string creation & output.
    ///
    /// This macro produces a value of type `fmt::Arguments`. This value can be
    /// passed to the functions in `std::fmt` for performing useful functions.
    /// All other formatting macros (`format!`, `write!`, `println!`, etc) are
    /// proxied through this one.
    ///
    /// For more information, see the documentation in `std::fmt`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::fmt;
    ///
    /// let s = fmt::format(format_args!("hello {}", "world"));
    /// assert_eq!(s, format!("hello {}", "world"));
    ///
    /// ```
    #[macro_export]
    macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
        /* compiler built-in */
    }) }

    /// Inspect an environment variable at compile time.
    ///
    /// This macro will expand to the value of the named environment variable at
    /// compile time, yielding an expression of type `&'static str`.
    ///
    /// If the environment variable is not defined, then a compilation error
    /// will be emitted.  To not emit a compile error, use the `option_env!`
    /// macro instead.
    ///
    /// # Examples
    ///
    /// ```
    /// let path: &'static str = env!("PATH");
    /// println!("the $PATH variable at the time of compiling was: {}", path);
    /// ```
    #[macro_export]
    macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Optionally inspect an environment variable at compile time.
    ///
    /// If the named environment variable is present at compile time, this will
    /// expand into an expression of type `Option<&'static str>` whose value is
    /// `Some` of the value of the environment variable. If the environment
    /// variable is not present, then this will expand to `None`.
    ///
    /// A compile time error is never emitted when using this macro regardless
    /// of whether the environment variable is present or not.
    ///
    /// # Examples
    ///
    /// ```
    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
    /// println!("the secret key might be: {:?}", key);
    /// ```
    #[macro_export]
    macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Concatenate identifiers into one identifier.
    ///
    /// This macro takes any number of comma-separated identifiers, and
    /// concatenates them all into one, yielding an expression which is a new
    /// identifier. Note that hygiene makes it such that this macro cannot
    /// capture local variables, and macros are only allowed in item,
    /// statement or expression position, meaning this macro may be difficult to
    /// use in some situations.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(concat_idents)]
    ///
    /// # fn main() {
    /// fn foobar() -> u32 { 23 }
    ///
    /// let f = concat_idents!(foo, bar);
    /// println!("{}", f());
    /// # }
    /// ```
    #[macro_export]
    macro_rules! concat_idents {
        ($($e:ident),*) => ({ /* compiler built-in */ })
    }

    /// Concatenates literals into a static string slice.
    ///
    /// This macro takes any number of comma-separated literals, yielding an
    /// expression of type `&'static str` which represents all of the literals
    /// concatenated left-to-right.
    ///
    /// Integer and floating point literals are stringified in order to be
    /// concatenated.
    ///
    /// # Examples
    ///
    /// ```
    /// let s = concat!("test", 10, 'b', true);
    /// assert_eq!(s, "test10btrue");
    /// ```
    #[macro_export]
    macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }

    /// A macro which expands to the line number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned line is not
    /// the invocation of the `line!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `line!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_line = line!();
    /// println!("defined on line: {}", current_line);
    /// ```
    #[macro_export]
    macro_rules! line { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the column number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned column is not
    /// the invocation of the `column!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `column!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_col = column!();
    /// println!("defined on column: {}", current_col);
    /// ```
    #[macro_export]
    macro_rules! column { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the file name from which it was invoked.
    ///
    /// The expanded expression has type `&'static str`, and the returned file
    /// is not the invocation of the `file!()` macro itself, but rather the
    /// first macro invocation leading up to the invocation of the `file!()`
    /// macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let this_file = file!();
    /// println!("defined in file: {}", this_file);
    /// ```
    #[macro_export]
    macro_rules! file { () => ({ /* compiler built-in */ }) }

    /// A macro which stringifies its argument.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// stringification of all the tokens passed to the macro. No restrictions
    /// are placed on the syntax of the macro invocation itself.
    ///
    /// # Examples
    ///
    /// ```
    /// let one_plus_one = stringify!(1 + 1);
    /// assert_eq!(one_plus_one, "1 + 1");
    /// ```
    #[macro_export]
    macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }

    /// Includes a utf8-encoded file as a string.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// contents of the filename specified. The file is located relative to the
    /// current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_str!("secret-key.ascii");
    /// ```
    #[macro_export]
    macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Includes a file as a byte slice.
    ///
    /// This macro will yield an expression of type `&'static [u8]` which is
    /// the contents of the filename specified. The file is located relative to
    /// the current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_bytes!("secret-key.bin");
    /// ```
    #[macro_export]
    macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Expands to a string that represents the current module path.
    ///
    /// The current module path can be thought of as the hierarchy of modules
    /// leading back up to the crate root. The first component of the path
    /// returned is the name of the crate currently being compiled.
    ///
    /// # Examples
    ///
    /// ```
    /// mod test {
    ///     pub fn foo() {
    ///         assert!(module_path!().ends_with("test"));
    ///     }
    /// }
    ///
    /// test::foo();
    /// ```
    #[macro_export]
    macro_rules! module_path { () => ({ /* compiler built-in */ }) }

    /// Boolean evaluation of configuration flags.
    ///
    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
    /// boolean expression evaluation of configuration flags. This frequently
    /// leads to less duplicated code.
    ///
    /// The syntax given to this macro is the same syntax as the `cfg`
    /// attribute.
    ///
    /// # Examples
    ///
    /// ```
    /// let my_directory = if cfg!(windows) {
    ///     "windows-specific-directory"
    /// } else {
    ///     "unix-directory"
    /// };
    /// ```
    #[macro_export]
    macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }

    /// Parse the current given file as an expression.
    ///
    /// This is generally a bad idea, because it's going to behave unhygenically.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// fn foo() {
    ///     include!("/path/to/a/file")
    /// }
    /// ```
    #[macro_export]
    macro_rules! include { ($cfg:tt) => ({ /* compiler built-in */ }) }
}
<|endoftext|>


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

//! A type representing either success or failure

#[allow(missing_doc)];

use clone::Clone;
use cmp::Eq;
use either;
use either::Either;
use iterator::IteratorUtil;
use option::{None, Option, Some};
use vec;
use vec::{OwnedVector, ImmutableVector};
use container::Container;

/// The result type
#[deriving(Clone, Eq)]
pub enum Result<T, U> {
    /// Contains the successful result value
    Ok(T),
    /// Contains the error value
    Err(U)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
#[inline]
pub fn to_either<T:Clone,U:Clone>(res: &Result<U, T>)
    -> Either<T, U> {
    match *res {
      Ok(ref res) => either::Right((*res).clone()),
      Err(ref fail_) => either::Left((*fail_).clone())
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_bytes(buf)
 *     }
 */
#[inline]
pub fn map<T, E: Clone, U: Clone>(res: &Result<T, E>, op: &fn(&T) -> U)
  -> Result<U, E> {
    match *res {
      Ok(ref t) => Ok(op(t)),
      Err(ref e) => Err((*e).clone())
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
#[inline]
pub fn map_err<T:Clone,E,F:Clone>(res: &Result<T, E>, op: &fn(&E) -> F)
  -> Result<T, F> {
    match *res {
      Ok(ref t) => Ok((*t).clone()),
      Err(ref e) => Err(op(e))
    }
}

impl<T, E> Result<T, E> {
    /**
     * Get a reference to the value out of a successful result
     *
     * # Failure
     *
     * If the result is an error
     */
    #[inline]
    pub fn get_ref<'a>(&'a self) -> &'a T {
        match *self {
        Ok(ref t) => t,
        Err(ref the_err) =>
            fail!("get_ref called on error result: %?", *the_err)
        }
    }

    /// 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()
    }

    /**
     * Call a function based on a previous result
     *
     * If `*self` is `ok` then the value is extracted and passed to `op` whereupon
     * `op`s result is returned. if `*self` is `err` then it is immediately
     * returned. This function can be used to compose the results of two
     * functions.
     *
     * Example:
     *
     *     read_file(file).iter() { |buf|
     *         print_buf(buf)
     *     }
     */
    #[inline]
    pub fn iter(&self, f: &fn(&T)) {
        match *self {
            Ok(ref t) => f(t),
            Err(_) => ()
        }
    }

    /**
     * Call a function based on a previous result
     *
     * If `*self` is `err` then the value is extracted and passed to `op` whereupon
     * `op`s result is returned. if `*self` is `ok` then it is immediately returned.
     * This function can be used to pass through a successful result while
     * handling an error.
     */
    #[inline]
    pub fn iter_err(&self, f: &fn(&E)) {
        match *self {
            Ok(_) => (),
            Err(ref e) => f(e)
        }
    }

    /// Unwraps a result, assuming it is an `ok(T)`
    #[inline]
    pub fn unwrap(self) -> T {
        match self {
            Ok(t) => t,
            Err(_) => fail!("unwrap called on an err result")
        }
    }

    /// Unwraps a result, assuming it is an `err(U)`
    #[inline]
    pub fn unwrap_err(self) -> E {
        match self {
            Err(u) => u,
            Ok(_) => fail!("unwrap called on an ok result")
        }
    }

    /**
     * Call a function based on a previous result
     *
     * If `self` is `ok` then the value is extracted and passed to `op` whereupon
     * `op`s result is returned. if `self` is `err` then it is immediately
     * returned. This function can be used to compose the results of two
     * functions.
     *
     * Example:
     *
     *     let res = read_file(file).chain(op) { |buf|
     *         ok(parse_bytes(buf))
     *     }
     */
    #[inline]
    pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
        match self {
            Ok(t) => op(t),
            Err(e) => Err(e)
        }
    }

    /**
    * Call a function based on a previous result
    *
    * If `self` is `err` then the value is extracted and passed to `op`
    * whereupon `op`s result is returned. if `self` is `ok` then it is
    * immediately returned.  This function can be used to pass through a
    * successful result while handling an error.
    */
    #[inline]
    pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
        match self {
            Ok(t) => Ok(t),
            Err(v) => op(v)
        }
    }
}

impl<T:Clone,E> Result<T, E> {
    /**
     * Get the value out of a successful result
     *
     * # Failure
     *
     * If the result is an error
     */
    #[inline]
    pub fn get(&self) -> T {
        match *self {
            Ok(ref t) => (*t).clone(),
            Err(ref e) => fail!("get called on error result: %?", *e),
        }
    }

    #[inline]
    pub fn map_err<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
        map_err(self, op)
    }
}

impl<T, E:Clone> Result<T, E> {
    /**
     * Get the value out of an error result
     *
     * # Failure
     *
     * If the result is not an error
     */
    #[inline]
    pub fn get_err(&self) -> E {
        match *self {
            Err(ref u) => (*u).clone(),
            Ok(_) => fail!("get_err called on ok result"),
        }
    }

    #[inline]
    pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
        map(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert!(incd == ~[2u, 3u, 4u]);
 *     }
 */
#[inline]
pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
                      -> Result<~[V],U> {
    let mut vs: ~[V] = vec::with_capacity(ts.len());
    for ts.iter().advance |t| {
        match op(t) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
    }
    return Ok(vs);
}

#[inline]
#[allow(missing_doc)]
pub fn map_opt<T,
               U,
               V>(
               o_t: &Option<T>,
               op: &fn(&T) -> Result<V,U>)
               -> Result<Option<V>,U> {
    match *o_t {
        None => Ok(None),
        Some(ref t) => match op(t) {
            Ok(v) => Ok(Some(v)),
            Err(e) => Err(e)
        }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
#[inline]
pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
                op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut vs = vec::with_capacity(n);
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map_zip()` but it is more efficient
 * on its own as no result vector is built.
 */
#[inline]
pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
                         op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(()) => (),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(());
}

#[cfg(test)]
mod tests {
    use result::{Err, Ok, Result};
    use result;

    pub fn op1() -> result::Result<int, ~str> { result::Ok(666) }

    pub fn op2(i: int) -> result::Result<uint, ~str> {
        result::Ok(i as uint + 1u)
    }

    pub fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }

    #[test]
    pub fn chain_success() {
        assert_eq!(op1().chain(op2).get(), 667u);
    }

    #[test]
    pub fn chain_failure() {
        assert_eq!(op3().chain( op2).get_err(), ~"sadface");
    }

    #[test]
    pub fn test_impl_iter() {
        let mut valid = false;
        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert!(valid);

        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert!(valid);
    }

    #[test]
    pub fn test_impl_iter_err() {
        let mut valid = true;
        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert!(valid);

        valid = false;
        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert!(valid);
    }

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

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

    #[test]
    pub fn test_get_ref_method() {
        let foo: Result<int, ()> = Ok(100);
        assert_eq!(*foo.get_ref(), 100);
    }
}
<commit_msg>cleanup .map and .map_err<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A type representing either success or failure

#[allow(missing_doc)];

use clone::Clone;
use cmp::Eq;
use either;
use either::Either;
use iterator::IteratorUtil;
use option::{None, Option, Some};
use vec;
use vec::{OwnedVector, ImmutableVector};
use container::Container;

/// The result type
#[deriving(Clone, Eq)]
pub enum Result<T, U> {
    /// Contains the successful result value
    Ok(T),
    /// Contains the error value
    Err(U)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
#[inline]
pub fn to_either<T:Clone,U:Clone>(res: &Result<U, T>)
    -> Either<T, U> {
    match *res {
      Ok(ref res) => either::Right((*res).clone()),
      Err(ref fail_) => either::Left((*fail_).clone())
    }
}

impl<T, E> Result<T, E> {
    /**
     * Get a reference to the value out of a successful result
     *
     * # Failure
     *
     * If the result is an error
     */
    #[inline]
    pub fn get_ref<'a>(&'a self) -> &'a T {
        match *self {
        Ok(ref t) => t,
        Err(ref the_err) =>
            fail!("get_ref called on error result: %?", *the_err)
        }
    }

    /// 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()
    }

    /**
     * Call a function based on a previous result
     *
     * If `*self` is `ok` then the value is extracted and passed to `op` whereupon
     * `op`s result is returned. if `*self` is `err` then it is immediately
     * returned. This function can be used to compose the results of two
     * functions.
     *
     * Example:
     *
     *     read_file(file).iter() { |buf|
     *         print_buf(buf)
     *     }
     */
    #[inline]
    pub fn iter(&self, f: &fn(&T)) {
        match *self {
            Ok(ref t) => f(t),
            Err(_) => ()
        }
    }

    /**
     * Call a function based on a previous result
     *
     * If `*self` is `err` then the value is extracted and passed to `op` whereupon
     * `op`s result is returned. if `*self` is `ok` then it is immediately returned.
     * This function can be used to pass through a successful result while
     * handling an error.
     */
    #[inline]
    pub fn iter_err(&self, f: &fn(&E)) {
        match *self {
            Ok(_) => (),
            Err(ref e) => f(e)
        }
    }

    /// Unwraps a result, assuming it is an `ok(T)`
    #[inline]
    pub fn unwrap(self) -> T {
        match self {
            Ok(t) => t,
            Err(_) => fail!("unwrap called on an err result")
        }
    }

    /// Unwraps a result, assuming it is an `err(U)`
    #[inline]
    pub fn unwrap_err(self) -> E {
        match self {
            Err(u) => u,
            Ok(_) => fail!("unwrap called on an ok result")
        }
    }

    /**
     * Call a function based on a previous result
     *
     * If `self` is `ok` then the value is extracted and passed to `op` whereupon
     * `op`s result is returned. if `self` is `err` then it is immediately
     * returned. This function can be used to compose the results of two
     * functions.
     *
     * Example:
     *
     *     let res = read_file(file).chain(op) { |buf|
     *         ok(parse_bytes(buf))
     *     }
     */
    #[inline]
    pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
        match self {
            Ok(t) => op(t),
            Err(e) => Err(e)
        }
    }

    /**
    * Call a function based on a previous result
    *
    * If `self` is `err` then the value is extracted and passed to `op`
    * whereupon `op`s result is returned. if `self` is `ok` then it is
    * immediately returned.  This function can be used to pass through a
    * successful result while handling an error.
    */
    #[inline]
    pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
        match self {
            Ok(t) => Ok(t),
            Err(v) => op(v)
        }
    }
}

impl<T:Clone,E> Result<T, E> {
    /**
     * Get the value out of a successful result
     *
     * # Failure
     *
     * If the result is an error
     */
    #[inline]
    pub fn get(&self) -> T {
        match *self {
            Ok(ref t) => (*t).clone(),
            Err(ref e) => fail!("get called on error result: %?", *e),
        }
    }

    /**
    * Call a function based on a previous result
    *
    * If `*self` is `err` then the value is extracted and passed to `op` whereupon
    * `op`s result is wrapped in an `err` and returned. if `*self` is `ok` then it
    * is immediately returned.  This function can be used to pass through a
    * successful result while handling an error.
    */
    #[inline]
    pub fn map_err<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
        match *self {
            Ok(ref t) => Ok(t.clone()),
            Err(ref e) => Err(op(e))
        }
    }
}

impl<T, E:Clone> Result<T, E> {
    /**
     * Get the value out of an error result
     *
     * # Failure
     *
     * If the result is not an error
     */
    #[inline]
    pub fn get_err(&self) -> E {
        match *self {
            Err(ref u) => (*u).clone(),
            Ok(_) => fail!("get_err called on ok result"),
        }
    }

    /**
    * Call a function based on a previous result
    *
    * If `res` is `ok` then the value is extracted and passed to `op` whereupon
    * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
    * immediately returned.  This function can be used to compose the results of
    * two functions.
    *
    * Example:
    *
    *     let res = map(read_file(file)) { |buf|
    *         parse_bytes(buf)
    *     }
    */
    #[inline]
    pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
        match *self {
            Ok(ref t) => Ok(op(t)),
            Err(ref e) => Err(e.clone())
        }
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert!(incd == ~[2u, 3u, 4u]);
 *     }
 */
#[inline]
pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
                      -> Result<~[V],U> {
    let mut vs: ~[V] = vec::with_capacity(ts.len());
    for ts.iter().advance |t| {
        match op(t) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
    }
    return Ok(vs);
}

#[inline]
#[allow(missing_doc)]
pub fn map_opt<T,
               U,
               V>(
               o_t: &Option<T>,
               op: &fn(&T) -> Result<V,U>)
               -> Result<Option<V>,U> {
    match *o_t {
        None => Ok(None),
        Some(ref t) => match op(t) {
            Ok(v) => Ok(Some(v)),
            Err(e) => Err(e)
        }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
#[inline]
pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
                op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut vs = vec::with_capacity(n);
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map_zip()` but it is more efficient
 * on its own as no result vector is built.
 */
#[inline]
pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
                         op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(()) => (),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(());
}

#[cfg(test)]
mod tests {
    use result::{Err, Ok, Result};
    use result;

    pub fn op1() -> result::Result<int, ~str> { result::Ok(666) }

    pub fn op2(i: int) -> result::Result<uint, ~str> {
        result::Ok(i as uint + 1u)
    }

    pub fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }

    #[test]
    pub fn chain_success() {
        assert_eq!(op1().chain(op2).get(), 667u);
    }

    #[test]
    pub fn chain_failure() {
        assert_eq!(op3().chain( op2).get_err(), ~"sadface");
    }

    #[test]
    pub fn test_impl_iter() {
        let mut valid = false;
        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert!(valid);

        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert!(valid);
    }

    #[test]
    pub fn test_impl_iter_err() {
        let mut valid = true;
        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert!(valid);

        valid = false;
        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert!(valid);
    }

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

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

    #[test]
    pub fn test_get_ref_method() {
        let foo: Result<int, ()> = Ok(100);
        assert_eq!(*foo.get_ref(), 100);
    }
}
<|endoftext|>