<commit_before>extern crate chrono;

extern crate rustc_serialize;

extern crate rs_es;
use rs_es::Client;
use rs_es::operations::search::{Sort, SortField, Order};
use rs_es::query::{Filter, Query};

extern crate postgres;
extern crate postgres_array;
use postgres::{Connection, SslMode};

mod user;
use user::User;

mod company;

mod filters;
use filters::{visibility_filters, VectorOfTerms};

#[derive(Debug, RustcDecodable)]
struct TalentsSearchResult {
  id: i32
}

const PG_URL: &'static str = "postgres://lando@localhost/lando_development";
const ES_INDEXES: &'static [&'static str] = &["honeypot_dev_talents"];

fn main() {
  let mut es = Client::new("localhost", 9200);
  let     pg = Connection::connect(PG_URL, SslMode::None).unwrap();

  let roles:         Vec<&str>   = vec!["Frontend", "Backend"];
  let languages:     Vec<&str>   = vec![];
  let experience:    Vec<&str>   = vec![];
  let locations:     Vec<&str>   = vec![];
  let authorization: Vec<&str>   = vec![];
  let company_ids:   Vec<i32>    = vec![];
  let company_id:    Option<i32> = None;

  let query = Query::build_filtered(Filter::build_bool()
                                           .with_must(
                                             vec![
                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_roles", &roles),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_languages", &languages),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_experience", &experience),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_locations", &locations),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                "work_authorization", &authorization),

                                               visibility_filters(&pg, &company_id)
                                             ].into_iter()
                                              .flat_map(|x| x)
                                              .collect::<Vec<Filter>>())
                                           .with_must_not(
                                             vec![
                                               <Filter as VectorOfTerms<i32>>::build_terms(
                                                 "company_ids", &company_ids),

                                               <Filter as VectorOfTerms<i32>>::build_terms(
                                                 "blocked_companies", &company_ids)
                                             ].into_iter()
                                              .flat_map(|x| x)
                                              .collect::<Vec<Filter>>())
                                           .build())
                    .build();

  let result = es.search_query()
                 .with_indexes(ES_INDEXES)
                 .with_query(&query)
                 .with_sort(&Sort::new(
                   vec![
                     SortField::new("updated_at", Some(Order::Desc)).build()
                   ]))
                 .send()
                 .ok()
                 .unwrap();

  // Actually ES returns lots of stuff here.
  // We could consider to fetch very few fields from the database
  for hit in result.hits.hits {
    let talent: TalentsSearchResult = hit.source().unwrap();

    match User::find(&pg, &talent.id) {
      Some(user) => println!("{:#?}", user),
      None       => {}
    }
  }
}
<commit_msg>main: put everything behind an HTTP server<commit_after>extern crate chrono;

extern crate rustc_serialize;
use rustc_serialize::json;

extern crate rs_es;
use rs_es::Client;
use rs_es::operations::search::{Sort, SortField, Order};
use rs_es::query::{Filter, Query};

extern crate postgres;
extern crate postgres_array;
use postgres::{Connection, SslMode};

extern crate hyper;
use hyper::Server;
use hyper::server::Request;
use hyper::server::Response;
use hyper::header::ContentType;
use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};

mod user;
use user::User;

mod company;

mod filters;
use filters::{visibility_filters, VectorOfTerms};

#[derive(Debug, RustcDecodable)]
struct TalentsSearchResult {
  id: i32
}

const PG_URL: &'static str = "postgres://lando@localhost/lando_development";
const ES_INDEXES: &'static [&'static str] = &["honeypot_dev_talents"];

fn main() {
  println!("Listening on http://127.0.0.1:3000");
  Server::http("127.0.0.1:3000").unwrap().handle(listener).unwrap();
}

fn listener(_: Request, mut res: Response) {
  res.headers_mut().set(ContentType(Mime(
                          TopLevel::Application,
                          SubLevel::Json,
                          vec![
                            (Attr::Charset, Value::Utf8)
                          ]
                        )));

  let mut es = Client::new("localhost", 9200);
  let     pg = Connection::connect(PG_URL, SslMode::None).unwrap();

  let roles:         Vec<&str>   = vec!["Frontend", "Backend"];
  let languages:     Vec<&str>   = vec![];
  let experience:    Vec<&str>   = vec![];
  let locations:     Vec<&str>   = vec![];
  let authorization: Vec<&str>   = vec![];
  let company_ids:   Vec<i32>    = vec![];
  let company_id:    Option<i32> = None;

  let query = Query::build_filtered(Filter::build_bool()
                                           .with_must(
                                             vec![
                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_roles", &roles),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_languages", &languages),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_experience", &experience),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                 "work_locations", &locations),

                                               <Filter as VectorOfTerms<&str>>::build_terms(
                                                "work_authorization", &authorization),

                                               visibility_filters(&pg, &company_id)
                                             ].into_iter()
                                              .flat_map(|x| x)
                                              .collect::<Vec<Filter>>())
                                           .with_must_not(
                                             vec![
                                               <Filter as VectorOfTerms<i32>>::build_terms(
                                                 "company_ids", &company_ids),

                                               <Filter as VectorOfTerms<i32>>::build_terms(
                                                 "blocked_companies", &company_ids)
                                             ].into_iter()
                                              .flat_map(|x| x)
                                              .collect::<Vec<Filter>>())
                                           .build())
                    .build();

  let result = es.search_query()
                 .with_indexes(ES_INDEXES)
                 .with_query(&query)
                 .with_sort(&Sort::new(
                   vec![
                     SortField::new("updated_at", Some(Order::Desc)).build()
                   ]))
                 .send()
                 .ok()
                 .unwrap();

  let user_ids = result.hits.hits.into_iter()
                                 .filter_map(|hit| {
                                   let talent: TalentsSearchResult = hit.source().unwrap();
                                   User::find(&pg, &talent.id)
                                 })
                                 .collect::<Vec<User>>();

  res.send(&json::encode(&user_ids).unwrap().into_bytes()).unwrap();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate reqwest;
#[macro_use]
extern crate clap;
extern crate geo;
extern crate num_traits;
extern crate rand;

use std::error::Error;
use std::process;
use std::boxed::Box;
use clap::{Arg, App, SubCommand, ArgMatches, Values};
use std::fmt;
use std::fmt::Display;
use reqwest::header::UserAgent;
use std::io::Write;
use geo::Point;
use geo::haversine_distance::HaversineDistance;
use rand::distributions::{IndependentSample, Range};

static NOMINATIM_ENDPOINT: &'static str = "http://nominatim.openstreetmap.org";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const NAME: &'static str = env!("CARGO_PKG_NAME");
const EARTH_RADIUS_KM: f64 = 6373.;

#[derive(Deserialize, Debug)]
struct Location {
    lat: String,
    lon: String,
}

impl Display for Location {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{},{}", self.lon, self.lat)
    }
}

#[derive(Deserialize, Debug)]
struct Place {
    display_name: String,
}

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

fn get_query_string(params: Vec<(&str, &str)>) -> String {
    let pairs: Vec<String> = params
        .into_iter()
        .map(|(k, v)| format!("{}={}", k, v))
        .collect();
    pairs.join("&")
}

