<commit_before>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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.

#[macro_use]
extern crate habitat_butterfly;
#[macro_use]
extern crate habitat_butterfly_test as btest;

mod encryption;
mod rumor;

use habitat_butterfly::member::Health;

#[test]
fn two_members_meshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(2);
    net.mesh();
    assert_wait_for_health_of!(net, 0, 1, Health::Alive);
    assert_wait_for_health_of!(net, 1, 0, Health::Alive);

    trace_it!(TEST: &net[0], "Paused");
    net[0].pause();
    assert_wait_for_health_of!(net, 1, 0, Health::Suspect);
    assert_wait_for_health_of!(net, 1, 0, Health::Confirmed);
}

#[test]
fn six_members_meshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(6);
    net.mesh();
    trace_it!(TEST: &net[0], "Paused");
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Confirmed);
}

#[test]
fn six_members_meshed_partition_one_node_from_another_node_remains_alive() {
    let mut net = btest::SwimNet::new(6);
    trace_it!(TEST_NET: net, "Mesh");
    net.mesh();
    net.block(0, 1);
    net.wait_for_rounds(2);
    assert_wait_for_health_of!(net, 1, Health::Alive);
}

#[test]
fn six_members_meshed_partition_half_of_nodes_from_each_other_both_sides_confirmed() {
    let mut net = btest::SwimNet::new(6);
    net.mesh();
    assert_wait_for_health_of!(net, 0, Health::Alive);
    net.partition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
}

#[test]
fn six_members_unmeshed_become_fully_meshed_via_gossip() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
}

#[test]
fn six_members_unmeshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Confirmed);
}

#[test]
fn six_members_unmeshed_partition_and_rejoin_no_persistent_peers() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    net.partition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
    net.unpartition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
}

#[test]
fn six_members_unmeshed_partition_and_rejoin_persistent_peers() {
    let mut net = btest::SwimNet::new(6);
    net[0]
        .member
        .write()
        .expect("Member lock is poisoned")
        .set_persistent();
    net[4]
        .member
        .write()
        .expect("Member lock is poisoned")
        .set_persistent();
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    net.partition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
    net.unpartition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Alive);
}

#[test]
fn six_members_unmeshed_allows_graceful_departure() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    trace_it!(TEST: &net[0], "Departing");
    net[0].set_departed();
    trace_it!(TEST: &net[0], "Paused");
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Departed);
}

//
// TODO: This test does not run on our test infrastructure and fails with a
// "thread 'push-worker' panicked at 'Failure to create the ZMQ push socket: Too many open files'"
// error.
//
// #[test]
// #[cfg_attr(feature = "ignore_inconsistent_tests", ignore)]
// fn fifty_members_meshed_confirm_one_member() {
//     let mut net = btest::SwimNet::new(50);
//     net.mesh();
//     net[0].pause();
//     assert_wait_for_health_of!(net, 0, Health::Confirmed);
// }
<commit_msg>Switch test from 50 to 10 members<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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.

#[macro_use]
extern crate habitat_butterfly;
#[macro_use]
extern crate habitat_butterfly_test as btest;

mod encryption;
mod rumor;

use habitat_butterfly::member::Health;

#[test]
fn two_members_meshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(2);
    net.mesh();
    assert_wait_for_health_of!(net, 0, 1, Health::Alive);
    assert_wait_for_health_of!(net, 1, 0, Health::Alive);

    trace_it!(TEST: &net[0], "Paused");
    net[0].pause();
    assert_wait_for_health_of!(net, 1, 0, Health::Suspect);
    assert_wait_for_health_of!(net, 1, 0, Health::Confirmed);
}

#[test]
fn six_members_meshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(6);
    net.mesh();
    trace_it!(TEST: &net[0], "Paused");
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Confirmed);
}

#[test]
fn six_members_meshed_partition_one_node_from_another_node_remains_alive() {
    let mut net = btest::SwimNet::new(6);
    trace_it!(TEST_NET: net, "Mesh");
    net.mesh();
    net.block(0, 1);
    net.wait_for_rounds(2);
    assert_wait_for_health_of!(net, 1, Health::Alive);
}

#[test]
fn six_members_meshed_partition_half_of_nodes_from_each_other_both_sides_confirmed() {
    let mut net = btest::SwimNet::new(6);
    net.mesh();
    assert_wait_for_health_of!(net, 0, Health::Alive);
    net.partition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
}

#[test]
fn six_members_unmeshed_become_fully_meshed_via_gossip() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
}

#[test]
fn six_members_unmeshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Confirmed);
}

#[test]
fn six_members_unmeshed_partition_and_rejoin_no_persistent_peers() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    net.partition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
    net.unpartition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
}

#[test]
fn six_members_unmeshed_partition_and_rejoin_persistent_peers() {
    let mut net = btest::SwimNet::new(6);
    net[0]
        .member
        .write()
        .expect("Member lock is poisoned")
        .set_persistent();
    net[4]
        .member
        .write()
        .expect("Member lock is poisoned")
        .set_persistent();
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    net.partition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Confirmed);
    net.unpartition(0..3, 3..6);
    assert_wait_for_health_of!(net, [0..3, 3..6], Health::Alive);
}

#[test]
fn six_members_unmeshed_allows_graceful_departure() {
    let mut net = btest::SwimNet::new(6);
    net.connect(0, 1);
    net.connect(1, 2);
    net.connect(2, 3);
    net.connect(3, 4);
    net.connect(4, 5);
    assert_wait_for_health_of!(net, [0..6, 0..6], Health::Alive);
    trace_it!(TEST: &net[0], "Departing");
    net[0].set_departed();
    trace_it!(TEST: &net[0], "Paused");
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Departed);
}

#[test]
#[cfg_attr(feature = "ignore_inconsistent_tests", ignore)]
fn ten_members_meshed_confirm_one_member() {
    let mut net = btest::SwimNet::new(10);
    net.mesh();
    net[0].pause();
    assert_wait_for_health_of!(net, 0, Health::Confirmed);
}
<|endoftext|>


<commit_before>use table::{TableRow, TableHeader, Table, get_column};
use definitions::{ResultColumn, RusqlStatement, InsertDef, SelectDef};
use definitions::{AlterTableDef, AlterTable, Expression, BinaryOperator};
use definitions::{LiteralValue, DeleteDef, InsertDataSource, UpdateDef};
use rusql::Rusql;

peg_file! parser("sql.rustpeg");

pub fn rusql_exec(db: &mut Rusql, sql_str: &str, callback: |&TableRow, &TableHeader|) {
    match parser::rusql_parse(sql_str) {
        Ok(res) => {
            for stmt in res.iter() {
                match stmt {
                    &RusqlStatement::AlterTable(ref alter_table_def) => alter_table(db, alter_table_def),
                    &RusqlStatement::CreateTable(ref table_def) => db.create_table(table_def),
                    &RusqlStatement::Delete(ref delete_def) => delete(db, delete_def),
                    &RusqlStatement::DropTable(ref drop_table_def) => db.drop_table(&drop_table_def.name),
                    &RusqlStatement::Insert(ref insert_def) => insert(db, insert_def),
                    &RusqlStatement::Select(ref select_def) => select(db, select_def, |a, b| callback(a, b)),
                    &RusqlStatement::Update(ref update_def) => update(db, update_def),
                }
            }
        }
        Err(e) => println!("syntax error: {}", e),
    }
}

fn alter_table(db: &mut Rusql, alter_table_def: &AlterTableDef) {
    match alter_table_def.mode {
        AlterTable::RenameTo(ref new_name) => db.rename_table(&alter_table_def.name, new_name),
        AlterTable::AddColumn(ref column_def) => db.get_mut_table(&alter_table_def.name)
                                                   .add_column(column_def),
    }
}

fn delete(db: &mut Rusql, delete_def: &DeleteDef) {
    let table = db.get_mut_table(&delete_def.name);

    if let Some(ref expr) = delete_def.where_expr {
        // FIXME just making the borrow checker happy...
        let header = table.header.clone();
        table.delete_where(|row| ExpressionEvaluator::new(row, &header, None).eval_bool(expr));
    } else {
        table.clear();
    }
}

fn insert(db: &mut Rusql, insert_def: &InsertDef) {
    match insert_def.data_source {
        InsertDataSource::Values(ref column_data) => {
            let mut table = db.get_mut_table(&insert_def.table_name);
            table.insert(column_data, &insert_def.column_names);
        }
        InsertDataSource::Select(ref select_def) => {
            let mut new_entries: Vec<TableRow> = Vec::new();

            // FIXME make sure we're putting in valid entries for this table...
            // FIXME Each row gets cloned twice...

            select(db, select_def, |row, _| {
                new_entries.push(row.clone());
            });
            let mut table = db.get_mut_table(&insert_def.table_name);

            for row in new_entries.into_iter() {
                table.push_row(row);
            }
        }
        _ => {}
    }
}

fn update(db: &mut Rusql, update_def: &UpdateDef) {
    let mut table = db.get_mut_table(&update_def.name);

    for (_, row) in table.data.iter_mut() {
        if let Some(ref expr) = update_def.where_expr {
            if !ExpressionEvaluator::new(row, &table.header, None).eval_bool(expr) {
                continue;
            }
        }

        for &(ref name, ref expr) in update_def.set.iter() {
            let x = table.header.iter().position(|ref cols| &cols.name == name).unwrap();

            row[x] = expr_to_literal(expr);
        }
    }
}

#[deriving(PartialEq)]
enum ExpressionResult {
    Boolean(bool),
    Value(LiteralValue),
    Null,
}

struct ExpressionEvaluator<'a, 'b> {
    // FIXME wtf am I doing?!?!?!
    row: &'a TableRow,
    head: &'a TableHeader,
    tables: Option<Vec<&'b Table>>,
}

impl<'a, 'b> ExpressionEvaluator<'a, 'b> {
    pub fn new(row: &'a TableRow, head: &'a TableHeader, tables: Option<Vec<&'b Table>>) -> ExpressionEvaluator<'a, 'b> {
        ExpressionEvaluator {
            row: row,
            head: head,
            tables: tables,
        }
    }

    fn eval_expr(&'a self, expr: &Expression) -> ExpressionResult {
        match expr {
            &Expression::LiteralValue(ref value) => ExpressionResult::Value(value.clone()),
            &Expression::TableName(_) => self.eval_column_name(expr, None, None),
            &Expression::ColumnName(ref name) => ExpressionResult::Value(get_column(name, self.row, self.head, None)),
            &Expression::BinaryOperator((b, ref exp1, ref exp2)) => self.eval_binary_operator(b, &**exp1,
                                                                                &**exp2),
        }
    }

