<commit_before>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program 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
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

#[macro_use]
extern crate log;
extern crate osmpbfreader;
extern crate rustc_serialize;
extern crate docopt;
extern crate mimirsbrunn;
extern crate rs_es;

use std::collections::HashSet;
use std::collections::HashMap;
use mimirsbrunn::rubber::Rubber;
use mimirsbrunn::objects::{Polygon, MultiPolygon};

pub type AdminsVec = Vec<mimirsbrunn::Admin>;

#[derive(RustcDecodable, Debug)]
struct Args {
    flag_input: String,
    flag_level: Vec<u32>,
    flag_connection_string: String,
}

static USAGE: &'static str = "
Usage:
    osm2mimir --help
    osm2mimir --input=<file> [--connection-string=<connection-string>] --level=<level>...

Options:
    -h, --help            Show this message.
    -i, --input=<file>    OSM PBF file.
    -l, --level=<level>   Admin levels to keep.
    -c, --connection-string=<connection-string>
                          Elasticsearch parameters, [default: http://localhost:9200/munin]
";

#[derive(Debug)]
struct AdminMatcher {
    admin_levels: HashSet<u32>,
}
impl AdminMatcher {
    pub fn new(levels: HashSet<u32>) -> AdminMatcher {
        AdminMatcher { admin_levels: levels }
    }

    pub fn is_admin(&self, obj: &osmpbfreader::OsmObj) -> bool {
        match *obj {
            osmpbfreader::OsmObj::Relation(ref rel) => {
                rel.tags.get("boundary").map_or(false, |v| v == "administrative") &&
                rel.tags.get("admin_level").map_or(false, |lvl| {
                    self.admin_levels.contains(&lvl.parse::<u32>().unwrap_or(0))
                })
            }
            _ => false,
        }
    }
}

struct BoundaryPart {
    nodes: Vec<osmpbfreader::Node>,
}

impl BoundaryPart {
    pub fn new(nodes: Vec<osmpbfreader::Node>) -> BoundaryPart {
        BoundaryPart { nodes: nodes }
    }
    pub fn first(&self) -> i64 {
        self.nodes.first().unwrap().id
    }
    pub fn last(&self) -> i64 {
        self.nodes.last().unwrap().id
    }
}

fn get_nodes(way: &osmpbfreader::Way,
             objects: &HashMap<osmpbfreader::OsmId, osmpbfreader::OsmObj>)
             -> Vec<osmpbfreader::Node> {
    let mut nodes = Vec::new();
    for node in &way.nodes {
        match objects.get(&osmpbfreader::OsmId::Node(*node)) {
            Some(n) => {
                match n {
                    &osmpbfreader::OsmObj::Node(ref node) => nodes.push(node.clone()),
                    _ => {}
                }
            }
            None => warn!("node not found ({}) for way {}", node, way.id),
        }
    }
    nodes
}

fn build_boundary(relation: &osmpbfreader::Relation,
                  objects: &HashMap<osmpbfreader::OsmId, osmpbfreader::OsmObj>)
                  -> Option<MultiPolygon> {
    let mut boundary_parts = Vec::new();
    for refe in relation.refs
                        .iter()
                        .filter(|rf| rf.role == "outer" || rf.role == "" || rf.role == "enclave") {
        match objects.get(&refe.member) {
            Some(m) => {
                match m {
                    &osmpbfreader::OsmObj::Way(ref way) => {
                        let nodes = get_nodes(&way, objects);
                        if nodes.len() < 2 {
                            continue;
                        }
                        boundary_parts.push(BoundaryPart::new(nodes));
                    }
                    _ => {}
                }
            }
            None => {
                warn!("not found member {:?} from rel {}: skipping the boundary",
                      refe.member,
                      relation.id);
                return None;//no hope to build the boundary here...
            }
        }
    }
    let mut multipoly = MultiPolygon { polygons: Vec::new() };
    while !boundary_parts.is_empty() {
        let mut current = -1;
        let mut first = 0;
        let mut nb_try = 0;

        let mut outer: Vec<osmpbfreader::Node> = Vec::new();
        let max_try = boundary_parts.len();
        while current != first && nb_try < max_try {
            let mut i = 0;
            while i < boundary_parts.len() {
                if outer.is_empty() {
                    first = boundary_parts[i].first();
                    current = boundary_parts[i].last();
                    outer.append(&mut boundary_parts[i].nodes);
                    boundary_parts.remove(i);
                    continue;

                }
                if current == boundary_parts[i].first() {
                    current = boundary_parts[i].last();
                    outer.append(&mut boundary_parts[i].nodes);
                    boundary_parts.remove(i);
                } else if current == boundary_parts[i].last() {
                    current = boundary_parts[i].first();
                    boundary_parts[i].nodes.reverse();
                    outer.append(&mut boundary_parts[i].nodes);
                    boundary_parts.remove(i);
                } else {
                    i += 1;
                }
                if current == first {
                    let polygon = Polygon::new(outer.iter()
                                                    .map(|n| {
                                                        mimirsbrunn::Coord {
                                                            lat: n.lat,
                                                            lon: n.lon,
                                                        }
                                                    })
                                                    .collect());
                    multipoly.polygons.push(polygon);
                    break;
                }
            }
            nb_try += 1;
        }
    }
    info!("{};{:?}", relation.id, multipoly.to_wkt());
    Some(multipoly)
}

fn administrative_regions(filename: &String, levels: HashSet<u32>) -> AdminsVec {
    let mut administrative_regions = AdminsVec::new();
    let path = std::path::Path::new(&filename);
    let r = std::fs::File::open(&path).unwrap();
    let mut pbf = osmpbfreader::OsmPbfReader::new(r);
    let matcher = AdminMatcher::new(levels);
    let objects = osmpbfreader::get_objs_and_deps(&mut pbf, |o| matcher.is_admin(o)).unwrap();
    // load administratives regions
    for (_, obj) in &objects {
        if !matcher.is_admin(&obj) {
            continue;
        }
        if let &osmpbfreader::OsmObj::Relation(ref relation) = obj {
            let level = relation.tags
                                .get("admin_level")
                                .and_then(|s| s.parse().ok());
            let level = match level {
                None => {
                    info!("invalid admin_level for relation {}: admin_level {:?}",
                          relation.id,
                          relation.tags.get("admin_level"));
                    continue;
                }
                Some(l) => l,
            };
            // administrative region with name ?
            let name = match relation.tags.get("name") {
                Some(val) => val,
                None => {
                    warn!("adminstrative region without name for relation {}:  admin_level {} \
                           ignored.",
                          relation.id,
                          level);
                    continue;
                }
            };
            // admininstrative region without coordinates
            let coord_centre = relation.refs
                                       .iter()
                                       .find(|rf| rf.role == "admin_centre")
                                       .and_then(|r| {
                                           objects.get(&r.member).and_then(|value| {
                                               match value {
                                                   &osmpbfreader::OsmObj::Node(ref node) => {
                                                       Some(mimirsbrunn::Coord {
                                                           lat: node.lat,
                                                           lon: node.lon,
                                                       })
                                                   }
                                                   _ => None,
                                               }
                                           })
                                       });

            let admin_id = match relation.tags.get("ref:INSEE") {
                Some(val) => format!("admin:fr:{}", val.trim_left_matches('0')),
                None => format!("admin:osm:{}", relation.id),
            };
            let zip_code = match relation.tags.get("addr:postcode") {
                Some(val) => &val[..],
                None => "",
            };
            let boundary = build_boundary(&relation, &objects);
            let admin = mimirsbrunn::Admin {
                id: admin_id,
                level: level,
                name: name.to_string(),
                zip_code: zip_code.to_string(),
                // TODO weight value ?
                weight: 1,
                coord: coord_centre,
                boundary: boundary,
            };
            administrative_regions.push(admin);
        }
    }
    return administrative_regions;
}

fn index_osm(es_cnx_string: &str, admins: &AdminsVec) -> Result<u32, rs_es::error::EsError> {
    let mut rubber = Rubber::new(es_cnx_string);
    rubber.create_index();
    match rubber.clean_db_by_doc_type(&["admin"]) {
        Err(e) => panic!("failed to clean data by document type: {}", e),
        Ok(nb) => info!("clean data by document type : {}", nb),
    }
    info!("Add data in elasticsearch db.");
    rubber.bulk_index(admins.iter())
}

fn main() {
    mimirsbrunn::logger_init().unwrap();
    debug!("importing adminstrative region into Mimir");
    let args: Args = docopt::Docopt::new(USAGE)
                         .and_then(|d| d.decode())
                         .unwrap_or_else(|e| e.exit());

    let levels = args.flag_level.iter().cloned().collect();
    let res = administrative_regions(&args.flag_input, levels);
    match index_osm(&args.flag_connection_string, &res) {
        Err(e) => panic!("failed to index osm because: {}", e),
        Ok(nb) => info!("Adminstrative regions: {}", nb),
    }

}
<commit_msg>code is more rustic!<commit_after>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program 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
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

#[macro_use]
extern crate log;
extern crate osmpbfreader;
extern crate rustc_serialize;
extern crate docopt;
extern crate mimirsbrunn;
extern crate rs_es;

use std::collections::HashSet;
use std::collections::HashMap;
use mimirsbrunn::rubber::Rubber;
use mimirsbrunn::objects::{Polygon, MultiPolygon};

pub type AdminsVec = Vec<mimirsbrunn::Admin>;

#[derive(RustcDecodable, Debug)]
struct Args {
    flag_input: String,
    flag_level: Vec<u32>,
    flag_connection_string: String,
}

static USAGE: &'static str = "
Usage:
    osm2mimir --help
    osm2mimir --input=<file> [--connection-string=<connection-string>] --level=<level>...

Options:
    -h, --help            Show this message.
    -i, --input=<file>    OSM PBF file.
    -l, --level=<level>   Admin levels to keep.
    -c, --connection-string=<connection-string>
                          Elasticsearch parameters, [default: http://localhost:9200/munin]
";

#[derive(Debug)]
struct AdminMatcher {
    admin_levels: HashSet<u32>,
}
impl AdminMatcher {
    pub fn new(levels: HashSet<u32>) -> AdminMatcher {
        AdminMatcher { admin_levels: levels }
    }

    pub fn is_admin(&self, obj: &osmpbfreader::OsmObj) -> bool {
        match *obj {
            osmpbfreader::OsmObj::Relation(ref rel) => {
                rel.tags.get("boundary").map_or(false, |v| v == "administrative") &&
                rel.tags.get("admin_level").map_or(false, |lvl| {
                    self.admin_levels.contains(&lvl.parse::<u32>().unwrap_or(0))
                })
            }
            _ => false,
        }
    }
}

struct BoundaryPart {
    nodes: Vec<osmpbfreader::Node>,
}

impl BoundaryPart {
    pub fn new(nodes: Vec<osmpbfreader::Node>) -> BoundaryPart {
        BoundaryPart { nodes: nodes }
    }
    pub fn first(&self) -> i64 {
        self.nodes.first().unwrap().id
    }
    pub fn last(&self) -> i64 {
        self.nodes.last().unwrap().id
    }
}

fn get_nodes(way: &osmpbfreader::Way,
             objects: &HashMap<osmpbfreader::OsmId, osmpbfreader::OsmObj>)
             -> Vec<osmpbfreader::Node> {
    way.nodes
       .iter()
       .filter_map(|node_id| objects.get(&osmpbfreader::OsmId::Node(*node_id)))
       .filter_map(|node_obj| if let &osmpbfreader::OsmObj::Node(ref node) = node_obj {
           Some(node.clone())
       } else {
           None
       })
       .collect()
}

fn build_boundary(relation: &osmpbfreader::Relation,
                  objects: &HashMap<osmpbfreader::OsmId, osmpbfreader::OsmObj>)
                  -> Option<MultiPolygon> {
    let mut boundary_parts: Vec<BoundaryPart> =
        relation.refs
                .iter()
                .filter(|rf| rf.role == "outer" || rf.role == "" || rf.role == "enclave")
                .filter_map(|refe| {
                    objects.get(&refe.member).or_else(|| {
                        warn!("missing element for relation {}", relation.id);
                        None
                    })
                })
                .filter_map(|way_obj| if let &osmpbfreader::OsmObj::Way(ref way) = way_obj {
                    Some(way)
                } else {
                    None
                })
                .map(|way| get_nodes(&way, objects))
                .filter(|nodes| nodes.len() > 1)
                .map(|nodes| BoundaryPart::new(nodes))
                .collect();
    let mut multipoly = MultiPolygon { polygons: Vec::new() };
    // we want to try build a polygon for a least each way
    while !boundary_parts.is_empty() {
        let mut current = -1;
        let mut first = 0;
        let mut nb_try = 0;

        let mut outer: Vec<osmpbfreader::Node> = Vec::new();
        // we try to close the polygon, if we can't we want to at least have tried one time per
        // way. We could improve that latter by trying to attach the way to both side of the
        // polygon
        let max_try = boundary_parts.len();
        while current != first && nb_try < max_try {
            let mut i = 0;
            while i < boundary_parts.len() {
                if outer.is_empty() {
                    // our polygon is empty, we initialise it with the current way
                    first = boundary_parts[i].first();
                    current = boundary_parts[i].last();
                    outer.append(&mut boundary_parts[i].nodes);
                    // this way has been used, we remove it from the pool
                    boundary_parts.remove(i);
                    continue;
                }
                if current == boundary_parts[i].first() {
                    // the start of current way touch the polygon, we add it and remove it from the
                    // pool
                    current = boundary_parts[i].last();
                    outer.append(&mut boundary_parts[i].nodes);
                    boundary_parts.remove(i);
                } else if current == boundary_parts[i].last() {
                    // the end of the current way touch the polygon, we reverse the way and add it
                    current = boundary_parts[i].first();
                    boundary_parts[i].nodes.reverse();
                    outer.append(&mut boundary_parts[i].nodes);
                    boundary_parts.remove(i);
                } else {
                    i += 1;
                    // didnt do anything, we want to explore the next way, if we had do something we
                    // will have removed the current way and there will be no need to increment
                }
                if current == first {
                    // our polygon is closed, we create it and add it to the multipolygon
                    let polygon = Polygon::new(outer.iter()
                                                    .map(|n| {
                                                        mimirsbrunn::Coord {
                                                            lat: n.lat,
                                                            lon: n.lon,
                                                        }
                                                    })
                                                    .collect());
                    multipoly.polygons.push(polygon);
                    break;
                }
            }
            nb_try += 1;
        }
    }
    debug!("polygon for relation {};{}", relation.id, multipoly.to_wkt());
    if multipoly.polygons.is_empty() {
        None
    } else {
        Some(multipoly)
    }
}

fn administrative_regions(filename: &String, levels: HashSet<u32>) -> AdminsVec {
    let mut administrative_regions = AdminsVec::new();
    let path = std::path::Path::new(&filename);
    let r = std::fs::File::open(&path).unwrap();
    let mut pbf = osmpbfreader::OsmPbfReader::new(r);
    let matcher = AdminMatcher::new(levels);
    let objects = osmpbfreader::get_objs_and_deps(&mut pbf, |o| matcher.is_admin(o)).unwrap();
    // load administratives regions
    for (_, obj) in &objects {
        if !matcher.is_admin(&obj) {
            continue;
        }
        if let &osmpbfreader::OsmObj::Relation(ref relation) = obj {
            let level = relation.tags
                                .get("admin_level")
                                .and_then(|s| s.parse().ok());
            let level = match level {
                None => {
                    info!("invalid admin_level for relation {}: admin_level {:?}",
                          relation.id,
                          relation.tags.get("admin_level"));
                    continue;
                }
                Some(l) => l,
            };
            // administrative region with name ?
            let name = match relation.tags.get("name") {
                Some(val) => val,
                None => {
                    warn!("adminstrative region without name for relation {}:  admin_level {} \
                           ignored.",
                          relation.id,
                          level);
                    continue;
                }
            };
            // admininstrative region without coordinates
            let coord_centre = relation.refs
                                       .iter()
                                       .find(|rf| rf.role == "admin_centre")
                                       .and_then(|r| {
                                           objects.get(&r.member).and_then(|value| {
                                               match value {
                                                   &osmpbfreader::OsmObj::Node(ref node) => {
                                                       Some(mimirsbrunn::Coord {
                                                           lat: node.lat,
                                                           lon: node.lon,
                                                       })
                                                   }
                                                   _ => None,
                                               }
                                           })
                                       });

            let admin_id = match relation.tags.get("ref:INSEE") {
                Some(val) => format!("admin:fr:{}", val.trim_left_matches('0')),
                None => format!("admin:osm:{}", relation.id),
            };
            let zip_code = match relation.tags.get("addr:postcode") {
                Some(val) => &val[..],
                None => "",
            };
            let boundary = build_boundary(&relation, &objects);
            let admin = mimirsbrunn::Admin {
                id: admin_id,
                level: level,
                name: name.to_string(),
                zip_code: zip_code.to_string(),
                // TODO weight value ?
                weight: 1,
                coord: coord_centre,
                boundary: boundary,
            };
            administrative_regions.push(admin);
        }
    }
    return administrative_regions;
}

fn index_osm(es_cnx_string: &str, admins: &AdminsVec) -> Result<u32, rs_es::error::EsError> {
    let mut rubber = Rubber::new(es_cnx_string);
    rubber.create_index();
    match rubber.clean_db_by_doc_type(&["admin"]) {
        Err(e) => panic!("failed to clean data by document type: {}", e),
        Ok(nb) => info!("clean data by document type : {}", nb),
    }
    info!("Add data in elasticsearch db.");
    rubber.bulk_index(admins.iter())
}

fn main() {
    mimirsbrunn::logger_init().unwrap();
    debug!("importing adminstrative region into Mimir");
    let args: Args = docopt::Docopt::new(USAGE)
                         .and_then(|d| d.decode())
                         .unwrap_or_else(|e| e.exit());

    let levels = args.flag_level.iter().cloned().collect();
    let res = administrative_regions(&args.flag_input, levels);
    match index_osm(&args.flag_connection_string, &res) {
        Err(e) => panic!("failed to index osm because: {}", e),
        Ok(nb) => info!("Adminstrative regions: {}", nb),
    }

}
<|endoftext|>


<commit_before>use super::schema::*;
use diesel::*;

#[test]
fn simple_distinct() {
    use schema::users::dsl::*;

    let connection = connection();
    connection
        .execute("INSERT INTO users (name) VALUES ('Sean'), ('Sean'), ('Tess')")
        .unwrap();

    let source = users.select(name).distinct();
    let expected_data = vec!["Sean".to_string(), "Tess".to_string()];
    let data: Vec<String> = source.load(&connection).unwrap();

    assert_eq!(expected_data, data);
}

#[cfg(feature = "postgres")]
#[test]
fn distinct_on() {
    use schema::users::dsl::*;

    let connection = connection();
    connection
        .execute(
            "INSERT INTO users (name, hair_color) VALUES ('Sean', 'black'), ('Sean', NULL), ('Tess', NULL), ('Tess', NULL)",
        )
        .unwrap();

    let source = users.select((name, hair_color)).distinct_on(name);
    let expected_data = vec![
        ("Sean".to_string(), Some("black".to_string())),
        ("Tess".to_string(), None),
    ];
    let data: Vec<_> = source.load(&connection).unwrap();

    assert_eq!(expected_data, data);
}
<commit_msg>Set order for distinct integration tests<commit_after>use super::schema::*;
use diesel::*;

#[test]
fn simple_distinct() {
    use schema::users::dsl::*;

    let connection = connection();
    connection
        .execute("INSERT INTO users (name) VALUES ('Sean'), ('Sean'), ('Tess')")
        .unwrap();

    let source = users.select(name).distinct().order(name);
    let expected_data = vec!["Sean".to_string(), "Tess".to_string()];
    let data: Vec<String> = source.load(&connection).unwrap();

    assert_eq!(expected_data, data);
}

#[cfg(feature = "postgres")]
#[test]
fn distinct_on() {
    use schema::users::dsl::*;

    let connection = connection();
    connection
        .execute(
            "INSERT INTO users (name, hair_color) VALUES ('Sean', 'black'), ('Sean', NULL), ('Tess', NULL), ('Tess', NULL)",
        )
        .unwrap();

    let source = users.select((name, hair_color)).order(name).distinct_on(name);
    let expected_data = vec![
        ("Sean".to_string(), Some("black".to_string())),
        ("Tess".to_string(), None),
    ];
    let data: Vec<_> = source.load(&connection).unwrap();

    assert_eq!(expected_data, data);
}
<|endoftext|>


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

extern crate combine;
extern crate edn;
extern crate mentat_query;

use self::combine::{eof, many1, parser, satisfy_map, Parser, ParseResult, Stream};
use self::combine::combinator::{Expected, FnParser, choice, try};
use self::edn::Value::PlainSymbol;
use self::mentat_query::{Element, FindSpec, Variable};

use super::error::{FindParseError, FindParseResult};

pub struct FindSp<I>(::std::marker::PhantomData<fn(I) -> I>);

type FindSpParser<O, I> = Expected<FnParser<I, fn(I) -> ParseResult<O, I>>>;

fn fn_parser<O, I>(f: fn(I) -> ParseResult<O, I>, err: &'static str) -> FindSpParser<O, I>
    where I: Stream<Item = edn::Value>
{
    parser(f).expected(err)
}

/// `satisfy_unwrap!` makes it a little easier to implement a `satisfy_map`
/// body that matches a particular `Value` enum case, otherwise returning `None`.
macro_rules! satisfy_unwrap {
    ( $cas: path, $var: ident, $body: block ) => {
        satisfy_map(|x: edn::Value| if let $cas($var) = x $body else { None })
    }
}

impl<I> FindSp<I>
    where I: Stream<Item = edn::Value>
{
    fn variable() -> FindSpParser<Variable, I> {
        fn_parser(FindSp::<I>::variable_, "variable")
    }

    fn variable_(input: I) -> ParseResult<Variable, I> {
        satisfy_map(|x: edn::Value| super::util::value_to_variable(&x)).parse_stream(input)
    }

    fn period() -> FindSpParser<(), I> {
        fn_parser(FindSp::<I>::period_, "period")
    }

    fn period_(input: I) -> ParseResult<(), I> {
        satisfy_map(|x: edn::Value| {
                if let PlainSymbol(ref s) = x {
                    if s.0.as_str() == "." {
                        return Some(());
                    }
                }
                return None;
            })
            .parse_stream(input)
    }

    fn ellipsis() -> FindSpParser<(), I> {
        fn_parser(FindSp::<I>::ellipsis_, "ellipsis")
    }

    fn ellipsis_(input: I) -> ParseResult<(), I> {
        satisfy_map(|x: edn::Value| {
                if let PlainSymbol(ref s) = x {
                    if s.0.as_str() == "..." {
                        return Some(());
                    }
                }
                return None;
            })
            .parse_stream(input)
    }

    fn find_scalar() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_scalar_, "find_scalar")
    }

    fn find_scalar_(input: I) -> ParseResult<FindSpec, I> {
        (FindSp::variable(), FindSp::period(), eof())
            .map(|(var, _, _)| FindSpec::FindScalar(Element::Variable(var)))
            .parse_stream(input)
    }

    fn find_coll() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_coll_, "find_coll")
    }

    fn find_coll_(input: I) -> ParseResult<FindSpec, I> {
        satisfy_unwrap!(edn::Value::Vector, y, {
                let mut p = (FindSp::variable(), FindSp::ellipsis(), eof())
                    .map(|(var, _, _)| FindSpec::FindColl(Element::Variable(var)));
                let r: ParseResult<FindSpec, _> = p.parse_lazy(&y[..]).into();
                FindSp::to_parsed_value(r)
            })
            .parse_stream(input)
    }

    fn elements() -> FindSpParser<Vec<Element>, I> {
        fn_parser(FindSp::<I>::elements_, "elements")
    }

    fn elements_(input: I) -> ParseResult<Vec<Element>, I> {
        (many1::<Vec<Variable>, _>(FindSp::variable()), eof())
            .map(|(vars, _)| {
                vars.into_iter()
                    .map(Element::Variable)
                    .collect()
            })
            .parse_stream(input)
    }

    fn find_rel() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_rel_, "find_rel")
    }

    fn find_rel_(input: I) -> ParseResult<FindSpec, I> {
        FindSp::elements().map(FindSpec::FindRel).parse_stream(input)
    }

    fn find_tuple() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_tuple_, "find_tuple")
    }

    fn find_tuple_(input: I) -> ParseResult<FindSpec, I> {
        satisfy_unwrap!(edn::Value::Vector, y, {
                let r: ParseResult<FindSpec, _> =
                    FindSp::elements().map(FindSpec::FindTuple).parse_lazy(&y[..]).into();
                FindSp::to_parsed_value(r)
            })
            .parse_stream(input)
    }

    fn find() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_, "find")
    }

    fn find_(input: I) -> ParseResult<FindSpec, I> {
        // Any one of the four specs might apply, so we combine them with `choice`.
        // Our parsers consume input, so we need to wrap them in `try` so that they
        // operate independently.
        choice::<[&mut Parser<Input = I, Output = FindSpec>; 4],
                 _>([&mut try(FindSp::find_scalar()),
                     &mut try(FindSp::find_coll()),
                     &mut try(FindSp::find_tuple()),
                     &mut try(FindSp::find_rel())])
            .parse_stream(input)
    }

    fn to_parsed_value<T>(r: ParseResult<T, I>) -> Option<T> {
        r.ok().map(|x| x.0)
    }
}