fn reverse_geocode(lon: &str, lat: &str) -> Result<Place, Box<Error>> {
    let params = vec![("format", "json"), ("lon", lon), ("lat", lat)];
    let query_string = get_query_string(params);
    let url = format!("{}/reverse?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let result = res.json::<Place>()?;
    Ok(result)
}

fn search(place_name: &str) -> Result<Location, Box<Error>> {
    let params = vec![("format", "jsonv2"), ("q", place_name), ("limit", "1")];
    let query_string = get_query_string(params);
    let url = format!("{}/search?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let mut results = res.json::<Vec<Location>>()?;
    results.reverse();
    let first = results.pop().ok_or("No result found")?;
    Ok(first)
}

fn is_float(x: String) -> Result<(), String> {
    match x.parse::<f64>() {
        Ok(_) => Ok(()),
        Err(_) => Err("Value is not a proper float.".to_string()),
    }
}

fn is_positive_float(x: String) -> Result<(), String> {
    match x.parse::<f64>() {
            Ok(f) => Ok(f),
            Err(_) => Err("Value is not a proper float.".to_string()),
        }
        .and_then(|f| match f < 0. {
                      false => Ok(()),
                      true => Err("Value is not positive.".to_string()),
                  })
}

fn get_loc_arg<'a, 'b>(name: &'a str, short: &str) -> Arg<'a, 'b> {
    Arg::with_name(name)
        .required(true)
        .require_delimiter(true)
        .short(short)
        .long(name)
        .value_name("lon,lat")
        .validator(is_float)
        .number_of_values(2)
        .takes_value(true)
}

fn get_cli_app<'a, 'b>() -> App<'a, 'b> {
    App::new("Location utility")
        .version(crate_version!())
        .author(crate_authors!())
        .subcommand(SubCommand::with_name("loc")
                        .about("Retrieve a location via search string")
                        .arg(Arg::with_name("place")
                                 .required(true)
                                 .short("P")
                                 .long("place")
                                 .value_name("place name")
                                 .number_of_values(1)
                                 .takes_value(true)))
        .subcommand(SubCommand::with_name("rev")
                        .about("Reverse geocode a place via location")
                        .arg(get_loc_arg("location", "L")))
        .subcommand(SubCommand::with_name("rnd")
                        .about("Get a random location within a km radius")
                        .arg(get_loc_arg("location", "L"))
                        .arg(Arg::with_name("radius")
                                 .required(true)
                                 .short("R")
                                 .long("radius")
                                 .value_name("radius in km")
                                 .validator(is_positive_float)
                                 .number_of_values(1)
                                 .takes_value(true)))
        .subcommand(SubCommand::with_name("dis")
                        .about("Return the distance between two points in meters")
                        .arg(get_loc_arg("location1", "1"))
                        .arg(get_loc_arg("location2", "2")))
}

fn bail_out(message: &str) {
    writeln!(&mut std::io::stderr(), "{}", message).expect("could not write to stderr");
    process::exit(1);
}

fn handle_rev(matches: &ArgMatches) {
    let mut parts: Vec<&str> = matches.values_of("location").unwrap().collect();
    let lat = parts.pop().unwrap();
    let lon = parts.pop().unwrap();
    match reverse_geocode(lon, lat) {
        Ok(data) => println!("{}", data),
        Err(e) => bail_out(e.description()),
    }
}

fn get_random_point(center: &Point<f64>, radius: f64) -> Point<f64> {
    let mut rng = rand::thread_rng();
    let dist_range = Range::new(0., radius);
    let distance = dist_range.ind_sample(&mut rng);
    let bearing_range = Range::new(0., 360.);
    let bearing = bearing_range.ind_sample(&mut rng);

    direction(center, bearing, distance)
}

#[cfg(test)]
mod get_random_point {
    use super::*;
    use geo::contains::Contains;
    use geo::{LineString, Polygon};
    use std::fs::File;

    #[derive(Deserialize, Debug)]
    struct TestCoordinates(f64, f64);

    #[test]
    fn stays_within_the_given_radius() {
        let file = File::open("test/circle.json").unwrap();
        let coordinates: Vec<TestCoordinates> = serde_json::from_reader(file).unwrap();
        let points: Vec<Point<f64>> = coordinates
            .into_iter()
            .map(|t| Point::new(t.0, t.1))
            .collect();
        let exterior = LineString(points);
        let polygon = Polygon::new(exterior, vec![]);

        let center_point = Point::new(9.177789688110352, 48.776781529534965);
        for _ in 0..1000 {
            let random_point = get_random_point(&center_point, 9.9);
            let contained = polygon.contains(&random_point);
            assert_eq!(contained, true);
        }
    }
}

fn handle_rnd(matches: &ArgMatches) {
    let center_loc = matches.values_of("location").unwrap();
    let center_point = parse_point(center_loc).unwrap();
    let rad_str = matches.value_of("radius").unwrap();
    let rad = rad_str.parse::<f64>().unwrap();
    let random_point = get_random_point(&center_point, rad);

    println!("{},{}", random_point.x(), random_point.y());
}

fn handle_loc(matches: &ArgMatches) {
    let place = matches.value_of("place").unwrap();
    match search(place) {
        Ok(data) => println!("{}", data),
        Err(e) => bail_out(e.description()),
    }
}

fn parse_point(mut loc: Values) -> Result<Point<f64>, Box<Error>> {
    let lon = loc.next().ok_or("Argument parse error")?;
    let lat = loc.next().ok_or("Argument parse error")?;
    let lon_f = lon.parse::<f64>()?;
    let lat_f = lat.parse::<f64>()?;
    Ok(Point::new(lon_f, lat_f))
}

fn direction(point: &Point<f64>, bearing: f64, distance: f64) -> Point<f64> {
    let pi = std::f64::consts::PI;
    let deg_to_rad = pi / 180.;
    let rad_to_deg = 180. / pi;
    let center_lng = deg_to_rad * point.x();
    let center_lat = deg_to_rad * point.y();
    let bearing_rad = deg_to_rad * bearing;

    let rad = distance / EARTH_RADIUS_KM;

    let lat = {
            center_lat.sin() * rad.cos() + center_lat.cos() * rad.sin() * bearing_rad.cos()
        }
        .asin();
    let lng = {
            bearing_rad.sin() * rad.sin() * center_lat.cos()
        }
        .atan2(rad.cos() - center_lat.sin() * lat.sin()) + center_lng;

    Point::new(lng * rad_to_deg, lat * rad_to_deg)
}

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

    #[test]
    fn returns_a_new_point() {
        let point_1 = Point::new(9.177789688110352, 48.776781529534965);
        let point_2 = direction(&point_1, 45., 10.);
        assert_eq!(point_2, Point::new(9.274379723017008, 48.840312896632746));
    }
}

fn handle_dis(matches: &ArgMatches) {
    let loc_1 = matches.values_of("location1").unwrap();
    let point_1 = parse_point(loc_1).unwrap();
    let loc_2 = matches.values_of("location2").unwrap();
    let point_2 = parse_point(loc_2).unwrap();
    let dist = point_1.haversine_distance(&point_2);
    println!("{:.0}", dist);
}

fn main() {
    let app = get_cli_app();
    let matches = app.get_matches();

    match matches.subcommand() {
        ("loc", Some(sub_m)) => handle_loc(sub_m),
        ("rnd", Some(sub_m)) => handle_rnd(sub_m),
        ("rev", Some(sub_m)) => handle_rev(sub_m),
        ("dis", Some(sub_m)) => handle_dis(sub_m),
        _ => bail_out(matches.usage()),
    }
}
<commit_msg>Simplified constant string declaration.<commit_after>#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate reqwest;
#[macro_use]
extern crate clap;
extern crate geo;
extern crate num_traits;
extern crate rand;

use std::error::Error;
use std::process;
use std::boxed::Box;
use clap::{Arg, App, SubCommand, ArgMatches, Values};
use std::fmt;
use std::fmt::Display;
use reqwest::header::UserAgent;
use std::io::Write;
use geo::Point;
use geo::haversine_distance::HaversineDistance;
use rand::distributions::{IndependentSample, Range};

static NOMINATIM_ENDPOINT: &str = "http://nominatim.openstreetmap.org";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const NAME: &str = env!("CARGO_PKG_NAME");
const EARTH_RADIUS_KM: f64 = 6373.;

#[derive(Deserialize, Debug)]
struct Location {
    lat: String,
    lon: String,
}

impl Display for Location {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{},{}", self.lon, self.lat)
    }
}

#[derive(Deserialize, Debug)]
struct Place {
    display_name: String,
}

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

fn get_query_string(params: Vec<(&str, &str)>) -> String {
    let pairs: Vec<String> = params
        .into_iter()
        .map(|(k, v)| format!("{}={}", k, v))
        .collect();
    pairs.join("&")
}