    pub fn eval_bool(&'a self, expr: &Expression) -> bool {
        match self.eval_expr(expr) {
            ExpressionResult::Boolean(b) => b,
            _ => false,
        }
    }

    fn eval_binary_operator(&'a self,
                            operator: BinaryOperator,
                            exp1: &Expression,
                            exp2: &Expression) -> ExpressionResult {
        match operator {
            BinaryOperator::Equals => {
                ExpressionResult::Boolean(self.eval_expr(exp1) == self.eval_expr(exp2))
            }
        }
    }

    fn eval_column_name(&'a self, expr: &Expression, table: Option<&Table>, offset: Option<uint>) -> ExpressionResult {
        match expr {
            &Expression::TableName((ref name, ref expr)) => {
                let mut table_opt: Option<&Table> = None;
                let mut offset = 0u;

                for table in self.tables.clone().unwrap().into_iter() {
                    if &table.name == name {
                        table_opt = Some(table);
                        break;
                    }
                    offset = offset + table.header.len();
                }
                if !table_opt.is_some() {
                    return ExpressionResult::Null;
                }

                self.eval_column_name(&**expr, table, Some(offset))
            }
            &Expression::ColumnName(ref name) => ExpressionResult::Value(get_column(name, self.row, self.head, offset)),
            _ => ExpressionResult::Boolean(false),
        }
    }
}

fn expr_to_literal(expr: &Expression) -> LiteralValue {
    match expr {
        &Expression::LiteralValue(ref literal_value) => literal_value.clone(),
        _ => LiteralValue::Null,
    }
}

fn product(tables: Vec<&Table>, result_table: &mut Table, new_row_opt: Option<TableRow>) {
    let mut remaining = tables.clone();
    if let Some(table) = remaining.remove(0) {
        for row in table.data.values() {
            let mut new_row: TableRow = if let Some(ref new_row) = new_row_opt {
                new_row.clone()
            } else {
                Vec::new()
            };

            new_row.push_all(&*row.clone());

            product(remaining.clone(), result_table, Some(new_row));
        }
    } else {
        if let Some(new_row) = new_row_opt {
            result_table.push_row(new_row);
        }
    }
}

fn select(db: &mut Rusql, select_def: &SelectDef, callback: |&TableRow, &TableHeader|) {
    let mut input_tables: Vec<&Table> = Vec::new();
    let mut result_header: TableHeader = Vec::new();

    for name in select_def.table_or_subquery.iter() {
        let table = db.get_table(name);
        input_tables.push(table);

        match select_def.result_column {
            ResultColumn::Asterisk => result_header.push_all(&*table.header.clone()),
        }
    }

    let mut result_table = Table::new_result_table(result_header);

    product(input_tables.clone(), &mut result_table, None);

    // FIXME would it be better if we did this as each row is generated?
    for row in result_table.data.values() {
        if let Some(ref expr) = select_def.where_expr {
            if !ExpressionEvaluator::new(row, &result_table.header, Some(input_tables.clone())).eval_bool(expr) {
                continue;
            }
        }
        callback(row, &result_table.header);
    }
}
<commit_msg>Misc. cleanup<commit_after>use table::{TableRow, TableHeader, Table, get_column};
use definitions::{ResultColumn, RusqlStatement, InsertDef, SelectDef};
use definitions::{AlterTableDef, AlterTable, Expression, BinaryOperator};
use definitions::{LiteralValue, DeleteDef, InsertDataSource, UpdateDef};
use rusql::Rusql;

peg_file! parser("sql.rustpeg");

pub fn rusql_exec(db: &mut Rusql, sql_str: &str, callback: |&TableRow, &TableHeader|) {
    match parser::rusql_parse(sql_str) {
        Ok(res) => {
            for stmt in res.iter() {
                match stmt {
                    &RusqlStatement::AlterTable(ref alter_table_def) => alter_table(db, alter_table_def),
                    &RusqlStatement::CreateTable(ref table_def) => db.create_table(table_def),
                    &RusqlStatement::Delete(ref delete_def) => delete(db, delete_def),
                    &RusqlStatement::DropTable(ref drop_table_def) => db.drop_table(&drop_table_def.name),
                    &RusqlStatement::Insert(ref insert_def) => insert(db, insert_def),
                    &RusqlStatement::Select(ref select_def) => select(db, select_def, |a, b| callback(a, b)),
                    &RusqlStatement::Update(ref update_def) => update(db, update_def),
                }
            }
        }
        Err(e) => println!("syntax error: {}", e),
    }
}

fn alter_table(db: &mut Rusql, alter_table_def: &AlterTableDef) {
    match alter_table_def.mode {
        AlterTable::RenameTo(ref new_name) => db.rename_table(&alter_table_def.name, new_name),
        AlterTable::AddColumn(ref column_def) => db.get_mut_table(&alter_table_def.name)
                                                   .add_column(column_def),
    }
}

fn delete(db: &mut Rusql, delete_def: &DeleteDef) {
    let table = db.get_mut_table(&delete_def.name);

    if let Some(ref expr) = delete_def.where_expr {
        // FIXME just making the borrow checker happy...
        let header = table.header.clone();
        table.delete_where(|row| ExpressionEvaluator::new(row, &header, None).eval_bool(expr));
    } else {
        table.clear();
    }
}

fn insert(db: &mut Rusql, insert_def: &InsertDef) {
    match insert_def.data_source {
        InsertDataSource::Values(ref column_data) => {
            let mut table = db.get_mut_table(&insert_def.table_name);
            table.insert(column_data, &insert_def.column_names);
        }
        InsertDataSource::Select(ref select_def) => {
            let mut new_entries: Vec<TableRow> = Vec::new();

            // FIXME make sure we're putting in valid entries for this table...
            // FIXME Each row gets cloned twice...

            select(db, select_def, |row, _| {
                new_entries.push(row.clone());
            });
            let mut table = db.get_mut_table(&insert_def.table_name);

            for row in new_entries.into_iter() {
                table.push_row(row);
            }
        }
        _ => {}
    }
}

fn update(db: &mut Rusql, update_def: &UpdateDef) {
    let mut table = db.get_mut_table(&update_def.name);

    for (_, row) in table.data.iter_mut() {
        if let Some(ref expr) = update_def.where_expr {
            if !ExpressionEvaluator::new(row, &table.header, None).eval_bool(expr) {
                continue;
            }
        }

        for &(ref name, ref expr) in update_def.set.iter() {
            let x = table.header.iter().position(|ref cols| &cols.name == name).unwrap();

            row[x] = expr_to_literal(expr);
        }
    }
}

#[deriving(PartialEq)]
enum ExpressionResult {
    Boolean(bool),
    Value(LiteralValue),
    Null,
}

struct ExpressionEvaluator<'a, 'b> {
    // FIXME wtf am I doing?!?!?!
    row: &'a TableRow,
    head: &'a TableHeader,
    tables: Option<Vec<&'b Table>>,
}

impl<'a, 'b> ExpressionEvaluator<'a, 'b> {
    pub fn new(row: &'a TableRow, head: &'a TableHeader, tables: Option<Vec<&'b Table>>) -> ExpressionEvaluator<'a, 'b> {
        ExpressionEvaluator {
            row: row,
            head: head,
            tables: tables,
        }
    }

    fn eval_expr(&'a self, expr: &Expression) -> ExpressionResult {
        match expr {
            &Expression::LiteralValue(ref value) => ExpressionResult::Value(value.clone()),
            &Expression::TableName(_) | &Expression::ColumnName(_) => self.eval_column_name(expr, None, None),
            &Expression::BinaryOperator((b, ref exp1, ref exp2)) => self.eval_binary_operator(b, &**exp1,
                                                                                &**exp2),
        }
    }

    pub fn eval_bool(&'a self, expr: &Expression) -> bool {
        match self.eval_expr(expr) {
            ExpressionResult::Boolean(b) => b,
            _ => false,
        }
    }

    fn eval_binary_operator(&'a self,
                            operator: BinaryOperator,
                            exp1: &Expression,
                            exp2: &Expression) -> ExpressionResult {
        match operator {
            BinaryOperator::Equals => {
                ExpressionResult::Boolean(self.eval_expr(exp1) == self.eval_expr(exp2))
            }
        }
    }

    fn eval_column_name(&'a self, expr: &Expression, table: Option<&Table>, offset: Option<uint>) -> ExpressionResult {
        match expr {
            &Expression::TableName((ref name, ref expr)) => {
                let mut table_opt: Option<&Table> = None;
                let mut offset = 0u;

                for table in self.tables.clone().unwrap().into_iter() {
                    if &table.name == name {
                        table_opt = Some(table);
                        break;
                    }
                    offset = offset + table.header.len();
                }
                if !table_opt.is_some() {
                    return ExpressionResult::Null;
                }

                self.eval_column_name(&**expr, table, Some(offset))
            }
            &Expression::ColumnName(ref name) => ExpressionResult::Value(get_column(name, self.row, self.head, offset)),
            _ => ExpressionResult::Null,
        }
    }
}

fn expr_to_literal(expr: &Expression) -> LiteralValue {
    match expr {
        &Expression::LiteralValue(ref literal_value) => literal_value.clone(),
        _ => LiteralValue::Null,
    }
}

fn product(tables: Vec<&Table>, result_table: &mut Table, new_row_opt: Option<TableRow>) {
    let mut remaining = tables.clone();
    if let Some(table) = remaining.remove(0) {
        for row in table.data.values() {
            let mut new_row: TableRow = if let Some(ref new_row) = new_row_opt {
                new_row.clone()
            } else {
                Vec::new()
            };

            new_row.push_all(&*row.clone());

            product(remaining.clone(), result_table, Some(new_row));
        }
    } else {
        if let Some(new_row) = new_row_opt {
            result_table.push_row(new_row);
        }
    }
}