macro_rules! assert_parses_to {
    ( $parser: path, $input: expr, $expected: expr ) => {{
        let mut par = $parser();
        let result = par.parse(&$input[..]);
        assert_eq!(result, Ok(($expected, &[][..])));
    }}
}

#[test]
fn test_find_sp_variable() {
    let sym = edn::PlainSymbol::new("?x");
    let input = [edn::Value::PlainSymbol(sym.clone())];
    assert_parses_to!(FindSp::variable, input, Variable(sym));
}

#[test]
fn test_find_scalar() {
    let sym = edn::PlainSymbol::new("?x");
    let period = edn::PlainSymbol::new(".");
    let input = [edn::Value::PlainSymbol(sym.clone()), edn::Value::PlainSymbol(period.clone())];
    assert_parses_to!(FindSp::find_scalar,
                      input,
                      FindSpec::FindScalar(Element::Variable(Variable(sym))));
}

#[test]
fn test_find_coll() {
    let sym = edn::PlainSymbol::new("?x");
    let period = edn::PlainSymbol::new("...");
    let input = [edn::Value::Vector(vec![edn::Value::PlainSymbol(sym.clone()),
                                         edn::Value::PlainSymbol(period.clone())])];
    assert_parses_to!(FindSp::find_coll,
                      input,
                      FindSpec::FindColl(Element::Variable(Variable(sym))));
}