fn reverse_geocode(lon: &str, lat: &str) -> Result<Place, Box<Error>> {
    let params = vec![("format", "json"), ("lon", lon), ("lat", lat)];
    let query_string = get_query_string(params);
    let url = format!("{}/reverse?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let result = res.json::<Place>()?;
    Ok(result)
}

fn search(place_name: &str) -> Result<Location, Box<Error>> {
    let params = vec![("format", "jsonv2"), ("q", place_name), ("limit", "1")];
    let query_string = get_query_string(params);
    let url = format!("{}/search?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let mut results = res.json::<Vec<Location>>()?;
    results.reverse();
    let first = results.pop().ok_or("No result found")?;
    Ok(first)
}

fn is_float(x: String) -> Result<(), String> {
    match x.parse::<f64>() {
        Ok(_) => Ok(()),
        Err(_) => Err("Value is not a proper float.".to_string()),
    }
}

fn is_positive_float(x: String) -> Result<(), String> {
    match x.parse::<f64>() {
            Ok(f) => Ok(f),
            Err(_) => Err("Value is not a proper float.".to_string()),
        }
        .and_then(|f| match f < 0. {
                      false => Ok(()),
                      true => Err("Value is not positive.".to_string()),
                  })
}

fn get_loc_arg<'a, 'b>(name: &'a str, short: &str) -> Arg<'a, 'b> {
    Arg::with_name(name)
        .required(true)
        .require_delimiter(true)
        .short(short)
        .long(name)
        .value_name("lon,lat")
        .validator(is_float)
        .number_of_values(2)
        .takes_value(true)
}

fn get_cli_app<'a, 'b>() -> App<'a, 'b> {
    App::new("Location utility")
        .version(crate_version!())
        .author(crate_authors!())
        .subcommand(SubCommand::with_name("loc")
                        .about("Retrieve a location via search string")
                        .arg(Arg::with_name("place")
                                 .required(true)
                                 .short("P")
                                 .long("place")
                                 .value_name("place name")
                                 .number_of_values(1)
                                 .takes_value(true)))
        .subcommand(SubCommand::with_name("rev")
                        .about("Reverse geocode a place via location")
                        .arg(get_loc_arg("location", "L")))
        .subcommand(SubCommand::with_name("rnd")
                        .about("Get a random location within a km radius")
                        .arg(get_loc_arg("location", "L"))
                        .arg(Arg::with_name("radius")
                                 .required(true)
                                 .short("R")
                                 .long("radius")
                                 .value_name("radius in km")
                                 .validator(is_positive_float)
                                 .number_of_values(1)
                                 .takes_value(true)))
        .subcommand(SubCommand::with_name("dis")
                        .about("Return the distance between two points in meters")
                        .arg(get_loc_arg("location1", "1"))
                        .arg(get_loc_arg("location2", "2")))
}

fn bail_out(message: &str) {
    writeln!(&mut std::io::stderr(), "{}", message).expect("could not write to stderr");
    process::exit(1);
}

fn handle_rev(matches: &ArgMatches) {
    let mut parts: Vec<&str> = matches.values_of("location").unwrap().collect();
    let lat = parts.pop().unwrap();
    let lon = parts.pop().unwrap();
    match reverse_geocode(lon, lat) {
        Ok(data) => println!("{}", data),
        Err(e) => bail_out(e.description()),
    }
}

fn get_random_point(center: &Point<f64>, radius: f64) -> Point<f64> {
    let mut rng = rand::thread_rng();
    let dist_range = Range::new(0., radius);
    let distance = dist_range.ind_sample(&mut rng);
    let bearing_range = Range::new(0., 360.);
    let bearing = bearing_range.ind_sample(&mut rng);

    direction(center, bearing, distance)
}

#[cfg(test)]
mod get_random_point {
    use super::*;
    use geo::contains::Contains;
    use geo::{LineString, Polygon};
    use std::fs::File;

    #[derive(Deserialize, Debug)]
    struct TestCoordinates(f64, f64);

    #[test]
    fn stays_within_the_given_radius() {
        let file = File::open("test/circle.json").unwrap();
        let coordinates: Vec<TestCoordinates> = serde_json::from_reader(file).unwrap();
        let points: Vec<Point<f64>> = coordinates
            .into_iter()
            .map(|t| Point::new(t.0, t.1))
            .collect();
        let exterior = LineString(points);
        let polygon = Polygon::new(exterior, vec![]);

        let center_point = Point::new(9.177789688110352, 48.776781529534965);
        for _ in 0..1000 {
            let random_point = get_random_point(&center_point, 9.9);
            let contained = polygon.contains(&random_point);
            assert_eq!(contained, true);
        }
    }
}

fn handle_rnd(matches: &ArgMatches) {
    let center_loc = matches.values_of("location").unwrap();
    let center_point = parse_point(center_loc).unwrap();
    let rad_str = matches.value_of("radius").unwrap();
    let rad = rad_str.parse::<f64>().unwrap();
    let random_point = get_random_point(&center_point, rad);

    println!("{},{}", random_point.x(), random_point.y());
}

fn handle_loc(matches: &ArgMatches) {
    let place = matches.value_of("place").unwrap();
    match search(place) {
        Ok(data) => println!("{}", data),
        Err(e) => bail_out(e.description()),
    }
}

fn parse_point(mut loc: Values) -> Result<Point<f64>, Box<Error>> {
    let lon = loc.next().ok_or("Argument parse error")?;
    let lat = loc.next().ok_or("Argument parse error")?;
    let lon_f = lon.parse::<f64>()?;
    let lat_f = lat.parse::<f64>()?;
    Ok(Point::new(lon_f, lat_f))
}

fn direction(point: &Point<f64>, bearing: f64, distance: f64) -> Point<f64> {
    let pi = std::f64::consts::PI;
    let deg_to_rad = pi / 180.;
    let rad_to_deg = 180. / pi;
    let center_lng = deg_to_rad * point.x();
    let center_lat = deg_to_rad * point.y();
    let bearing_rad = deg_to_rad * bearing;

    let rad = distance / EARTH_RADIUS_KM;

    let lat = {
            center_lat.sin() * rad.cos() + center_lat.cos() * rad.sin() * bearing_rad.cos()
        }
        .asin();
    let lng = {
            bearing_rad.sin() * rad.sin() * center_lat.cos()
        }
        .atan2(rad.cos() - center_lat.sin() * lat.sin()) + center_lng;

    Point::new(lng * rad_to_deg, lat * rad_to_deg)
}

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

    #[test]
    fn returns_a_new_point() {
        let point_1 = Point::new(9.177789688110352, 48.776781529534965);
        let point_2 = direction(&point_1, 45., 10.);
        assert_eq!(point_2, Point::new(9.274379723017008, 48.840312896632746));
    }
}

fn handle_dis(matches: &ArgMatches) {
    let loc_1 = matches.values_of("location1").unwrap();
    let point_1 = parse_point(loc_1).unwrap();
    let loc_2 = matches.values_of("location2").unwrap();
    let point_2 = parse_point(loc_2).unwrap();
    let dist = point_1.haversine_distance(&point_2);
    println!("{:.0}", dist);
}

fn main() {
    let app = get_cli_app();
    let matches = app.get_matches();

    match matches.subcommand() {
        ("loc", Some(sub_m)) => handle_loc(sub_m),
        ("rnd", Some(sub_m)) => handle_rnd(sub_m),
        ("rev", Some(sub_m)) => handle_rev(sub_m),
        ("dis", Some(sub_m)) => handle_dis(sub_m),
        _ => bail_out(matches.usage()),
    }
}
<|endoftext|>


<commit_before>extern crate git2;
use git2::*;
use std::process::Command;

fn main() {

  let repo = match Repository::init("/tmp/bla") {
      Ok(repo) => repo,
      Err(e) => panic!("failed to init: {}", e),
  };
  println!("Hello, world!");
}
<commit_msg>porting<commit_after>extern crate git2;
extern crate clap;
use git2::*;
use std::process::Command;
use std::process::exit;
use std::env;
use std::path::Path;

const CENTRAL_NAME:    &'static str = "bsw/central";
const AUTOMATION_USER: &'static str = "automation";
const TMP_REPO_DIR:    &'static str = "/home/christian/gerrit_testsite/tmp_automation_repo";

fn module_review_upload() { }

fn central_review_upload() { }
fn central_submit() { }
fn central_direct_push() { }

fn in_tmp_repo(cmd: &str) -> String {
  let args: Vec<&str> = cmd.split(" ").collect();
  let output = Command::new("git")
    .env("GIT_DIR",TMP_REPO_DIR)
    .args(&args).output().unwrap();
  return format!("{}", String::from_utf8_lossy(&output.stdout));
}

fn setup_tmp_repo(name: &str, modules: &Vec<String>) -> Repository {
  let repo = Repository::init_bare(name).unwrap();

  if !repo.find_remote("central_repo").is_ok() {
    repo.remote("central_repo",
      &format!("ssh://{}@gerrit-test-git/{}.git",AUTOMATION_USER,CENTRAL_NAME)
    );
  }

  for module in modules.iter() {
    let output = Command::new("ssh")
      .arg("-p").arg("29418")
      .arg("gerrit-test-git")
        .arg("gerrit")
        .arg("create-project")
          .arg(format!("bsw/modules/{}",module))
          .arg("--empty-commit")
      .output()
      .expect("failed to create project");

    println!("create-project: {}", String::from_utf8_lossy(&output.stdout));

    let remote_url = format!("ssh://{}@gerrit-test-git:29418/bsw/modules/{}.git",
      AUTOMATION_USER,
      module
    );

    let remote_name = format!("modules/{}",module);
    if !repo.find_remote(&remote_name).is_ok() {
        repo.remote(&remote_name, &remote_url);
    }
  }

  in_tmp_repo("fetch --all");

  return repo;
}

fn module_to_subfolder(module: Tree, master: Tree) {
  let modules_oid = master.get_path(&Path::new("modules")).unwrap().id();
  let tmp_repo = Repository::init_bare(TMP_REPO_DIR).unwrap();

  let modules_tree = tmp_repo.find_tree(modules_oid).unwrap();
  // let mbuilder = TreeBuilder::new(modules_tree);
  // let mbuilder = tmp_repo.treebuilder(modules_tree);
}

fn get_module_names(rev: &str) -> Vec<String> {
  let central_repo = Repository::open(".").unwrap();

  let object = central_repo.revparse_single(rev).unwrap();
  let commit = object.as_commit().unwrap();
  let tree = commit.tree().unwrap();

  let modules_o = tree.get_path(&Path::new("modules")).unwrap()
                      .to_object(&central_repo).unwrap();
  let modules = modules_o.as_tree().unwrap();

  let mut names = Vec::<String>::new();
  for module in modules.iter() {
    names.push(module.name().unwrap().to_string());
  }
  return names;
}

fn main() {

  let args = clap::App::new("centralgithook")
      .arg(clap::Arg::with_name("newrev").long("newrev").takes_value(true))
      .arg(clap::Arg::with_name("project").long("project").takes_value(true))
      .arg(clap::Arg::with_name("refname").long("refname").takes_value(true))
      .arg(clap::Arg::with_name("uploader").long("uploader").takes_value(true))
      .arg(clap::Arg::with_name("commit").long("commit").takes_value(true))
      .get_matches();

  let newrev = args.value_of("newrev").unwrap_or("");
  let project = args.value_of("project").unwrap_or("");
  let refname = args.value_of("refname").unwrap_or("");
  let uploader = args.value_of("uploader").unwrap_or("");
  let commit = args.value_of("commit").unwrap_or("");

  if let Some(hook) = env::args().nth(0) {
    let is_review = refname == "refs/for/master";
    let is_automation = uploader.contains("Automation");
    let is_module = project != CENTRAL_NAME;
    let is_update = hook.ends_with("ref-update");
    let is_submit = hook.ends_with("change-merged");

    if !is_review && !is_automation {
      println!("only push to refs/for/master");
      exit(1);
    }

    if is_module && is_update && is_review { module_review_upload(); }
    if !is_module && is_update && is_review { central_review_upload(); }
    if !is_module && is_update && !is_review { central_direct_push(); }
    if !is_module && is_submit { central_submit(); }
  }

  let repo = match Repository::open(".") {
      Ok(repo) => repo,
      Err(e) => panic!("failed to init: {}", e),
  };
  println!("Hello, world!");
  exit(0);
}
<|endoftext|>


<commit_before>use std::char;
use std::collections::BTreeSet;

const NSQRT: usize = 3;
const N: usize = NSQRT * NSQRT;
const NSQ: usize = N*N;

/// Return the 0-based row index of `cell`.
fn row(cell: usize) -> usize {
    cell / N
}

/// Return the 0-based row index of `cell`.
fn col(cell: usize) -> usize {
    cell % N
}

/// Return the 0-based index of the upper-left cell of `cell`'s group.
fn group(cell: usize) -> usize {
    let r = row(cell);
    let c = col(cell);
    (N * (r - r % NSQRT)) + (c - c % NSQRT)
}

fn neighbors(cell: usize) -> BTreeSet<usize> {
    let mut all_neighbors: BTreeSet<usize> = BTreeSet::new();

    // Neighbors on row
    for col in 0..N {
        all_neighbors.insert((N * row(cell)) + col);
    }

    // Neighbors on column
    for row in 0..N {
        all_neighbors.insert((N * row) + col(cell));
    }

    // Neighbors in group
    let leader = group(cell);
    for r in row(leader) .. row(leader) + NSQRT {
        for c in col(leader) .. col(leader) + NSQRT {
            all_neighbors.insert(N * r + c);
        }
    }

    all_neighbors.remove(&cell);
    return all_neighbors;
}

#[derive(Debug)]
struct SudokuBoard(Vec<u8>);

impl SudokuBoard {
    fn from_str(digits: &str) -> Self {
        let mut v = Vec::with_capacity(NSQ);
        for d in digits.chars() {
            match d {
                '.' => { v.push(0); }
                '1' ... '9' => {
                    let n = d.to_digit(10).unwrap() as u8;
                    v.push(n);
                }
                _ => { panic!("invalid digit ({:?}) in string", d); }
            }
        }
        SudokuBoard(v)
    }

    fn to_str(&self) -> String {
        /*
        let mut s = String::with_capacity(NSQ);
        for n in self.0.iter() {
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
        }
        s
         */
        let mut s = String::with_capacity(N + NSQ);
        let mut i = 0;
        for n in self.0.iter() {
            if i % N == 0 {
                s.push('\n');
            }
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
            i += 1;
        }
        s
    }

    fn is_solved(&self, cell: usize) -> bool {
        self.0[cell] != 0
    }

    fn candidates(&self, cell: usize) -> BTreeSet<u8> {
        let mut non_candidates = BTreeSet::new();
        for n in neighbors(cell) {
            let x = self.0[n];
            if x != 0 {
                non_candidates.insert(x);
            }
        }
        let mut candidates: BTreeSet<u8> = (1_u8 .. (N+1) as u8).collect();
        for nc in non_candidates {
            candidates.remove(&nc);
        }
        candidates
    }

    fn solve(&mut self, cell: usize) -> bool {
        if cell >= NSQ {
            return true;
        }

        if self.is_solved(cell) {
            return self.solve(cell + 1);
        }

        for c in self.candidates(cell) {
            self.0[cell] = c;
            if self.solve(cell + 1) {
                return true;
            } else {
                self.0[cell] = 0;
            }
        }
        return false;
    }
}

fn main() {
    let mut sb = SudokuBoard::from_str(".94...13..............76..2.8..1.....32.........2...6.....5.4.......8..7..63.4..8");
    println!("{}", sb.to_str());
    sb.solve(0);
    println!("{}", sb.to_str());
}

#[test]
fn test_row_col() {
    assert_eq!(row(11), 1);
    assert_eq!(col(11), 2);
}

#[test]
fn test_group() {
    assert_eq!(group(0), 0);
    assert_eq!(group(1), 0);
    assert_eq!(group(2), 0);
    assert_eq!(group(9), 0);
    assert_eq!(group(10), 0);
    assert_eq!(group(11), 0);
    assert_eq!(group(18), 0);
    assert_eq!(group(19), 0);
    assert_eq!(group(20), 0);
    assert_eq!(group(60), 60);
    assert_eq!(group(61), 60);
    assert_eq!(group(62), 60);
    assert_eq!(group(69), 60);
    assert_eq!(group(70), 60);
    assert_eq!(group(71), 60);
    assert_eq!(group(78), 60);
    assert_eq!(group(79), 60);
    assert_eq!(group(80), 60);
}

#[test]
fn test_is_solved() {
    let sb = SudokuBoard(vec![0, 1]);
    assert!(!sb.is_solved(0));
    assert!(sb.is_solved(1));
}

#[test]
fn test_neighbors() {
    assert!(!neighbors(0).contains(&0));
    // Neighbors of 0 on the same row
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&3));
    assert!(neighbors(0).contains(&4));
    assert!(neighbors(0).contains(&5));
    assert!(neighbors(0).contains(&6));
    assert!(neighbors(0).contains(&7));
    assert!(neighbors(0).contains(&8));
    // Neighbors of 0 on the same col
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&27));
    assert!(neighbors(0).contains(&36));
    assert!(neighbors(0).contains(&45));
    assert!(neighbors(0).contains(&54));
    assert!(neighbors(0).contains(&63));
    assert!(neighbors(0).contains(&72));
    // Neighbors of 0 in the same group
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&10));
    assert!(neighbors(0).contains(&11));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&19));
    assert!(neighbors(0).contains(&20));
}

