<commit_before>#![crate_name = "abc"]
#![crate_type = "lib"]

#![warn(missing_docs)]

//! Runs Karaboga's Artificial Bee Colony algorithm in parallel.
//!
//! To take advantage of this crate, the user must implement the
//! [`Solution`](trait.Solution.html) trait for a type of their creation.
//! A [`Hive`](struct.Hive.html) of the appropriate type can then be built,
//! which will search the solution space for the fittest candidate.
//!
//! # Examples
//!
//! ```
//! // ABC algorithm with canonical (proportionate) fitness scaling
//! // to minimize the 10-dimensional Rastrigin function.
//!
//! extern crate abc;
//! extern crate rand;
//!
//! use std::f32::consts::PI;
//! use rand::{random, Closed01, thread_rng, Rng};
//! use abc::{Solution, Candidate, HiveBuilder};
//!
//! const SIZE: usize = 10;
//!
//! #[derive(Clone, Debug)]
//! struct S([f32;SIZE]);
//!
//! // Not really necessary; we're using this mostly to demonstrate usage.
//! struct SBuilder {
//!     min: f32,
//!     max: f32,
//! }
//!
//! impl Solution for S {
//!     type Builder = SBuilder;
//!
//!     fn make(builder: &mut SBuilder) -> S {
//!         let mut new = [0.0;SIZE];
//!         for i in 0..SIZE {
//!             let Closed01(x) = random::<Closed01<f32>>();
//!             new[i] = (x * (builder.max - builder.min)) + builder.min;
//!         }
//!         S(new)
//!     }
//!
//!     fn evaluate_fitness(&self) -> f64 {
//!         let a = 10.0;
//!         let sum = self.0.iter()
//!                         .map(|x| x.powf(2.0) - a * (*x * 2.0 * PI).cos())
//!                         .fold(0.0, |total, next| total + next);
//!         let rastrigin = ((a * SIZE as f32) + sum) as f64;
//!
//!         // Minimize.
//!         if rastrigin >= 0.0 {
//!             1.0 / (1.0 + rastrigin)
//!         } else {
//!             1.0 + rastrigin.abs()
//!         }
//!     }
//!
//!     fn explore(field: &[Candidate<S>], index: usize) -> S {
//!         // new[i] = current[i] + Φ * (current[i] - other[i]), where:
//!         //      -1.0 <= Φ <= 1.0
//!         //      other is a solution, other than current, chosen at random
//!
//!         let S(ref current) = field[index].solution;
//!         let mut new = [0_f32;SIZE];
//!
//!         for i in 0..SIZE {
//!             // Choose a different vector at random.
//!             let mut rng = thread_rng();
//!             let mut index2 = rng.gen_range(0, current.len() - 1);
//!             if index2 >= index { index2 += 1; }
//!             let S(ref other) = field[index2].solution;
//!
//!             let phi = random::<Closed01<f32>>().0 * 2.0 - 1.0;
//!             new[i] = current[i] + (phi * (current[i] - other[i]));
//!         }
//!
//!         S(new)
//!     }
//! }
//!
//! fn main() {
//!     let mut builder = SBuilder { min: -5.12, max: 5.12 };
//!     let hive = HiveBuilder::<S>::new(builder, 10);
//!     println!("{:?}", hive.build().unwrap().run_for_rounds(100).unwrap());
//! }
//! ```

mod result;
mod task;
mod solution;
mod candidate;
mod hive;

pub mod scaling;

pub use result::{Error, Result};
pub use solution::Solution;
pub use candidate::Candidate;
pub use hive::{HiveBuilder, Hive};
<commit_msg>Add documentation root<commit_after>#![crate_name = "abc"]
#![crate_type = "lib"]
#![doc(html_root_url = "https://daviddonna.github.io/abc-rs/")]

#![warn(missing_docs)]

//! Runs Karaboga's Artificial Bee Colony algorithm in parallel.
//!
//! To take advantage of this crate, the user must implement the
//! [`Solution`](trait.Solution.html) trait for a type of their creation.
//! A [`Hive`](struct.Hive.html) of the appropriate type can then be built,
//! which will search the solution space for the fittest candidate.
//!
//! # Examples
//!
//! ```
//! // ABC algorithm with canonical (proportionate) fitness scaling
//! // to minimize the 10-dimensional Rastrigin function.
//!
//! extern crate abc;
//! extern crate rand;
//!
//! use std::f32::consts::PI;
//! use rand::{random, Closed01, thread_rng, Rng};
//! use abc::{Solution, Candidate, HiveBuilder};
//!
//! const SIZE: usize = 10;
//!
//! #[derive(Clone, Debug)]
//! struct S([f32;SIZE]);
//!
//! // Not really necessary; we're using this mostly to demonstrate usage.
//! struct SBuilder {
//!     min: f32,
//!     max: f32,
//! }
//!
//! impl Solution for S {
//!     type Builder = SBuilder;
//!
//!     fn make(builder: &mut SBuilder) -> S {
//!         let mut new = [0.0;SIZE];
//!         for i in 0..SIZE {
//!             let Closed01(x) = random::<Closed01<f32>>();
//!             new[i] = (x * (builder.max - builder.min)) + builder.min;
//!         }
//!         S(new)
//!     }
//!
//!     fn evaluate_fitness(&self) -> f64 {
//!         let a = 10.0;
//!         let sum = self.0.iter()
//!                         .map(|x| x.powf(2.0) - a * (*x * 2.0 * PI).cos())
//!                         .fold(0.0, |total, next| total + next);
//!         let rastrigin = ((a * SIZE as f32) + sum) as f64;
//!
//!         // Minimize.
//!         if rastrigin >= 0.0 {
//!             1.0 / (1.0 + rastrigin)
//!         } else {
//!             1.0 + rastrigin.abs()
//!         }
//!     }
//!
//!     fn explore(field: &[Candidate<S>], index: usize) -> S {
//!         // new[i] = current[i] + Φ * (current[i] - other[i]), where:
//!         //      -1.0 <= Φ <= 1.0
//!         //      other is a solution, other than current, chosen at random
//!
//!         let S(ref current) = field[index].solution;
//!         let mut new = [0_f32;SIZE];
//!
//!         for i in 0..SIZE {
//!             // Choose a different vector at random.
//!             let mut rng = thread_rng();
//!             let mut index2 = rng.gen_range(0, current.len() - 1);
//!             if index2 >= index { index2 += 1; }
//!             let S(ref other) = field[index2].solution;
//!
//!             let phi = random::<Closed01<f32>>().0 * 2.0 - 1.0;
//!             new[i] = current[i] + (phi * (current[i] - other[i]));
//!         }
//!
//!         S(new)
//!     }
//! }
//!
//! fn main() {
//!     let mut builder = SBuilder { min: -5.12, max: 5.12 };
//!     let hive = HiveBuilder::<S>::new(builder, 10);
//!     println!("{:?}", hive.build().unwrap().run_for_rounds(100).unwrap());
//! }
//! ```

mod result;
mod task;
mod solution;
mod candidate;
mod hive;

pub mod scaling;

pub use result::{Error, Result};
pub use solution::Solution;
pub use candidate::Candidate;
pub use hive::{HiveBuilder, Hive};
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use std::process::Command;