fn select(db: &mut Rusql, select_def: &SelectDef, callback: |&TableRow, &TableHeader|) {
    let mut input_tables: Vec<&Table> = Vec::new();
    let mut result_header: TableHeader = Vec::new();

    for name in select_def.table_or_subquery.iter() {
        let table = db.get_table(name);
        input_tables.push(table);

        match select_def.result_column {
            ResultColumn::Asterisk => result_header.push_all(&*table.header.clone()),
        }
    }

    let mut result_table = Table::new_result_table(result_header);

    product(input_tables.clone(), &mut result_table, None);

    // FIXME would it be better if we did this as each row is generated?
    for row in result_table.data.values() {
        if let Some(ref expr) = select_def.where_expr {
            if !ExpressionEvaluator::new(row, &result_table.header, Some(input_tables.clone())).eval_bool(expr) {
                continue;
            }
        }
        callback(row, &result_table.header);
    }
}
<|endoftext|>


<commit_before>//! Abstractions for asynchronous programming.
//!
//! This crate provides a number of core abstractions for writing asynchronous code:
//!
//! - [Futures](::Future) (sometimes called promises), which represent a single
//! asychronous computation that may result in a final value or an error.
//!
//! - [Streams](::Stream), which represent a series of values or errors produced asynchronously.
//!
//! - [Sinks](::Sink), which support asynchronous writing of data.
//!
//! - [Executors](::executor), which are responsible for running asynchronous tasks.
//!
//! The crate also contains abstractions for [asynchronous I/O](::io) and
//! [cross-task communication](::channel).
//!
//! Underlying all of this is the *task system*, which is a form of lightweight
//! threading. Large asynchronous computations are built up using futures,
//! streams and sinks, and then spawned as independent tasks that are run to
//! completion, but *do not block* the thread running them.

#![no_std]
#![doc(html_root_url = "https://docs.rs/futures/0.2.0-beta")]

#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(feature = "nightly", feature(use_extern_macros))]

extern crate futures_async_runtime;
extern crate futures_core;
extern crate futures_channel;
extern crate futures_executor;
extern crate futures_io;
extern crate futures_sink;
extern crate futures_stable;
extern crate futures_util;

#[cfg(feature = "nightly")] extern crate futures_macro_async;
#[cfg(feature = "nightly")] extern crate futures_macro_await;

pub use futures_core::future::{Future, IntoFuture};
pub use futures_util::future::FutureExt;
pub use futures_core::stream::Stream;
pub use futures_util::stream::StreamExt;
pub use futures_sink::Sink;
pub use futures_util::sink::SinkExt;

// Macros redefined here because macro re-exports are unstable.

/// A macro for extracting the successful type of a `Poll<T, E>`.
///
/// This macro bakes in propagation of both errors and `Pending` signals by
/// returning early.
#[macro_export]
macro_rules! try_ready {
    ($e:expr) => (match $e {
        Ok($crate::prelude::Async::Ready(t)) => t,
        Ok($crate::prelude::Async::Pending) => return Ok($crate::prelude::Async::Pending),
        Err(e) => return Err(From::from(e)),
    })
}

/// A macro to create a `static` of type `LocalKey`.
///
/// This macro is intentionally similar to the `thread_local!`, and creates a
/// `static` which has a `get_mut` method to access the data on a task.
///
/// The data associated with each task local is per-task, so different tasks
/// will contain different values.
#[macro_export]
macro_rules! task_local {
    (static $NAME:ident: $t:ty = $e:expr) => (
        static $NAME: $crate::task::LocalKey<$t> = {
            fn __init() -> $t { $e }
            fn __key() -> ::std::any::TypeId {
                struct __A;
                ::std::any::TypeId::of::<__A>()
            }
            $crate::task::LocalKey {
                __init: __init,
                __key: __key,
            }
        };
    )
}

pub use futures_core::{Async, Poll, Never};

#[cfg(feature = "std")]
pub mod channel {
    //! Cross-task communication.
    //!
    //! Like threads, concurrent tasks sometimes need to communicate with each
    //! other. This module contains two basic abstractions for doing so:
    //!
    //! - [oneshot](::channel::oneshot), a way of sending a single value from
    //! one task to another.
    //!
    //! - [mpsc](::channel::mpsc), a multi-producer, single-consumer channel for
    //! sending values between tasks, analogous to the similarly-named structure
    //! in the standard library.

    pub use futures_channel::{oneshot, mpsc};
}

#[cfg(feature = "std")]
pub mod executor {
    //! Task execution.
    //!
    //! All asynchronous computation occurs within an executor, which is
    //! capable of spawning futures as tasks. This module provides several
    //! built-in executors, as well as tools for building your own.
    //!
    //! # Using a thread pool (M:N task scheduling)
    //!
    //! Most of the time tasks should be executed on a [thread
    //! pool](::executor::ThreadPool). A small set of worker threads can handle
    //! a very large set of spawned tasks (which are much lighter weight than
    //! threads).
    //!
    //! The simplest way to use a thread pool is to
    //! [`run`](::executor::ThreadPool::run) an initial task on it, which can
    //! then spawn further tasks back onto the pool to complete its work:
    //!
    //! ```
    //! use futures::executor::ThreadPool;
    //! # use futures::future::{Future, lazy};
    //! # let my_app: Box<Future<Item = (), Error = ()>> = Box::new(lazy(|_| Ok(())));
    //!
    //! // assumping `my_app: Future`
    //! ThreadPool::new().run(my_app);
    //! ```
    //!
    //! The call to [`run`](::executor::ThreadPool::run) will block the current
    //! thread until the future defined by `my_app` completes, and will return
    //! the result of that future.
    //!
    //! # Spawning additional tasks
    //!
    //! There are two ways to spawn a task:
    //!
    //! - Spawn onto a "default" execuctor by calling the top-level
    //! [`spawn`](::executor::spawn) function or [pulling the executor from the
    //! task context](::task::Context::executor).
    //!
    //! - Spawn onto a specific executor by calling its
    //! [`spawn`](::executor::Executor::spawn) method directly.
    //!
    //! Every task always has an associated default executor, which is usually
    //! the executor on which the task is running.
    //!
    //! # Single-threaded execution
    //!
    //! In addition to thread pools, it's possible to run a task (and the tasks
    //! it spawns) entirely within a single thread via the
    //! [`LocalPool`](::executor::LocalPool) executor. Aside from cutting down
    //! on synchronization costs, this executor also makes it possible to
    //! execute non-`Send` tasks, via
    //! [`spawn_local`](::executor::LocalExecutor::spawn_local). The `LocalPool`
    //! is best suited for running I/O-bound tasks that do relatively little
    //! work between I/O operations.
    //!
    //! There is also a convenience function,
    //! [`block_on`](::executor::block_on), for simply running a future to
    //! completion on the current thread, while routing any spawned tasks
    //! to a global thread pool.
    // TODO: add docs (or link to apr) for implementing an executor

    pub use futures_executor::{
        Enter, EnterError, LocalExecutor, LocalPool, Spawn, SpawnWithHandle, ThreadPool,
        ThreadPoolBuilder, JoinHandle, block_on, enter, spawn, spawn_with_handle
    };
    pub use futures_core::executor::{SpawnError, Executor};
}

pub mod future {
    //! Asynchronous values.
    //!
    //! This module contains:
    //!
    //! - The [`Future` trait](::Future).
    //!
    //! - The [`FutureExt`](::future::FutureExt) trait, which provides adapters
    //! for chaining and composing futures.
    //!
    //! - Top-level future combinators like [`lazy`](::future::lazy) which
    //! creates a future from a closure that defines its return value, and
    //! [`result`](::future::result), which constructs a future with an
    //! immediate defined value.

    pub use futures_core::future::{
        FutureOption, FutureResult, Future, IntoFuture, err, ok, result
    };
    pub use futures_util::future::{
        AndThen, Empty, Flatten, FlattenStream, ErrInto, Fuse,
        Inspect, IntoStream, Join, Join3, Join4, Join5, Lazy, LoopFn,
        Map, MapErr, OrElse, PollFn, Select, Then, Either, Loop, FutureExt, empty,
        lazy, loop_fn, poll_fn
    };

    #[cfg(feature = "std")]
    pub use futures_util::future::{
        CatchUnwind, JoinAll, SelectAll, SelectOk, Shared, SharedError, SharedItem,
        join_all, select_all, select_ok
    };
}

#[cfg(feature = "std")]
pub mod io {
    //! Asynchronous I/O.
    //!
    //! This module is the asynchronous version of `std::io`. It defines two
    //! traits, [`AsyncRead`](::io::AsyncRead) and
    //! [`AsyncWrite`](::io::AsyncWrite), which mirror the `Read` and `Write`
    //! traits of the standard library. However, these traits integrate with the
    //! asynchronous task system, so that if an I/O object isn't ready for
    //! reading (or writing), the thread is not blocked, and instead the current
    //! task is queued to be woken when I/O is ready.
    //!
    //! In addition, the [`AsyncReadExt`](::io::AsyncReadExt) and
    //! [`AsyncWriteExt`](::io::AsyncWriteExt) extension traits offer a variety
    //! of useful combinators for operating with asynchronous I/O objects,
    //! including ways to work with them using futures, streams and sinks.

    pub use futures_io::{
        Error, Initializer, IoVec, ErrorKind, AsyncRead, AsyncWrite, Result
    };
    pub use futures_util::io::{
        AsyncReadExt, AsyncWriteExt, AllowStdIo, Close, CopyInto, Flush,
        Read, ReadExact, ReadHalf, ReadToEnd, Window, WriteAll, WriteHalf,
    };
}

#[cfg(feature = "std")]
pub mod never {
    //! This module contains the `Never` type.
    //!
    //! Values of this type can never be created and will never exist.
    pub use futures_core::never::*;
}

pub mod prelude {
    //! A "prelude" for crates using the `futures` crate.
    //!
    //! This prelude is similar to the standard library's prelude in that you'll
    //! almost always want to import its entire contents, but unlike the standard
    //! library's prelude you'll have to do so manually:
    //!
    //! ```
    //! use futures::prelude::*;
    //! ```
    //!
    //! The prelude may grow over time as additional items see ubiquitous use.

    pub use futures_core::{
        Future,
        IntoFuture,
        Stream,
        Async,
        Poll,
        Never,
        task,
    };

    #[cfg(feature = "std")]
    pub use futures_core::executor::Executor;

    pub use futures_sink::Sink;

    #[cfg(feature = "std")]
    pub use futures_io::{
        AsyncRead,
        AsyncWrite,
    };

    pub use futures_util::{
        FutureExt,
        StreamExt,
        SinkExt,
    };

    #[cfg(feature = "std")]
    pub use futures_util::{
        AsyncReadExt,
        AsyncWriteExt,
    };