#[test]
fn test_candidates() {
    let sb = SudokuBoard::from_str(".2......34..........6...................................................5........");
    assert!(!sb.candidates(0).contains(&2));
    assert!(!sb.candidates(0).contains(&3));
    assert!(!sb.candidates(0).contains(&4));
    assert!(!sb.candidates(0).contains(&5));
    assert!(!sb.candidates(0).contains(&6));
    assert!(sb.candidates(0).contains(&1));
    assert!(sb.candidates(0).contains(&7));
    assert!(sb.candidates(0).contains(&8));
    assert!(sb.candidates(0).contains(&9));
}
<commit_msg>Remove commented impl. of to_str<commit_after>use std::char;
use std::collections::BTreeSet;

const NSQRT: usize = 3;
const N: usize = NSQRT * NSQRT;
const NSQ: usize = N*N;

/// Return the 0-based row index of `cell`.
fn row(cell: usize) -> usize {
    cell / N
}

/// Return the 0-based row index of `cell`.
fn col(cell: usize) -> usize {
    cell % N
}

/// Return the 0-based index of the upper-left cell of `cell`'s group.
fn group(cell: usize) -> usize {
    let r = row(cell);
    let c = col(cell);
    (N * (r - r % NSQRT)) + (c - c % NSQRT)
}

fn neighbors(cell: usize) -> BTreeSet<usize> {
    let mut all_neighbors: BTreeSet<usize> = BTreeSet::new();

    // Neighbors on row
    for col in 0..N {
        all_neighbors.insert((N * row(cell)) + col);
    }

    // Neighbors on column
    for row in 0..N {
        all_neighbors.insert((N * row) + col(cell));
    }

    // Neighbors in group
    let leader = group(cell);
    for r in row(leader) .. row(leader) + NSQRT {
        for c in col(leader) .. col(leader) + NSQRT {
            all_neighbors.insert(N * r + c);
        }
    }

    all_neighbors.remove(&cell);
    return all_neighbors;
}

#[derive(Debug)]
struct SudokuBoard(Vec<u8>);

impl SudokuBoard {
    fn from_str(digits: &str) -> Self {
        let mut v = Vec::with_capacity(NSQ);
        for d in digits.chars() {
            match d {
                '.' => { v.push(0); }
                '1' ... '9' => {
                    let n = d.to_digit(10).unwrap() as u8;
                    v.push(n);
                }
                _ => { panic!("invalid digit ({:?}) in string", d); }
            }
        }
        SudokuBoard(v)
    }

    fn to_str(&self) -> String {
        let mut s = String::with_capacity(N + NSQ);
        let mut i = 0;
        for n in self.0.iter() {
            if i % N == 0 {
                s.push('\n');
            }
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
            i += 1;
        }
        s
    }

    fn is_solved(&self, cell: usize) -> bool {
        self.0[cell] != 0
    }

    fn candidates(&self, cell: usize) -> BTreeSet<u8> {
        let mut non_candidates = BTreeSet::new();
        for n in neighbors(cell) {
            let x = self.0[n];
            if x != 0 {
                non_candidates.insert(x);
            }
        }
        let mut candidates: BTreeSet<u8> = (1_u8 .. (N+1) as u8).collect();
        for nc in non_candidates {
            candidates.remove(&nc);
        }
        candidates
    }

    fn solve(&mut self, cell: usize) -> bool {
        if cell >= NSQ {
            return true;
        }

        if self.is_solved(cell) {
            return self.solve(cell + 1);
        }

        for c in self.candidates(cell) {
            self.0[cell] = c;
            if self.solve(cell + 1) {
                return true;
            } else {
                self.0[cell] = 0;
            }
        }
        return false;
    }
}

fn main() {
    let mut sb = SudokuBoard::from_str(".94...13..............76..2.8..1.....32.........2...6.....5.4.......8..7..63.4..8");
    println!("{}", sb.to_str());
    sb.solve(0);
    println!("{}", sb.to_str());
}

#[test]
fn test_row_col() {
    assert_eq!(row(11), 1);
    assert_eq!(col(11), 2);
}

#[test]
fn test_group() {
    assert_eq!(group(0), 0);
    assert_eq!(group(1), 0);
    assert_eq!(group(2), 0);
    assert_eq!(group(9), 0);
    assert_eq!(group(10), 0);
    assert_eq!(group(11), 0);
    assert_eq!(group(18), 0);
    assert_eq!(group(19), 0);
    assert_eq!(group(20), 0);
    assert_eq!(group(60), 60);
    assert_eq!(group(61), 60);
    assert_eq!(group(62), 60);
    assert_eq!(group(69), 60);
    assert_eq!(group(70), 60);
    assert_eq!(group(71), 60);
    assert_eq!(group(78), 60);
    assert_eq!(group(79), 60);
    assert_eq!(group(80), 60);
}

#[test]
fn test_is_solved() {
    let sb = SudokuBoard(vec![0, 1]);
    assert!(!sb.is_solved(0));
    assert!(sb.is_solved(1));
}

#[test]
fn test_neighbors() {
    assert!(!neighbors(0).contains(&0));
    // Neighbors of 0 on the same row
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&3));
    assert!(neighbors(0).contains(&4));
    assert!(neighbors(0).contains(&5));
    assert!(neighbors(0).contains(&6));
    assert!(neighbors(0).contains(&7));
    assert!(neighbors(0).contains(&8));
    // Neighbors of 0 on the same col
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&27));
    assert!(neighbors(0).contains(&36));
    assert!(neighbors(0).contains(&45));
    assert!(neighbors(0).contains(&54));
    assert!(neighbors(0).contains(&63));
    assert!(neighbors(0).contains(&72));
    // Neighbors of 0 in the same group
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&10));
    assert!(neighbors(0).contains(&11));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&19));
    assert!(neighbors(0).contains(&20));
}

#[test]
fn test_candidates() {
    let sb = SudokuBoard::from_str(".2......34..........6...................................................5........");
    assert!(!sb.candidates(0).contains(&2));
    assert!(!sb.candidates(0).contains(&3));
    assert!(!sb.candidates(0).contains(&4));
    assert!(!sb.candidates(0).contains(&5));
    assert!(!sb.candidates(0).contains(&6));
    assert!(sb.candidates(0).contains(&1));
    assert!(sb.candidates(0).contains(&7));
    assert!(sb.candidates(0).contains(&8));
    assert!(sb.candidates(0).contains(&9));
}
<|endoftext|>


<commit_before>extern crate rand;

use std::env;
use std::fs;
use std::io;
use std::io::Read;
use std::path::Path;

const NUM_REGISTERS: usize = 16;
const GFX_MEMORY_SIZE: usize = 64 * 32;
const MEMORY_SIZE: usize = 4096;
const STACK_SIZE: usize = 16;
const NUM_KEYS: usize = 16;
const PROGRAM_START: usize = 0x200;
const FONT_SET_SIZE: usize = 80;
const FONT_SET: [u8; FONT_SET_SIZE] =
    [0xF0, 0x90, 0x90, 0x90, 0xF0, 0x20, 0x60, 0x20, 0x20, 0x70, 0xF0, 0x10, 0xF0, 0x80, 0xF0,
     0xF0, 0x10, 0xF0, 0x10, 0xF0, 0x90, 0x90, 0xF0, 0x10, 0x10, 0xF0, 0x80, 0xF0, 0x10, 0xF0,
     0xF0, 0x80, 0xF0, 0x90, 0xF0, 0xF0, 0x10, 0x20, 0x40, 0x40, 0xF0, 0x90, 0xF0, 0x90, 0xF0,
     0xF0, 0x90, 0xF0, 0x10, 0xF0, 0xF0, 0x90, 0xF0, 0x90, 0x90, 0xE0, 0x90, 0xE0, 0x90, 0xE0,
     0xF0, 0x80, 0x80, 0x80, 0xF0, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0xF0, 0x80, 0xF0, 0x80, 0xF0,
     0xF0, 0x80, 0xF0, 0x80, 0x80];

struct Opcode {
    opcode: u16,
}

impl Opcode {
    fn new(opcode: u16) -> Opcode {
        Opcode { opcode: opcode }
    }

    fn category(&self) -> u8 {
        (self.opcode & 0xF000 >> 12) as u8
    }

    fn x(&self) -> usize {
        (self.opcode & 0x0F00 >> 8) as usize
    }

    fn y(&self) -> usize {
        (self.opcode & 0x00F0 >> 4) as usize
    }

    fn address(&self) -> u16 {
        self.opcode & 0x0FFF
    }

    fn get_8bit(&self) -> u8 {
        (self.opcode & 0x00FF) as u8
    }

    fn get_4bit(&self) -> u8 {
        (self.opcode & 0x000F) as u8
    }
}

struct Chip8 {
    reg_v: [u8; NUM_REGISTERS],
    reg_gfx: [u8; GFX_MEMORY_SIZE],
    memory: [u8; MEMORY_SIZE],
    stack: [u16; STACK_SIZE],
    keys: [u8; NUM_KEYS],
    stack_pointer: u16,
    program_counter: u16,
    reg_i: u16,
    delay_timer: u8,
    sound_timer: u8,
}

impl Chip8 {
    fn new() -> Chip8 {
        Chip8 {
            reg_v: [0; NUM_REGISTERS],
            reg_gfx: [0; GFX_MEMORY_SIZE],
            memory: [0; MEMORY_SIZE],
            stack: [0; STACK_SIZE],
            keys: [0; NUM_KEYS],
            stack_pointer: 0,
            program_counter: 0,
            reg_i: 0,
            delay_timer: 0,
            sound_timer: 0,
        }
    }

    fn initialize(&mut self) {
        self.program_counter = PROGRAM_START as u16;
        self.reg_v = [0; NUM_REGISTERS];
        self.reg_gfx = [0; GFX_MEMORY_SIZE];
        self.stack = [0; STACK_SIZE];
        self.keys = [0; NUM_KEYS];
        self.stack_pointer = 0;
        self.reg_i = 0;
        for (index, element) in FONT_SET.into_iter().enumerate() {
            self.memory[index] = *element;
        }
    }

    fn run(&mut self) {
        loop {
            self.cycle();

            let duration = std::time::Duration::from_millis(16);
            std::thread::sleep(duration);
        }
    }

    fn load_rom(&mut self, rom: Vec<u8>) {
        for (index, element) in rom.into_iter().enumerate() {
            self.memory[index + PROGRAM_START] = element;
        }
    }

    fn cycle(&mut self) {
        let opcode = self.fetch_opcode();
        println!("OpCode={:X}", opcode.opcode);

        self.execute_opcode(opcode);

        if self.delay_timer > 0 {
            self.delay_timer = self.delay_timer - 1;
        }

        if self.sound_timer > 0 {
            self.sound_timer = self.sound_timer - 1;
        }
    }

    fn fetch_opcode(&mut self) -> Opcode {
        let opcode = ((self.memory[self.program_counter as usize] as u16) << 8) +
                     (self.memory[self.program_counter as usize + 1] as u16);
        self.program_counter = self.program_counter + 2;
        Opcode::new(opcode)
    }

    fn clear_screen(&mut self) {
        // TODO
    }

    fn display(&mut self, x: usize, y: usize, height: u8) {
        // TODO
    }