use config::Config;
use errors::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Author {
  pub name: String,
  pub email: String,
}

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_active(&self, inits: &[&str]) -> Result<()> {
    self.get_authors(inits)
      .and_then(|_| self.config.set("active", &inits.join("+")))
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> Result<&'a mut Command> {
    let active = try!(self.config.get("active"));
    let inits: Vec<_> = active.split('+').collect();
    let authors = try!(self.get_authors(&inits));

    let cmd = match authors.get(0) {
      Some(author) => {
        cmd.env("GIT_AUTHOR_NAME", author.name.clone())
          .env("GIT_AUTHOR_EMAIL", author.email.clone())
      }
      _ => cmd,
    };

    let cmd = match authors.get(1) {
      Some(committer) => {
        cmd.env("GIT_COMMITTER_NAME", committer.name.clone())
          .env("GIT_COMMITTER_EMAIL", committer.email.clone())
          .arg("--signoff")
      }
      _ => cmd,
    };

    Ok(cmd)
  }

  fn get_active(&self) -> Result<Vec<String>> {
    self.config
      .get("active")
      .map(|active| active.split('+').map(|s| s.into()).collect())
  }

  pub fn rotate_active(&self) -> Result<()> {
    self.get_active().and_then(|active| {
      let mut inits: Vec<_> = active.iter().map(String::as_ref).collect();
      if !inits.is_empty() {
        let author = inits.remove(0);
        inits.push(author);
      }
      self.set_active(&inits[..])
    })
  }

  fn get_authors(&self, inits: &[&str]) -> Result<Vec<Author>> {
    let domain = try!(self.config.get("domain"));
    inits.iter()
      .map(|&init| {
        self.config
          .get(&format!("authors.{}", init))
          .chain_err(|| ErrorKind::AuthorNotFound(init.into()))
          .and_then(|raw| {
            if raw.is_empty() {
              return Err(ErrorKind::InvalidAuthor(raw).into());
            }

            let mut split = raw.split(';');
            let name = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let username = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let email = format!("{}@{}", username, domain);

            Ok(Author {
              name: name.into(),
              email: email,
            })
          })
      })
      .collect()
  }
}

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

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn get_authors_no_domain() {
    let config = MockConfig::new(&[("authors.jh", "James Holden; jholden")]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
  }

  #[test]
  fn get_authors() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", ""),
                                   ("authors.nn", "Naomi Nagata"),
                                   ("authors.ab", "Amos Burton; aburton"),
                                   ("authors.ak", "Alex Kamal; akamal") /* ("authors.ca", "Chrisjen Avasarala;"),
                                                                         * ("authors.bd", "Bobbie Draper; bdraper@mars.mil"),
                                                                         * ("authors.jm", "Joe Miller; jmiller@starhelix.com"), */]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
    assert!(gt.get_authors(&["nn"]).is_err());
    // assert!(gt.get_authors(&["ca"]).is_err());
    // assert!(gt.get_authors(&["jh", "bd"]).is_err());

    assert_eq!(gt.get_authors(&["ab", "ak"]).unwrap(),
               vec![
               Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
               Author { name: "Alex Kamal".into(), email: "akamal@rocinante.com".into() },
               ]);
    // assert_eq!(gt.get_authors(&["ab", "bd", "jm"]).unwrap(),
    //            vec![Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
    // Author { name: "Bobbie Draper".into(), email: "bdraper@mars.mil".into() },
    // Author { name: "Joe Miller".into(), email: "jmiller@starhelix.com".into() },
    // ]);
  }

  #[test]
  fn set_active() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.set_active(&["jh"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh"]);

    gt.set_active(&["jh", "nn"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh", "nn"]);
  }

  #[test]
  fn rotate_active() {
    let config = MockConfig::new(&[("active", "jh+nn"),
                                   ("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.rotate_active().unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["nn", "jh"]);
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl MockConfig {
    fn new(data: &[(&str, &str)]) -> MockConfig {
      let data = data.iter()
        .map(|&(k, v)| (k.into(), v.into()))
        .collect();
      MockConfig { data: RefCell::new(data) }
    }
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data
        .borrow()
        .get(name.into())
        .cloned()
        .ok_or(format!("name not found: '{}'", name).into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<commit_msg>extract method for creating an author<commit_after>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use std::process::Command;

use config::Config;
use errors::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Author {
  pub name: String,
  pub email: String,
}

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_active(&self, inits: &[&str]) -> Result<()> {
    self.get_authors(inits)
      .and_then(|_| self.config.set("active", &inits.join("+")))
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> Result<&'a mut Command> {
    let active = try!(self.config.get("active"));
    let inits: Vec<_> = active.split('+').collect();
    let authors = try!(self.get_authors(&inits));

    let cmd = match authors.get(0) {
      Some(author) => {
        cmd.env("GIT_AUTHOR_NAME", author.name.clone())
          .env("GIT_AUTHOR_EMAIL", author.email.clone())
      }
      _ => cmd,
    };

    let cmd = match authors.get(1) {
      Some(committer) => {
        cmd.env("GIT_COMMITTER_NAME", committer.name.clone())
          .env("GIT_COMMITTER_EMAIL", committer.email.clone())
          .arg("--signoff")
      }
      _ => cmd,
    };

    Ok(cmd)
  }

  fn get_active(&self) -> Result<Vec<String>> {
    self.config
      .get("active")
      .map(|active| active.split('+').map(|s| s.into()).collect())
  }

  pub fn rotate_active(&self) -> Result<()> {
    self.get_active().and_then(|active| {
      let mut inits: Vec<_> = active.iter().map(String::as_ref).collect();
      if !inits.is_empty() {
        let author = inits.remove(0);
        inits.push(author);
      }
      self.set_active(&inits[..])
    })
  }

  fn get_authors(&self, inits: &[&str]) -> Result<Vec<Author>> {
    let domain = try!(self.config.get("domain"));
    inits.iter()
      .map(|&init| {
        self.config
          .get(&format!("authors.{}", init))
          .chain_err(|| ErrorKind::AuthorNotFound(init.into()))
          .and_then(|raw| {
            if raw.is_empty() {
              return Err(ErrorKind::InvalidAuthor(raw).into());
            }

            Self::author(&domain, &raw)
          })
      })
      .collect()
  }

  fn author(domain: &str, raw: &str) -> Result<Author> {
    let mut split = raw.split(';');
    let name = try!(split.next()
        .ok_or(ErrorKind::InvalidAuthor(raw.into())))
      .trim();
    let username = try!(split.next()
        .ok_or(ErrorKind::InvalidAuthor(raw.into())))
      .trim();
    let email = format!("{}@{}", username, domain);

    Ok(Author {
      name: name.into(),
      email: email,
    })
  }
}

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

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn get_authors_no_domain() {
    let config = MockConfig::new(&[("authors.jh", "James Holden; jholden")]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
  }

  #[test]
  fn get_authors() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", ""),
                                   ("authors.nn", "Naomi Nagata"),
                                   ("authors.ab", "Amos Burton; aburton"),
                                   ("authors.ak", "Alex Kamal; akamal") /* ("authors.ca", "Chrisjen Avasarala;"),
                                                                         * ("authors.bd", "Bobbie Draper; bdraper@mars.mil"),
                                                                         * ("authors.jm", "Joe Miller; jmiller@starhelix.com"), */]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
    assert!(gt.get_authors(&["nn"]).is_err());
    // assert!(gt.get_authors(&["ca"]).is_err());
    // assert!(gt.get_authors(&["jh", "bd"]).is_err());

    assert_eq!(gt.get_authors(&["ab", "ak"]).unwrap(),
               vec![
               Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
               Author { name: "Alex Kamal".into(), email: "akamal@rocinante.com".into() },
               ]);
    // assert_eq!(gt.get_authors(&["ab", "bd", "jm"]).unwrap(),
    //            vec![Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
    // Author { name: "Bobbie Draper".into(), email: "bdraper@mars.mil".into() },
    // Author { name: "Joe Miller".into(), email: "jmiller@starhelix.com".into() },
    // ]);
  }

  #[test]
  fn set_active() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.set_active(&["jh"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh"]);

    gt.set_active(&["jh", "nn"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh", "nn"]);
  }

  #[test]
  fn rotate_active() {
    let config = MockConfig::new(&[("active", "jh+nn"),
                                   ("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.rotate_active().unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["nn", "jh"]);
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl MockConfig {
    fn new(data: &[(&str, &str)]) -> MockConfig {
      let data = data.iter()
        .map(|&(k, v)| (k.into(), v.into()))
        .collect();
      MockConfig { data: RefCell::new(data) }
    }
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data
        .borrow()
        .get(name.into())
        .cloned()
        .ok_or(format!("name not found: '{}'", name).into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<|endoftext|>


<commit_before>use std::env;
extern crate rawloader;
extern crate time;
use rawloader::decoders;

fn usage() {
  println!("benchmark <file>");
  std::process::exit(1);
}

static STEP_ITERATIONS: u32 = 10;
static MIN_ITERATIONS: u32 = 100;
static MIN_TIME: u64 = 10000000000;

fn error(err: &str) {
  println!("ERROR: {}", err);
  std::process::exit(2);
}

fn main() {
  let args: Vec<_> = env::args().collect();
  if args.len() != 2 {
    usage();
  }
  let file = &args[1];
  println!("Loading file \"{}\"", file);

  let rawloader = decoders::RawLoader::new();
  let from_time = time::precise_time_ns();
  let mut iterations = 0;
  loop {
    for _ in 0..STEP_ITERATIONS {
      match rawloader.decode_safe(file) {
        Ok(_) => {},
        Err(e) => error(&e),
      }
    }
    iterations += STEP_ITERATIONS;
    let to_time = time::precise_time_ns();
    if iterations >= MIN_ITERATIONS && (to_time-from_time) >= MIN_TIME {
      println!("Average decode time: {} ms ({} iterations)", (to_time-from_time)/(iterations as u64)/1000000, iterations);
      break;
    }
  }
}
<commit_msg>Exclude the file reading from the benchmark<commit_after>use std::env;
use std::fs::File;
use std::error::Error;

extern crate rawloader;
extern crate time;
use rawloader::decoders;

fn usage() {
  println!("benchmark <file>");
  std::process::exit(1);
}

static STEP_ITERATIONS: u32 = 10;
static MIN_ITERATIONS: u32 = 100;
static MIN_TIME: u64 = 10000000000;

fn error(err: &str) {
  println!("ERROR: {}", err);
  std::process::exit(2);
}

fn main() {
  let args: Vec<_> = env::args().collect();
  if args.len() != 2 {
    usage();
  }
  let file = &args[1];
  println!("Loading file \"{}\"", file);

  let mut iterations = 0;
  let mut f = match File::open(file) {
    Ok(val) => val,
    Err(e) => {error(e.description());return},
  };
  let buffer = match decoders::Buffer::new(&mut f) {
    Ok(val) => val,
    Err(e) => {error(&e); return},
  };
  let rawloader = decoders::RawLoader::new();
  let from_time = time::precise_time_ns();
  loop {
    for _ in 0..STEP_ITERATIONS {
      let decoder = match rawloader.get_decoder(&buffer) {
        Ok(val) => val,
        Err(e) => {error(&e); return},
      };
      match decoder.image() {
        Ok(_) => {},
        Err(e) => error(&e),
      }
    }
    iterations += STEP_ITERATIONS;
    let to_time = time::precise_time_ns();
    if iterations >= MIN_ITERATIONS && (to_time-from_time) >= MIN_TIME {
      println!("Average decode time: {} ms ({} iterations)", (to_time-from_time)/(iterations as u64)/1000000, iterations);
      break;
    }
  }
}
<|endoftext|>


<commit_before>//! jsonrpc http server.
//!
//! ```no_run
//! extern crate jsonrpc_core;
//! extern crate json_ipc_server;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::*;
//! use json_ipc_server::Server;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! 	fn execute(&self, _params: Params) -> Result<Value, Error> {
//! 		Ok(Value::String("hello".to_string()))
//! 	}
//! }
//!
//! fn main() {
//! 	let io = IoHandler::new();
//! 	io.add_method("say_hello", SayHello);
//! 	let server = Server::new("/tmp/json-ipc-test.ipc", &Arc::new(io)).unwrap();
//!     ::std::thread::spawn(move || server.run());
//! }
//! ```

extern crate mio;
extern crate jsonrpc_core;
extern crate bytes;
extern crate slab;

use mio::*;
use mio::unix::*;
use bytes::{Buf, ByteBuf, MutByteBuf};
use std::io;
use jsonrpc_core::IoHandler;
use std::sync::*;

const SERVER: Token = Token(0);

struct SocketConnection {
    socket: UnixStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet,
}

type Slab<T> = slab::Slab<T, Token>;

impl SocketConnection {
    fn new(sock: UnixStream) -> Self {
        SocketConnection {
            socket: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            token: None,
            interest: EventSet::hup(),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<RpcServer>, _handler: &IoHandler) -> io::Result<()> {
        use std::io::Write;
        if let Some(buf) = self.buf.take() {
            try!(self.socket.write_all(&buf.bytes()));
        }

        self.interest.remove(EventSet::writable());
        self.interest.insert(EventSet::readable());

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }

    fn readable(&mut self, event_loop: &mut EventLoop<RpcServer>, handler: &IoHandler) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap_or_else(|| panic!("unwrapping mutable buffer which is None"));

        match self.socket.try_read_buf(&mut buf) {
            Ok(None) => {
                self.mut_buf = Some(buf);
            }
            Ok(Some(_)) => {
                String::from_utf8(buf.bytes().to_vec())
                    .map(|rpc_msg| {
                        let response: Option<String> = handler.handle_request(&rpc_msg);
                        if let Some(response_str) = response {
                            let response_bytes = response_str.into_bytes();
                            self.buf = Some(ByteBuf::from_slice(&response_bytes));
                        }
                    }).unwrap();

                self.mut_buf = Some(buf);

                self.interest.remove(EventSet::readable());
                self.interest.insert(EventSet::writable());
            }
            Err(_) => {
                //warn!(target: "ipc", "Error receiving data: {:?}", e);
                self.interest.remove(EventSet::readable());
            }

        };

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }
}

struct RpcServer {
    socket: UnixListener,
    connections: Slab<SocketConnection>,
    io_handler: Arc<IoHandler>,
}

pub struct Server {
    rpc_server: RwLock<RpcServer>,
    event_loop: RwLock<EventLoop<RpcServer>>,
}

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
}

impl std::convert::From<std::io::Error> for Error {
    fn from(io_error: std::io::Error) -> Error {
        Error::Io(io_error)
    }
}

impl Server {
    /// New server
    pub fn new(socket_addr: &str, io_handler: &Arc<IoHandler>) -> Result<Server, Error> {
        let (server, event_loop) = try!(RpcServer::start(socket_addr, io_handler));
        Ok(Server {
            rpc_server: RwLock::new(server),
            event_loop: RwLock::new(event_loop),
        })
    }

    /// Run server (blocking)
    pub fn run(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();
        event_loop.run(&mut server).unwrap();
    }

    /// Poll server requests
    pub fn poll(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();

        event_loop.run_once(&mut server, Some(100)).unwrap();
    }
}

impl RpcServer {

    /// start ipc rpc server (blocking)
    pub fn start(addr: &str, io_handler: &Arc<IoHandler>) -> Result<(RpcServer, EventLoop<RpcServer>), Error> {
        let mut event_loop = try!(EventLoop::new());
        ::std::fs::remove_file(addr).unwrap_or_else(|_| {} ); // ignore error (if no file)
        let socket = try!(UnixListener::bind(&addr));
        event_loop.register(&socket, SERVER, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
        let server = RpcServer {
            socket: socket,
            connections: Slab::new_starting_at(Token(1), 8),
            io_handler: io_handler.clone(),
        };
        Ok((server, event_loop))
    }

    fn accept(&mut self, event_loop: &mut EventLoop<RpcServer>) -> io::Result<()> {
        let new_client_socket = self.socket.accept().unwrap().unwrap();
        let connection = SocketConnection::new(new_client_socket);
        let token = self.connections.insert(connection).ok().expect("fatal: Could not add connectiont o slab (memory issue?)");

        self.connections[token].token = Some(token);
        event_loop.register(
            &self.connections[token].socket,
            token,
            EventSet::readable(),
            PollOpt::edge() | PollOpt::oneshot()
        ).ok().expect("could not register socket with event loop (memory issue?)");

        Ok(())
    }

    fn connection_readable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).readable(event_loop, &io_handler)
    }

    fn connection_writable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).writable(event_loop, &io_handler)
    }

    fn connection<'a>(&'a mut self, tok: Token) -> &'a mut SocketConnection {
        &mut self.connections[tok]
    }
}

impl Handler for RpcServer {
    type Timeout = usize;
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<RpcServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                _ => self.connection_readable(event_loop, token).unwrap()
            };
        }

        if events.is_writable() {
            match token {
                SERVER => { },
                _ => self.connection_writable(event_loop, token).unwrap_or_else(|_| {}), // todo: disqualify connection from list on error
            };
        }
    }
}

#[cfg(test)]
fn dummy_request(addr: &str, buf: &[u8]) -> Vec<u8> {
    use std::io::{Read, Write};

    let mut poll = Poll::new().unwrap();
    let mut sock = UnixStream::connect(addr).unwrap();
    poll.register(&sock, Token(0), EventSet::writable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
    poll.poll(Some(500)).unwrap();
    sock.write_all(buf).unwrap();
    poll.reregister(&sock, Token(0), EventSet::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
    poll.poll(Some(500)).unwrap();

    let mut buf = Vec::new();
    sock.read_to_end(&mut buf).unwrap_or_else(|_| { 0 });
    buf
}

#[cfg(test)]
fn dummy_io_handler() -> Arc<IoHandler> {
    use std::sync::Arc;
    use jsonrpc_core::*;

    struct SayHello;
    impl MethodCommand for SayHello {
        fn execute(&self, _params: Params) -> Result<Value, Error> {
            Ok(Value::String("hello".to_string()))
        }
    }

    let io = IoHandler::new();
    io.add_method("say_hello", SayHello);
    Arc::new(io)
}

#[test]
pub fn test_reqrep() {
    let addr = "/tmp/test10";
    let io = dummy_io_handler();
    let server = Server::new(addr, &io).unwrap();
    std::thread::spawn(move || {
        server.run()
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello","id":1}"#;

    assert_eq!(String::from_utf8(dummy_request(addr, request.as_bytes())).unwrap(), response.to_string());
}
#[test]
pub fn test_reqrep_poll() {
    let addr = "/tmp/test20";
    let io = dummy_io_handler();
    let server = Server::new(addr, &io).unwrap();
    std::thread::spawn(move || {
        loop {
            server.poll();
        }
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello","id":1}"#;
    assert_eq!(String::from_utf8(dummy_request(addr, request.as_bytes())).unwrap(), response.to_string());

    std::thread::sleep(std::time::Duration::from_millis(500));
}<commit_msg>::io::IoHandler<commit_after>//! jsonrpc http server.
//!
//! ```no_run
//! extern crate jsonrpc_core;
//! extern crate json_ipc_server;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::*;
//! use json_ipc_server::Server;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! 	fn execute(&self, _params: Params) -> Result<Value, Error> {
//! 		Ok(Value::String("hello".to_string()))
//! 	}
//! }
//!
//! fn main() {
//! 	let io = IoHandler::new();
//! 	io.add_method("say_hello", SayHello);
//! 	let server = Server::new("/tmp/json-ipc-test.ipc", &Arc::new(io)).unwrap();
//!     ::std::thread::spawn(move || server.run());
//! }
//! ```

extern crate mio;
extern crate jsonrpc_core;
extern crate bytes;
extern crate slab;

use mio::*;
use mio::unix::*;
use bytes::{Buf, ByteBuf, MutByteBuf};
use std::io;
use jsonrpc_core::io::IoHandler;
use std::sync::*;

const SERVER: Token = Token(0);

struct SocketConnection {
    socket: UnixStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet,
}

type Slab<T> = slab::Slab<T, Token>;

impl SocketConnection {
    fn new(sock: UnixStream) -> Self {
        SocketConnection {
            socket: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            token: None,
            interest: EventSet::hup(),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<RpcServer>, _handler: &IoHandler) -> io::Result<()> {
        use std::io::Write;
        if let Some(buf) = self.buf.take() {
            try!(self.socket.write_all(&buf.bytes()));
        }

        self.interest.remove(EventSet::writable());
        self.interest.insert(EventSet::readable());

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }

    fn readable(&mut self, event_loop: &mut EventLoop<RpcServer>, handler: &IoHandler) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap_or_else(|| panic!("unwrapping mutable buffer which is None"));

        match self.socket.try_read_buf(&mut buf) {
            Ok(None) => {
                self.mut_buf = Some(buf);
            }
            Ok(Some(_)) => {
                String::from_utf8(buf.bytes().to_vec())
                    .map(|rpc_msg| {
                        let response: Option<String> = handler.handle_request(&rpc_msg);
                        if let Some(response_str) = response {
                            let response_bytes = response_str.into_bytes();
                            self.buf = Some(ByteBuf::from_slice(&response_bytes));
                        }
                    }).unwrap();

                self.mut_buf = Some(buf);

                self.interest.remove(EventSet::readable());
                self.interest.insert(EventSet::writable());
            }
            Err(_) => {
                //warn!(target: "ipc", "Error receiving data: {:?}", e);
                self.interest.remove(EventSet::readable());
            }

        };

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }
}

struct RpcServer {
    socket: UnixListener,
    connections: Slab<SocketConnection>,
    io_handler: Arc<IoHandler>,
}

pub struct Server {
    rpc_server: RwLock<RpcServer>,
    event_loop: RwLock<EventLoop<RpcServer>>,
}

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
}

impl std::convert::From<std::io::Error> for Error {
    fn from(io_error: std::io::Error) -> Error {
        Error::Io(io_error)
    }
}

impl Server {
    /// New server
    pub fn new(socket_addr: &str, io_handler: &Arc<IoHandler>) -> Result<Server, Error> {
        let (server, event_loop) = try!(RpcServer::start(socket_addr, io_handler));
        Ok(Server {
            rpc_server: RwLock::new(server),
            event_loop: RwLock::new(event_loop),
        })
    }

    /// Run server (blocking)
    pub fn run(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();
        event_loop.run(&mut server).unwrap();
    }

    /// Poll server requests
    pub fn poll(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();

        event_loop.run_once(&mut server, Some(100)).unwrap();
    }
}

impl RpcServer {

    /// start ipc rpc server (blocking)
    pub fn start(addr: &str, io_handler: &Arc<IoHandler>) -> Result<(RpcServer, EventLoop<RpcServer>), Error> {
        let mut event_loop = try!(EventLoop::new());
        ::std::fs::remove_file(addr).unwrap_or_else(|_| {} ); // ignore error (if no file)
        let socket = try!(UnixListener::bind(&addr));
        event_loop.register(&socket, SERVER, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
        let server = RpcServer {
            socket: socket,
            connections: Slab::new_starting_at(Token(1), 8),
            io_handler: io_handler.clone(),
        };
        Ok((server, event_loop))
    }

    fn accept(&mut self, event_loop: &mut EventLoop<RpcServer>) -> io::Result<()> {
        let new_client_socket = self.socket.accept().unwrap().unwrap();
        let connection = SocketConnection::new(new_client_socket);
        let token = self.connections.insert(connection).ok().expect("fatal: Could not add connectiont o slab (memory issue?)");

        self.connections[token].token = Some(token);
        event_loop.register(
            &self.connections[token].socket,
            token,
            EventSet::readable(),
            PollOpt::edge() | PollOpt::oneshot()
        ).ok().expect("could not register socket with event loop (memory issue?)");

        Ok(())
    }

    fn connection_readable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).readable(event_loop, &io_handler)
    }

    fn connection_writable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).writable(event_loop, &io_handler)
    }

    fn connection<'a>(&'a mut self, tok: Token) -> &'a mut SocketConnection {
        &mut self.connections[tok]
    }
}

impl Handler for RpcServer {
    type Timeout = usize;
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<RpcServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                _ => self.connection_readable(event_loop, token).unwrap()
            };
        }

        if events.is_writable() {
            match token {
                SERVER => { },
                _ => self.connection_writable(event_loop, token).unwrap_or_else(|_| {}), // todo: disqualify connection from list on error
            };
        }
    }
}

#[cfg(test)]
fn dummy_request(addr: &str, buf: &[u8]) -> Vec<u8> {
    use std::io::{Read, Write};

    let mut poll = Poll::new().unwrap();
    let mut sock = UnixStream::connect(addr).unwrap();
    poll.register(&sock, Token(0), EventSet::writable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
    poll.poll(Some(500)).unwrap();
    sock.write_all(buf).unwrap();
    poll.reregister(&sock, Token(0), EventSet::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
    poll.poll(Some(500)).unwrap();

    let mut buf = Vec::new();
    sock.read_to_end(&mut buf).unwrap_or_else(|_| { 0 });
    buf
}

#[cfg(test)]
fn dummy_io_handler() -> Arc<IoHandler> {
    use std::sync::Arc;
    use jsonrpc_core::*;

    struct SayHello;
    impl MethodCommand for SayHello {
        fn execute(&self, _params: Params) -> Result<Value, Error> {
            Ok(Value::String("hello".to_string()))
        }
    }

    let io = IoHandler::new();
    io.add_method("say_hello", SayHello);
    Arc::new(io)
}

#[test]
pub fn test_reqrep() {
    let addr = "/tmp/test10";
    let io = dummy_io_handler();
    let server = Server::new(addr, &io).unwrap();
    std::thread::spawn(move || {
        server.run()
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello","id":1}"#;

    assert_eq!(String::from_utf8(dummy_request(addr, request.as_bytes())).unwrap(), response.to_string());
}
#[test]
pub fn test_reqrep_poll() {
    let addr = "/tmp/test20";
    let io = dummy_io_handler();
    let server = Server::new(addr, &io).unwrap();
    std::thread::spawn(move || {
        loop {
            server.poll();
        }
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello","id":1}"#;
    assert_eq!(String::from_utf8(dummy_request(addr, request.as_bytes())).unwrap(), response.to_string());

    std::thread::sleep(std::time::Duration::from_millis(500));
}<|endoftext|>


<commit_before>//! Data types that represent playing cards.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

#![feature(slicing_syntax)]

use std::fmt;
use std::str::FromStr;

use Suit::{Spade, Heart, Dia, Club};

/// Playing card's suite.
#[allow(missing_docs, unused_qualifications)] // FIXME rust-lang/rust#19102
#[deriving(Eq, PartialEq, Copy, Clone)]
pub enum Suit {
    Spade,
    Heart,
    Dia,
    Club
}

impl fmt::Show for Suit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match self {
            &Spade => "S",
            &Heart => "H",
            &Dia   => "D",
            &Club  => "C"
        };

        write!(f, "{}", s)
    }
}

impl FromStr for Suit {
    fn from_str(s: &str) -> Option<Suit> {
        if s.len() != 1 { return None; }
        return match s {
            "S" => Some(Spade),
            "H" => Some(Heart),
            "D" => Some(Dia),
            "C" => Some(Club),
            _   => None
        };
    }
}

/// Playing card that only contains suit cards.
#[allow(missing_docs)]
#[deriving(Eq, PartialEq, Copy, Clone)]
pub struct SuitCard {
    pub num: uint,
    pub suit: Suit
}

impl fmt::Show for SuitCard {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SuitCard { num: 1,  suit: s } => write!(f, "A{}", s),
            SuitCard { num: 10, suit: s } => write!(f, "T{}", s),
            SuitCard { num: 11, suit: s } => write!(f, "J{}", s),
            SuitCard { num: 12, suit: s } => write!(f, "Q{}", s),
            SuitCard { num: 13, suit: s } => write!(f, "K{}", s),
            SuitCard { num: n,  suit: s } => write!(f, "{}{}", n, s)
        }
    }
}

impl FromStr for SuitCard {
    fn from_str(s: &str) -> Option<SuitCard> {
        if s.len() != 2 { return None }
        let (c0, c1) = s.slice_shift_char().unwrap();
        let suit = FromStr::from_str(c1);
                let num = match c0 {
                    'A' => Some(1),
                    'T' => Some(10),
                    'J' => Some(11),
                    'Q' => Some(12),
                    'K' => Some(13),
                    d => d.to_digit(10)
                };
        if let (Some(n), Some(s)) = (num, suit) {
            Some(SuitCard { num: n, suit: s })
        } else {
            None
        }
    }
}

/// Playing card that also contaiins jokers.
#[allow(missing_docs)]
#[deriving(Eq, PartialEq, Copy, Clone)]
pub enum Card {
    Suit(SuitCard),
    BlackJoker,
    WhiteJoker
}

impl fmt::Show for Card {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Card::BlackJoker => write!(f, "BJ"),
            Card::WhiteJoker => write!(f, "WJ"),
            Card::Suit(sc) => write!(f, "{}", sc),
        }
    }
}

impl FromStr for Card {
    fn from_str(s: &str) -> Option<Card> {
        match s {
            "BJ" => Some(Card::BlackJoker),
            "WJ" => Some(Card::WhiteJoker),
            _    => FromStr::from_str(s).map(|sc| Card::Suit(sc))
        }
    }
}

impl Card {
    /// Creates new `SuitCard`.
    pub fn new(n: uint, s: Suit) -> Card {
        Card::Suit(SuitCard { num: n, suit: s })
    }
}

#[cfg(test)]
mod tests {
    use super::{Suit, Card};
    use super::Suit::{Spade, Heart, Dia, Club};

    #[test]
    fn show_suit() {
        fn check_pair(s: String, suite: Suit) {
            assert_eq!(s, format!("{}", suite));
            assert_eq!(Some(suite), from_str(s[]));
        }
        check_pair("S".to_string(), Spade);
        check_pair("H".to_string(), Heart);
        check_pair("D".to_string(), Dia);
        check_pair("C".to_string(), Club);
    }

    #[test]
    fn show_card() {
        fn check_pair(s: String, card: Card) {
            assert_eq!(s, format!("{}", card));
            assert_eq!(Some(card), from_str(s[]));
        }
        check_pair("BJ".to_string(), Card::BlackJoker);
        check_pair("WJ".to_string(), Card::WhiteJoker);
        check_pair("AH".to_string(), Card::new(1, Heart));
        check_pair("2C".to_string(), Card::new(2, Club));
        check_pair("9D".to_string(), Card::new(9, Dia));
        check_pair("TS".to_string(), Card::new(10, Spade));
        check_pair("JH".to_string(), Card::new(11, Heart));
        check_pair("QC".to_string(), Card::new(12, Club));
        check_pair("KD".to_string(), Card::new(13, Dia));
    }
}
<commit_msg>fix test warnings<commit_after>//! Data types that represent playing cards.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

#![feature(slicing_syntax)]

use std::fmt;
use std::str::FromStr;

use Suit::{Spade, Heart, Dia, Club};

/// Playing card's suite.
#[allow(missing_docs, unused_qualifications)] // FIXME rust-lang/rust#19102
#[deriving(Eq, PartialEq, Copy, Clone)]
pub enum Suit {
    Spade,
    Heart,
    Dia,
    Club
}

impl fmt::Show for Suit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match self {
            &Spade => "S",
            &Heart => "H",
            &Dia   => "D",
            &Club  => "C"
        };

        write!(f, "{}", s)
    }
}

impl FromStr for Suit {
    fn from_str(s: &str) -> Option<Suit> {
        if s.len() != 1 { return None; }
        return match s {
            "S" => Some(Spade),
            "H" => Some(Heart),
            "D" => Some(Dia),
            "C" => Some(Club),
            _   => None
        };
    }
}

/// Playing card that only contains suit cards.
#[allow(missing_docs)]
#[deriving(Eq, PartialEq, Copy, Clone)]
pub struct SuitCard {
    pub num: uint,
    pub suit: Suit
}

impl fmt::Show for SuitCard {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SuitCard { num: 1,  suit: s } => write!(f, "A{}", s),
            SuitCard { num: 10, suit: s } => write!(f, "T{}", s),
            SuitCard { num: 11, suit: s } => write!(f, "J{}", s),
            SuitCard { num: 12, suit: s } => write!(f, "Q{}", s),
            SuitCard { num: 13, suit: s } => write!(f, "K{}", s),
            SuitCard { num: n,  suit: s } => write!(f, "{}{}", n, s)
        }
    }
}