#[test]
fn test_find_rel() {
    let vx = edn::PlainSymbol::new("?x");
    let vy = edn::PlainSymbol::new("?y");
    let input = [edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(vy.clone())];
    assert_parses_to!(FindSp::find_rel,
                      input,
                      FindSpec::FindRel(vec![Element::Variable(Variable(vx)),
                                             Element::Variable(Variable(vy))]));
}

#[test]
fn test_find_tuple() {
    let vx = edn::PlainSymbol::new("?x");
    let vy = edn::PlainSymbol::new("?y");
    let input = [edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()),
                                         edn::Value::PlainSymbol(vy.clone())])];
    assert_parses_to!(FindSp::find_tuple,
                      input,
                      FindSpec::FindTuple(vec![Element::Variable(Variable(vx)),
                                               Element::Variable(Variable(vy))]));
}

// Parse a sequence of values into one of four find specs.
//
// `:find` must be an array of plain var symbols (?foo), pull expressions, and aggregates.
// For now we only support variables and the annotations necessary to declare which
// flavor of :find we want:
//
//
//     `?x ?y ?z  `     = FindRel
//     `[?x ...]  `     = FindColl
//     `?x .      `     = FindScalar
//     `[?x ?y ?z]`     = FindTuple
//
pub fn find_seq_to_find_spec(find: &[edn::Value]) -> FindParseResult {
    FindSp::find()
        .parse(find)
        .map(|x| x.0)
        .map_err(|_| FindParseError::Err)
}

#[test]
fn test_find_processing() {
    let vx = edn::PlainSymbol::new("?x");
    let vy = edn::PlainSymbol::new("?y");
    let ellipsis = edn::PlainSymbol::new("...");
    let period = edn::PlainSymbol::new(".");

    let scalar = [edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(period.clone())];
    let tuple = [edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()),
                                         edn::Value::PlainSymbol(vy.clone())])];
    let coll = [edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()),
                                        edn::Value::PlainSymbol(ellipsis.clone())])];
    let rel = [edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(vy.clone())];

    assert_eq!(Ok(FindSpec::FindScalar(Element::Variable(Variable(vx.clone())))),
               find_seq_to_find_spec(&scalar));
    assert_eq!(Ok(FindSpec::FindTuple(vec![Element::Variable(Variable(vx.clone())),
                                           Element::Variable(Variable(vy.clone()))])),
               find_seq_to_find_spec(&tuple));
    assert_eq!(Ok(FindSpec::FindColl(Element::Variable(Variable(vx.clone())))),
               find_seq_to_find_spec(&coll));
    assert_eq!(Ok(FindSpec::FindRel(vec![Element::Variable(Variable(vx.clone())),
                                         Element::Variable(Variable(vy.clone()))])),
               find_seq_to_find_spec(&rel));
}
<commit_msg>Move query-parser test functions into a submodule.<commit_after>// Copyright 2016 Mozilla
//
// 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.