    #[cfg(feature = "nightly")]
    pub use futures_macro_async::{
        async,
        async_move,
        async_stream,
        async_stream_move,
        async_block,
        async_stream_block
    };

    #[cfg(feature = "nightly")]
    pub use futures_macro_await::{
        await,
        stream_yield,
        await_item
    };
}

pub mod sink {
    //! Asynchronous sinks.
    //!
    //! This module contains:
    //!
    //! - The [`Sink` trait](::Sink), which allows you to asynchronously write data.
    //!
    //! - The [`SinkExt`](::sink::SinkExt) trait, which provides adapters
    //! for chaining and composing sinks.

    pub use futures_sink::Sink;

    pub use futures_util::sink::{
        Close, Fanout, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
        WithFlatMap, SinkExt, close, flush,
    };

    #[cfg(feature = "std")]
    pub use futures_util::sink::Buffer;
}

pub mod stream {
    //! Asynchronous streams.
    //!
    //! This module contains:
    //!
    //! - The [`Stream` trait](::Stream), for objects that can asynchronously
    //! produce a sequence of values.
    //!
    //! - The [`StreamExt`](::future::StreamExt) trait, which provides adapters
    //! for chaining and composing streams.
    //!
    //! - Top-level stream contructors like [`iter_ok`](::stream::iter_ok) which
    //! creates a stream from an iterator, and
    //! [`futures_unordered`](::stream::futures_unordered()), which constructs a
    //! stream from a collection of futures.

    pub use futures_core::stream::Stream;

    pub use futures_util::stream::{
        AndThen, Chain, Concat, Empty, Filter, FilterMap, Flatten, Fold,
        ForEach, Forward, ErrInto, Fuse, Inspect, InspectErr, IterOk,
        IterResult, Map, MapErr, Once, OrElse, Peekable, PollFn, Repeat, Select,
        Skip, SkipWhile, StreamFuture, Take, TakeWhile, Then, Unfold, Zip,
        StreamExt, empty, iter_ok, iter_result, once, poll_fn, repeat, unfold,
    };

    #[cfg(feature = "std")]
    pub use futures_util::stream::{
        futures_unordered, select_all, BufferUnordered, Buffered, CatchUnwind, Chunks, Collect,
        FuturesUnordered, FuturesOrdered, ReuniteError, SelectAll, SplitSink, SplitStream,
        futures_ordered,
    };
}

pub mod task {
    //! Tools for working with tasks.
    //!
    //! This module contains:
    //!
    //! - [`Context`](::task::Context), which provides contextual data present
    //! for every task, including a handle for waking up the task.
    //!
    //! - [`Waker`](::task::Waker), a handle for waking up a task.
    //!
    //! - [`LocalKey`](::task::LocalKey), a key for task-local data; you should
    //! use the [`task_local` macro](../macro.task_local.html) to set up such keys.
    //!
    //! Tasks themselves are generally created by spawning a future onto [an
    //! executor](::executor). However, you can manually construct a task by
    //! creating your own `Context` instance, and polling a future with it.
    //!
    //! The remaining types and traits in the module are used for implementing
    //! executors or dealing with synchronization issues around task wakeup.

    pub use futures_core::task::{
        Context, LocalMap, Waker, UnsafeWake,
    };

    #[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
    pub use futures_core::task::AtomicWaker;

    #[cfg(feature = "std")]
    pub use futures_core::task::{LocalKey, Wake};
}

#[cfg(feature = "nightly")]
pub mod stable {
    pub use futures_stable::{StableFuture, StableStream};

    #[cfg(feature = "std")]
    pub use futures_stable::{StableExecutor, block_on_stable};
}

#[cfg(feature = "nightly")]
pub mod __rt {
    pub extern crate std;
    pub use futures_async_runtime::*;
}
<commit_msg>Hide __rt from documentation<commit_after>//! Abstractions for asynchronous programming.
//!
//! This crate provides a number of core abstractions for writing asynchronous code:
//!
//! - [Futures](::Future) (sometimes called promises), which represent a single
//! asychronous computation that may result in a final value or an error.
//!
//! - [Streams](::Stream), which represent a series of values or errors produced asynchronously.
//!
//! - [Sinks](::Sink), which support asynchronous writing of data.
//!
//! - [Executors](::executor), which are responsible for running asynchronous tasks.
//!
//! The crate also contains abstractions for [asynchronous I/O](::io) and
//! [cross-task communication](::channel).
//!
//! Underlying all of this is the *task system*, which is a form of lightweight
//! threading. Large asynchronous computations are built up using futures,
//! streams and sinks, and then spawned as independent tasks that are run to
//! completion, but *do not block* the thread running them.

#![no_std]
#![doc(html_root_url = "https://docs.rs/futures/0.2.0-beta")]

#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(feature = "nightly", feature(use_extern_macros))]

extern crate futures_async_runtime;
extern crate futures_core;
extern crate futures_channel;
extern crate futures_executor;
extern crate futures_io;
extern crate futures_sink;
extern crate futures_stable;
extern crate futures_util;

#[cfg(feature = "nightly")] extern crate futures_macro_async;
#[cfg(feature = "nightly")] extern crate futures_macro_await;

pub use futures_core::future::{Future, IntoFuture};
pub use futures_util::future::FutureExt;
pub use futures_core::stream::Stream;
pub use futures_util::stream::StreamExt;
pub use futures_sink::Sink;
pub use futures_util::sink::SinkExt;

// Macros redefined here because macro re-exports are unstable.

/// A macro for extracting the successful type of a `Poll<T, E>`.
///
/// This macro bakes in propagation of both errors and `Pending` signals by
/// returning early.
#[macro_export]
macro_rules! try_ready {
    ($e:expr) => (match $e {
        Ok($crate::prelude::Async::Ready(t)) => t,
        Ok($crate::prelude::Async::Pending) => return Ok($crate::prelude::Async::Pending),
        Err(e) => return Err(From::from(e)),
    })
}

/// A macro to create a `static` of type `LocalKey`.
///
/// This macro is intentionally similar to the `thread_local!`, and creates a
/// `static` which has a `get_mut` method to access the data on a task.
///
/// The data associated with each task local is per-task, so different tasks
/// will contain different values.
#[macro_export]
macro_rules! task_local {
    (static $NAME:ident: $t:ty = $e:expr) => (
        static $NAME: $crate::task::LocalKey<$t> = {
            fn __init() -> $t { $e }
            fn __key() -> ::std::any::TypeId {
                struct __A;
                ::std::any::TypeId::of::<__A>()
            }
            $crate::task::LocalKey {
                __init: __init,
                __key: __key,
            }
        };
    )
}

pub use futures_core::{Async, Poll, Never};

#[cfg(feature = "std")]
pub mod channel {
    //! Cross-task communication.
    //!
    //! Like threads, concurrent tasks sometimes need to communicate with each
    //! other. This module contains two basic abstractions for doing so:
    //!
    //! - [oneshot](::channel::oneshot), a way of sending a single value from
    //! one task to another.
    //!
    //! - [mpsc](::channel::mpsc), a multi-producer, single-consumer channel for
    //! sending values between tasks, analogous to the similarly-named structure
    //! in the standard library.

    pub use futures_channel::{oneshot, mpsc};
}

#[cfg(feature = "std")]
pub mod executor {
    //! Task execution.
    //!
    //! All asynchronous computation occurs within an executor, which is
    //! capable of spawning futures as tasks. This module provides several
    //! built-in executors, as well as tools for building your own.
    //!
    //! # Using a thread pool (M:N task scheduling)
    //!
    //! Most of the time tasks should be executed on a [thread
    //! pool](::executor::ThreadPool). A small set of worker threads can handle
    //! a very large set of spawned tasks (which are much lighter weight than
    //! threads).
    //!
    //! The simplest way to use a thread pool is to
    //! [`run`](::executor::ThreadPool::run) an initial task on it, which can
    //! then spawn further tasks back onto the pool to complete its work:
    //!
    //! ```
    //! use futures::executor::ThreadPool;
    //! # use futures::future::{Future, lazy};
    //! # let my_app: Box<Future<Item = (), Error = ()>> = Box::new(lazy(|_| Ok(())));
    //!
    //! // assumping `my_app: Future`
    //! ThreadPool::new().run(my_app);
    //! ```
    //!
    //! The call to [`run`](::executor::ThreadPool::run) will block the current
    //! thread until the future defined by `my_app` completes, and will return
    //! the result of that future.
    //!
    //! # Spawning additional tasks
    //!
    //! There are two ways to spawn a task:
    //!
    //! - Spawn onto a "default" execuctor by calling the top-level
    //! [`spawn`](::executor::spawn) function or [pulling the executor from the
    //! task context](::task::Context::executor).
    //!
    //! - Spawn onto a specific executor by calling its
    //! [`spawn`](::executor::Executor::spawn) method directly.
    //!
    //! Every task always has an associated default executor, which is usually
    //! the executor on which the task is running.
    //!
    //! # Single-threaded execution
    //!
    //! In addition to thread pools, it's possible to run a task (and the tasks
    //! it spawns) entirely within a single thread via the
    //! [`LocalPool`](::executor::LocalPool) executor. Aside from cutting down
    //! on synchronization costs, this executor also makes it possible to
    //! execute non-`Send` tasks, via
    //! [`spawn_local`](::executor::LocalExecutor::spawn_local). The `LocalPool`
    //! is best suited for running I/O-bound tasks that do relatively little
    //! work between I/O operations.
    //!
    //! There is also a convenience function,
    //! [`block_on`](::executor::block_on), for simply running a future to
    //! completion on the current thread, while routing any spawned tasks
    //! to a global thread pool.
    // TODO: add docs (or link to apr) for implementing an executor

    pub use futures_executor::{
        Enter, EnterError, LocalExecutor, LocalPool, Spawn, SpawnWithHandle, ThreadPool,
        ThreadPoolBuilder, JoinHandle, block_on, enter, spawn, spawn_with_handle
    };
    pub use futures_core::executor::{SpawnError, Executor};
}

pub mod future {
    //! Asynchronous values.
    //!
    //! This module contains:
    //!
    //! - The [`Future` trait](::Future).
    //!
    //! - The [`FutureExt`](::future::FutureExt) trait, which provides adapters
    //! for chaining and composing futures.
    //!
    //! - Top-level future combinators like [`lazy`](::future::lazy) which
    //! creates a future from a closure that defines its return value, and
    //! [`result`](::future::result), which constructs a future with an
    //! immediate defined value.