impl FromStr for SuitCard {
    fn from_str(s: &str) -> Option<SuitCard> {
        if s.len() != 2 { return None }
        let (c0, c1) = s.slice_shift_char().unwrap();
        let suit = FromStr::from_str(c1);
                let num = match c0 {
                    'A' => Some(1),
                    'T' => Some(10),
                    'J' => Some(11),
                    'Q' => Some(12),
                    'K' => Some(13),
                    d => d.to_digit(10)
                };
        if let (Some(n), Some(s)) = (num, suit) {
            Some(SuitCard { num: n, suit: s })
        } else {
            None
        }
    }
}

/// Playing card that also contaiins jokers.
#[allow(missing_docs)]
#[deriving(Eq, PartialEq, Copy, Clone)]
pub enum Card {
    Suit(SuitCard),
    BlackJoker,
    WhiteJoker
}

impl fmt::Show for Card {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Card::BlackJoker => write!(f, "BJ"),
            Card::WhiteJoker => write!(f, "WJ"),
            Card::Suit(sc) => write!(f, "{}", sc),
        }
    }
}

impl FromStr for Card {
    fn from_str(s: &str) -> Option<Card> {
        match s {
            "BJ" => Some(Card::BlackJoker),
            "WJ" => Some(Card::WhiteJoker),
            _    => FromStr::from_str(s).map(|sc| Card::Suit(sc))
        }
    }
}