extern crate combine;
extern crate edn;
extern crate mentat_query;

use self::combine::{eof, many1, parser, satisfy_map, Parser, ParseResult, Stream};
use self::combine::combinator::{Expected, FnParser, choice, try};
use self::edn::Value::PlainSymbol;
use self::mentat_query::{Element, FindSpec, Variable};

use super::error::{FindParseError, FindParseResult};

pub struct FindSp<I>(::std::marker::PhantomData<fn(I) -> I>);

type FindSpParser<O, I> = Expected<FnParser<I, fn(I) -> ParseResult<O, I>>>;

fn fn_parser<O, I>(f: fn(I) -> ParseResult<O, I>, err: &'static str) -> FindSpParser<O, I>
    where I: Stream<Item = edn::Value>
{
    parser(f).expected(err)
}

/// `satisfy_unwrap!` makes it a little easier to implement a `satisfy_map`
/// body that matches a particular `Value` enum case, otherwise returning `None`.
macro_rules! satisfy_unwrap {
    ( $cas: path, $var: ident, $body: block ) => {
        satisfy_map(|x: edn::Value| if let $cas($var) = x $body else { None })
    }
}

impl<I> FindSp<I>
    where I: Stream<Item = edn::Value>
{
    fn variable() -> FindSpParser<Variable, I> {
        fn_parser(FindSp::<I>::variable_, "variable")
    }

    fn variable_(input: I) -> ParseResult<Variable, I> {
        satisfy_map(|x: edn::Value| super::util::value_to_variable(&x)).parse_stream(input)
    }

    fn period() -> FindSpParser<(), I> {
        fn_parser(FindSp::<I>::period_, "period")
    }

    fn period_(input: I) -> ParseResult<(), I> {
        satisfy_map(|x: edn::Value| {
                if let PlainSymbol(ref s) = x {
                    if s.0.as_str() == "." {
                        return Some(());
                    }
                }
                return None;
            })
            .parse_stream(input)
    }

    fn ellipsis() -> FindSpParser<(), I> {
        fn_parser(FindSp::<I>::ellipsis_, "ellipsis")
    }

    fn ellipsis_(input: I) -> ParseResult<(), I> {
        satisfy_map(|x: edn::Value| {
                if let PlainSymbol(ref s) = x {
                    if s.0.as_str() == "..." {
                        return Some(());
                    }
                }
                return None;
            })
            .parse_stream(input)
    }

    fn find_scalar() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_scalar_, "find_scalar")
    }

    fn find_scalar_(input: I) -> ParseResult<FindSpec, I> {
        (FindSp::variable(), FindSp::period(), eof())
            .map(|(var, _, _)| FindSpec::FindScalar(Element::Variable(var)))
            .parse_stream(input)
    }

    fn find_coll() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_coll_, "find_coll")
    }

    fn find_coll_(input: I) -> ParseResult<FindSpec, I> {
        satisfy_unwrap!(edn::Value::Vector, y, {
                let mut p = (FindSp::variable(), FindSp::ellipsis(), eof())
                    .map(|(var, _, _)| FindSpec::FindColl(Element::Variable(var)));
                let r: ParseResult<FindSpec, _> = p.parse_lazy(&y[..]).into();
                FindSp::to_parsed_value(r)
            })
            .parse_stream(input)
    }

    fn elements() -> FindSpParser<Vec<Element>, I> {
        fn_parser(FindSp::<I>::elements_, "elements")
    }

    fn elements_(input: I) -> ParseResult<Vec<Element>, I> {
        (many1::<Vec<Variable>, _>(FindSp::variable()), eof())
            .map(|(vars, _)| {
                vars.into_iter()
                    .map(Element::Variable)
                    .collect()
            })
            .parse_stream(input)
    }

    fn find_rel() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_rel_, "find_rel")
    }

    fn find_rel_(input: I) -> ParseResult<FindSpec, I> {
        FindSp::elements().map(FindSpec::FindRel).parse_stream(input)
    }

    fn find_tuple() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_tuple_, "find_tuple")
    }

    fn find_tuple_(input: I) -> ParseResult<FindSpec, I> {
        satisfy_unwrap!(edn::Value::Vector, y, {
                let r: ParseResult<FindSpec, _> =
                    FindSp::elements().map(FindSpec::FindTuple).parse_lazy(&y[..]).into();
                FindSp::to_parsed_value(r)
            })
            .parse_stream(input)
    }

    fn find() -> FindSpParser<FindSpec, I> {
        fn_parser(FindSp::<I>::find_, "find")
    }

    fn find_(input: I) -> ParseResult<FindSpec, I> {
        // Any one of the four specs might apply, so we combine them with `choice`.
        // Our parsers consume input, so we need to wrap them in `try` so that they
        // operate independently.
        choice::<[&mut Parser<Input = I, Output = FindSpec>; 4],
                 _>([&mut try(FindSp::find_scalar()),
                     &mut try(FindSp::find_coll()),
                     &mut try(FindSp::find_tuple()),
                     &mut try(FindSp::find_rel())])
            .parse_stream(input)
    }

    fn to_parsed_value<T>(r: ParseResult<T, I>) -> Option<T> {
        r.ok().map(|x| x.0)
    }
}

// Parse a sequence of values into one of four find specs.
//
// `:find` must be an array of plain var symbols (?foo), pull expressions, and aggregates.
// For now we only support variables and the annotations necessary to declare which
// flavor of :find we want:
//
//
//     `?x ?y ?z  `     = FindRel
//     `[?x ...]  `     = FindColl
//     `?x .      `     = FindScalar
//     `[?x ?y ?z]`     = FindTuple
//
pub fn find_seq_to_find_spec(find: &[edn::Value]) -> FindParseResult {
    FindSp::find()
        .parse(find)
        .map(|x| x.0)
        .map_err(|_| FindParseError::Err)
}

#[cfg(test)]
mod test {
    extern crate combine;
    extern crate edn;
    extern crate mentat_query;

    use self::combine::Parser;
    use self::mentat_query::{Element, FindSpec, Variable};

    use super::*;

    macro_rules! assert_parses_to {
        ( $parser: path, $input: expr, $expected: expr ) => {{
            let mut par = $parser();
            let result = par.parse(&$input[..]);
            assert_eq!(result, Ok(($expected, &[][..])));
        }}
    }

    #[test]
    fn test_find_sp_variable() {
        let sym = edn::PlainSymbol::new("?x");
        let input = [edn::Value::PlainSymbol(sym.clone())];
        assert_parses_to!(FindSp::variable, input, Variable(sym));
    }

    #[test]
    fn test_find_scalar() {
        let sym = edn::PlainSymbol::new("?x");
        let period = edn::PlainSymbol::new(".");
        let input = [edn::Value::PlainSymbol(sym.clone()), edn::Value::PlainSymbol(period.clone())];
        assert_parses_to!(FindSp::find_scalar,
                          input,
                          FindSpec::FindScalar(Element::Variable(Variable(sym))));
    }

    #[test]
    fn test_find_coll() {
        let sym = edn::PlainSymbol::new("?x");
        let period = edn::PlainSymbol::new("...");
        let input = [edn::Value::Vector(vec![edn::Value::PlainSymbol(sym.clone()),
                                             edn::Value::PlainSymbol(period.clone())])];
        assert_parses_to!(FindSp::find_coll,
                          input,
                          FindSpec::FindColl(Element::Variable(Variable(sym))));
    }

    #[test]
    fn test_find_rel() {
        let vx = edn::PlainSymbol::new("?x");
        let vy = edn::PlainSymbol::new("?y");
        let input = [edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(vy.clone())];
        assert_parses_to!(FindSp::find_rel,
                          input,
                          FindSpec::FindRel(vec![Element::Variable(Variable(vx)),
                                                 Element::Variable(Variable(vy))]));
    }

    #[test]
    fn test_find_tuple() {
        let vx = edn::PlainSymbol::new("?x");
        let vy = edn::PlainSymbol::new("?y");
        let input = [edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()),
                                             edn::Value::PlainSymbol(vy.clone())])];
        assert_parses_to!(FindSp::find_tuple,
                          input,
                          FindSpec::FindTuple(vec![Element::Variable(Variable(vx)),
                                                   Element::Variable(Variable(vy))]));
    }

    #[test]
    fn test_find_processing() {
        let vx = edn::PlainSymbol::new("?x");
        let vy = edn::PlainSymbol::new("?y");
        let ellipsis = edn::PlainSymbol::new("...");
        let period = edn::PlainSymbol::new(".");

        let scalar = [edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(period.clone())];
        let tuple = [edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()),
                                             edn::Value::PlainSymbol(vy.clone())])];
        let coll = [edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()),
                                            edn::Value::PlainSymbol(ellipsis.clone())])];
        let rel = [edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(vy.clone())];

        assert_eq!(Ok(FindSpec::FindScalar(Element::Variable(Variable(vx.clone())))),
                   find_seq_to_find_spec(&scalar));
        assert_eq!(Ok(FindSpec::FindTuple(vec![Element::Variable(Variable(vx.clone())),
                                               Element::Variable(Variable(vy.clone()))])),
                   find_seq_to_find_spec(&tuple));
        assert_eq!(Ok(FindSpec::FindColl(Element::Variable(Variable(vx.clone())))),
                   find_seq_to_find_spec(&coll));
        assert_eq!(Ok(FindSpec::FindRel(vec![Element::Variable(Variable(vx.clone())),
                                             Element::Variable(Variable(vy.clone()))])),
                   find_seq_to_find_spec(&rel));
    }
}
<|endoftext|>