    pub use futures_core::future::{
        FutureOption, FutureResult, Future, IntoFuture, err, ok, result
    };
    pub use futures_util::future::{
        AndThen, Empty, Flatten, FlattenStream, ErrInto, Fuse,
        Inspect, IntoStream, Join, Join3, Join4, Join5, Lazy, LoopFn,
        Map, MapErr, OrElse, PollFn, Select, Then, Either, Loop, FutureExt, empty,
        lazy, loop_fn, poll_fn
    };

    #[cfg(feature = "std")]
    pub use futures_util::future::{
        CatchUnwind, JoinAll, SelectAll, SelectOk, Shared, SharedError, SharedItem,
        join_all, select_all, select_ok
    };
}

#[cfg(feature = "std")]
pub mod io {
    //! Asynchronous I/O.
    //!
    //! This module is the asynchronous version of `std::io`. It defines two
    //! traits, [`AsyncRead`](::io::AsyncRead) and
    //! [`AsyncWrite`](::io::AsyncWrite), which mirror the `Read` and `Write`
    //! traits of the standard library. However, these traits integrate with the
    //! asynchronous task system, so that if an I/O object isn't ready for
    //! reading (or writing), the thread is not blocked, and instead the current
    //! task is queued to be woken when I/O is ready.
    //!
    //! In addition, the [`AsyncReadExt`](::io::AsyncReadExt) and
    //! [`AsyncWriteExt`](::io::AsyncWriteExt) extension traits offer a variety
    //! of useful combinators for operating with asynchronous I/O objects,
    //! including ways to work with them using futures, streams and sinks.

    pub use futures_io::{
        Error, Initializer, IoVec, ErrorKind, AsyncRead, AsyncWrite, Result
    };
    pub use futures_util::io::{
        AsyncReadExt, AsyncWriteExt, AllowStdIo, Close, CopyInto, Flush,
        Read, ReadExact, ReadHalf, ReadToEnd, Window, WriteAll, WriteHalf,
    };
}

#[cfg(feature = "std")]
pub mod never {
    //! This module contains the `Never` type.
    //!
    //! Values of this type can never be created and will never exist.
    pub use futures_core::never::*;
}

pub mod prelude {
    //! A "prelude" for crates using the `futures` crate.
    //!
    //! This prelude is similar to the standard library's prelude in that you'll
    //! almost always want to import its entire contents, but unlike the standard
    //! library's prelude you'll have to do so manually:
    //!
    //! ```
    //! use futures::prelude::*;
    //! ```
    //!
    //! The prelude may grow over time as additional items see ubiquitous use.

    pub use futures_core::{
        Future,
        IntoFuture,
        Stream,
        Async,
        Poll,
        Never,
        task,
    };

    #[cfg(feature = "std")]
    pub use futures_core::executor::Executor;

    pub use futures_sink::Sink;

    #[cfg(feature = "std")]
    pub use futures_io::{
        AsyncRead,
        AsyncWrite,
    };

    pub use futures_util::{
        FutureExt,
        StreamExt,
        SinkExt,
    };

    #[cfg(feature = "std")]
    pub use futures_util::{
        AsyncReadExt,
        AsyncWriteExt,
    };

    #[cfg(feature = "nightly")]
    pub use futures_macro_async::{
        async,
        async_move,
        async_stream,
        async_stream_move,
        async_block,
        async_stream_block
    };

    #[cfg(feature = "nightly")]
    pub use futures_macro_await::{
        await,
        stream_yield,
        await_item
    };
}

pub mod sink {
    //! Asynchronous sinks.
    //!
    //! This module contains:
    //!
    //! - The [`Sink` trait](::Sink), which allows you to asynchronously write data.
    //!
    //! - The [`SinkExt`](::sink::SinkExt) trait, which provides adapters
    //! for chaining and composing sinks.

    pub use futures_sink::Sink;

    pub use futures_util::sink::{
        Close, Fanout, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
        WithFlatMap, SinkExt, close, flush,
    };

    #[cfg(feature = "std")]
    pub use futures_util::sink::Buffer;
}

pub mod stream {
    //! Asynchronous streams.
    //!
    //! This module contains:
    //!
    //! - The [`Stream` trait](::Stream), for objects that can asynchronously
    //! produce a sequence of values.
    //!
    //! - The [`StreamExt`](::future::StreamExt) trait, which provides adapters
    //! for chaining and composing streams.
    //!
    //! - Top-level stream contructors like [`iter_ok`](::stream::iter_ok) which
    //! creates a stream from an iterator, and
    //! [`futures_unordered`](::stream::futures_unordered()), which constructs a
    //! stream from a collection of futures.

    pub use futures_core::stream::Stream;

    pub use futures_util::stream::{
        AndThen, Chain, Concat, Empty, Filter, FilterMap, Flatten, Fold,
        ForEach, Forward, ErrInto, Fuse, Inspect, InspectErr, IterOk,
        IterResult, Map, MapErr, Once, OrElse, Peekable, PollFn, Repeat, Select,
        Skip, SkipWhile, StreamFuture, Take, TakeWhile, Then, Unfold, Zip,
        StreamExt, empty, iter_ok, iter_result, once, poll_fn, repeat, unfold,
    };

    #[cfg(feature = "std")]
    pub use futures_util::stream::{
        futures_unordered, select_all, BufferUnordered, Buffered, CatchUnwind, Chunks, Collect,
        FuturesUnordered, FuturesOrdered, ReuniteError, SelectAll, SplitSink, SplitStream,
        futures_ordered,
    };
}

pub mod task {
    //! Tools for working with tasks.
    //!
    //! This module contains:
    //!
    //! - [`Context`](::task::Context), which provides contextual data present
    //! for every task, including a handle for waking up the task.
    //!
    //! - [`Waker`](::task::Waker), a handle for waking up a task.
    //!
    //! - [`LocalKey`](::task::LocalKey), a key for task-local data; you should
    //! use the [`task_local` macro](../macro.task_local.html) to set up such keys.
    //!
    //! Tasks themselves are generally created by spawning a future onto [an
    //! executor](::executor). However, you can manually construct a task by
    //! creating your own `Context` instance, and polling a future with it.
    //!
    //! The remaining types and traits in the module are used for implementing
    //! executors or dealing with synchronization issues around task wakeup.

    pub use futures_core::task::{
        Context, LocalMap, Waker, UnsafeWake,
    };

    #[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
    pub use futures_core::task::AtomicWaker;

    #[cfg(feature = "std")]
    pub use futures_core::task::{LocalKey, Wake};
}

#[cfg(feature = "nightly")]
pub mod stable {
    pub use futures_stable::{StableFuture, StableStream};

    #[cfg(feature = "std")]
    pub use futures_stable::{StableExecutor, block_on_stable};
}

#[cfg(feature = "nightly")]
#[doc(hidden)]
pub mod __rt {
    pub extern crate std;
    pub use futures_async_runtime::*;
}
<|endoftext|>


<commit_before>static LOREM_IPSUM: &'static str =
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
";

use std::error::Error;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;

fn main() {
    let path = Path::new("out/lorem_ipsum.txt");
    let display = path.display();

    // Open a file in write-only mode, returns `io::Result<File>`
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}",
                           display,
                           why.description()),
        Ok(file) => file,
    };

    // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>`
    match file.write_all(LOREM_IPSUM.as_bytes()) {
        Err(why) => {
            panic!("couldn't write to {}: {}", display,
                                               why.description())
        },
        Ok(_) => println!("successfully wrote to {}", display),
    }
}
<commit_msg>Translate examples/std_misc/file/create/create.rs<commit_after>static LOREM_IPSUM: &'static str =
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
";

use std::error::Error;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;

fn main() {
    let path = Path::new("out/lorem_ipsum.txt");
    let display = path.display();

    // 以只写模式打开文件，返回 `io::Result<File>`
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}",
                           display,
                           why.description()),
        Ok(file) => file,
    };

    // 将 `LOREM_IPSUM` 字符串写进 `file`，返回 `io::Result<()>`
    match file.write_all(LOREM_IPSUM.as_bytes()) {
        Err(why) => {
            panic!("couldn't write to {}: {}", display,
                                               why.description())
        },
        Ok(_) => println!("successfully wrote to {}", display),
    }
}
<|endoftext|>


<commit_before>use std::ptr;
use std::mem;

// TODO: GrpcResult
// return message and size consumed
pub fn parse_grpc_frame(stream: &[u8]) -> Option<(&[u8], usize)> {
    let header_len = 5;
    if stream.len() < header_len {
        return None;
    }
    let compressed = match stream[0] {
        0 => false,
        1 => true,
        _ => panic!("unknown compression flag"),
    };
    if compressed {
        panic!("compression is not implemented");
    }
    let mut len_raw = 0u32;
    unsafe {
        ptr::copy_nonoverlapping(&stream[1] as *const u8, &mut len_raw as *mut u32 as *mut u8, 4);
    }
    let len = len_raw.to_be() as usize;
    let end = len + header_len;
    if end > stream.len() {
        return None;
    }

    Some((&stream[header_len..end], end))
}

pub fn parse_grpc_frame_completely(stream: &[u8]) -> Option<&[u8]> {
    match parse_grpc_frame(stream) {
        Some((bytes, pos)) if pos == stream.len() => Some(bytes),
        _ => None,
    }
}

pub fn write_grpc_frame(stream: &mut Vec<u8>, frame: &[u8]) {
	stream.push(0); // compressed flag
	let len_raw: [u8; 4] = unsafe {
	    mem::transmute((frame.len() as u32).to_be())
	};
	stream.extend(&len_raw);
	stream.extend(frame);
}

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

    #[test]
    fn test_parse_frame() {
        assert_eq!(None, parse_frame(b""));
        assert_eq!(None, parse_frame(b"1"));
        assert_eq!(None, parse_frame(b"14sc"));
        assert_eq!(
            None,
            parse_frame(b"\x00\x00\x00\x00\x07\x0a\x05wo"));
        assert_eq!(
            Some((&b"\x0a\x05world"[..], 12)),
            parse_frame(b"\x00\x00\x00\x00\x07\x0a\x05world"));
    }
}
<commit_msg>fix test<commit_after>use std::ptr;
use std::mem;