impl Card {
    /// Creates new `SuitCard`.
    pub fn new(n: uint, s: Suit) -> Card {
        Card::Suit(SuitCard { num: n, suit: s })
    }
}

#[cfg(test)]
mod tests {
    use super::{Suit, Card};
    use super::Suit::{Spade, Heart, Dia, Club};

    #[test]
    fn show_suit() {
        fn check_pair(s: String, suite: Suit) {
            assert_eq!(s, format!("{}", suite));
            assert_eq!(Some(suite), s.parse());
        }
        check_pair("S".to_string(), Spade);
        check_pair("H".to_string(), Heart);
        check_pair("D".to_string(), Dia);
        check_pair("C".to_string(), Club);
    }

    #[test]
    fn show_card() {
        fn check_pair(s: String, card: Card) {
            assert_eq!(s, format!("{}", card));
            assert_eq!(Some(card), s.parse());
        }
        check_pair("BJ".to_string(), Card::BlackJoker);
        check_pair("WJ".to_string(), Card::WhiteJoker);
        check_pair("AH".to_string(), Card::new(1, Heart));
        check_pair("2C".to_string(), Card::new(2, Club));
        check_pair("9D".to_string(), Card::new(9, Dia));
        check_pair("TS".to_string(), Card::new(10, Spade));
        check_pair("JH".to_string(), Card::new(11, Heart));
        check_pair("QC".to_string(), Card::new(12, Club));
        check_pair("KD".to_string(), Card::new(13, Dia));
    }
}
<|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2012-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