<commit_before>use criterion::Criterion;
use criterion::{black_box, criterion_group, criterion_main, Benchmark};
use env_logger::{Builder, Env};
use test_harness::BeaconChainHarness;
use types::{ChainSpec, Hash256};

fn mid_epoch_state_transition(c: &mut Criterion) {
    Builder::from_env(Env::default().default_filter_or("debug")).init();

    let validator_count = 1000;
    let mut rig = BeaconChainHarness::new(ChainSpec::foundation(), validator_count);

    let epoch_depth = (rig.spec.epoch_length * 2) + (rig.spec.epoch_length / 2);

    for _ in 0..epoch_depth {
        rig.advance_chain_with_block();
    }

    let state = rig.beacon_chain.state.read().clone();

    assert!((state.slot + 1) % rig.spec.epoch_length != 0);

    c.bench_function("mid-epoch state transition 10k validators", move |b| {
        let state = state.clone();
        b.iter(|| {
            let mut state = state.clone();
            black_box(state.per_slot_processing(Hash256::zero(), &rig.spec))
        })
    });
}

fn epoch_boundary_state_transition(c: &mut Criterion) {
    // Builder::from_env(Env::default().default_filter_or("debug")).init();

    let validator_count = 10000;
    let mut rig = BeaconChainHarness::new(ChainSpec::foundation(), validator_count);

    let epoch_depth = rig.spec.epoch_length * 2;

    for _ in 0..(epoch_depth - 1) {
        rig.advance_chain_with_block();
    }

    let state = rig.beacon_chain.state.read().clone();

    assert_eq!((state.slot + 1) % rig.spec.epoch_length, 0);

    c.bench(
        "routines",
        Benchmark::new("routine_1", move |b| {
            let state = state.clone();
            b.iter(|| {
                let mut state = state.clone();
                black_box(black_box(
                    state.per_slot_processing(Hash256::zero(), &rig.spec),
                ))
            })
        })
        .sample_size(5),
    );

    /*
    c.bench_function("mid-epoch state transition 10k validators", move |b| {
        let state = state.clone();
        b.iter(|| {
            let mut state = state.clone();
            black_box(black_box(
                state.per_slot_processing(Hash256::zero(), &rig.spec),
            ))
        })
    });
    */
}

criterion_group!(
    benches,
    // mid_epoch_state_transition,
    epoch_boundary_state_transition
);
criterion_main!(benches);
<commit_msg>Tidy benches<commit_after>use criterion::Criterion;
use criterion::{black_box, criterion_group, criterion_main, Benchmark};
// use env_logger::{Builder, Env};
use test_harness::BeaconChainHarness;
use types::{ChainSpec, Hash256};

fn mid_epoch_state_transition(c: &mut Criterion) {
    // Builder::from_env(Env::default().default_filter_or("debug")).init();

    let validator_count = 1000;
    let mut rig = BeaconChainHarness::new(ChainSpec::foundation(), validator_count);

    let epoch_depth = (rig.spec.epoch_length * 2) + (rig.spec.epoch_length / 2);

    for _ in 0..epoch_depth {
        rig.advance_chain_with_block();
    }

    let state = rig.beacon_chain.state.read().clone();

    assert!((state.slot + 1) % rig.spec.epoch_length != 0);

    c.bench_function("mid-epoch state transition 10k validators", move |b| {
        let state = state.clone();
        b.iter(|| {
            let mut state = state.clone();
            black_box(state.per_slot_processing(Hash256::zero(), &rig.spec))
        })
    });
}

fn epoch_boundary_state_transition(c: &mut Criterion) {
    // Builder::from_env(Env::default().default_filter_or("debug")).init();

    let validator_count = 10000;
    let mut rig = BeaconChainHarness::new(ChainSpec::foundation(), validator_count);

    let epoch_depth = rig.spec.epoch_length * 2;

    for _ in 0..(epoch_depth - 1) {
        rig.advance_chain_with_block();
    }

    let state = rig.beacon_chain.state.read().clone();

    assert_eq!((state.slot + 1) % rig.spec.epoch_length, 0);

    c.bench(
        "routines",
        Benchmark::new("routine_1", move |b| {
            let state = state.clone();
            b.iter(|| {
                let mut state = state.clone();
                black_box(black_box(
                    state.per_slot_processing(Hash256::zero(), &rig.spec),
                ))
            })
        })
        .sample_size(5), // sample size is low because function is sloooow.
    );
}

criterion_group!(
    benches,
    mid_epoch_state_transition,
    epoch_boundary_state_transition
);
criterion_main!(benches);
<|endoftext|>


<commit_before>// this is just a test binary that can be hooked up to Instruments
extern crate lonlat_bng;
use lonlat_bng::{convert_to_bng_threaded, convert_vec_c, Array};

extern crate rand;
use rand::distributions::{IndependentSample, Range};

extern crate libc;

fn main() {
    let num_coords = 1000000;
    let between_lon = Range::new(-6.379880, 1.768960);
    let between_lat = Range::new(49.871159, 55.811741);
    let mut rng = rand::thread_rng();
    let lon_vec = vec![between_lon.ind_sample(&mut rng) as f32; num_coords];
    let lat_vec = vec![between_lat.ind_sample(&mut rng) as f32; num_coords];
    let lon_arr = Array {
        data: lon_vec.as_ptr() as *const libc::c_void,
        len: lon_vec.len() as libc::size_t,
    };
    let lat_arr = Array {
        data: lat_vec.as_ptr() as *const libc::c_void,
        len: lat_vec.len() as libc::size_t,
    };

    // convert_vec_c(lon_arr, lat_arr);
    convert_to_bng_threaded(lon_arr, lat_arr);
}<commit_msg>Fix missing newline<commit_after>// this is just a test binary that can be hooked up to Instruments
extern crate lonlat_bng;
use lonlat_bng::{convert_to_bng_threaded, convert_vec_c, Array};

extern crate rand;
use rand::distributions::{IndependentSample, Range};

extern crate libc;

fn main() {
    let num_coords = 1000000;
    let between_lon = Range::new(-6.379880, 1.768960);
    let between_lat = Range::new(49.871159, 55.811741);
    let mut rng = rand::thread_rng();
    let lon_vec = vec![between_lon.ind_sample(&mut rng) as f32; num_coords];
    let lat_vec = vec![between_lat.ind_sample(&mut rng) as f32; num_coords];
    let lon_arr = Array {
        data: lon_vec.as_ptr() as *const libc::c_void,
        len: lon_vec.len() as libc::size_t,
    };
    let lat_arr = Array {
        data: lat_vec.as_ptr() as *const libc::c_void,
        len: lat_vec.len() as libc::size_t,
    };

    // convert_vec_c(lon_arr, lat_arr);
    convert_to_bng_threaded(lon_arr, lat_arr);
}
<|endoftext|>


<commit_before>extern crate document;

use std::cmp::min;
use std::io::File;
use std::io::BufferedWriter;
use std::io::stdio::stdout_raw;

use document::parser::Parser;

fn pretty_error(xml: &str, position: uint) -> &str {
    let s = xml.slice_from(position);
    let l = s.chars().count();
    s.slice_chars(0, min(l, 15))
}

fn main() {
    let mut args = std::os::args();

    let filename = args.remove(1).expect("File required");
    let path = Path::new(filename);
    let mut file = File::open(&path);

    let data = match file.read_to_string() {
        Ok(x) => x,
        Err(x) => panic!("Can't read: {}", x),
    };

    let p = Parser::new();

    let package = match p.parse(data.as_slice()) {
        Ok(d) => d,
        Err(point) => panic!("Unable to parse: {}", pretty_error(data.as_slice(), point)),
    };

    let mut out = BufferedWriter::new(stdout_raw());

    {
        let d = package.as_document();
        document::writer::format_document(&d, &mut out).ok().expect("I can't output");
    }
}
<commit_msg>Allow the main method to be dead code when compiling tests<commit_after>extern crate document;

use std::cmp::min;
use std::io::File;
use std::io::BufferedWriter;
use std::io::stdio::stdout_raw;

use document::parser::Parser;

fn pretty_error(xml: &str, position: uint) -> &str {
    let s = xml.slice_from(position);
    let l = s.chars().count();
    s.slice_chars(0, min(l, 15))
}

#[allow(dead_code)]
fn main() {
    let mut args = std::os::args();

    let filename = args.remove(1).expect("File required");
    let path = Path::new(filename);
    let mut file = File::open(&path);

    let data = match file.read_to_string() {
        Ok(x) => x,
        Err(x) => panic!("Can't read: {}", x),
    };

    let p = Parser::new();

    let package = match p.parse(data.as_slice()) {
        Ok(d) => d,
        Err(point) => panic!("Unable to parse: {}", pretty_error(data.as_slice(), point)),
    };

    let mut out = BufferedWriter::new(stdout_raw());

    {
        let d = package.as_document();
        document::writer::format_document(&d, &mut out).ok().expect("I can't output");
    }
}
<|endoftext|>


<commit_before>#![crate_name = "rboy"]
#![feature(phase)]

#[phase(plugin, link)] extern crate log;
                       extern crate getopts;
                       extern crate sdl2;
                       extern crate rboy;

use rboy::device::Device;
use std::time::Duration;
use std::sync::{Arc,RWLock};
use std::sync::mpsc::{Sender,Receiver};
use std::sync::mpsc::TryRecvError::{Disconnected,Empty};