    fn execute_opcode(&mut self, opcode: Opcode) {
        match opcode.category() {
            0 => {
                match opcode.get_8bit() {
                    0xE0 => self.clear_screen(),
                    0xEE => {
                        self.program_counter = self.stack[self.stack_pointer as usize];
                        self.stack_pointer = self.stack_pointer - 1;
                    }
                    _ => {}
                }
            }
            1 => self.program_counter = opcode.address(),
            2 => {
                self.stack[self.stack_pointer as usize] = self.program_counter;
                self.stack_pointer = self.stack_pointer + 1;
                self.program_counter = opcode.address();
            }
            3 => {
                if self.reg_v[opcode.x()] == opcode.get_8bit() {
                    self.program_counter = self.program_counter + 2;
                }
            }
            4 => {
                if self.reg_v[opcode.x()] != opcode.get_8bit() {
                    self.program_counter = self.program_counter + 2;
                }
            }
            5 => {
                if self.reg_v[opcode.x()] == self.reg_v[opcode.y()] {
                    self.program_counter = self.program_counter + 2;
                }
            }
            6 => self.reg_v[opcode.x()] = opcode.get_8bit(),
            7 => self.reg_v[opcode.x()] = self.reg_v[opcode.x()] + opcode.get_8bit(),
            8 => {
                match opcode.get_4bit() {
                    0 => self.reg_v[opcode.x()] = self.reg_v[opcode.y()],
                    1 => self.reg_v[opcode.x()] = self.reg_v[opcode.x()] | self.reg_v[opcode.y()],
                    2 => self.reg_v[opcode.x()] = self.reg_v[opcode.x()] & self.reg_v[opcode.y()],
                    3 => self.reg_v[opcode.x()] = self.reg_v[opcode.x()] ^ self.reg_v[opcode.y()],
                    4 => {
                        self.memory[0xF] = if opcode.y() > (0xFF - opcode.x()) {
                            1
                        } else {
                            0
                        };
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] + self.reg_v[opcode.y()]
                    }
                    5 => {
                        self.memory[0xF] = if opcode.y() > opcode.x() { 1 } else { 0 };
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] - self.reg_v[opcode.y()]
                    }
                    6 => {
                        self.memory[0xF] = self.reg_v[opcode.x()] & 0x01;
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] >> 1
                    }
                    7 => {
                        self.memory[0xF] = if opcode.x() > opcode.y() { 1 } else { 0 };
                        self.reg_v[opcode.x()] = self.reg_v[opcode.y()] - self.reg_v[opcode.x()]
                    }
                    0xE => {
                        self.memory[0xF] = self.reg_v[opcode.x()] & 0x80;
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] << 1
                    }
                    _ => {}
                }
            }
            9 => {
                if self.reg_v[opcode.x()] != self.reg_v[opcode.y()] {
                    self.program_counter = self.program_counter + 2;
                }
            }
            0xA => self.reg_i = opcode.address(),
            0xB => self.program_counter = opcode.address() + self.reg_v[opcode.x()] as u16,
            0xC => self.reg_v[opcode.x()] = rand::random::<u8>() & opcode.get_8bit(),
            0xD => self.display(opcode.x(), opcode.y(), opcode.get_4bit()),
            0xE => {
                match opcode.get_8bit() {
                    0x9E => {
                        if self.keys[self.reg_v[opcode.x()] as usize] != 0 {
                            self.program_counter = self.program_counter + 2;
                        }
                    }
                    0xA1 => {
                        if self.keys[self.reg_v[opcode.x()] as usize] == 0 {
                            self.program_counter = self.program_counter + 2;
                        }
                    }
                    _ => {}
                }
            }
            0xF => {
                match opcode.get_8bit() {
                    0x07 => self.reg_v[opcode.x()] = self.delay_timer,
                    0x0A => {
                        // TODO
                    }
                    0x15 => self.delay_timer = self.reg_v[opcode.x()],
                    0x18 => self.sound_timer = self.reg_v[opcode.x()],
                    0x1E => {
                        // TODO
                    }
                    0x29 => {
                        // TODO
                    }
                    0x33 => {
                        // TODO
                    }
                    0x55 => {
                        // TODO
                    }
                    0x65 => {
                        // TODO
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }
}

fn main() {
    if let Some(rom_file_name) = env::args().nth(1) {
        println!("Reading ROM: {}...", rom_file_name);
        let rom = read_rom(rom_file_name).unwrap_or_else(|err| {
            println!("Could not read ROM: {}!", err);
            Vec::new()
        });

        if !rom.is_empty() {
            println!("Starting CHIP-8 emulator...");
            let mut chip = Chip8::new();
            chip.initialize();
            chip.load_rom(rom);
            chip.run();
        }
    } else {
        println!("Usage: chip8 <rom>");
    }
}

fn read_rom<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
    let mut file = try!(fs::File::open(path));
    let mut file_buffer = Vec::new();
    try!(file.read_to_end(&mut file_buffer));
    Ok(file_buffer)
}
<commit_msg>Implemented remaining instructions<commit_after>extern crate rand;

#[cfg(not(test))]
use std::io;
#[cfg(not(test))]
use std::path::Path;

const DISPLAY_HEIGHT: usize = 32;
const DISPLAY_WIDTH: usize = 64;
const GFX_MEMORY_SIZE: usize = DISPLAY_HEIGHT * DISPLAY_WIDTH;
const NUM_REGISTERS: usize = 16;
const MEMORY_SIZE: usize = 4096;
const STACK_SIZE: usize = 16;
const NUM_KEYS: usize = 16;
const PROGRAM_START: usize = 0x200;
const FONT_SET_SIZE: usize = 80;
const FONT_SET: [u8; FONT_SET_SIZE] =
    [0xF0, 0x90, 0x90, 0x90, 0xF0, 0x20, 0x60, 0x20, 0x20, 0x70, 0xF0, 0x10, 0xF0, 0x80, 0xF0,
     0xF0, 0x10, 0xF0, 0x10, 0xF0, 0x90, 0x90, 0xF0, 0x10, 0x10, 0xF0, 0x80, 0xF0, 0x10, 0xF0,
     0xF0, 0x80, 0xF0, 0x90, 0xF0, 0xF0, 0x10, 0x20, 0x40, 0x40, 0xF0, 0x90, 0xF0, 0x90, 0xF0,
     0xF0, 0x90, 0xF0, 0x10, 0xF0, 0xF0, 0x90, 0xF0, 0x90, 0x90, 0xE0, 0x90, 0xE0, 0x90, 0xE0,
     0xF0, 0x80, 0x80, 0x80, 0xF0, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0xF0, 0x80, 0xF0, 0x80, 0xF0,
     0xF0, 0x80, 0xF0, 0x80, 0x80];

struct Opcode {
    opcode: u16,
}

impl Opcode {
    fn new(opcode: u16) -> Opcode {
        Opcode { opcode: opcode }
    }

    fn category(&self) -> u8 {
        ((self.opcode & 0xF000) >> 12) as u8
    }

    fn x(&self) -> usize {
        ((self.opcode & 0x0F00) >> 8) as usize
    }

    fn y(&self) -> usize {
        ((self.opcode & 0x00F0) >> 4) as usize
    }

    fn address(&self) -> u16 {
        self.opcode & 0x0FFF
    }

    fn get_8bit(&self) -> u8 {
        (self.opcode & 0x00FF) as u8
    }

    fn get_4bit(&self) -> u8 {
        (self.opcode & 0x000F) as u8
    }
}

struct Chip8 {
    reg_v: [u8; NUM_REGISTERS],
    reg_gfx: [u8; GFX_MEMORY_SIZE],
    memory: [u8; MEMORY_SIZE],
    stack: [u16; STACK_SIZE],
    keys: [u8; NUM_KEYS],
    stack_pointer: u16,
    program_counter: u16,
    reg_i: u16,
    delay_timer: u8,
    sound_timer: u8,
    refresh: bool,
}

impl Chip8 {
    fn new() -> Chip8 {
        Chip8 {
            reg_v: [0; NUM_REGISTERS],
            reg_gfx: [0; GFX_MEMORY_SIZE],
            memory: [0; MEMORY_SIZE],
            stack: [0; STACK_SIZE],
            keys: [0; NUM_KEYS],
            stack_pointer: 0,
            program_counter: 0,
            reg_i: 0,
            delay_timer: 0,
            sound_timer: 0,
            refresh: true,
        }
    }

    fn initialize(&mut self) {
        self.program_counter = PROGRAM_START as u16;
        self.reg_v = [0; NUM_REGISTERS];
        self.memory = [0; MEMORY_SIZE];
        self.reg_gfx = [0; GFX_MEMORY_SIZE];
        self.stack = [0; STACK_SIZE];
        self.keys = [0; NUM_KEYS];
        self.stack_pointer = 0;
        self.reg_i = 0;
        self.refresh = true;
        for (index, element) in FONT_SET.into_iter().enumerate() {
            self.memory[index] = *element;
        }
    }

    #[cfg(not(test))]
    fn run(&mut self) {
        loop {
            self.cycle();

            if self.refresh {
                self.render();
                self.refresh = false;
            }

            let duration = std::time::Duration::from_millis(16);
            std::thread::sleep(duration);
        }
    }

    fn render(&self) {}

    fn load_rom(&mut self, rom: Vec<u8>) {
        for (index, element) in rom.into_iter().enumerate() {
            self.memory[index + PROGRAM_START] = element;
        }
    }

    fn cycle(&mut self) {
        let opcode = self.fetch_opcode();
        self.execute_opcode(opcode);

        if self.delay_timer > 0 {
            self.delay_timer = self.delay_timer - 1;
        }

        if self.sound_timer > 0 {
            self.sound_timer = self.sound_timer - 1;
        }
    }

    fn fetch_opcode(&self) -> Opcode {
        let opcode = ((self.memory[self.program_counter as usize] as u16) << 8) +
                     (self.memory[self.program_counter as usize + 1] as u16);
        Opcode::new(opcode)
    }

    fn clear_screen(&mut self) {
        self.reg_gfx = [0; GFX_MEMORY_SIZE];
        self.refresh = true;
    }

    fn display(&mut self, x: usize, y: usize, height: u8) {
        self.reg_v[0xF] = 0x00;
        self.refresh = true;
        for y_line in 0..height {
            let memory_position = (self.reg_i + y_line as u16) as usize;
            let pixel = self.memory[memory_position];
            for x_line in 0..8 {
                if (pixel & (0x80 >> x_line)) != 0x00 {
                    let gfx_position = x + x_line + ((y + y_line as usize) * DISPLAY_WIDTH);
                    let current_pixel = self.reg_gfx[gfx_position];
                    if current_pixel == 0x01 {
                        self.reg_v[0xF] = 1;
                    }

                    self.reg_gfx[gfx_position] = self.reg_gfx[gfx_position] ^ 1;
                }
            }
        }
    }