// no-pretty-expanded FIXME #15189

#![allow(non_snake_case)]

use std::from_str::FromStr;
use std::iter::count;
use std::cmp::min;
use std::os;
use std::sync::{Arc, RWLock};

fn A(i: uint, j: uint) -> f64 {
    ((i + j) * (i + j + 1) / 2 + i + 1) as f64
}

fn dot(v: &[f64], u: &[f64]) -> f64 {
    let mut sum = 0.0;
    for (&v_i, &u_i) in v.iter().zip(u.iter()) {
        sum += v_i * u_i;
    }
    sum
}

fn mult(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>,
        f: fn(&Vec<f64>, uint) -> f64) {
    // We launch in different tasks the work to be done.  To finish
    // this function, we need to wait for the completion of every
    // tasks.  To do that, we give to each tasks a wait_chan that we
    // drop at the end of the work.  At the end of this function, we
    // wait until the channel hang up.
    let (tx, rx) = channel();

    let len = out.read().len();
    let chunk = len / 20 + 1;
    for chk in count(0, chunk) {
        if chk >= len {break;}
        let tx = tx.clone();
        let v = v.clone();
        let out = out.clone();
        spawn(proc() {
            for i in range(chk, min(len, chk + chunk)) {
                let val = f(&*v.read(), i);
                *out.write().get_mut(i) = val;
            }
            drop(tx)
        });
    }

    // wait until the channel hang up (every task finished)
    drop(tx);
    for () in rx.iter() {}
}

fn mult_Av_impl(v: &Vec<f64> , i: uint) -> f64 {
    let mut sum = 0.;
    for (j, &v_j) in v.iter().enumerate() {
        sum += v_j / A(i, j);
    }
    sum
}

fn mult_Av(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>) {
    mult(v, out, mult_Av_impl);
}

fn mult_Atv_impl(v: &Vec<f64> , i: uint) -> f64 {
    let mut sum = 0.;
    for (j, &v_j) in v.iter().enumerate() {
        sum += v_j / A(j, i);
    }
    sum
}

fn mult_Atv(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>) {
    mult(v, out, mult_Atv_impl);
}

fn mult_AtAv(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>,
             tmp: Arc<RWLock<Vec<f64>>>) {
    mult_Av(v, tmp.clone());
    mult_Atv(tmp, out);
}

fn main() {
    let args = os::args();
    let args = args.as_slice();
    let n = if os::getenv("RUST_BENCH").is_some() {
        5500
    } else if args.len() < 2 {
        2000
    } else {
        FromStr::from_str(args[1].as_slice()).unwrap()
    };
    let u = Arc::new(RWLock::new(Vec::from_elem(n, 1f64)));
    let v = Arc::new(RWLock::new(Vec::from_elem(n, 1f64)));
    let tmp = Arc::new(RWLock::new(Vec::from_elem(n, 1f64)));
    for _ in range(0u8, 10) {
        mult_AtAv(u.clone(), v.clone(), tmp.clone());
        mult_AtAv(v.clone(), u.clone(), tmp.clone());
    }

    let u = u.read();
    let v = v.read();
    println!("{:.9f}", (dot(u.as_slice(), v.as_slice()) /
                        dot(v.as_slice(), v.as_slice())).sqrt());
}
<commit_msg>auto merge of #17989 : alexcrichton/rust/spectralnorm, r=thestinger<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2012-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

// no-pretty-expanded FIXME #15189

#![allow(non_snake_case)]
#![feature(unboxed_closures, overloaded_calls)]

use std::iter::AdditiveIterator;
use std::mem;
use std::os;
use std::raw::Repr;
use std::simd::f64x2;

fn main() {
    let args = os::args();
    let answer = spectralnorm(if os::getenv("RUST_BENCH").is_some() {
        5500
    } else if args.len() < 2 {
        2000
    } else {
        from_str(args[1].as_slice()).unwrap()
    });
    println!("{:.9f}", answer);
}

fn spectralnorm(n: uint) -> f64 {
    assert!(n % 2 == 0, "only even lengths are accepted");
    let mut u = Vec::from_elem(n, 1.0);
    let mut v = Vec::from_elem(n, 1.0);
    let mut tmp = Vec::from_elem(n, 1.0);
    for _ in range(0u, 10) {
        mult_AtAv(u.as_slice(), v.as_mut_slice(), tmp.as_mut_slice());
        mult_AtAv(v.as_slice(), u.as_mut_slice(), tmp.as_mut_slice());
    }
    (dot(u.as_slice(), v.as_slice()) / dot(v.as_slice(), v.as_slice())).sqrt()
}

fn mult_AtAv(v: &[f64], out: &mut [f64], tmp: &mut [f64]) {
    mult_Av(v, tmp);
    mult_Atv(tmp, out);
}

fn mult_Av(v: &[f64], out: &mut [f64]) {
    parallel(out, |&: start, out| mult(v, out, start, |i, j| A(i, j)));
}

fn mult_Atv(v: &[f64], out: &mut [f64]) {
    parallel(out, |&: start, out| mult(v, out, start, |i, j| A(j, i)));
}

fn mult(v: &[f64], out: &mut [f64], start: uint, a: |uint, uint| -> f64) {
    for (i, slot) in out.iter_mut().enumerate().map(|(i, s)| (i + start, s)) {
        let mut sum = f64x2(0.0, 0.0);
        for (j, chunk) in v.chunks(2).enumerate().map(|(j, s)| (2 * j, s)) {
            let top = f64x2(chunk[0], chunk[1]);
            let bot = f64x2(a(i, j), a(i, j + 1));
            sum += top / bot;
        }
        let f64x2(a, b) = sum;
        *slot = a + b;
    }
}

fn A(i: uint, j: uint) -> f64 {
    ((i + j) * (i + j + 1) / 2 + i + 1) as f64
}

fn dot(v: &[f64], u: &[f64]) -> f64 {
    v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum()
}