// TODO: GrpcResult
// return message and size consumed
pub fn parse_grpc_frame(stream: &[u8]) -> Option<(&[u8], usize)> {
    let header_len = 5;
    if stream.len() < header_len {
        return None;
    }
    let compressed = match stream[0] {
        0 => false,
        1 => true,
        _ => panic!("unknown compression flag"),
    };
    if compressed {
        panic!("compression is not implemented");
    }
    let mut len_raw = 0u32;
    unsafe {
        ptr::copy_nonoverlapping(&stream[1] as *const u8, &mut len_raw as *mut u32 as *mut u8, 4);
    }
    let len = len_raw.to_be() as usize;
    let end = len + header_len;
    if end > stream.len() {
        return None;
    }

    Some((&stream[header_len..end], end))
}

pub fn parse_grpc_frame_completely(stream: &[u8]) -> Option<&[u8]> {
    match parse_grpc_frame(stream) {
        Some((bytes, pos)) if pos == stream.len() => Some(bytes),
        _ => None,
    }
}

pub fn write_grpc_frame(stream: &mut Vec<u8>, frame: &[u8]) {
	stream.push(0); // compressed flag
	let len_raw: [u8; 4] = unsafe {
	    mem::transmute((frame.len() as u32).to_be())
	};
	stream.extend(&len_raw);
	stream.extend(frame);
}

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

    #[test]
    fn test_parse_frame() {
        assert_eq!(None, parse_grpc_frame(b""));
        assert_eq!(None, parse_grpc_frame(b"1"));
        assert_eq!(None, parse_grpc_frame(b"14sc"));
        assert_eq!(
            None,
            parse_grpc_frame(b"\x00\x00\x00\x00\x07\x0a\x05wo"));
        assert_eq!(
            Some((&b"\x0a\x05world"[..], 12)),
            parse_grpc_frame(b"\x00\x00\x00\x00\x07\x0a\x05world"));
    }
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use ffi;
use types::{gchar,gpointer};
use util::is_false;

use libc;
use std::error::Error;
use std::fmt;
use std::mem::transmute;
use std::ptr;
use std::slice;
use std::str;

const NUL: u8 = 0;

pub struct GStr {
    ptr: *const gchar,
}

impl GStr {

    pub unsafe fn from_raw_buf(ptr: *mut gchar) -> GStr {
        assert!(ptr.is_not_null());
        GStr { ptr: ptr as *const gchar }
    }

    pub fn parse_as_bytes<'a>(&'a self) -> &'a [u8] {
        unsafe {
            let r: &'a *const u8 = transmute(&self.ptr);
            slice::from_raw_buf(r, libc::strlen(self.ptr) as uint)
        }
    }

    #[inline]
    pub fn parse_as_utf8<'a>(&'a self) -> Result<&'a str, str::Utf8Error> {
        str::from_utf8(self.parse_as_bytes())
    }

    #[inline]
    pub unsafe fn parse_as_utf8_unchecked<'a>(&'a self) -> &'a str {
        str::from_utf8_unchecked(self.parse_as_bytes())
    }
}

impl Drop for GStr {
    fn drop(&mut self) {
        unsafe { ffi::g_free(self.ptr as gpointer) }
    }
}

impl Clone for GStr {
    fn clone(&self) -> GStr {
        unsafe {
            GStr::from_raw_buf(ffi::g_strdup(self.ptr))
        }
    }
}

impl PartialEq for GStr {
    fn eq(&self, other: &GStr) -> bool {
        unsafe { libc::strcmp(self.ptr, other.ptr) == 0 }
    }
}

impl Eq for GStr { }

#[deriving(Copy)]
pub enum StrDataError {
    ContainsNul(uint),
    InvalidUtf8(uint)
}

impl Error for StrDataError {

    fn description(&self) -> &str {
        match *self {
            StrDataError::ContainsNul(_)
                => "invalid data for C string: contains a zero byte",
            StrDataError::InvalidUtf8(_)
                => "invalid UTF-8 sequence",
        }
    }

    fn detail(&self) -> Option<String> {
        match *self {
            StrDataError::ContainsNul(pos)
                => Some(format!("NUL at position {}", pos)),
            StrDataError::InvalidUtf8(pos)
                => Some(format!("Invalid sequence at {}", pos)),
        }
    }
}

impl fmt::Show for StrDataError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StrDataError::ContainsNul(pos)
                => write!(f, "invalid data for C string: NUL at position {}", pos),
            StrDataError::InvalidUtf8(pos)
                => write!(f, "invalid UTF-8 sequence at position {}", pos),
        }
    }
}

enum GStrData {
    Static(&'static [u8]),
    Owned(Vec<u8>),
    GLib(GStr)
}

pub struct Utf8Arg {
    data: GStrData
}

fn vec_into_utf8(mut v: Vec<u8>) -> Utf8Arg {
    v.push(NUL);
    Utf8Arg { data: GStrData::Owned(v) }
}

impl Utf8Arg {

    pub fn from_str(s: &str) -> Result<Utf8Arg, StrDataError> {
        let bytes = s.as_bytes();
        if let Some(pos) = bytes.position_elem(&NUL) {
            return Err(StrDataError::ContainsNul(pos));
        }
        Ok(vec_into_utf8(bytes.to_vec()))
    }

    pub fn from_static_str(s: &'static str) -> Utf8Arg {
        let bytes = s.as_bytes();
        if bytes[bytes.len() - 1] != 0 {
            panic!("static string is not null-terminated: \"{}\"", s);
        }
        Utf8Arg { data: GStrData::Static(bytes) }
    }

    pub fn as_ptr(&self) -> *const gchar {
        match self.data {
            GStrData::Static(s) => s.as_ptr() as *const gchar,
            GStrData::Owned(ref v) => v.as_ptr() as *const gchar,
            GStrData::GLib(ref g) => g.ptr
        }
    }
}

pub trait IntoUtf8 {

    fn into_utf8(self) -> Result<Utf8Arg, StrDataError>;

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg;
}

impl<'a> IntoUtf8 for &'a str {

    #[inline]
    fn into_utf8(self) -> Result<Utf8Arg, StrDataError> {
        Utf8Arg::from_str(self)
    }

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg {
        vec_into_utf8(self.as_bytes().to_vec())
    }
}

impl IntoUtf8 for String {

    fn into_utf8(self) -> Result<Utf8Arg, StrDataError> {
        if let Some(pos) = self.as_bytes().position_elem(&NUL) {
            return Err(StrDataError::ContainsNul(pos));
        }
        Ok(vec_into_utf8(self.into_bytes()))
    }

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg {
        vec_into_utf8(self.into_bytes())
    }
}

impl IntoUtf8 for GStr {

    fn into_utf8(self) -> Result<Utf8Arg, StrDataError> {
        let mut end: *const gchar = ptr::null_mut();
        let valid = unsafe { ffi::g_utf8_validate(self.ptr, -1, &mut end) };
        if is_false(valid) {
            let pos = end as uint - self.ptr as uint;
            return Err(StrDataError::InvalidUtf8(pos));
        }
        Ok(Utf8Arg { data: GStrData::GLib(self) })
    }

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg {
        Utf8Arg { data: GStrData::GLib(self) }
    }
}
<commit_msg>gstr: Added parse methods to convert raw pointers to slices<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use ffi;
use types::{gchar,gpointer};
use util::is_false;

use libc;
use std::error::Error;
use std::fmt;
use std::mem;
use std::ptr;
use std::slice;
use std::str;

const NUL: u8 = 0;

pub struct GStr {
    ptr: *const gchar,
}

pub unsafe fn parse_as_bytes(raw: & *const gchar) -> &[u8] {
    assert!(raw.is_not_null());
    let r = mem::copy_lifetime(raw, &(*raw as *const u8));
    slice::from_raw_buf(r, libc::strlen(*raw) as uint)
}

#[inline]
pub unsafe fn parse_as_utf8(raw: & *const gchar)
                           -> Result<&str, str::Utf8Error>
{
    str::from_utf8(parse_as_bytes(raw))
}

#[inline]
pub unsafe fn parse_as_utf8_unchecked(raw: & *const gchar) -> &str {
    str::from_utf8_unchecked(parse_as_bytes(raw))
}

impl GStr {

    pub unsafe fn from_raw_buf(ptr: *mut gchar) -> GStr {
        assert!(ptr.is_not_null());
        GStr { ptr: ptr as *const gchar }
    }

    pub fn parse_as_bytes<'a>(&'a self) -> &'a [u8] {
        unsafe {
            let r = mem::copy_lifetime(self, &(self.ptr as *const u8));
            slice::from_raw_buf(r, libc::strlen(self.ptr) as uint)
        }
    }

    #[inline]
    pub fn parse_as_utf8<'a>(&'a self) -> Result<&'a str, str::Utf8Error> {
        str::from_utf8(self.parse_as_bytes())
    }

    #[inline]
    pub unsafe fn parse_as_utf8_unchecked<'a>(&'a self) -> &'a str {
        str::from_utf8_unchecked(self.parse_as_bytes())
    }
}

impl Drop for GStr {
    fn drop(&mut self) {
        unsafe { ffi::g_free(self.ptr as gpointer) }
    }
}

impl Clone for GStr {
    fn clone(&self) -> GStr {
        unsafe {
            GStr::from_raw_buf(ffi::g_strdup(self.ptr))
        }
    }
}

impl PartialEq for GStr {
    fn eq(&self, other: &GStr) -> bool {
        unsafe { libc::strcmp(self.ptr, other.ptr) == 0 }
    }
}

impl Eq for GStr { }

#[deriving(Copy)]
pub enum StrDataError {
    ContainsNul(uint),
    InvalidUtf8(uint)
}

impl Error for StrDataError {

    fn description(&self) -> &str {
        match *self {
            StrDataError::ContainsNul(_)
                => "invalid data for C string: contains a zero byte",
            StrDataError::InvalidUtf8(_)
                => "invalid UTF-8 sequence",
        }
    }

    fn detail(&self) -> Option<String> {
        match *self {
            StrDataError::ContainsNul(pos)
                => Some(format!("NUL at position {}", pos)),
            StrDataError::InvalidUtf8(pos)
                => Some(format!("Invalid sequence at {}", pos)),
        }
    }
}

impl fmt::Show for StrDataError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StrDataError::ContainsNul(pos)
                => write!(f, "invalid data for C string: NUL at position {}", pos),
            StrDataError::InvalidUtf8(pos)
                => write!(f, "invalid UTF-8 sequence at position {}", pos),
        }
    }
}