    fn execute_opcode(&mut self, opcode: Opcode) {
        match opcode.category() {
            0 => {
                match opcode.get_8bit() {
                    0xE0 => {
                        self.clear_screen();
                        self.program_counter = self.program_counter + 2;
                    }
                    0xEE => {
                        self.program_counter = self.stack[self.stack_pointer as usize];
                        self.stack_pointer = self.stack_pointer - 1;
                        self.program_counter = self.program_counter + 2;
                    }
                    _ => panic!("Invalid OpCode"),
                }
            }
            1 => self.program_counter = opcode.address(),
            2 => {
                self.stack_pointer = self.stack_pointer + 1;
                self.stack[self.stack_pointer as usize] = self.program_counter;
                self.program_counter = opcode.address();
            }
            3 => {
                if self.reg_v[opcode.x()] == opcode.get_8bit() {
                    self.program_counter = self.program_counter + 4;
                } else {
                    self.program_counter = self.program_counter + 2;
                }
            }
            4 => {
                if self.reg_v[opcode.x()] != opcode.get_8bit() {
                    self.program_counter = self.program_counter + 4;
                } else {
                    self.program_counter = self.program_counter + 2;
                }
            }
            5 => {
                if self.reg_v[opcode.x()] == self.reg_v[opcode.y()] {
                    self.program_counter = self.program_counter + 4;
                } else {
                    self.program_counter = self.program_counter + 2;
                }
            }
            6 => {
                self.reg_v[opcode.x()] = opcode.get_8bit();
                self.program_counter = self.program_counter + 2;
            }
            7 => {
                self.reg_v[opcode.x()] = self.reg_v[opcode.x()] + opcode.get_8bit();
                self.program_counter = self.program_counter + 2;
            }
            8 => {
                match opcode.get_4bit() {
                    0 => {
                        self.reg_v[opcode.x()] = self.reg_v[opcode.y()];
                        self.program_counter = self.program_counter + 2;
                    }
                    1 => {
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] | self.reg_v[opcode.y()];
                        self.program_counter = self.program_counter + 2;
                    }
                    2 => {
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] & self.reg_v[opcode.y()];
                        self.program_counter = self.program_counter + 2;
                    }
                    3 => {
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] ^ self.reg_v[opcode.y()];
                        self.program_counter = self.program_counter + 2;
                    }
                    4 => {
                        self.memory[0xF] = if opcode.y() > (0xFF - opcode.x()) {
                            1
                        } else {
                            0
                        };
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] + self.reg_v[opcode.y()];
                        self.program_counter = self.program_counter + 2;
                    }
                    5 => {
                        self.memory[0xF] = if opcode.y() > opcode.x() { 1 } else { 0 };
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] - self.reg_v[opcode.y()];
                        self.program_counter = self.program_counter + 2;
                    }
                    6 => {
                        self.memory[0xF] = self.reg_v[opcode.x()] & 0x01;
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] >> 1;
                        self.program_counter = self.program_counter + 2;
                    }
                    7 => {
                        self.memory[0xF] = if opcode.x() > opcode.y() { 1 } else { 0 };
                        self.reg_v[opcode.x()] = self.reg_v[opcode.y()] - self.reg_v[opcode.x()];
                        self.program_counter = self.program_counter + 2;
                    }
                    0xE => {
                        self.memory[0xF] = self.reg_v[opcode.x()] & 0x80;
                        self.reg_v[opcode.x()] = self.reg_v[opcode.x()] << 1;
                        self.program_counter = self.program_counter + 2;
                    }
                    _ => panic!("Invalid OpCode"),
                }
            }
            9 => {
                if self.reg_v[opcode.x()] != self.reg_v[opcode.y()] {
                    self.program_counter = self.program_counter + 4;
                } else {
                    self.program_counter = self.program_counter + 2;
                }
            }
            0xA => {
                self.reg_i = opcode.address();
                self.program_counter = self.program_counter + 2;
            }
            0xB => {
                self.program_counter = opcode.address() + self.reg_v[opcode.x()] as u16;
                self.program_counter = self.program_counter + 2;
            }
            0xC => {
                self.reg_v[opcode.x()] = rand::random::<u8>() & opcode.get_8bit();
                self.program_counter = self.program_counter + 2;
            }
            0xD => {
                self.display(opcode.x(), opcode.y(), opcode.get_4bit());
                self.program_counter = self.program_counter + 2;
            }
            0xE => {
                match opcode.get_8bit() {
                    0x9E => {
                        if self.keys[self.reg_v[opcode.x()] as usize] != 0 {
                            self.program_counter = self.program_counter + 4;
                        } else {
                            self.program_counter = self.program_counter + 2;
                        }
                    }
                    0xA1 => {
                        if self.keys[self.reg_v[opcode.x()] as usize] == 0 {
                            self.program_counter = self.program_counter + 4;
                        } else {
                            self.program_counter = self.program_counter + 2;
                        }
                    }
                    _ => panic!("Invalid OpCode!"),
                }
            }
            0xF => {
                match opcode.get_8bit() {
                    0x07 => {
                        self.reg_v[opcode.x()] = self.delay_timer;
                        self.program_counter = self.program_counter + 2;
                    }
                    0x0A => {
                        for index in 0..NUM_KEYS {
                            if self.keys[index] != 0x00 {
                                self.reg_v[opcode.x()] = self.keys[index];
                                self.program_counter = self.program_counter + 2;
                                break;
                            }
                        }
                    }
                    0x15 => {
                        self.delay_timer = self.reg_v[opcode.x()];
                        self.program_counter = self.program_counter + 2;
                    }
                    0x18 => {
                        self.sound_timer = self.reg_v[opcode.x()];
                        self.program_counter = self.program_counter + 2;
                    }
                    0x1E => {
                        let i = self.reg_i + self.reg_v[opcode.x()] as u16;
                        if i > 0xFFF {
                            self.reg_v[0xF] = 1;
                        } else {
                            self.reg_v[0xF] = 0;
                        }

                        self.reg_i = i;
                        self.program_counter = self.program_counter + 2;
                    }
                    0x29 => {
                        self.reg_i = self.reg_v[opcode.x()] as u16 * 0x5;
                        self.program_counter = self.program_counter + 2;
                    }
                    0x33 => {
                        let x = self.reg_v[opcode.x()];
                        self.memory[self.reg_i as usize] = x / 100;
                        self.memory[(self.reg_i + 1) as usize] = (x / 10) % 10;
                        self.memory[(self.reg_i + 2) as usize] = x % 100 % 10;
                        self.program_counter = self.program_counter + 2;
                    }
                    0x55 => {
                        for x in 0..opcode.x() {
                            self.memory[self.reg_i as usize + x] = self.reg_v[x];
                        }

                        self.program_counter = self.program_counter + 2;
                    }
                    0x65 => {
                        for x in 0..opcode.x() {
                            self.reg_v[x] = self.memory[self.reg_i as usize + x];
                        }

                        self.program_counter = self.program_counter + 2;
                    }
                    _ => panic!("Invalid OpCode"),
                }
            }
            _ => panic!("Invalid OpCode"),
        }
    }
}

#[cfg(not(test))]
fn main() {
    use std::env;

    if let Some(rom_file_name) = env::args().nth(1) {
        println!("Reading ROM: {}...", rom_file_name);
        let rom = read_rom(rom_file_name).unwrap_or_else(|err| {
            println!("Could not read ROM: {}!", err);
            Vec::new()
        });

        if !rom.is_empty() {
            println!("Starting CHIP-8 emulator...");
            let mut chip = Chip8::new();
            chip.initialize();
            chip.load_rom(rom);
            chip.run();
        }
    } else {
        println!("Usage: chip8 <rom>");
    }
}

#[cfg(not(test))]
fn read_rom<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
    use std::fs;
    use std::io::Read;

    let mut file = try!(fs::File::open(path));
    let mut file_buffer = Vec::new();
    try!(file.read_to_end(&mut file_buffer));
    Ok(file_buffer)
}

#[cfg(test)]
mod test {

    #[test]
    fn instruction_clear_display() {
        let rom = vec![0x00, 00];

        let mut chip = ::Chip8::new();
        chip.initialize();
        chip.load_rom(rom);
        chip.cycle();

        assert_eq!(chip.program_counter, 0x0202);
    }

    #[test]
    fn instruction_call() {
        let rom = vec![0x22, 0xFC];

        let mut chip = ::Chip8::new();
        chip.initialize();
        chip.load_rom(rom);
        chip.cycle();

        assert_eq!(chip.program_counter, 0x02FC);
        assert_eq!(chip.stack_pointer, 0x0001);
        assert_eq!(chip.stack[chip.stack_pointer as usize], 0x200);
    }

    #[test]
    fn instruction_return() {
        let rom = vec![0x22, 0x04, 0x00, 0x00, 0x00, 0xEE];

        let mut chip = ::Chip8::new();
        chip.initialize();
        chip.load_rom(rom);
        chip.cycle();
        chip.cycle();

        assert_eq!(chip.program_counter, 0x0202);
        assert_eq!(chip.stack_pointer, 0x0000);
    }

    #[test]
    fn instruction_jump() {
        let rom = vec![0x12, 0xFC];

        let mut chip = ::Chip8::new();
        chip.initialize();
        chip.load_rom(rom);
        chip.cycle();

        assert_eq!(chip.program_counter, 0x02FC);
    }
}<|endoftext|>


<commit_before>extern crate rand;

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

const N: usize = 50;
const P: usize = 128;

fn schwefel(solution: &[f64; N]) -> f64 {
    418.9829_f64 * N as f64
        + solution.iter().fold(0_f64, |sum, x| sum + x * x.abs().sqrt().sin())
}

fn main() {
    let mut rng = rand::thread_rng();
    let range = Range::new(-512.03, 511.97);

    let mut population = [[0_f64; N]; P];

    for solution in &mut population[..] {
        for x in &mut solution[..] {
            *x = range.ind_sample(&mut rng);
        }
    }

    // debug print of solutions
    for solution in &population[..] {
        for x in &solution[..] {
            println!("{} ", x);
        }
    }
    println!("The best solution's fitness was {}", schwefel(&population[0]));
}
<commit_msg>Initialize Vector of Vectors using from_iter<commit_after>extern crate rand;

use std::iter::FromIterator;
use rand::distributions::{IndependentSample, Range};

const N: usize = 50;
const P: usize = 128;

fn schwefel(solution: &Vec<f64>) -> f64 {
    418.9829_f64 * solution.len() as f64
        + solution.iter().fold(0_f64, |sum, x| sum + x * x.abs().sqrt().sin())
}

fn main() {
    let mut rng = rand::thread_rng();
    let range = Range::new(-512.03, 511.97);

    // initialize population
    let population = Vec::from_iter((0..P).map(|_| {
        Vec::from_iter((0..N).map(|_| {
            range.ind_sample(&mut rng)
        }))
    }));

    // debug print of solutions
    for solution in &population[..] {
        for x in &solution[..] {
            println!("{} ", x);
        }
    }
    println!("The best solution's fitness was {}", schwefel(&population[0]));
}
<|endoftext|>


<commit_before>#![feature(box_patterns,box_syntax)]
#![feature(scheme)]
#![feature(compile)]
#![feature(collections)]
extern crate rustc_serialize;
extern crate docopt;

extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

#[macro_use]
extern crate log;

use docopt::Docopt;
use std::io;
use std::io::{Write, BufRead,BufReader};
use std::error::Error;

static USAGE: &'static str = "
Usage:
    seax repl [-vd]
    seax [-vd] <bin>