// Executes a closure in parallel over the given mutable slice. The closure `f`
// is run in parallel and yielded the starting index within `v` as well as a
// sub-slice of `v`.
fn parallel<'a, T, F>(v: &'a mut [T], f: F)
                      where T: Send + Sync,
                            F: Fn(uint, &'a mut [T]) + Sync {
    let (tx, rx) = channel();
    let size = v.len() / os::num_cpus() + 1;

    for (i, chunk) in v.chunks_mut(size).enumerate() {
        let tx = tx.clone();

        // Need to convert `f` and `chunk` to something that can cross the task
        // boundary.
        let f = &f as *const _ as *const uint;
        let raw = chunk.repr();
        spawn(proc() {
            let f = f as *const F;
            unsafe { (*f)(i * size, mem::transmute(raw)) }
            drop(tx)
        });
    }
    drop(tx);
    for () in rx.iter() {}
}
<|endoftext|>


<commit_before>#![feature(std_misc)]

use std::ops::{Index, IndexMut};
use std::num::Float;

#[derive(Copy, Clone, PartialEq)]
pub struct Matrix4([[f32; 4]; 4]);

impl Index<usize> for Matrix4 {
    type Output = [f32; 4];

    fn index<'a>(&'a self, row: &usize) -> &'a [f32; 4] {
        &self.0[*row]
    }
}

impl IndexMut<usize> for Matrix4 {
    type Output = [f32; 4];

    fn index_mut<'a>(&'a mut self, row: &usize) -> &'a mut [f32; 4] {
        &mut self.0[*row]
    }
}

impl Matrix4 {
    pub fn as_array(&self) -> &[[f32; 4]; 4] {
        &self.0
    }

    pub fn from_array(array: [[f32; 4]; 4]) -> Self {
        Matrix4(array)
    }

    pub fn identity() -> Self {
        Matrix4::from_array([[1.0, 0.0, 0.0, 0.0],
                             [0.0, 1.0, 0.0, 0.0],
                             [0.0, 0.0, 1.0, 0.0],
                             [0.0, 0.0, 0.0, 1.0]])
    }

    pub fn ortho(left: f32, right: f32, bottom: f32, top: f32) -> Self {
        let mut m = Matrix4::identity();
        m.0[0][0] = 2.0 / (right - left);
        m.0[1][1] = 2.0 / (top - bottom);
        m.0[2][2] = -1.0;
        m.0[3][0] = -(right + left) / (right - left);
        m.0[3][1] = -(top + bottom) / (top - bottom);
        m
    }

    /// Builds a scale 4 * 4 matrix created from 3 scalars.
    /// Input matrix multiplied by this scale matrix.
    pub fn scale(&mut self, x: f32, y: f32, z: f32) {
        self.0[0][0] *= x;
        self.0[0][1] *= x;
        self.0[0][2] *= x;
        self.0[0][3] *= x;

        self.0[1][0] *= y;
        self.0[1][1] *= y;
        self.0[1][2] *= y;
        self.0[1][3] *= y;

        self.0[2][0] *= z;
        self.0[2][1] *= z;
        self.0[2][2] *= z;
        self.0[2][3] *= z;
    }

    pub fn scale_by_vector(&mut self, v: &Vector3) {
        self.scale(v[0], v[1], v[2])
    }

    /// Builds a translation 4 * 4 matrix created from a vector of 3 components.
    /// Input matrix multiplied by this translation matrix.
    pub fn translate(&mut self, x: f32, y: f32, z: f32) {
        self.0[3][0] += self.0[0][0] * x + self.0[1][0] * y + self.0[2][0] * z;
        self.0[3][1] += self.0[0][1] * x + self.0[1][1] * y + self.0[2][1] * z;
        self.0[3][2] += self.0[0][2] * x + self.0[1][2] * y + self.0[2][2] * z;
    }

    pub fn translate_by_vector(&mut self, v: &Vector3) {
        self.translate(v[0], v[1], v[2])
    }
}

#[derive(Copy, Clone, PartialEq)]
pub struct Vector3([f32; 3]);

impl Index<usize> for Vector3 {
    type Output = f32;

    fn index<'a>(&'a self, index: &usize) -> &'a f32 {
        &self.0[*index]
    }
}

impl IndexMut<usize> for Vector3 {
    type Output = f32;

    fn index_mut<'a>(&'a mut self, index: &usize) -> &'a mut f32 {
        &mut self.0[*index]
    }
}

impl Vector3 {
    pub fn as_array(&self) -> &[f32; 3] {
        &self.0
    }

    pub fn from_array(array: [f32; 3]) -> Self {
        Vector3(array)
    }

    pub fn new(x: f32, y: f32, z: f32) -> Self {
        Vector3::from_array([x, y, z])
    }

    pub fn from_scalar(scalar: f32) -> Self {
        Vector3::from_array([scalar, scalar, scalar])
    }

    pub fn length(&self) -> f32 {
        self.dot(self).sqrt()
    }

    pub fn distance(&self, other: &Vector3) -> f32 {
        let mut result = other.clone();
        result.subtract(self);
        result.length()
    }

    pub fn dot(&self, other: &Vector3) -> f32 {
        self.0[0] * other.0[0] +
        self.0[1] * other.0[1] +
        self.0[2] * other.0[2]
    }

    /// returns the cross product
    pub fn cross(&self, other: &Vector3) -> Vector3 {
        Vector3::new(
            self.0[1] * other.0[2] - other.0[1] * self.0[2],
            self.0[2] * other.0[0] - other.0[2] * self.0[0],
            self.0[0] * other.0[1] - other.0[0] * self.0[1])
    }

    pub fn normalize(&mut self) {
        let value = self.dot(self).rsqrt();
        self.scale(value);
    }

    pub fn subtract(&mut self, other: &Vector3) {
        let mut result = other.clone();
        result.negate();
        self.add(&result);
    }

    pub fn add(&mut self, other: &Vector3) {
        self.0[0] += other.0[0];
        self.0[1] += other.0[1];
        self.0[2] += other.0[2];
    }

    pub fn negate(&mut self) {
        self.0[0] = -self.0[0];
        self.0[1] = -self.0[1];
        self.0[2] = -self.0[2];
    }

    pub fn scale(&mut self, scalar: f32) {
        self.0[0] *= scalar;
        self.0[1] *= scalar;
        self.0[2] *= scalar;
    }
}

#[test]
fn test_matrix_to_array() {
    let array = {
        let foo = Matrix4::from_array([[1.0, 0.0, 0.0, 0.0],
                                       [0.0, 1.0, 0.0, 0.0],
                                       [0.0, 0.0, 1.0, 0.0],
                                       [0.0, 0.0, 0.0, 1.0]]);
        assert_eq!(foo.as_array()[0][0], 1.0);
        *foo.as_array()
    };
    assert_eq!(array[1][1], 1.0);
}

#[test]
fn test_scale() {
    let mut m = Matrix4::identity();
    assert_eq!(m[2][2], 1.0);
    m.scale(3.0, 3.0, 3.0);
    assert_eq!(m[2][2], 3.0);
    m.scale_by_vector(&Vector3::new(2.0, 4.0, 3.0));
    assert_eq!(m[2][2], 9.0);
}

#[test]
fn test_translate() {
    let mut m = Matrix4::identity();
    m.translate(1.0, 2.0, 3.0);
    assert_eq!(m[3][0], 1.0);
    assert_eq!(m[3][1], 2.0);
    assert_eq!(m[3][2], 3.0);
}

#[test]
fn test_ortho() {
    let m = Matrix4::ortho(0.0, 640.0, 480.0, 0.0);
    assert_eq!(m[0][0], 0.003125);
    assert_eq!((m[1][1] * 100000.0).round(), -417.0);
    assert_eq!(m[2][2], -1.0);
    assert_eq!(m[3][3], 1.0);

    assert_eq!(m[3][0], -1.0);
    assert_eq!(m[3][1], 1.0);
    assert_eq!(m[3][2], 0.0);
}
<commit_msg>docs for ortho<commit_after>#![feature(std_misc)]

use std::ops::{Index, IndexMut};
use std::num::Float;

#[derive(Copy, Clone, PartialEq)]
pub struct Matrix4([[f32; 4]; 4]);

impl Index<usize> for Matrix4 {
    type Output = [f32; 4];

    fn index<'a>(&'a self, row: &usize) -> &'a [f32; 4] {
        &self.0[*row]
    }
}

impl IndexMut<usize> for Matrix4 {
    type Output = [f32; 4];

    fn index_mut<'a>(&'a mut self, row: &usize) -> &'a mut [f32; 4] {
        &mut self.0[*row]
    }
}

impl Matrix4 {
    pub fn as_array(&self) -> &[[f32; 4]; 4] {
        &self.0
    }

    pub fn from_array(array: [[f32; 4]; 4]) -> Self {
        Matrix4(array)
    }

    pub fn identity() -> Self {
        Matrix4::from_array([[1.0, 0.0, 0.0, 0.0],
                             [0.0, 1.0, 0.0, 0.0],
                             [0.0, 0.0, 1.0, 0.0],
                             [0.0, 0.0, 0.0, 1.0]])
    }

    /// Creates a matrix for an orthographic parallel viewing volume.
    pub fn ortho(left: f32, right: f32, bottom: f32, top: f32) -> Self {
        let mut m = Matrix4::identity();
        m.0[0][0] = 2.0 / (right - left);
        m.0[1][1] = 2.0 / (top - bottom);
        m.0[2][2] = -1.0;
        m.0[3][0] = -(right + left) / (right - left);
        m.0[3][1] = -(top + bottom) / (top - bottom);
        m
    }