enum GStrData {
    Static(&'static [u8]),
    Owned(Vec<u8>),
    GLib(GStr)
}

pub struct Utf8Arg {
    data: GStrData
}

fn vec_into_utf8(mut v: Vec<u8>) -> Utf8Arg {
    v.push(NUL);
    Utf8Arg { data: GStrData::Owned(v) }
}

impl Utf8Arg {

    pub fn from_str(s: &str) -> Result<Utf8Arg, StrDataError> {
        let bytes = s.as_bytes();
        if let Some(pos) = bytes.position_elem(&NUL) {
            return Err(StrDataError::ContainsNul(pos));
        }
        Ok(vec_into_utf8(bytes.to_vec()))
    }

    pub fn from_static_str(s: &'static str) -> Utf8Arg {
        let bytes = s.as_bytes();
        if bytes[bytes.len() - 1] != 0 {
            panic!("static string is not null-terminated: \"{}\"", s);
        }
        Utf8Arg { data: GStrData::Static(bytes) }
    }

    pub fn as_ptr(&self) -> *const gchar {
        match self.data {
            GStrData::Static(s) => s.as_ptr() as *const gchar,
            GStrData::Owned(ref v) => v.as_ptr() as *const gchar,
            GStrData::GLib(ref g) => g.ptr
        }
    }
}

pub trait IntoUtf8 {

    fn into_utf8(self) -> Result<Utf8Arg, StrDataError>;

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg;
}

impl<'a> IntoUtf8 for &'a str {

    #[inline]
    fn into_utf8(self) -> Result<Utf8Arg, StrDataError> {
        Utf8Arg::from_str(self)
    }

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg {
        vec_into_utf8(self.as_bytes().to_vec())
    }
}

impl IntoUtf8 for String {

    fn into_utf8(self) -> Result<Utf8Arg, StrDataError> {
        if let Some(pos) = self.as_bytes().position_elem(&NUL) {
            return Err(StrDataError::ContainsNul(pos));
        }
        Ok(vec_into_utf8(self.into_bytes()))
    }

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg {
        vec_into_utf8(self.into_bytes())
    }
}

impl IntoUtf8 for GStr {

    fn into_utf8(self) -> Result<Utf8Arg, StrDataError> {
        let mut end: *const gchar = ptr::null_mut();
        let valid = unsafe { ffi::g_utf8_validate(self.ptr, -1, &mut end) };
        if is_false(valid) {
            let pos = end as uint - self.ptr as uint;
            return Err(StrDataError::InvalidUtf8(pos));
        }
        Ok(Utf8Arg { data: GStrData::GLib(self) })
    }

    unsafe fn into_utf8_unchecked(self) -> Utf8Arg {
        Utf8Arg { data: GStrData::GLib(self) }
    }
}
<|endoftext|>


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

#[derive(Copy, Clone)]
struct PhantomVertex;
#[derive(Copy, Clone)]
struct PhantomFace;
#[derive(Copy, Clone)]
struct PhantomEdge;
#[derive(Copy, Clone)]
struct PhantomHalfedge;
pub type Vertex = Handle<PhantomVertex>;
pub type Face = Handle<PhantomFace>;
pub type Edge = Handle<PhantomEdge>;
pub type Halfedge = Handle<PhantomHalfedge>;

#[derive(Copy, Clone)]
pub struct Handle<A> {
    type_ : PhantomData<A>,
    index_ : Option<usize>,
}

impl<A> Handle<A> {
    pub fn invalid() -> Handle<A> {
        Handle {
            type_ : PhantomData,
            index_ : None,
        }
    }

    pub fn new(idx : usize) -> Handle<A> {
        Handle {
            type_ : PhantomData,
            index_ : Some(idx),
        }
    }

    pub fn idx(&self) -> Option<usize> {
        self.index_
    }

    pub fn reset(&mut self) {
        self.index_ = None;
    }

    pub fn is_valid(&self) -> bool {
        self.index_.is_some()
    }
}

impl<A> Ord for Handle<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.index_.cmp(&other.index_)
    }
}

impl<A> PartialOrd for Handle<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.index_.cmp(&other.index_))
    }
}

impl<A> PartialEq for Handle<A> {
    fn eq(&self, other: &Self) -> bool {
        self.index_ == other.index_
    }
}
impl<A> Eq for Handle<A> { }

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

    #[test]
    fn invalid() {
        let handle = Vertex::invalid();
        assert!(!handle.is_valid());
        assert!(handle.idx().is_none());
    }

    #[test]
    fn idx() {
        let idx = 42;
        let handle = Vertex::new(idx);
        assert!(handle.is_valid());

        assert!(handle.idx().is_some());
        assert!(handle.idx().unwrap() == idx);
    }

    #[test]
    fn reset() {
        let idx = 42;
        let mut handle = Vertex::new(idx);
        assert!(handle.is_valid());

        handle.reset();
        assert!(!handle.is_valid());
    }

    #[test]
    fn cmp() {
        let idx1 = 42;
        let idx2 = 13;
        let h1 = Vertex::new(idx1);
        let h2 = Vertex::new(idx2);
        let h3 = Vertex::new(idx1);

        assert!(h1!=h2);
        assert!(h1>h2);
        assert!(h2<h1);
        assert!(h1==h3);
        assert!(h1<=h3);
        assert_eq!(h2.cmp(&h1), Ordering::Less);
        assert_eq!(h1.cmp(&h2), Ordering::Greater);
        assert_eq!(h1.cmp(&h3), Ordering::Equal);
    }
}
<commit_msg>handle : adds documentation<commit_after>use std::marker::PhantomData;
use std::cmp::Ordering;

#[derive(Copy, Clone)]
struct PhantomVertex;
#[derive(Copy, Clone)]
struct PhantomFace;
#[derive(Copy, Clone)]
struct PhantomEdge;
#[derive(Copy, Clone)]
struct PhantomHalfedge;

pub type Vertex = Handle<PhantomVertex>;
pub type Face = Handle<PhantomFace>;
pub type Edge = Handle<PhantomEdge>;
pub type Halfedge = Handle<PhantomHalfedge>;

/// A basic handle
///
/// `Handle<A>` is a nice encapsulation for an `usize`. It's an elegant way to manipulate
/// elements (`Vertex`, `Face`, `Edge`, `Halfedge`).
#[derive(Copy, Clone)]
pub struct Handle<A> {
    type_ : PhantomData<A>,
    index_ : Option<usize>,
}

impl<A> Handle<A> {
    /// Constructs an invalid `Handle<A>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::handle::Vertex;
    ///
    /// let v = Vertex::invalid();
    /// ```
    pub fn invalid() -> Handle<A> {
        Handle {
            type_ : PhantomData,
            index_ : None,
        }
    }

    /// Constructs a new `Handle<A>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::handle::Vertex;
    ///
    /// let v = Vertex::new(3);
    /// ```
    pub fn new(idx : usize) -> Handle<A> {
        Handle {
            type_ : PhantomData,
            index_ : Some(idx),
        }
    }

    /// Returns the index of the given `Handle<A>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::handle::Vertex;
    ///
    /// let v = Vertex::new(42);
    /// assert!(v.idx().unwrap()==42);
    /// ```
    pub fn idx(&self) -> Option<usize> {
        self.index_
    }

    /// Reset the `Handle<A>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::handle::Vertex;
    ///
    /// let mut v = Vertex::new(42);
    /// v.reset();
    /// assert!(!v.is_valid());
    /// ```
    pub fn reset(&mut self) {
        self.index_ = None;
    }

    /// Returns if the `Handle<A>` is valid.
    ///
    /// # Examples
    ///
    /// ```
    /// use lwmesh::handle::Vertex;
    ///
    /// let mut v = Vertex::new(42);
    /// assert!(v.is_valid());
    /// ```
    pub fn is_valid(&self) -> bool {
        self.index_.is_some()
    }
}

impl<A> Ord for Handle<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.index_.cmp(&other.index_)
    }
}

impl<A> PartialOrd for Handle<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.index_.cmp(&other.index_))
    }
}

impl<A> PartialEq for Handle<A> {
    fn eq(&self, other: &Self) -> bool {
        self.index_ == other.index_
    }
}
impl<A> Eq for Handle<A> { }

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

    #[test]
    fn invalid() {
        let handle = Vertex::invalid();
        assert!(!handle.is_valid());
        assert!(handle.idx().is_none());
    }

    #[test]
    fn idx() {
        let idx = 42;
        let handle = Vertex::new(idx);
        assert!(handle.is_valid());

        assert!(handle.idx().is_some());
        assert!(handle.idx().unwrap() == idx);
    }

    #[test]
    fn reset() {
        let idx = 42;
        let mut handle = Vertex::new(idx);
        assert!(handle.is_valid());

        handle.reset();
        assert!(!handle.is_valid());
    }

    #[test]
    fn cmp() {
        let idx1 = 42;
        let idx2 = 13;
        let h1 = Vertex::new(idx1);
        let h2 = Vertex::new(idx2);
        let h3 = Vertex::new(idx1);

        assert!(h1!=h2);
        assert!(h1>h2);
        assert!(h2<h1);
        assert!(h1==h3);
        assert!(h1<=h3);
        assert_eq!(h2.cmp(&h1), Ordering::Less);
        assert_eq!(h1.cmp(&h2), Ordering::Greater);
        assert_eq!(h1.cmp(&h3), Ordering::Equal);
    }
}
<|endoftext|>


<commit_before><commit_msg>changed import_tasks to return a Vec of Results: Vec<Result<Task>><commit_after><|endoftext|>


<commit_before><commit_msg>fix: Add back in Abs filter<commit_after><|endoftext|>


<commit_before>pub use libc::{c_char, c_int, c_long};

use libc::c_void;
use libc::uintptr_t;
use libc::intptr_t;

pub type Value = uintptr_t;
pub type SignedValue = intptr_t;
pub type Id = uintptr_t;

pub type Argc = c_int;

<commit_msg>remove warning<commit_after>pub use libc::{c_char, c_int, c_long};

use libc::uintptr_t;
use libc::intptr_t;

pub type Value = uintptr_t;
pub type SignedValue = intptr_t;
pub type Id = uintptr_t;

pub type Argc = c_int;

<|endoftext|>


<commit_before>/*
 * Copyright 2018 Google Inc. All rights reserved.
 *
 * 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.
 */