Options:
    -v, --verbose   Enable verbose mode
    -d, --debug     Enable debug mode
";

#[derive(RustcDecodable)]
struct Args {
    cmd_repl: bool,
    arg_bin: String,
    flag_verbose: bool,
    flag_debug: bool,
}

mod loggers;

fn main() {
    let args: Args = Docopt::new(USAGE)
                .and_then(|d| d.decode())
                .unwrap_or_else(|e| e.exit());

    if args.flag_verbose {
        let _ = log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Debug);
            Box::new(loggers::DebugLogger)
        });
    } else {
        let _ = log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Info);
            Box::new(loggers::DefaultLogger)
        });
    };

    if args.cmd_repl {
        let stdin = BufReader::new(io::stdin());
        let mut stdout = io::stdout();

        print!("scheme> ");
        let _ = stdout.flush();

        for line in stdin.lines() {
            match line.map_err(|error| String::from_str(error.description()) )
                .and_then(  |ref code| scheme::compile(code) )
                .and_then(  |program | svm::eval_program(program, args.flag_debug) ) {
                    Ok(result)  => println!(">> {:?}",result),
                    Err(why)    => error!("{}", why)
                };
            print!("scheme> ");
            let _ = stdout.flush();
        }
    }
}
<commit_msg>Start on file interpreting<commit_after>#![feature(box_patterns,box_syntax)]
#![feature(scheme)]
#![feature(compile)]
#![feature(collections)]
extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

#[macro_use]
extern crate log;

use docopt::Docopt;
use regex::Regex;

use std::io;
use std::io::{Write, BufRead,BufReader};
use std::error::Error;

static USAGE: &'static str = "
Usage:
    seax repl [-vd]
    seax [-vd] <file>

Options:
    -v, --verbose   Enable verbose mode
    -d, --debug     Enable debug mode
";

#[derive(RustcDecodable)]
struct Args {
    cmd_repl: bool,
    arg_file: String,
    flag_verbose: bool,
    flag_debug: bool,
}

mod loggers;

fn main() {
    let args: Args = Docopt::new(USAGE)
                .and_then(|d| d.decode())
                .unwrap_or_else(|e| e.exit());

    let ext_re = Regex::new(r".+?(?P<ext>\.[^.]*$|$)").unwrap();

    if args.flag_verbose {
        let _ = log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Debug);
            Box::new(loggers::DebugLogger)
        });
    } else {
        let _ = log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Info);
            Box::new(loggers::DefaultLogger)
        });
    };

    if args.cmd_repl {
        let stdin = BufReader::new(io::stdin());
        let mut stdout = io::stdout();

        print!("scheme> ");
        let _ = stdout.flush();

        for line in stdin.lines() {
            match line.map_err(|error| String::from_str(error.description()) )
                .and_then(  |ref code| scheme::compile(code) )
                .and_then(  |program | svm::eval_program(program, args.flag_debug) ) {
                    Ok(result)  => println!(">> {:?}",result),
                    Err(why)    => error!("{}", why)
                };
            print!("scheme> ");
            let _ = stdout.flush();
        }
    } else {
        match ext_re
            .captures(args.arg_file.as_ref())
            .and_then(|c| c.name("ext")) {
            Some(".scm")   => {
                debug!("Interpreting Scheme file {}", args.arg_file);
                unimplemented!()
                }, // interpret scheme
            _              => {
                debug!("Executing binary {}", args.arg_file);
                unimplemented!()
            } // bin, figure out
        }
    }
}
<|endoftext|>


<commit_before>pub use self::core::MoveCell;

#[allow(unsafe_code)]
mod core {
    use std::cell::UnsafeCell;
    use std::mem;

    /// A mutable memory location that clones its contents on retrieval.
    pub struct MoveCell<T>(UnsafeCell<T>);

    unsafe impl<T> Send for MoveCell<T> where T: Send {}

    impl<T> MoveCell<T> {
        /// Creates a new `MoveCell` containing the given value.
        ///
        /// # Example
        ///
        /// ```
        /// use mitochondria::MoveCell;
        ///
        /// let c = MoveCell::new("Hello cytosol!".to_owned());
        /// ```
        #[inline]
        pub fn new(value: T) -> Self {
            MoveCell(UnsafeCell::new(value))
        }

        /// Replaces the value of this cell, returning the old one.
        ///
        /// # Example
        ///
        /// ```
        /// use mitochondria::MoveCell;
        ///
        /// let c = MoveCell::new("Hello lysosome!".to_owned());
        ///
        /// let greeting = c.replace("Goodbye!".to_owned());
        /// ```
        #[inline]
        pub fn replace(&self, value: T) -> T {
            unsafe {
                mem::replace(&mut *self.0.get(), value)
            }
        }
    }
}

impl<T> MoveCell<T> {
    /// Sets the value of this cell, dropping the old one.
    ///
    /// # Example
    ///
    /// ```
    /// use mitochondria::MoveCell;
    ///
    /// let c = MoveCell::new("Hello vacuole!".to_owned());
    ///
    /// c.set("Hello cytoskeleton!".to_owned());
    /// ```
    #[inline]
    pub fn set(&self, value: T) {
        drop(self.replace(value));
    }
}

impl<T: Default> Default for MoveCell<T> {
    #[inline]
    fn default() -> Self {
        MoveCell::new(Default::default())
    }
}

impl<T: Default> MoveCell<T> {
    /// Returns the value in this cell, replacing it by `T::default`.
    ///
    /// # Example
    ///
    /// ```
    /// use mitochondria::MoveCell;
    ///
    /// let c = MoveCell::new(vec!["vacuole", "cytoskeleton"]);
    ///
    /// assert_eq!(c.take(), &["vacuole", "cytoskeleton"]);
    /// assert_eq!(c.take(), &[] as &[&str]);
    /// ```
    #[inline]
    pub fn take(&self) -> T {
        self.replace(T::default())
    }
}
<commit_msg>Fix documentation of MoveCell<commit_after>pub use self::core::MoveCell;

#[allow(unsafe_code)]
mod core {
    use std::cell::UnsafeCell;
    use std::mem;

    /// A mutable memory location that steals ownership.
    pub struct MoveCell<T>(UnsafeCell<T>);

    unsafe impl<T> Send for MoveCell<T> where T: Send {}

    impl<T> MoveCell<T> {
        /// Creates a new `MoveCell` containing the given value.
        ///
        /// # Example
        ///
        /// ```
        /// use mitochondria::MoveCell;
        ///
        /// let c = MoveCell::new("Hello cytosol!".to_owned());
        /// ```
        #[inline]
        pub fn new(value: T) -> Self {
            MoveCell(UnsafeCell::new(value))
        }

        /// Replaces the value of this cell, returning the old one.
        ///
        /// # Example
        ///
        /// ```
        /// use mitochondria::MoveCell;
        ///
        /// let c = MoveCell::new("Hello lysosome!".to_owned());
        ///
        /// let greeting = c.replace("Goodbye!".to_owned());
        /// ```
        #[inline]
        pub fn replace(&self, value: T) -> T {
            unsafe {
                mem::replace(&mut *self.0.get(), value)
            }
        }
    }
}

impl<T> MoveCell<T> {
    /// Sets the value of this cell, dropping the old one.
    ///
    /// # Example
    ///
    /// ```
    /// use mitochondria::MoveCell;
    ///
    /// let c = MoveCell::new("Hello vacuole!".to_owned());
    ///
    /// c.set("Hello cytoskeleton!".to_owned());
    /// ```
    #[inline]
    pub fn set(&self, value: T) {
        drop(self.replace(value));
    }
}

impl<T: Default> Default for MoveCell<T> {
    #[inline]
    fn default() -> Self {
        MoveCell::new(Default::default())
    }
}

impl<T: Default> MoveCell<T> {
    /// Returns the value in this cell, replacing it by `T::default`.
    ///
    /// # Example
    ///
    /// ```
    /// use mitochondria::MoveCell;
    ///
    /// let c = MoveCell::new(vec!["vacuole", "cytoskeleton"]);
    ///
    /// assert_eq!(c.take(), &["vacuole", "cytoskeleton"]);
    /// assert_eq!(c.take(), &[] as &[&str]);
    /// ```
    #[inline]
    pub fn take(&self) -> T {
        self.replace(T::default())
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//! Enumeration of errors returned by the logger.

use std;
use std::error::Error;
use std::fmt;

/// Describes the errors which may occur while handling logging scenarios.
#[derive(Debug)]
pub enum LoggerError {
    /// First attempt at initialization failed.
    NeverInitialized(String),
    /// The logger is locked while preinitializing.
    IsPreinitializing,
    /// The logger is locked while initializing
    IsInitializing,
    /// The logger does not allow reinitialization.
    AlreadyInitialized,
    /// Invalid logger option specified.
    InvalidLogOption(String),
    /// Opening named pipe fails.
    OpenFIFO(std::io::Error),
    /// Writing to named pipe fails.
    LogWrite(std::io::Error),
    /// Flushing to disk fails.
    LogFlush(std::io::Error),
    /// Error obtaining lock on mutex.
    MutexLockFailure(String),
    /// Error in the logging of the metrics.
    LogMetricFailure(String),
    /// Signals not logging a metric due to rate limiting.
    LogMetricRateLimit,
}

impl fmt::Display for LoggerError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let printable = match *self {
            LoggerError::NeverInitialized(ref e) => e.to_string(),
            LoggerError::IsPreinitializing => {
                "The logger is preinitializing. Can't perform the requested action right now."
                    .to_string()
            }
            LoggerError::IsInitializing => {
                "The logger is initializing. Can't perform the requested action right now."
                    .to_string()
            }
            LoggerError::AlreadyInitialized => {
                "Reinitialization of logger not allowed.".to_string()
            }
            LoggerError::InvalidLogOption(ref s) => format!("Invalid log option: {}", s),
            LoggerError::OpenFIFO(ref e) => {
                format!("Failed to open pipe. Error: {}", e.description())
            }
            LoggerError::LogWrite(ref e) => {
                format!("Failed to write logs. Error: {}", e.description())
            }
            LoggerError::LogFlush(ref e) => {
                format!("Failed to flush logs. Error: {}", e.description())
            }
            LoggerError::MutexLockFailure(ref e) => e.to_string(),
            LoggerError::LogMetricFailure(ref e) => e.to_string(),
            LoggerError::LogMetricRateLimit => "Metric will not yet be logged.".to_string(),
        };
        write!(f, "{}", printable)
    }
}

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

    #[test]
    fn test_formatting() {
        assert!(format!(
            "{:?}",
            LoggerError::NeverInitialized(String::from("Bad Log Path Provided"))
        )
        .contains("NeverInitialized"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::NeverInitialized(String::from("Bad Log Path Provided"))
            ),
            "Bad Log Path Provided"
        );

        assert!(format!("{:?}", LoggerError::AlreadyInitialized).contains("AlreadyInitialized"));
        assert_eq!(
            format!("{}", LoggerError::AlreadyInitialized),
            "Reinitialization of logger not allowed."
        );

        assert_eq!(
            format!("{}", LoggerError::IsPreinitializing),
            "The logger is preinitializing. Can't perform the requested action right now."
        );

        assert_eq!(
            format!("{}", LoggerError::IsInitializing),
            "The logger is initializing. Can't perform the requested action right now."
        );

        assert!(format!(
            "{:?}",
            LoggerError::LogWrite(std::io::Error::new(ErrorKind::Interrupted, "write"))
        )
        .contains("LogWrite"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::LogWrite(std::io::Error::new(ErrorKind::Interrupted, "write"))
            ),
            "Failed to write logs. Error: write"
        );

        assert!(format!(
            "{:?}",
            LoggerError::LogFlush(std::io::Error::new(ErrorKind::Interrupted, "flush"))
        )
        .contains("LogFlush"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::LogFlush(std::io::Error::new(ErrorKind::Interrupted, "flush"))
            ),
            "Failed to flush logs. Error: flush"
        );

        assert!(format!(
            "{:?}",
            LoggerError::MutexLockFailure(String::from("Mutex lock"))
        )
        .contains("MutexLockFailure"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::MutexLockFailure(String::from("Mutex lock"))
            ),
            "Mutex lock"
        );

        assert!(format!(
            "{:?}",
            LoggerError::LogMetricFailure("Failure in the logging of the metrics.".to_string())
        )
        .contains("LogMetricFailure"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::LogMetricFailure("Failed to log metrics.".to_string())
            ),
            "Failed to log metrics."
        );

        assert!(format!("{:?}", LoggerError::LogMetricRateLimit).contains("LogMetricRateLimit"));
        assert_eq!(
            format!("{}", LoggerError::LogMetricRateLimit),
            "Metric will not yet be logged."
        );
    }
}
<commit_msg>logger: remove unused error items<commit_after>// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//! Enumeration of errors returned by the logger.