static SCALE: uint = 2;
static EXITCODE_INCORRECTOPTIONS: int = 1;
static EXITCODE_CPULOADFAILS: int = 2;

#[cfg(not(test))]
fn set_exit_status(exitcode: int)
{
    std::os::set_exit_status(exitcode);
}

fn main() {
	let args = std::os::args();
	let opts = &[ getopts::optflag("s", "serial", "Output serial to stdout"), getopts::optflag("c", "classic", "Force Classic mode") ];
	let matches = match getopts::getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => { println!("{}", f); return }
	};

	let filename = if !matches.free.is_empty() {
		matches.free[0].clone()
	} else {
		let mut info_start = args[0].clone();
		info_start.push_str(" <filename>");
		println!("{}", getopts::usage(info_start.as_slice(), opts));
		set_exit_status(EXITCODE_INCORRECTOPTIONS);
		return;
	};

	sdl2::init(sdl2::INIT_VIDEO);
	let window = match sdl2::video::Window::new("RBoy - A gameboy in Rust",
												sdl2::video::WindowPos::PosUndefined,
												sdl2::video::WindowPos::PosUndefined,
												160*SCALE as int,
												144*SCALE as int,
												sdl2::video::WindowFlags::empty()) {
		Ok(window) => window,
		Err(err) => panic!("failed to open window: {}", err),
	};
	let renderer = match sdl2::render::Renderer::from_window(window, sdl2::render::RenderDriverIndex::Auto, sdl2::render::ACCELERATED) {
		Ok(screen) => screen,
		Err(err) => panic!("failed to open screen: {}", err),
	};

	let (sdl_tx, cpu_rx) = std::sync::mpsc::channel();
	let (cpu_tx, sdl_rx) = std::sync::mpsc::channel();
	let rawscreen = ::std::iter::repeat(0u8).take(160*144*3).collect();
	let arc = Arc::new(RWLock::new(rawscreen));
	let arc2 = arc.clone();

	let cpuloop_thread = std::thread::Thread::spawn(move|| cpuloop(&cpu_tx, &cpu_rx, arc2, filename.as_slice(), &matches));

	let mut timer = std::io::timer::Timer::new().unwrap();
	let periodic = timer.periodic(Duration::milliseconds(8));

	'main : loop {
		periodic.recv();
		match sdl_rx.try_recv() {
			Err(Disconnected) => { break 'main },
			Ok(_) => recalculate_screen(&renderer, &arc),
			Err(Empty) => {},
		}
		'event : loop {
			match sdl2::event::poll_event() {
				sdl2::event::Event::Quit(_) => break 'main,
				sdl2::event::Event::None => break 'event,
				sdl2::event::Event::KeyDown(_, _, sdl2::keycode::KeyCode::Escape, _, _, _)
					=> break 'main,
				sdl2::event::Event::KeyDown(_, _, sdl2::keycode::KeyCode::LShift, _, _, _)
					=> { sdl_tx.send(GBEvent::SpeedUp); },
				sdl2::event::Event::KeyUp(_, _, sdl2::keycode::KeyCode::LShift, _, _, _)
					=> { sdl_tx.send(GBEvent::SlowDown); },
				sdl2::event::Event::KeyDown(_, _, sdlkey, _, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) =>  { sdl_tx.send(GBEvent::KeyDown(key)); },
						None => {},
					}
				},
				sdl2::event::Event::KeyUp(_, _, sdlkey, _, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) => { sdl_tx.send(GBEvent::KeyUp(key)); },
						None => {},
					}
				},
				_ => {}
			}
		}
	}

    drop(sdl_tx); // Disconnect such that the cpuloop will exit
    let _ = cpuloop_thread.join();
}

fn sdl_to_keypad(key: sdl2::keycode::KeyCode) -> Option<rboy::KeypadKey> {
	match key {
		sdl2::keycode::KeyCode::Z => Some(rboy::KeypadKey::A),
		sdl2::keycode::KeyCode::X => Some(rboy::KeypadKey::B),
		sdl2::keycode::KeyCode::Up => Some(rboy::KeypadKey::Up),
		sdl2::keycode::KeyCode::Down => Some(rboy::KeypadKey::Down),
		sdl2::keycode::KeyCode::Left => Some(rboy::KeypadKey::Left),
		sdl2::keycode::KeyCode::Right => Some(rboy::KeypadKey::Right),
		sdl2::keycode::KeyCode::Space => Some(rboy::KeypadKey::Select),
		sdl2::keycode::KeyCode::Return => Some(rboy::KeypadKey::Start),
		_ => None,
	}
}

fn recalculate_screen(screen: &sdl2::render::Renderer, arc: &Arc<RWLock<Vec<u8>>>) {
	screen.set_draw_color(sdl2::pixels::Color::RGB(0xFF, 0xFF, 0xFF)).unwrap();
	screen.clear().unwrap();

	let data =  arc.read().unwrap().clone();
	for y in range(0u, 144) {
		for x in range(0u, 160) {
			screen.set_draw_color(sdl2::pixels::Color::RGB(data[y*160*3 + x*3 + 0],
															data[y*160*3 + x*3 + 1],
															data[y*160*3 + x*3 + 2])).unwrap();
			screen.draw_rect(&sdl2::rect::Rect::new((x*SCALE) as i32, (y*SCALE) as i32, SCALE as i32, SCALE as i32)).unwrap();
		}
	}
	screen.present();
}

enum GBEvent {
	KeyUp(rboy::KeypadKey),
	KeyDown(rboy::KeypadKey),
	SpeedUp,
	SlowDown,
}

fn cpuloop(cpu_tx: &Sender<uint>, cpu_rx: &Receiver<GBEvent>, arc: Arc<RWLock<Vec<u8>>>, filename: &str, matches: &getopts::Matches) {
	let opt_c = match matches.opt_present("classic") {
		true => Device::new(filename),
		false => Device::new_cgb(filename),
	};
	let mut c = match opt_c
	{
		Some(cpu) => { cpu },
		None => { error!("Could not get a valid gameboy"); set_exit_status(EXITCODE_CPULOADFAILS); return; },
	};
	c.set_stdout(matches.opt_present("serial"));

	let mut timer = std::io::timer::Timer::new().unwrap();
	let periodic = timer.periodic(Duration::milliseconds(8));
	let mut limit_speed = true;

	let waitticks = (4194.304f32 * 4.0) as uint;

	let mut ticks = 0;
	'cpuloop: loop {
		while ticks < waitticks {
			ticks += c.do_cycle();
			if c.check_and_reset_gpu_updated() {
				let mut data = arc.write().unwrap();
				let gpu_data = c.get_gpu_data();
				for i in range(0, data.len()) { data[i] = gpu_data[i]; }
				if cpu_tx.send(0).is_err() { break 'cpuloop };
			}
		}
		ticks -= waitticks;
		if limit_speed { periodic.recv(); }

		match cpu_rx.try_recv() {
			Ok(event) => match event {
				GBEvent::KeyUp(key) => c.keyup(key),
				GBEvent::KeyDown(key) => c.keydown(key),
				GBEvent::SpeedUp => limit_speed = false,
				GBEvent::SlowDown => limit_speed = true,
			},
			Err(Empty) => {},
			Err(Disconnected) => { break },
		};
	}
}
<commit_msg>Ignore all send / recv results<commit_after>#![crate_name = "rboy"]
#![feature(phase)]

#[phase(plugin, link)] extern crate log;
                       extern crate getopts;
                       extern crate sdl2;
                       extern crate rboy;

use rboy::device::Device;
use std::time::Duration;
use std::sync::{Arc,RWLock};
use std::sync::mpsc::{Sender,Receiver};
use std::sync::mpsc::TryRecvError::{Disconnected,Empty};

static SCALE: uint = 2;
static EXITCODE_INCORRECTOPTIONS: int = 1;
static EXITCODE_CPULOADFAILS: int = 2;

#[cfg(not(test))]
fn set_exit_status(exitcode: int)
{
    std::os::set_exit_status(exitcode);
}

fn main() {
	let args = std::os::args();
	let opts = &[ getopts::optflag("s", "serial", "Output serial to stdout"), getopts::optflag("c", "classic", "Force Classic mode") ];
	let matches = match getopts::getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => { println!("{}", f); return }
	};

	let filename = if !matches.free.is_empty() {
		matches.free[0].clone()
	} else {
		let mut info_start = args[0].clone();
		info_start.push_str(" <filename>");
		println!("{}", getopts::usage(info_start.as_slice(), opts));
		set_exit_status(EXITCODE_INCORRECTOPTIONS);
		return;
	};

	sdl2::init(sdl2::INIT_VIDEO);
	let window = match sdl2::video::Window::new("RBoy - A gameboy in Rust",
												sdl2::video::WindowPos::PosUndefined,
												sdl2::video::WindowPos::PosUndefined,
												160*SCALE as int,
												144*SCALE as int,
												sdl2::video::WindowFlags::empty()) {
		Ok(window) => window,
		Err(err) => panic!("failed to open window: {}", err),
	};
	let renderer = match sdl2::render::Renderer::from_window(window, sdl2::render::RenderDriverIndex::Auto, sdl2::render::ACCELERATED) {
		Ok(screen) => screen,
		Err(err) => panic!("failed to open screen: {}", err),
	};

	let (sdl_tx, cpu_rx) = std::sync::mpsc::channel();
	let (cpu_tx, sdl_rx) = std::sync::mpsc::channel();
	let rawscreen = ::std::iter::repeat(0u8).take(160*144*3).collect();
	let arc = Arc::new(RWLock::new(rawscreen));
	let arc2 = arc.clone();

	let cpuloop_thread = std::thread::Thread::spawn(move|| cpuloop(&cpu_tx, &cpu_rx, arc2, filename.as_slice(), &matches));

	let mut timer = std::io::timer::Timer::new().unwrap();
	let periodic = timer.periodic(Duration::milliseconds(8));

	'main : loop {
		let _ = periodic.recv();
		match sdl_rx.try_recv() {
			Err(Disconnected) => { break 'main },
			Ok(_) => recalculate_screen(&renderer, &arc),
			Err(Empty) => {},
		}
		'event : loop {
			match sdl2::event::poll_event() {
				sdl2::event::Event::Quit(_) => break 'main,
				sdl2::event::Event::None => break 'event,
				sdl2::event::Event::KeyDown(_, _, sdl2::keycode::KeyCode::Escape, _, _, _)
					=> break 'main,
				sdl2::event::Event::KeyDown(_, _, sdl2::keycode::KeyCode::LShift, _, _, _)
					=> { let _ = sdl_tx.send(GBEvent::SpeedUp); },
				sdl2::event::Event::KeyUp(_, _, sdl2::keycode::KeyCode::LShift, _, _, _)
					=> { let _ = sdl_tx.send(GBEvent::SlowDown); },
				sdl2::event::Event::KeyDown(_, _, sdlkey, _, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) =>  { let _ = sdl_tx.send(GBEvent::KeyDown(key)); },
						None => {},
					}
				},
				sdl2::event::Event::KeyUp(_, _, sdlkey, _, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) => { let _ = sdl_tx.send(GBEvent::KeyUp(key)); },
						None => {},
					}
				},
				_ => {}
			}
		}
	}

    drop(sdl_tx); // Disconnect such that the cpuloop will exit
    let _ = cpuloop_thread.join();
}