    /// Builds a scale 4 * 4 matrix created from 3 scalars.
    /// Input matrix multiplied by this scale matrix.
    pub fn scale(&mut self, x: f32, y: f32, z: f32) {
        self.0[0][0] *= x;
        self.0[0][1] *= x;
        self.0[0][2] *= x;
        self.0[0][3] *= x;

        self.0[1][0] *= y;
        self.0[1][1] *= y;
        self.0[1][2] *= y;
        self.0[1][3] *= y;

        self.0[2][0] *= z;
        self.0[2][1] *= z;
        self.0[2][2] *= z;
        self.0[2][3] *= z;
    }

    pub fn scale_by_vector(&mut self, v: &Vector3) {
        self.scale(v[0], v[1], v[2])
    }

    /// Builds a translation 4 * 4 matrix created from a vector of 3 components.
    /// Input matrix multiplied by this translation matrix.
    pub fn translate(&mut self, x: f32, y: f32, z: f32) {
        self.0[3][0] += self.0[0][0] * x + self.0[1][0] * y + self.0[2][0] * z;
        self.0[3][1] += self.0[0][1] * x + self.0[1][1] * y + self.0[2][1] * z;
        self.0[3][2] += self.0[0][2] * x + self.0[1][2] * y + self.0[2][2] * z;
    }

    pub fn translate_by_vector(&mut self, v: &Vector3) {
        self.translate(v[0], v[1], v[2])
    }
}

#[derive(Copy, Clone, PartialEq)]
pub struct Vector3([f32; 3]);

impl Index<usize> for Vector3 {
    type Output = f32;

    fn index<'a>(&'a self, index: &usize) -> &'a f32 {
        &self.0[*index]
    }
}

impl IndexMut<usize> for Vector3 {
    type Output = f32;

    fn index_mut<'a>(&'a mut self, index: &usize) -> &'a mut f32 {
        &mut self.0[*index]
    }
}

impl Vector3 {
    pub fn as_array(&self) -> &[f32; 3] {
        &self.0
    }

    pub fn from_array(array: [f32; 3]) -> Self {
        Vector3(array)
    }

    pub fn new(x: f32, y: f32, z: f32) -> Self {
        Vector3::from_array([x, y, z])
    }

    pub fn from_scalar(scalar: f32) -> Self {
        Vector3::from_array([scalar, scalar, scalar])
    }

    pub fn length(&self) -> f32 {
        self.dot(self).sqrt()
    }

    pub fn distance(&self, other: &Vector3) -> f32 {
        let mut result = other.clone();
        result.subtract(self);
        result.length()
    }

    pub fn dot(&self, other: &Vector3) -> f32 {
        self.0[0] * other.0[0] +
        self.0[1] * other.0[1] +
        self.0[2] * other.0[2]
    }

    /// returns the cross product
    pub fn cross(&self, other: &Vector3) -> Vector3 {
        Vector3::new(
            self.0[1] * other.0[2] - other.0[1] * self.0[2],
            self.0[2] * other.0[0] - other.0[2] * self.0[0],
            self.0[0] * other.0[1] - other.0[0] * self.0[1])
    }

    pub fn normalize(&mut self) {
        let value = self.dot(self).rsqrt();
        self.scale(value);
    }

    pub fn subtract(&mut self, other: &Vector3) {
        let mut result = other.clone();
        result.negate();
        self.add(&result);
    }

    pub fn add(&mut self, other: &Vector3) {
        self.0[0] += other.0[0];
        self.0[1] += other.0[1];
        self.0[2] += other.0[2];
    }

    pub fn negate(&mut self) {
        self.0[0] = -self.0[0];
        self.0[1] = -self.0[1];
        self.0[2] = -self.0[2];
    }

    pub fn scale(&mut self, scalar: f32) {
        self.0[0] *= scalar;
        self.0[1] *= scalar;
        self.0[2] *= scalar;
    }
}

#[test]
fn test_matrix_to_array() {
    let array = {
        let foo = Matrix4::from_array([[1.0, 0.0, 0.0, 0.0],
                                       [0.0, 1.0, 0.0, 0.0],
                                       [0.0, 0.0, 1.0, 0.0],
                                       [0.0, 0.0, 0.0, 1.0]]);
        assert_eq!(foo.as_array()[0][0], 1.0);
        *foo.as_array()
    };
    assert_eq!(array[1][1], 1.0);
}

#[test]
fn test_scale() {
    let mut m = Matrix4::identity();
    assert_eq!(m[2][2], 1.0);
    m.scale(3.0, 3.0, 3.0);
    assert_eq!(m[2][2], 3.0);
    m.scale_by_vector(&Vector3::new(2.0, 4.0, 3.0));
    assert_eq!(m[2][2], 9.0);
}

#[test]
fn test_translate() {
    let mut m = Matrix4::identity();
    m.translate(1.0, 2.0, 3.0);
    assert_eq!(m[3][0], 1.0);
    assert_eq!(m[3][1], 2.0);
    assert_eq!(m[3][2], 3.0);
}

#[test]
fn test_ortho() {
    let m = Matrix4::ortho(0.0, 640.0, 480.0, 0.0);
    assert_eq!(m[0][0], 0.003125);
    assert_eq!((m[1][1] * 100000.0).round(), -417.0);
    assert_eq!(m[2][2], -1.0);
    assert_eq!(m[3][3], 1.0);

    assert_eq!(m[3][0], -1.0);
    assert_eq!(m[3][1], 1.0);
    assert_eq!(m[3][2], 0.0);
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::Hash;

pub struct RehashingHashMap<K, V> {
    // NOTE: I tried to make an array of 2 elements, but run into borrowing problems
    hashmap1: HashMap<K, V>,
    hashmap2: HashMap<K, V>,
    is1main: bool,
    rehashing: bool,
}

impl<K, V> RehashingHashMap<K, V>
    where K: Eq + Hash + Clone
{
    pub fn new() -> RehashingHashMap<K, V> {
        RehashingHashMap {
            hashmap1: HashMap::new(),
            hashmap2: HashMap::new(),
            is1main: true,
            rehashing: false,
        }
    }

    pub fn with_capacity(capacity: usize) -> RehashingHashMap<K, V> {
        RehashingHashMap {
            hashmap1: HashMap::with_capacity(capacity),
            hashmap2: HashMap::new(),
            is1main: true,
            rehashing: false,
        }
    }

    fn get_main(&self) -> &HashMap<K, V> {
        if self.is1main { &self.hashmap1 } else { &self.hashmap2 }
    }

    fn get_mut_main(&mut self) -> &mut HashMap<K, V> {
        if self.is1main { &mut self.hashmap1 } else { &mut self.hashmap2 }
    }

    fn get_secondary(&self) -> &HashMap<K, V> {
        if self.is1main { &self.hashmap2 } else { &self.hashmap1 }
    }

    fn rehash(&mut self) {
        if self.rehashing {
            if self.get_secondary().len() == 0 {
                self.drop_secondary();
                return;
            }
            let (mut main, mut sec) = if self.is1main {
                (&mut self.hashmap1, &mut self.hashmap2)
            } else {
                (&mut self.hashmap2, &mut self.hashmap1)
            };
            // unwrap is safe, checked len() > 0 already
            let k: K = sec.keys().take(1).next().unwrap().clone();
            // FIXME: I wish I did not have to clone they key
            // unwrap is safe, we know the key exists in the hashmap
            let val = sec.remove(&k).unwrap();
            main.insert(k, val);
        }
    }

    pub fn capacity(&self) -> usize {
        self.get_main().capacity()
    }

    pub fn reserve(&mut self, additional: usize) {
        self.rehash();
        self.get_mut_main().reserve(additional)
    }

    pub fn is_rehashing(&self) -> bool {
        if !self.rehashing {
            assert_eq!(self.get_secondary().len(), 0);
        }
        self.rehashing
    }

    pub fn shrink_to_fit(&mut self) {
        if !self.rehashing {
            self.rehashing = true;
            self.is1main = !self.is1main;
            let len = self.len();
            self.get_mut_main().reserve(len)
        }
    }

    pub fn len(&self) -> usize {
        self.get_main().len() + self.get_secondary().len()
    }

    pub fn is_empty(&self) -> bool {
        self.get_main().is_empty() && self.get_secondary().is_empty()
    }

    fn drop_secondary(&mut self) {
        self.rehashing = false;
        if self.is1main {
            self.hashmap2 = HashMap::new();
        } else {
            self.hashmap1 = HashMap::new();
        }
    }

    fn assert_state(&self) {
        #![allow(dead_code)]
        if self.rehashing {
            assert!(self.get_secondary().capacity() > 0);
        } else {
            assert!(self.get_secondary().capacity() == 0);
        }
    }

    pub fn clear(&mut self) {
        self.get_mut_main().clear();
        self.drop_secondary();
    }

    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        // while rehashing, they key can be in either hashmap1 or hashmap2
        // but we want to remove them from wherever it is and add it to main
        let mut ret = None;
        if self.rehashing || self.is1main {
            ret = self.hashmap1.remove(&k);
        }
        if ret.is_none() && (self.rehashing || !self.is1main) {
            ret = self.hashmap2.remove(&k);
        }
        self.get_mut_main().insert(k, v);
        self.rehash();
        ret
    }

    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
            where K: Borrow<Q>, Q: Hash + Eq {
        if self.rehashing {
            match self.get_main().get(k) {
                Some(ref v) => Some(v),
                None => self.get_secondary().get(k),
            }
        } else {
            self.get_main().get(k)
        }
    }
}

#[test]
fn capacity() {
    let mut hash:RehashingHashMap<u8, u8> = RehashingHashMap::with_capacity(20);
    assert!(hash.capacity() >= 20);
    hash.reserve(40);
    assert!(hash.capacity() >= 40);
}