use std;
use std::error::Error;
use std::fmt;

/// Describes the errors which may occur while handling logging scenarios.
#[derive(Debug)]
pub enum LoggerError {
    /// First attempt at initialization failed.
    NeverInitialized(String),
    /// The logger is locked while preinitializing.
    IsPreinitializing,
    /// The logger is locked while initializing
    IsInitializing,
    /// The logger does not allow reinitialization.
    AlreadyInitialized,
    /// Invalid logger option specified.
    InvalidLogOption(String),
    /// Writing to named pipe fails.
    LogWrite(std::io::Error),
    /// Flushing to disk fails.
    LogFlush(std::io::Error),
    /// Error in the logging of the metrics.
    LogMetricFailure(String),
}

impl fmt::Display for LoggerError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let printable = match *self {
            LoggerError::NeverInitialized(ref e) => e.to_string(),
            LoggerError::IsPreinitializing => {
                "The logger is preinitializing. Can't perform the requested action right now."
                    .to_string()
            }
            LoggerError::IsInitializing => {
                "The logger is initializing. Can't perform the requested action right now."
                    .to_string()
            }
            LoggerError::AlreadyInitialized => {
                "Reinitialization of logger not allowed.".to_string()
            }
            LoggerError::InvalidLogOption(ref s) => format!("Invalid log option: {}", s),
            LoggerError::LogWrite(ref e) => {
                format!("Failed to write logs. Error: {}", e.description())
            }
            LoggerError::LogFlush(ref e) => {
                format!("Failed to flush logs. Error: {}", e.description())
            }
            LoggerError::LogMetricFailure(ref e) => e.to_string(),
        };
        write!(f, "{}", printable)
    }
}

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

    #[test]
    fn test_formatting() {
        assert!(format!(
            "{:?}",
            LoggerError::NeverInitialized(String::from("Bad Log Path Provided"))
        )
        .contains("NeverInitialized"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::NeverInitialized(String::from("Bad Log Path Provided"))
            ),
            "Bad Log Path Provided"
        );

        assert!(format!("{:?}", LoggerError::AlreadyInitialized).contains("AlreadyInitialized"));
        assert_eq!(
            format!("{}", LoggerError::AlreadyInitialized),
            "Reinitialization of logger not allowed."
        );

        assert_eq!(
            format!("{}", LoggerError::IsPreinitializing),
            "The logger is preinitializing. Can't perform the requested action right now."
        );

        assert_eq!(
            format!("{}", LoggerError::IsInitializing),
            "The logger is initializing. Can't perform the requested action right now."
        );

        assert!(format!(
            "{:?}",
            LoggerError::LogWrite(std::io::Error::new(ErrorKind::Interrupted, "write"))
        )
        .contains("LogWrite"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::LogWrite(std::io::Error::new(ErrorKind::Interrupted, "write"))
            ),
            "Failed to write logs. Error: write"
        );

        assert!(format!(
            "{:?}",
            LoggerError::LogFlush(std::io::Error::new(ErrorKind::Interrupted, "flush"))
        )
        .contains("LogFlush"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::LogFlush(std::io::Error::new(ErrorKind::Interrupted, "flush"))
            ),
            "Failed to flush logs. Error: flush"
        );

        assert!(format!(
            "{:?}",
            LoggerError::LogMetricFailure("Failure in the logging of the metrics.".to_string())
        )
        .contains("LogMetricFailure"));
        assert_eq!(
            format!(
                "{}",
                LoggerError::LogMetricFailure("Failed to log metrics.".to_string())
            ),
            "Failed to log metrics."
        );
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::fmt;

/// An RFC1035 `<domain-name>` (sequence of labels)
///
#[deriving(PartialEq,Eq,Hash,Clone)]
pub struct Name {
    labels: Vec<String>,
}

impl Name {
    pub fn new() -> Name {
        Name { labels: Vec::new() }
    }

    /// Parse a byte slice containing an already-decompressed name.
    pub fn parse_decompressed(buf: &[u8]) -> io::IoResult<Name> {
        let mut labels: Vec<String> = Vec::with_capacity(10);
        let mut reader = io::BufReader::new(buf);
        loop {
            let llen = try!(reader.read_u8());
            if llen == 0 {
                break;
            } else if llen > 63 {
                return Err(io::standard_error(io::InvalidInput));
            } else {
                let str_read = String::from_utf8(try!(reader.read_exact(llen as uint)));
                match str_read {
                    Ok(s) => labels.push(s),
                    Err(_) => return Err(io::standard_error(io::InvalidInput)),
                }
            }
        }
        Ok(Name { labels: labels })
    }

    /// Generate a `Vec<u8>` containing this name in fully-expanded
    /// RFC1035 label format.
    pub fn to_bytes(&self) -> io::IoResult<Vec<u8>> {
        let mut vec: Vec<u8> = Vec::new();
        for l in self.labels.iter() {
            try!(vec.write_u8(l.len() as u8));
            try!(vec.write_str(l.as_slice()));
        }
        try!(vec.write_u8(0));
        Ok(vec)
    }

    /// Push this name in fully-expanded RFC1035 label format onto an
    /// existing `Vec<u8>`
    pub fn push_bytes(&self, vec: &mut Vec<u8>) -> io::IoResult<()> {
        for l in self.labels.iter() {
            try!(vec.write_u8(l.len() as u8));
            try!(vec.write_str(l.as_slice()));
        }
        try!(vec.write_u8(0));
        Ok(())
    }

    /// Generate a vector of Name objects containing
    pub fn gen_suffixes(&self) -> Vec<Name> {
        let mut output: Vec<Name> = Vec::new();
        let mut clone = self.clone();

        for i in range(0, output.len() - 1) {
            match clone.labels.remove(0) {
                Some(_) => {
                    output.push(clone.clone());
                    continue;
                },
                None => {
                    break;
                },
            }
        }

        output
    }
}
impl fmt::Show for Name {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "{}", self.labels.connect(".")));
        write!(f, ".")
    }
}

/// Trait for `io::Reader`s that implement DNS packet parsing.
/// Due to the way DNS name compression works readers likely
/// need to implement `io::Seek`.
pub trait DNSNameReader {
    fn read_dns_name(&mut self) -> io::IoResult<Name>;
}
impl<'a> DNSNameReader for io::BufReader<'a> {
    fn read_dns_name(&mut self) -> io::IoResult<Name> {

        let mut labels: Vec<String> = Vec::new();

        let mut follow = false;
        let mut return_to = 0u64;

        // Read in labels
        loop {
            // Get the next label's size
            let llen = try!(self.read_u8());

            if llen == 0 {
                // Zero length labels are the root, so we're done
                break;
            } else if (llen & 0xC0) == 0xC0 {
                // Labels with the two high order bits set (0xC0)
                // are pointers.
                let jump_to = try!(self.read_u8()) as i64;

                // If this is the first pointer encountered, store
                // the current reader location to restore later.
                if !follow {
                    return_to = try!(self.tell());
                    follow = true;
                }

                // Seek to the pointer location
                try!(self.seek(jump_to, io::SeekStyle::SeekSet));
                continue;
            } else {
                let str_read = String::from_utf8(try!(self.read_exact(llen as uint)));
                match str_read {
                    Ok(s) => labels.push(s),
                    Err(_) => return Err(io::standard_error(io::InvalidInput)),
                }
            }
        }

        if follow {
            // Restore the reader location to the byte after the first
            // pointer followed during the read.
            try!(self.seek(return_to as i64, io::SeekStyle::SeekSet));
        }

        Ok(Name { labels: labels })
    }
}

#[cfg(test)]
mod test_dns_name_reader {
    use std::io;
    use super::DNSNameReader;

    static NET1_RS: &'static [u8] = include_bin!("../tests/packets/net1-rs.bin");

    #[test]
    fn test_read_name() {
        let mut r = io::BufReader::new(NET1_RS);

        // Regular pointerless read (first name in packet)
        r.seek(0x0C, io::SeekStyle::SeekSet).ok();
        let l1 = r.read_dns_name().ok().unwrap();
        assert_eq!(l1.labels.len(), 1);
        assert_eq!(l1.labels[0].as_slice(), "net");
    }
    #[test]
    fn test_read_single_ptr_follow() {
        let mut r = io::BufReader::new(NET1_RS);

        // Single pointer follow (second name in packet)
        r.seek(0x21, io::SeekStyle::SeekSet).ok();
        let l2 = r.read_dns_name().ok().unwrap();
        assert_eq!(l2.labels.len(), 3);
        assert_eq!(l2.labels[0].as_slice(), "m");
        assert_eq!(l2.labels[1].as_slice(), "gtld-servers");
        assert_eq!(l2.labels[2].as_slice(), "net");
    }
    #[test]
    fn test_read_multi_ptr_follow() {
        let mut r = io::BufReader::new(NET1_RS);

        // Multi-pointer follow (nth name in packet)
        r.seek(0x5e, io::SeekStyle::SeekSet).ok();
        let l2 = r.read_dns_name().ok().unwrap();
        assert_eq!(l2.labels.len(), 3);
        assert_eq!(l2.labels[0].as_slice(), "j");
        assert_eq!(l2.labels[1].as_slice(), "gtld-servers");
        assert_eq!(l2.labels[2].as_slice(), "net");
        // Test seek restoration after multi-pointer follow
        let l1 = r.read_dns_name().ok().unwrap();
        assert_eq!(l1.labels.len(), 1);
        assert_eq!(l1.labels[0].as_slice(), "net");
    }
}<commit_msg>Remove straggler.<commit_after><|endoftext|>