fn sdl_to_keypad(key: sdl2::keycode::KeyCode) -> Option<rboy::KeypadKey> {
	match key {
		sdl2::keycode::KeyCode::Z => Some(rboy::KeypadKey::A),
		sdl2::keycode::KeyCode::X => Some(rboy::KeypadKey::B),
		sdl2::keycode::KeyCode::Up => Some(rboy::KeypadKey::Up),
		sdl2::keycode::KeyCode::Down => Some(rboy::KeypadKey::Down),
		sdl2::keycode::KeyCode::Left => Some(rboy::KeypadKey::Left),
		sdl2::keycode::KeyCode::Right => Some(rboy::KeypadKey::Right),
		sdl2::keycode::KeyCode::Space => Some(rboy::KeypadKey::Select),
		sdl2::keycode::KeyCode::Return => Some(rboy::KeypadKey::Start),
		_ => None,
	}
}

fn recalculate_screen(screen: &sdl2::render::Renderer, arc: &Arc<RWLock<Vec<u8>>>) {
	screen.set_draw_color(sdl2::pixels::Color::RGB(0xFF, 0xFF, 0xFF)).unwrap();
	screen.clear().unwrap();

	let data =  arc.read().unwrap().clone();
	for y in range(0u, 144) {
		for x in range(0u, 160) {
			screen.set_draw_color(sdl2::pixels::Color::RGB(data[y*160*3 + x*3 + 0],
															data[y*160*3 + x*3 + 1],
															data[y*160*3 + x*3 + 2])).unwrap();
			screen.draw_rect(&sdl2::rect::Rect::new((x*SCALE) as i32, (y*SCALE) as i32, SCALE as i32, SCALE as i32)).unwrap();
		}
	}
	screen.present();
}

enum GBEvent {
	KeyUp(rboy::KeypadKey),
	KeyDown(rboy::KeypadKey),
	SpeedUp,
	SlowDown,
}

fn cpuloop(cpu_tx: &Sender<uint>, cpu_rx: &Receiver<GBEvent>, arc: Arc<RWLock<Vec<u8>>>, filename: &str, matches: &getopts::Matches) {
	let opt_c = match matches.opt_present("classic") {
		true => Device::new(filename),
		false => Device::new_cgb(filename),
	};
	let mut c = match opt_c
	{
		Some(cpu) => { cpu },
		None => { error!("Could not get a valid gameboy"); set_exit_status(EXITCODE_CPULOADFAILS); return; },
	};
	c.set_stdout(matches.opt_present("serial"));

	let mut timer = std::io::timer::Timer::new().unwrap();
	let periodic = timer.periodic(Duration::milliseconds(8));
	let mut limit_speed = true;

	let waitticks = (4194.304f32 * 4.0) as uint;

	let mut ticks = 0;
	'cpuloop: loop {
		while ticks < waitticks {
			ticks += c.do_cycle();
			if c.check_and_reset_gpu_updated() {
				let mut data = arc.write().unwrap();
				let gpu_data = c.get_gpu_data();
				for i in range(0, data.len()) { data[i] = gpu_data[i]; }
				if cpu_tx.send(0).is_err() { break 'cpuloop };
			}
		}
		ticks -= waitticks;
		if limit_speed { let _ = periodic.recv(); }

		match cpu_rx.try_recv() {
			Ok(event) => match event {
				GBEvent::KeyUp(key) => c.keyup(key),
				GBEvent::KeyDown(key) => c.keydown(key),
				GBEvent::SpeedUp => limit_speed = false,
				GBEvent::SlowDown => limit_speed = true,
			},
			Err(Empty) => {},
			Err(Disconnected) => { break },
		};
	}
}
<|endoftext|>


<commit_before>use cargo::ops;
use cargo::util::{CliResult, CliError, Human, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};

#[derive(RustcDecodable)]
pub struct Options {
    arg_args: Vec<String>,
    flag_features: Vec<String>,
    flag_jobs: Option<u32>,
    flag_manifest_path: Option<String>,
    flag_no_default_features: bool,
    flag_no_run: bool,
    flag_package: Vec<String>,
    flag_target: Option<String>,
    flag_lib: bool,
    flag_doc: bool,
    flag_bin: Vec<String>,
    flag_example: Vec<String>,
    flag_test: Vec<String>,
    flag_bench: Vec<String>,
    flag_verbose: Option<bool>,
    flag_quiet: Option<bool>,
    flag_color: Option<String>,
    flag_release: bool,
    flag_no_fail_fast: bool,
}

pub const USAGE: &'static str = "
Execute all unit and integration tests of a local package

Usage:
    cargo test [options] [--] [<args>...]

Options:
    -h, --help                   Print this message
    --lib                        Test only this package's library
    --doc                        Test only this library's documentation
    --bin NAME                   Test only the specified binary
    --example NAME               Test only the specified example
    --test NAME                  Test only the specified integration test target
    --bench NAME                 Test only the specified benchmark target
    --no-run                     Compile, but don't run tests
    -p SPEC, --package SPEC ...  Package to run tests for
    -j N, --jobs N               The number of jobs to run in parallel
    --release                    Build artifacts in release mode, with optimizations
    --features FEATURES          Space-separated list of features to also build
    --no-default-features        Do not build the `default` feature
    --target TRIPLE              Build for the target triple
    --manifest-path PATH         Path to the manifest to build tests for
    -v, --verbose                Use verbose output
    -q, --quiet                  No output printed to stdout
    --color WHEN                 Coloring: auto, always, never
    --no-fail-fast               Run all tests regardless of failure

All of the trailing arguments are passed to the test binaries generated for
filtering tests and generally providing options configuring how they run. For
example, this will run all tests with the name `foo` in their name:

    cargo test foo

If the --package argument is given, then SPEC is a package id specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.

The --jobs argument affects the building of the test executable but does
not affect how many jobs are used when running the tests.

Compilation can be configured via the `test` profile in the manifest.

By default the rust test harness hides output from test execution to
keep results readable. Test output can be recovered (e.g. for debugging)
by passing `--nocapture` to the test binaries:

  cargo test -- --nocapture
";

pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
    try!(config.configure_shell(options.flag_verbose,
                                options.flag_quiet,
                                &options.flag_color));
    let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));

    let empty = Vec::new();
    let (mode, filter);
    if options.flag_doc {
        mode = ops::CompileMode::Build;
        filter = ops::CompileFilter::new(true, &empty, &empty, &empty, &empty);
    } else {
        mode = ops::CompileMode::Test;
        filter = ops::CompileFilter::new(options.flag_lib,
                                         &options.flag_bin,
                                         &options.flag_test,
                                         &options.flag_example,
                                         &options.flag_bench);
    }

    let ops = ops::TestOptions {
        no_run: options.flag_no_run,
        no_fail_fast: options.flag_no_fail_fast,
        only_doc: options.flag_doc,
        compile_opts: ops::CompileOptions {
            config: config,
            jobs: options.flag_jobs,
            target: options.flag_target.as_ref().map(|s| &s[..]),
            features: &options.flag_features,
            no_default_features: options.flag_no_default_features,
            spec: &options.flag_package,
            exec_engine: None,
            release: options.flag_release,
            mode: mode,
            filter: filter,
            target_rustdoc_args: None,
            target_rustc_args: None,
        },
    };

    let err = try!(ops::run_tests(&root, &ops, &options.arg_args));
    match err {
        None => Ok(None),
        Some(err) => {
            Err(match err.exit.as_ref().and_then(|e| e.code()) {
                Some(i) => CliError::new("test failed", i),
                None => CliError::from_error(Human(err), 101)
            })
        }
    }
}
<commit_msg>Auto merge of #2777 - matklad:harness-help, r=alexcrichton<commit_after>use cargo::ops;
use cargo::util::{CliResult, CliError, Human, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};

#[derive(RustcDecodable)]
pub struct Options {
    arg_args: Vec<String>,
    flag_features: Vec<String>,
    flag_jobs: Option<u32>,
    flag_manifest_path: Option<String>,
    flag_no_default_features: bool,
    flag_no_run: bool,
    flag_package: Vec<String>,
    flag_target: Option<String>,
    flag_lib: bool,
    flag_doc: bool,
    flag_bin: Vec<String>,
    flag_example: Vec<String>,
    flag_test: Vec<String>,
    flag_bench: Vec<String>,
    flag_verbose: Option<bool>,
    flag_quiet: Option<bool>,
    flag_color: Option<String>,
    flag_release: bool,
    flag_no_fail_fast: bool,
}