#[test]
fn insert() {
    let mut hash = RehashingHashMap::new();
    let key = 0;
    let value1 = 2;
    let value2 = 3;

    assert_eq!(hash.insert(key.clone(), value1.clone()), None);
    assert_eq!(hash.insert(key.clone(), value2.clone()), Some(value1.clone()));
    hash.shrink_to_fit();
    assert!(hash.is_rehashing());
    assert_eq!(hash.insert(key.clone(), value1.clone()), Some(value2.clone()));
    assert!(!hash.is_rehashing());
    hash.assert_state();
}

#[test]
fn insert_many_rehash_get() {
    let mut hash = RehashingHashMap::new();

    let len = 1000;

    for i in 0..len {
        hash.insert(i.clone(), i.clone());
    }
    hash.shrink_to_fit();
    for _ in 0..(len / 2){
        hash.rehash();
    }
    assert!(hash.is_rehashing());

    assert_eq!(hash.len(), len);

    for i in 0..len {
        assert_eq!(hash.get(&i).unwrap(), &i);
    }
    for i in len..(len * 2) {
        assert!(hash.get(&i).is_none());
    }

    for _ in 0..(len / 2 + 1){
        hash.rehash();
    }
    assert!(!hash.is_rehashing());
    hash.assert_state();

    assert_eq!(hash.len(), len);

    for i in 0..len {
        assert_eq!(hash.get(&i).unwrap(), &i);
    }
    for i in len..(len * 2) {
        assert!(hash.get(&i).is_none());
    }
}

#[test]
fn is_empty() {
    let mut hash = RehashingHashMap::new();
    assert!(hash.is_empty());

    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    assert!(!hash.is_empty());
    hash.shrink_to_fit();
    assert!(hash.is_rehashing());
    assert!(!hash.is_empty());
    hash.rehash();
    hash.rehash();
    assert!(!hash.is_rehashing());
    assert!(!hash.is_empty());
}

#[test]
fn clear() {
    let mut hash = RehashingHashMap::with_capacity(1000);
    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    hash.clear();
    hash.assert_state();

    assert!(hash.capacity() >= 1000);
}
<commit_msg>Add remove<commit_after>use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::Hash;

pub struct RehashingHashMap<K, V> {
    // NOTE: I tried to make an array of 2 elements, but run into borrowing problems
    hashmap1: HashMap<K, V>,
    hashmap2: HashMap<K, V>,
    is1main: bool,
    rehashing: bool,
}

impl<K, V> RehashingHashMap<K, V>
    where K: Eq + Hash + Clone
{
    pub fn new() -> RehashingHashMap<K, V> {
        RehashingHashMap {
            hashmap1: HashMap::new(),
            hashmap2: HashMap::new(),
            is1main: true,
            rehashing: false,
        }
    }

    pub fn with_capacity(capacity: usize) -> RehashingHashMap<K, V> {
        RehashingHashMap {
            hashmap1: HashMap::with_capacity(capacity),
            hashmap2: HashMap::new(),
            is1main: true,
            rehashing: false,
        }
    }

    fn get_main(&self) -> &HashMap<K, V> {
        if self.is1main { &self.hashmap1 } else { &self.hashmap2 }
    }

    fn get_mut_main(&mut self) -> &mut HashMap<K, V> {
        if self.is1main { &mut self.hashmap1 } else { &mut self.hashmap2 }
    }

    fn get_secondary(&self) -> &HashMap<K, V> {
        if self.is1main { &self.hashmap2 } else { &self.hashmap1 }
    }

    fn get_mut_secondary(&mut self) -> &mut HashMap<K, V> {
        if self.is1main { &mut self.hashmap2 } else { &mut self.hashmap1 }
    }

    pub fn rehash(&mut self) {
        if self.rehashing {
            if self.get_secondary().len() == 0 {
                self.drop_secondary();
                return;
            }
            let (mut main, mut sec) = if self.is1main {
                (&mut self.hashmap1, &mut self.hashmap2)
            } else {
                (&mut self.hashmap2, &mut self.hashmap1)
            };
            // unwrap is safe, checked len() > 0 already
            let k: K = sec.keys().take(1).next().unwrap().clone();
            // FIXME: I wish I did not have to clone they key
            // unwrap is safe, we know the key exists in the hashmap
            let val = sec.remove(&k).unwrap();
            main.insert(k, val);
        }
    }

    pub fn capacity(&self) -> usize {
        self.get_main().capacity()
    }

    pub fn reserve(&mut self, additional: usize) {
        self.rehash();
        self.get_mut_main().reserve(additional)
    }

    pub fn is_rehashing(&self) -> bool {
        if !self.rehashing {
            assert_eq!(self.get_secondary().len(), 0);
        }
        self.rehashing
    }

    pub fn shrink_to_fit(&mut self) {
        if !self.rehashing {
            self.rehashing = true;
            self.is1main = !self.is1main;
            let len = self.len();
            self.get_mut_main().reserve(len)
        }
    }

    pub fn len(&self) -> usize {
        self.get_main().len() + self.get_secondary().len()
    }

    pub fn is_empty(&self) -> bool {
        self.get_main().is_empty() && self.get_secondary().is_empty()
    }

    fn drop_secondary(&mut self) {
        self.rehashing = false;
        assert_eq!(self.get_secondary().len(), 0);
        if self.is1main {
            self.hashmap2 = HashMap::new();
        } else {
            self.hashmap1 = HashMap::new();
        }
    }

    fn assert_state(&self) {
        #![allow(dead_code)]
        if self.rehashing {
            assert!(self.get_secondary().capacity() > 0);
        } else {
            assert!(self.get_secondary().capacity() == 0);
        }
    }

    pub fn clear(&mut self) {
        self.get_mut_main().clear();
        self.drop_secondary();
    }

    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        // while rehashing, they key can be in either hashmap1 or hashmap2
        // but we want to remove them from wherever it is and add it to main
        let mut ret = None;
        if self.rehashing || self.is1main {
            ret = self.hashmap1.remove(&k);
        }
        if ret.is_none() && (self.rehashing || !self.is1main) {
            ret = self.hashmap2.remove(&k);
        }
        self.get_mut_main().insert(k, v);
        self.rehash();
        ret
    }

    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
            where K: Borrow<Q>, Q: Hash + Eq {
        if self.rehashing {
            match self.get_main().get(k) {
                Some(ref v) => Some(v),
                None => self.get_secondary().get(k),
            }
        } else {
            self.get_main().get(k)
        }
    }

    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>, Q: Hash + Eq {
        if self.rehashing {
            self.rehash();
            match self.get_mut_main().remove(k) {
                Some(v) => Some(v),
                None => self.get_mut_secondary().remove(k),
            }
        } else {
            self.get_mut_main().remove(k)
        }
    }
}

#[test]
fn capacity() {
    let mut hash:RehashingHashMap<u8, u8> = RehashingHashMap::with_capacity(20);
    assert!(hash.capacity() >= 20);
    hash.reserve(40);
    assert!(hash.capacity() >= 40);
}

#[test]
fn insert() {
    let mut hash = RehashingHashMap::new();
    let key = 0;
    let value1 = 2;
    let value2 = 3;

    assert_eq!(hash.insert(key.clone(), value1.clone()), None);
    assert_eq!(hash.insert(key.clone(), value2.clone()), Some(value1.clone()));
    hash.shrink_to_fit();
    assert!(hash.is_rehashing());
    assert_eq!(hash.insert(key.clone(), value1.clone()), Some(value2.clone()));
    assert!(!hash.is_rehashing());
    hash.assert_state();
}

#[test]
fn insert_many_rehash_get() {
    let mut hash = RehashingHashMap::new();

    let len = 1000;

    for i in 0..len {
        hash.insert(i.clone(), i.clone());
    }
    hash.shrink_to_fit();
    for _ in 0..(len / 2){
        hash.rehash();
    }
    assert!(hash.is_rehashing());

    assert_eq!(hash.len(), len);

    for i in 0..len {
        assert_eq!(hash.get(&i).unwrap(), &i);
    }
    for i in len..(len * 2) {
        assert!(hash.get(&i).is_none());
    }

    for _ in 0..(len / 2 + 1){
        hash.rehash();
    }
    assert!(!hash.is_rehashing());
    hash.assert_state();

    assert_eq!(hash.len(), len);

    for i in 0..len {
        assert_eq!(hash.get(&i).unwrap(), &i);
    }
    for i in len..(len * 2) {
        assert!(hash.get(&i).is_none());
    }
}

#[test]
fn is_empty() {
    let mut hash = RehashingHashMap::new();
    assert!(hash.is_empty());

    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    assert!(!hash.is_empty());
    hash.shrink_to_fit();
    assert!(hash.is_rehashing());
    assert!(!hash.is_empty());
    hash.rehash();
    hash.rehash();
    assert!(!hash.is_rehashing());
    assert!(!hash.is_empty());
}

#[test]
fn clear() {
    let mut hash = RehashingHashMap::with_capacity(1000);
    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    hash.clear();
    hash.assert_state();

    assert!(hash.capacity() >= 1000);
}

#[test]
fn remove0() {
    let mut hash = RehashingHashMap::new();
    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    hash.shrink_to_fit();
    assert!(hash.is_rehashing());
    assert_eq!(hash.remove(&key).unwrap(), value);
}

#[test]
fn remove1() {
    let mut hash = RehashingHashMap::new();
    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    hash.shrink_to_fit();
    hash.rehash();
    assert!(hash.is_rehashing());
    assert_eq!(hash.remove(&key).unwrap(), value);
}

#[test]
fn remove2() {
    let mut hash = RehashingHashMap::new();
    let key = 0;
    let value = 2;
    assert_eq!(hash.insert(key.clone(), value.clone()), None);
    hash.shrink_to_fit();
    hash.rehash();
    hash.rehash();
    assert!(!hash.is_rehashing());
    assert_eq!(hash.remove(&key).unwrap(), value);
}
<|endoftext|>