// import the flatbuffers runtime library
extern crate flatbuffers;

// import the generated code
#[allow(dead_code, unused_imports)]
#[path = "./monster_generated.rs"]
#[allow(clippy::approx_constant)]  // We use low precision PI as a default value.
mod monster_generated;
pub use monster_generated::my_game::sample::{Color, Equipment,
                                             Monster, MonsterArgs,
                                             Vec3,
                                             Weapon, WeaponArgs};

// Example how to use FlatBuffers to create and read binary buffers.
#[allow(clippy::float_cmp)]
fn main() {
  // Build up a serialized buffer algorithmically.
  // Initialize it with a capacity of 1024 bytes.
  let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);

  // Serialize some weapons for the Monster: A 'sword' and an 'axe'.
  let weapon_one_name = builder.create_string("Sword");
  let weapon_two_name = builder.create_string("Axe");

  // Use the `Weapon::create` shortcut to create Weapons with named field
  // arguments.
  let sword = Weapon::create(&mut builder, &WeaponArgs{
      name: Some(weapon_one_name),
      damage: 3,
  });
  let axe = Weapon::create(&mut builder, &WeaponArgs{
      name: Some(weapon_two_name),
      damage: 5,
  });

  // Name of the Monster.
  let name = builder.create_string("Orc");

  // Inventory.
  let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

  // Create a FlatBuffer `vector` that contains offsets to the sword and axe
  // we created above.
  let weapons = builder.create_vector(&[sword, axe]);

  // Create the path vector of Vec3 objects:
  //let x = Vec3::new(1.0, 2.0, 3.0);
  //let y = Vec3::new(4.0, 5.0, 6.0);
  //let path = builder.create_vector(&[x, y]);

  // Note that, for convenience, it is also valid to create a vector of
  // references to structs, like this:
  // let path = builder.create_vector(&[&x, &y]);

  // Create the monster using the `Monster::create` helper function. This
  // function accepts a `MonsterArgs` struct, which supplies all of the data
  // needed to build a `Monster`. To supply empty/default fields, just use the
  // Rust built-in `Default::default()` function, as demononstrated below.
  let orc = Monster::create(&mut builder, &MonsterArgs{
      pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)),
      mana: 150,
      hp: 80,
      name: Some(name),
      inventory: Some(inventory),
      color: Color::Red,
      weapons: Some(weapons),
      equipped_type: Equipment::Weapon,
      equipped: Some(axe.as_union_value()),
      //path: Some(path),
      ..Default::default()
  });

  // Serialize the root of the object, without providing a file identifier.
  builder.finish(orc, None);

  // We now have a FlatBuffer we can store on disk or send over a network.

  // ** file/network code goes here :) **

  // Instead, we're going to access it right away (as if we just received it).
  // This must be called after `finish()`.
  let buf = builder.finished_data(); // Of type `&[u8]`

  // Get access to the root:
  let monster = flatbuffers::root::<Monster>(buf).unwrap();

  // Get and test some scalar types from the FlatBuffer.
  let hp = monster.hp();
  let mana = monster.mana();
  let name = monster.name();

  assert_eq!(hp, 80);
  assert_eq!(mana, 150);  // default
  assert_eq!(name, Some("Orc"));

  // Get and test a field of the FlatBuffer's `struct`.
  assert!(monster.pos().is_some());
  let pos = monster.pos().unwrap();
  let x = pos.x();
  let y = pos.y();
  let z = pos.z();
  assert_eq!(x, 1.0f32);
  assert_eq!(y, 2.0f32);
  assert_eq!(z, 3.0f32);

  // Get an element from the `inventory` FlatBuffer's `vector`.
  assert!(monster.inventory().is_some());
  let inv = monster.inventory().unwrap();

  // Note that this vector is returned as a slice, because direct access for
  // this type, a u8 vector, is safe on all platforms:
  let third_item = inv[2];
  assert_eq!(third_item, 2);

  // Get and test the `weapons` FlatBuffers's `vector`.
  assert!(monster.weapons().is_some());
  let weps = monster.weapons().unwrap();
  //let weps_len = weps.len();
  let wep2 = weps.get(1);
  let second_weapon_name = wep2.name();
  let second_weapon_damage = wep2.damage();
  assert_eq!(second_weapon_name, Some("Axe"));
  assert_eq!(second_weapon_damage, 5);

  // Get and test the `Equipment` union (`equipped` field).
  assert_eq!(monster.equipped_type(), Equipment::Weapon);
  let equipped = monster.equipped_as_weapon().unwrap();
  let weapon_name = equipped.name();
  let weapon_damage = equipped.damage();
  assert_eq!(weapon_name, Some("Axe"));
  assert_eq!(weapon_damage, 5);

  // Get and test the `path` FlatBuffers's `vector`.
  //assert_eq!(monster.path().unwrap().len(), 2);
  //assert_eq!(monster.path().unwrap()[0].x(), 1.0);
  //assert_eq!(monster.path().unwrap()[1].x(), 4.0);

  println!("The FlatBuffer was successfully created and accessed!");
  dbg!(monster);
}

#[cfg(test)]
#[test]
fn test_main() {
    main()
}
<commit_msg>[Rust] Fix small mistyping (#6585)<commit_after>/*
 * Copyright 2018 Google Inc. All rights reserved.
 *
 * 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.
 */

// import the flatbuffers runtime library
extern crate flatbuffers;

// import the generated code
#[allow(dead_code, unused_imports)]
#[path = "./monster_generated.rs"]
#[allow(clippy::approx_constant)]  // We use low precision PI as a default value.
mod monster_generated;
pub use monster_generated::my_game::sample::{Color, Equipment,
                                             Monster, MonsterArgs,
                                             Vec3,
                                             Weapon, WeaponArgs};

// Example how to use FlatBuffers to create and read binary buffers.
#[allow(clippy::float_cmp)]
fn main() {
  // Build up a serialized buffer algorithmically.
  // Initialize it with a capacity of 1024 bytes.
  let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);

  // Serialize some weapons for the Monster: A 'sword' and an 'axe'.
  let weapon_one_name = builder.create_string("Sword");
  let weapon_two_name = builder.create_string("Axe");

  // Use the `Weapon::create` shortcut to create Weapons with named field
  // arguments.
  let sword = Weapon::create(&mut builder, &WeaponArgs{
      name: Some(weapon_one_name),
      damage: 3,
  });
  let axe = Weapon::create(&mut builder, &WeaponArgs{
      name: Some(weapon_two_name),
      damage: 5,
  });

  // Name of the Monster.
  let name = builder.create_string("Orc");

  // Inventory.
  let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

  // Create a FlatBuffer `vector` that contains offsets to the sword and axe
  // we created above.
  let weapons = builder.create_vector(&[sword, axe]);

  // Create the path vector of Vec3 objects:
  //let x = Vec3::new(1.0, 2.0, 3.0);
  //let y = Vec3::new(4.0, 5.0, 6.0);
  //let path = builder.create_vector(&[x, y]);

  // Note that, for convenience, it is also valid to create a vector of
  // references to structs, like this:
  // let path = builder.create_vector(&[&x, &y]);

  // Create the monster using the `Monster::create` helper function. This
  // function accepts a `MonsterArgs` struct, which supplies all of the data
  // needed to build a `Monster`. To supply empty/default fields, just use the
  // Rust built-in `Default::default()` function, as demonstrated below.
  let orc = Monster::create(&mut builder, &MonsterArgs{
      pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)),
      mana: 150,
      hp: 80,
      name: Some(name),
      inventory: Some(inventory),
      color: Color::Red,
      weapons: Some(weapons),
      equipped_type: Equipment::Weapon,
      equipped: Some(axe.as_union_value()),
      //path: Some(path),
      ..Default::default()
  });

  // Serialize the root of the object, without providing a file identifier.
  builder.finish(orc, None);

  // We now have a FlatBuffer we can store on disk or send over a network.

  // ** file/network code goes here :) **

  // Instead, we're going to access it right away (as if we just received it).
  // This must be called after `finish()`.
  let buf = builder.finished_data(); // Of type `&[u8]`

  // Get access to the root:
  let monster = flatbuffers::root::<Monster>(buf).unwrap();

  // Get and test some scalar types from the FlatBuffer.
  let hp = monster.hp();
  let mana = monster.mana();
  let name = monster.name();

  assert_eq!(hp, 80);
  assert_eq!(mana, 150);  // default
  assert_eq!(name, Some("Orc"));

  // Get and test a field of the FlatBuffer's `struct`.
  assert!(monster.pos().is_some());
  let pos = monster.pos().unwrap();
  let x = pos.x();
  let y = pos.y();
  let z = pos.z();
  assert_eq!(x, 1.0f32);
  assert_eq!(y, 2.0f32);
  assert_eq!(z, 3.0f32);

  // Get an element from the `inventory` FlatBuffer's `vector`.
  assert!(monster.inventory().is_some());
  let inv = monster.inventory().unwrap();

  // Note that this vector is returned as a slice, because direct access for
  // this type, a u8 vector, is safe on all platforms:
  let third_item = inv[2];
  assert_eq!(third_item, 2);

  // Get and test the `weapons` FlatBuffers's `vector`.
  assert!(monster.weapons().is_some());
  let weps = monster.weapons().unwrap();
  //let weps_len = weps.len();
  let wep2 = weps.get(1);
  let second_weapon_name = wep2.name();
  let second_weapon_damage = wep2.damage();
  assert_eq!(second_weapon_name, Some("Axe"));
  assert_eq!(second_weapon_damage, 5);

  // Get and test the `Equipment` union (`equipped` field).
  assert_eq!(monster.equipped_type(), Equipment::Weapon);
  let equipped = monster.equipped_as_weapon().unwrap();
  let weapon_name = equipped.name();
  let weapon_damage = equipped.damage();
  assert_eq!(weapon_name, Some("Axe"));
  assert_eq!(weapon_damage, 5);

  // Get and test the `path` FlatBuffers's `vector`.
  //assert_eq!(monster.path().unwrap().len(), 2);
  //assert_eq!(monster.path().unwrap()[0].x(), 1.0);
  //assert_eq!(monster.path().unwrap()[1].x(), 4.0);

  println!("The FlatBuffer was successfully created and accessed!");
  dbg!(monster);
}

#[cfg(test)]
#[test]
fn test_main() {
    main()
}
<|endoftext|>