pub const USAGE: &'static str = "
Execute all unit and integration tests of a local package

Usage:
    cargo test [options] [--] [<args>...]

Options:
    -h, --help                   Print this message
    --lib                        Test only this package's library
    --doc                        Test only this library's documentation
    --bin NAME                   Test only the specified binary
    --example NAME               Test only the specified example
    --test NAME                  Test only the specified integration test target
    --bench NAME                 Test only the specified benchmark target
    --no-run                     Compile, but don't run tests
    -p SPEC, --package SPEC ...  Package to run tests for
    -j N, --jobs N               The number of jobs to run in parallel
    --release                    Build artifacts in release mode, with optimizations
    --features FEATURES          Space-separated list of features to also build
    --no-default-features        Do not build the `default` feature
    --target TRIPLE              Build for the target triple
    --manifest-path PATH         Path to the manifest to build tests for
    -v, --verbose                Use verbose output
    -q, --quiet                  No output printed to stdout
    --color WHEN                 Coloring: auto, always, never
    --no-fail-fast               Run all tests regardless of failure

All of the trailing arguments are passed to the test binaries generated for
filtering tests and generally providing options configuring how they run. For
example, this will run all tests with the name `foo` in their name:

    cargo test foo

If the --package argument is given, then SPEC is a package id specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.

The --jobs argument affects the building of the test executable but does
not affect how many jobs are used when running the tests.

Compilation can be configured via the `test` profile in the manifest.

By default the rust test harness hides output from test execution to
keep results readable. Test output can be recovered (e.g. for debugging)
by passing `--nocapture` to the test binaries:

  cargo test -- --nocapture

To get the list of all options available for the test binaries use this:

  cargo test -- --help
";

pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
    try!(config.configure_shell(options.flag_verbose,
                                options.flag_quiet,
                                &options.flag_color));
    let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));

    let empty = Vec::new();
    let (mode, filter);
    if options.flag_doc {
        mode = ops::CompileMode::Build;
        filter = ops::CompileFilter::new(true, &empty, &empty, &empty, &empty);
    } else {
        mode = ops::CompileMode::Test;
        filter = ops::CompileFilter::new(options.flag_lib,
                                         &options.flag_bin,
                                         &options.flag_test,
                                         &options.flag_example,
                                         &options.flag_bench);
    }

    let ops = ops::TestOptions {
        no_run: options.flag_no_run,
        no_fail_fast: options.flag_no_fail_fast,
        only_doc: options.flag_doc,
        compile_opts: ops::CompileOptions {
            config: config,
            jobs: options.flag_jobs,
            target: options.flag_target.as_ref().map(|s| &s[..]),
            features: &options.flag_features,
            no_default_features: options.flag_no_default_features,
            spec: &options.flag_package,
            exec_engine: None,
            release: options.flag_release,
            mode: mode,
            filter: filter,
            target_rustdoc_args: None,
            target_rustc_args: None,
        },
    };

    let err = try!(ops::run_tests(&root, &ops, &options.arg_args));
    match err {
        None => Ok(None),
        Some(err) => {
            Err(match err.exit.as_ref().and_then(|e| e.code()) {
                Some(i) => CliError::new("test failed", i),
                None => CliError::from_error(Human(err), 101)
            })
        }
    }
}
<|endoftext|>


<commit_before>//! [Church booleans](https://en.wikipedia.org/wiki/Church_encoding#Church_Booleans)

use term::*;
use term::Term::*;

/// A Church-encoded boolean true.
///
/// TRUE := λab.a = λ λ 2
pub fn tru() -> Term { abs(abs(Var(2))) }

/// A Church-encoded boolean false.
///
/// FALSE := λab.b = λ λ 1
pub fn fls() -> Term { abs(abs(Var(1))) }

/// Applied to two Church-encoded booleans it returns their Church-encoded conjunction.
///
/// AND := λpq.p q p = λ λ 2 1 2
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{and, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(and().app(tru()).app(tru())), tru());
/// assert_eq!(normalize(and().app(tru()).app(fls())), fls());
/// assert_eq!(normalize(and().app(fls()).app(tru())), fls());
/// assert_eq!(normalize(and().app(fls()).app(fls())), fls());
/// ```
pub fn and() -> Term { abs(abs(Var(2).app(Var(1)).app(Var(2)))) }

/// Applied to two Church-encoded booleans it returns their Church-encoded disjunction.
///
/// OR := λpq.p p q = λ λ 2 2 1
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{or, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(or().app(tru()).app(tru())), tru());
/// assert_eq!(normalize(or().app(tru()).app(fls())), tru());
/// assert_eq!(normalize(or().app(fls()).app(tru())), tru());
/// assert_eq!(normalize(or().app(fls()).app(fls())), fls());
/// ```
pub fn or() -> Term { abs(abs(Var(2).app(Var(2)).app(Var(1)))) }

/// Applied to a Church-encoded boolean it returns its Church-encoded negation.
///
/// NOT := λp.p FALSE TRUE = λ 1 FALSE TRUE
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{not, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(not().app(tru())), fls());
/// assert_eq!(normalize(not().app(fls())), tru());
/// ```
pub fn not() -> Term { abs(Var(1).app(fls()).app(tru())) }

/// Applied to a Church-encoded boolean it returns its Church-encoded exclusive disjunction.
///
/// XOR := λab.a (NOT b) b = λ λ 2 (NOT 1) 1
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{xor, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(xor().app(tru()).app(tru())), fls());
/// assert_eq!(normalize(xor().app(tru()).app(fls())), tru());
/// assert_eq!(normalize(xor().app(fls()).app(tru())), tru());
/// assert_eq!(normalize(xor().app(fls()).app(fls())), fls());
/// ```
pub fn xor() -> Term { abs(abs(Var(2).app(not().app(Var(1))).app(Var(1)))) }

/// Applied to a Church encoded predicate and two terms it returns the first one if the predicate is
/// true or the second one if the predicate is false.
///
/// IF_ELSE := λpab.p a b = λ λ λ 3 2 1
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{if_else, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(if_else().app(tru()).app(one()).app(zero())), one());
/// assert_eq!(normalize(if_else().app(fls()).app(one()).app(zero())), zero());
/// ```
pub fn if_else() -> Term { abs(abs(abs(Var(3).app(Var(2)).app(Var(1))))) }
<commit_msg>Fix one test<commit_after>//! [Church booleans](https://en.wikipedia.org/wiki/Church_encoding#Church_Booleans)

use term::*;
use term::Term::*;

/// A Church-encoded boolean true.
///
/// TRUE := λab.a = λ λ 2
pub fn tru() -> Term { abs(abs(Var(2))) }

/// A Church-encoded boolean false.
///
/// FALSE := λab.b = λ λ 1
pub fn fls() -> Term { abs(abs(Var(1))) }

/// Applied to two Church-encoded booleans it returns their Church-encoded conjunction.
///
/// AND := λpq.p q p = λ λ 2 1 2
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{and, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(and().app(tru()).app(tru())), tru());
/// assert_eq!(normalize(and().app(tru()).app(fls())), fls());
/// assert_eq!(normalize(and().app(fls()).app(tru())), fls());
/// assert_eq!(normalize(and().app(fls()).app(fls())), fls());
/// ```
pub fn and() -> Term { abs(abs(Var(2).app(Var(1)).app(Var(2)))) }

/// Applied to two Church-encoded booleans it returns their Church-encoded disjunction.
///
/// OR := λpq.p p q = λ λ 2 2 1
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{or, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(or().app(tru()).app(tru())), tru());
/// assert_eq!(normalize(or().app(tru()).app(fls())), tru());
/// assert_eq!(normalize(or().app(fls()).app(tru())), tru());
/// assert_eq!(normalize(or().app(fls()).app(fls())), fls());
/// ```
pub fn or() -> Term { abs(abs(Var(2).app(Var(2)).app(Var(1)))) }

/// Applied to a Church-encoded boolean it returns its Church-encoded negation.
///
/// NOT := λp.p FALSE TRUE = λ 1 FALSE TRUE
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{not, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(not().app(tru())), fls());
/// assert_eq!(normalize(not().app(fls())), tru());
/// ```
pub fn not() -> Term { abs(Var(1).app(fls()).app(tru())) }

/// Applied to a Church-encoded boolean it returns its Church-encoded exclusive disjunction.
///
/// XOR := λab.a (NOT b) b = λ λ 2 (NOT 1) 1
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{xor, tru, fls};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(xor().app(tru()).app(tru())), fls());
/// assert_eq!(normalize(xor().app(tru()).app(fls())), tru());
/// assert_eq!(normalize(xor().app(fls()).app(tru())), tru());
/// assert_eq!(normalize(xor().app(fls()).app(fls())), fls());
/// ```
pub fn xor() -> Term { abs(abs(Var(2).app(not().app(Var(1))).app(Var(1)))) }

/// Applied to a Church encoded predicate and two terms it returns the first one if the predicate is
/// true or the second one if the predicate is false.
///
/// IF_ELSE := λpab.p a b = λ λ λ 3 2 1
///
/// # Examples
/// ```
/// use lambda_calculus::booleans::{if_else, tru, fls};
/// use lambda_calculus::arithmetic::{zero, one};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(if_else().app(tru()).app(one()).app(zero())), one());
/// assert_eq!(normalize(if_else().app(fls()).app(one()).app(zero())), zero());
/// ```
pub fn if_else() -> Term { abs(abs(abs(Var(3).app(Var(2)).app(Var(1))))) }
<|endoftext|>