<commit_before>use glib::object::Cast;
use gtk::{self, Type, Widget};
use gtk::{BoxExt, CellLayoutExt, ContainerExt, ScrolledWindowExt, TreeModelExt, WidgetExt};

use sysinfo::*;

use notebook::NoteBook;

use std::cell::Cell;
use std::collections::HashMap;
use std::rc::Rc;

#[allow(dead_code)]
pub struct Procs {
    pub left_tree: gtk::TreeView,
    pub scroll: gtk::ScrolledWindow,
    pub current_pid: Rc<Cell<Option<i32>>>,
    pub kill_button: gtk::Button,
    pub info_button: gtk::Button,
    pub vertical_layout: gtk::Box,
    pub list_store: gtk::ListStore,
    pub columns: Vec<gtk::TreeViewColumn>,
}

impl Procs {
    pub fn new(proc_list: &HashMap<i32, Process>, note: &mut NoteBook) -> Procs {
        let left_tree = gtk::TreeView::new();
        let scroll = gtk::ScrolledWindow::new(None, None);
        let current_pid = Rc::new(Cell::new(None));
        let kill_button = gtk::Button::new_with_label("End task");
        let info_button = gtk::Button::new_with_label("More information");
        let current_pid1 = current_pid.clone();
        let kill_button1 = kill_button.clone();
        let info_button1 = info_button.clone();

        scroll.set_min_content_height(800);
        scroll.set_min_content_width(600);

        let mut columns : Vec<gtk::TreeViewColumn> = Vec::new();

        let list_store = gtk::ListStore::new(&[
            // The first four columns of the model are going to be visible in the view.
            Type::I32,       // pid
            Type::String,    // name
            Type::String,    // CPU
            Type::U32,       // mem
            // These two will serve as keys when sorting by process name and CPU usage.
            Type::String,    // name_lowercase
            Type::F32,       // CPU_f32
        ]);

        append_column("pid", &mut columns, &left_tree);
        append_column("process name", &mut columns, &left_tree);
        append_column("cpu usage", &mut columns, &left_tree);
        append_column("memory usage (in kB)", &mut columns, &left_tree);

        // When we click the "name" column the order is defined by the
        // "name_lowercase" effectively making the built-in comparator ignore case.
        columns[1].set_sort_column_id(4);
        // Likewise clicking the "CPU" column sorts by the "CPU_f32" one because
        // we want the order to be numerical not lexicographical.
        columns[2].set_sort_column_id(5);

        for (_, pro) in proc_list {
            create_and_fill_model(&list_store, pro.pid, &format!("{:?}", &pro.cmd), &pro.name,
                                  pro.cpu_usage, pro.memory);
        }

        left_tree.set_model(Some(&list_store));
        left_tree.set_headers_visible(true);
        //let filter = gtk::TreeModelFilter::new(&list_store, None);
        scroll.add(&left_tree);
        let vertical_layout = gtk::Box::new(gtk::Orientation::Vertical, 0);
        let horizontal_layout = gtk::Grid::new();
        /*let list_store1 = list_store.clone();

        filter.set_modify_func(|_, iter, value| {
            list_store1.get_value(&iter, 4).get::<String>().unwrap()
                       .contains(value.get::<String>().unwrap().to_lowercase())
        });*/

        left_tree.connect_cursor_changed(move |tree_view| {
            let selection = tree_view.get_selection();
            let (pid, ret) = if let Some((model, iter)) = selection.get_selected() {
                if let Some(x) = model.get_value(&iter, 0).get() {
                    (Some(x), true)
                } else {
                    (None, false)
                }
            } else {
                (None, false)
            };
            current_pid1.set(pid);
            kill_button1.set_sensitive(ret);
            info_button1.set_sensitive(ret);
        });
        kill_button.set_sensitive(false);
        info_button.set_sensitive(false);

        vertical_layout.pack_start(&scroll, true, true, 0);
        horizontal_layout.attach(&info_button, 0, 0, 2, 1);
        horizontal_layout.attach_next_to(&kill_button, Some(&info_button),
                                         gtk::PositionType::Right, 2, 1);
        horizontal_layout.set_column_homogeneous(true);
        vertical_layout.pack_start(&horizontal_layout, false, true, 0);

        let vertical_layout : Widget = vertical_layout.upcast();
        note.create_tab("Process list", &vertical_layout);

        Procs {
            left_tree: left_tree,
            scroll: scroll,
            current_pid: current_pid,
            kill_button: kill_button,
            info_button: info_button,
            vertical_layout: vertical_layout.downcast::<gtk::Box>().unwrap(),
            list_store: list_store,
            columns: columns,
        }
    }
}

fn append_column(title: &str, v: &mut Vec<gtk::TreeViewColumn>, left_tree: &gtk::TreeView) {
    let id = v.len() as i32;
    let renderer = gtk::CellRendererText::new();

    let column = gtk::TreeViewColumn::new();
    column.set_title(title);
    column.set_resizable(true);
    column.pack_start(&renderer, true);
    column.add_attribute(&renderer, "text", id);
    column.set_clickable(true);
    column.set_sort_column_id(id);
    left_tree.append_column(&column);
    v.push(column);
}

pub fn create_and_fill_model(list_store: &gtk::ListStore, pid: i32, cmdline: &str, name: &str,
                             cpu: f32, memory: u64) {
    if cmdline.len() < 1 {
        return;
    }
    list_store.insert_with_values(None,
                                  &[0, 1, 2, 3, 4, 5],
                                  &[&pid,
                                    &name,
                                    &format!("{:.1}", cpu),
                                    &memory,
                                    &name.to_lowercase(),
                                    &cpu
                                   ]);
}
<commit_msg>Fix invalid window size<commit_after>use glib::object::Cast;
use gtk::{self, Type, Widget};
use gtk::{BoxExt, CellLayoutExt, ContainerExt, ScrolledWindowExt, TreeModelExt, WidgetExt};

use sysinfo::*;

use notebook::NoteBook;

use std::cell::Cell;
use std::collections::HashMap;
use std::rc::Rc;

#[allow(dead_code)]
pub struct Procs {
    pub left_tree: gtk::TreeView,
    pub scroll: gtk::ScrolledWindow,
    pub current_pid: Rc<Cell<Option<i32>>>,
    pub kill_button: gtk::Button,
    pub info_button: gtk::Button,
    pub vertical_layout: gtk::Box,
    pub list_store: gtk::ListStore,
    pub columns: Vec<gtk::TreeViewColumn>,
}

impl Procs {
    pub fn new(proc_list: &HashMap<i32, Process>, note: &mut NoteBook) -> Procs {
        let left_tree = gtk::TreeView::new();
        let scroll = gtk::ScrolledWindow::new(None, None);
        let current_pid = Rc::new(Cell::new(None));
        let kill_button = gtk::Button::new_with_label("End task");
        let info_button = gtk::Button::new_with_label("More information");
        let current_pid1 = current_pid.clone();
        let kill_button1 = kill_button.clone();
        let info_button1 = info_button.clone();

        let mut columns: Vec<gtk::TreeViewColumn> = Vec::new();

        let list_store = gtk::ListStore::new(&[
            // The first four columns of the model are going to be visible in the view.
            Type::I32,       // pid
            Type::String,    // name
            Type::String,    // CPU
            Type::U32,       // mem
            // These two will serve as keys when sorting by process name and CPU usage.
            Type::String,    // name_lowercase
            Type::F32,       // CPU_f32
        ]);

        append_column("pid", &mut columns, &left_tree);
        append_column("process name", &mut columns, &left_tree);
        append_column("cpu usage", &mut columns, &left_tree);
        append_column("memory usage (in kB)", &mut columns, &left_tree);

        // When we click the "name" column the order is defined by the
        // "name_lowercase" effectively making the built-in comparator ignore case.
        columns[1].set_sort_column_id(4);
        // Likewise clicking the "CPU" column sorts by the "CPU_f32" one because
        // we want the order to be numerical not lexicographical.
        columns[2].set_sort_column_id(5);

        for (_, pro) in proc_list {
            create_and_fill_model(&list_store, pro.pid, &format!("{:?}", &pro.cmd), &pro.name,
                                  pro.cpu_usage, pro.memory);
        }

        left_tree.set_model(Some(&list_store));
        left_tree.set_headers_visible(true);
        //let filter = gtk::TreeModelFilter::new(&list_store, None);
        scroll.add(&left_tree);
        let vertical_layout = gtk::Box::new(gtk::Orientation::Vertical, 0);
        let horizontal_layout = gtk::Grid::new();
        /*let list_store1 = list_store.clone();

        filter.set_modify_func(|_, iter, value| {
            list_store1.get_value(&iter, 4).get::<String>().unwrap()
                       .contains(value.get::<String>().unwrap().to_lowercase())
        });*/

        left_tree.connect_cursor_changed(move |tree_view| {
            let selection = tree_view.get_selection();
            let (pid, ret) = if let Some((model, iter)) = selection.get_selected() {
                if let Some(x) = model.get_value(&iter, 0).get() {
                    (Some(x), true)
                } else {
                    (None, false)
                }
            } else {
                (None, false)
            };
            current_pid1.set(pid);
            kill_button1.set_sensitive(ret);
            info_button1.set_sensitive(ret);
        });
        kill_button.set_sensitive(false);
        info_button.set_sensitive(false);

        vertical_layout.pack_start(&scroll, true, true, 0);
        horizontal_layout.attach(&info_button, 0, 0, 2, 1);
        horizontal_layout.attach_next_to(&kill_button, Some(&info_button),
                                         gtk::PositionType::Right, 2, 1);
        horizontal_layout.set_column_homogeneous(true);
        vertical_layout.pack_start(&horizontal_layout, false, true, 0);

        let vertical_layout : Widget = vertical_layout.upcast();
        note.create_tab("Process list", &vertical_layout);

        Procs {
            left_tree: left_tree,
            scroll: scroll,
            current_pid: current_pid,
            kill_button: kill_button,
            info_button: info_button,
            vertical_layout: vertical_layout.downcast::<gtk::Box>().unwrap(),
            list_store: list_store,
            columns: columns,
        }
    }
}

fn append_column(title: &str, v: &mut Vec<gtk::TreeViewColumn>, left_tree: &gtk::TreeView) {
    let id = v.len() as i32;
    let renderer = gtk::CellRendererText::new();

    let column = gtk::TreeViewColumn::new();
    column.set_title(title);
    column.set_resizable(true);
    column.pack_start(&renderer, true);
    column.add_attribute(&renderer, "text", id);
    column.set_clickable(true);
    column.set_sort_column_id(id);
    left_tree.append_column(&column);
    v.push(column);
}

pub fn create_and_fill_model(list_store: &gtk::ListStore, pid: i32, cmdline: &str, name: &str,
                             cpu: f32, memory: u64) {
    if cmdline.len() < 1 {
        return;
    }
    list_store.insert_with_values(None,
                                  &[0, 1, 2, 3, 4, 5],
                                  &[&pid,
                                    &name,
                                    &format!("{:.1}", cpu),
                                    &memory,
                                    &name.to_lowercase(),
                                    &cpu
                                   ]);
}
<|endoftext|>


<commit_before>use clap;
use info::discovery_service_info;
use select::{read_only_environment, select_collection, writable_environment};
use serde_json::ser::to_string_pretty;
use wdsapi::common::{Credentials, QueryParams};
use wdsapi::query;

fn query_params(matches: &clap::ArgMatches,
                default_count: &str)
                -> QueryParams {
    QueryParams {
        filter: matches.value_of("filter").map(|s| s.to_string()),
        query: matches.value_of("query").map(|s| s.to_string()),
        natural_language_query: matches.value_of("natural_language_query")
                                       .map(|s| s.to_string()),
        passages: Some(matches.is_present("oldest")),
        aggregation: matches.value_of("aggregation").map(|s| s.to_string()),
        count: matches.value_of("count")
                      .unwrap_or(default_count)
                      .parse::<u64>()
                      .unwrap(),
        return_hierarchy: matches.value_of("return_hierarchy")
                                 .map(|s| s.to_string()),
        offset: matches.value_of("offset").map(|s| s.parse::<u64>().unwrap()),
        sort: matches.value_of("sort").map(|s| s.to_string()),
    }
}

pub fn query(creds: Credentials, matches: &clap::ArgMatches) {
    let info = discovery_service_info(creds);
    let env_info = if matches.is_present("read-only") {
        read_only_environment(&info)
    } else {
        writable_environment(&info)
    };
    let collection = select_collection(&env_info, matches);
    let env_id = env_info.environment_id;
    let params = query_params(matches, "1");

    match query::query(&info.creds,
                       &env_id,
                       collection["collection_id"].as_str().unwrap(),
                       params) {
        Ok(response) => {
            println!("{}",
                     to_string_pretty(&response)
                         .expect("Internal error: failed to format \
                                  query::query response"))
        }
        Err(e) => println!("Failed to lookup collection {}", e),
    }
}

pub fn notices(creds: Credentials, matches: &clap::ArgMatches) {
    let info = discovery_service_info(creds);
    let env_info = writable_environment(&info);
    let collection = select_collection(&env_info, matches);
    let env_id = env_info.environment_id;
    let params = query_params(matches, "10");

    match query::notices(&info.creds,
                         &env_id,
                         collection["collection_id"].as_str().unwrap(),
                         params) {
        Ok(response) => {
            println!("{}",
                     to_string_pretty(&response)
                         .expect("Internal error: failed to format \
                                  query::notices response"))
        }
        Err(e) => println!("Failed to lookup collection {}", e),
    }
}
<commit_msg>Bug fix for query --passages<commit_after>use clap;
use info::discovery_service_info;
use select::{read_only_environment, select_collection, writable_environment};
use serde_json::ser::to_string_pretty;
use wdsapi::common::{Credentials, QueryParams};
use wdsapi::query;

fn query_params(matches: &clap::ArgMatches,
                default_count: &str)
                -> QueryParams {
    QueryParams {
        filter: matches.value_of("filter").map(|s| s.to_string()),
        query: matches.value_of("query").map(|s| s.to_string()),
        natural_language_query: matches.value_of("natural_language_query")
                                       .map(|s| s.to_string()),
        passages: Some(matches.is_present("passages")),
        aggregation: matches.value_of("aggregation").map(|s| s.to_string()),
        count: matches.value_of("count")
                      .unwrap_or(default_count)
                      .parse::<u64>()
                      .unwrap(),
        return_hierarchy: matches.value_of("return_hierarchy")
                                 .map(|s| s.to_string()),
        offset: matches.value_of("offset").map(|s| s.parse::<u64>().unwrap()),
        sort: matches.value_of("sort").map(|s| s.to_string()),
    }
}

pub fn query(creds: Credentials, matches: &clap::ArgMatches) {
    let info = discovery_service_info(creds);
    let env_info = if matches.is_present("read-only") {
        read_only_environment(&info)
    } else {
        writable_environment(&info)
    };
    let collection = select_collection(&env_info, matches);
    let env_id = env_info.environment_id;
    let params = query_params(matches, "1");

    match query::query(&info.creds,
                       &env_id,
                       collection["collection_id"].as_str().unwrap(),
                       params) {
        Ok(response) => {
            println!("{}",
                     to_string_pretty(&response)
                         .expect("Internal error: failed to format \
                                  query::query response"))
        }
        Err(e) => println!("Failed to lookup collection {}", e),
    }
}

pub fn notices(creds: Credentials, matches: &clap::ArgMatches) {
    let info = discovery_service_info(creds);
    let env_info = writable_environment(&info);
    let collection = select_collection(&env_info, matches);
    let env_id = env_info.environment_id;
    let params = query_params(matches, "10");

    match query::notices(&info.creds,
                         &env_id,
                         collection["collection_id"].as_str().unwrap(),
                         params) {
        Ok(response) => {
            println!("{}",
                     to_string_pretty(&response)
                         .expect("Internal error: failed to format \
                                  query::notices response"))
        }
        Err(e) => println!("Failed to lookup collection {}", e),
    }
}
<|endoftext|>


<commit_before>#![crate_id = "rustyredis#0.1"]
#![desc = "A Rust client library for Redis based off hiredis"]
#![crate_type = "lib"]

use std::io::net::tcp::TcpStream;

enum Global {
  RedisReaderMaxBuf = 1024 * 16
}

struct RedisReadTask {
  kind: int,
  elm: int,
  idx: int,
  obj: String, // this prob isn't right
}

struct RedisReader {
  err: int,
  errstr: String,
  buf: String,
  reply: String,
  pos: int,
  len: int,
  maxbuf: Global,

  rstack: [RedisReadTask, ..9],
  ridx: int
}

pub struct RedisContext {
  err: int,
  errstr: String,
  tcpstream: TcpStream,
  flags: int,
  obuf: String,
  reader: RedisReader
}

impl RedisReadTask {
  fn new() -> RedisReadTask {
    RedisReadTask {
      kind: -1,
      elm: -1,
      idx: -1,
      obj: String::new(),
    }
  }
}

impl RedisReader {

  fn process_item(&self) ->Result<(), String> {
    unimplemented!();
  }

  fn process_reply(&mut self) -> Result<(), String> {
    if self.len == 0 {
      return Ok(())
    }

    if self.ridx == -1 {
      self.ridx = 0;
    }

    while self.ridx >= 0 {
      try!(self.process_item());
    }

    Ok(())
  }

  //fn get_reply(&mut self) -> Option<String> {
  //  Some(self.reply)
  //}

  fn feed(&mut self, buf: &mut [u8], len: uint){
    let mut i = 0;
    while i < len {
      let c = buf[i].to_ascii();
      self.buf.push_char(c.to_char());
      i = i + 1;
    }
    println!("{}", self.buf);
  }

  fn new() -> RedisReader {
    RedisReader {
      err: 0,
      errstr: String::new(),
      buf: String::new(),
      reply: String::new(),
      pos: 0,
      len: 0,
      maxbuf: RedisReaderMaxBuf,
      rstack: [RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new()],
      ridx: -1
    }
  }
}

impl RedisContext {
  fn format_command(&self, format: &str) -> String {
    let mut argc: uint = 0;
    let mut c = String::new();
    let mut finalc = String::new();

    for arg in format.split(' '){
      let arglen = arg.len();
      c = c.append("$");
      c = c.append(arglen.to_str().as_slice());
      c = c.append("\r\n");
      c = c.append(arg);
      c = c.append("\r\n");
      argc = argc + 1;
    }
    finalc = finalc.append("*");
    finalc = finalc.append(argc.to_str().as_slice());
    finalc = finalc.append("\r\n");
    finalc = finalc.append(c.as_slice());
    finalc
  }

  fn set_error(&mut self, err: int, errstr: &str){
    self.err = err;
    self.errstr = errstr.to_str();
  }

  fn get_reply_reader(&mut self) -> Result<Option<String>, String> {
    //self.reader.get_reply();
    Err("ERR".to_str())
  }

  fn buffer_write(&mut self) -> int {
    println!("{}", self.obuf);
    match self.tcpstream.write_str(self.obuf.as_slice()){
      Err(e) => { self.set_error(1, e.desc ); 1 }
      _ => 0
    }
  }

  fn buffer_read(&mut self) -> int {
    let mut buf = [0, ..RedisReaderMaxBuf as uint];
    let res = self.tcpstream.read(buf);
    match res {
      Ok(s) => { self.reader.feed(buf, s); 0 },
      Err(e) => { self.set_error(1, e.desc); 1 }
    }

  }

  fn block_for_reply(&mut self) -> Result<Option<String>, String> {
    let o = try!(self.get_reply_reader());
    match o {
      Some(s) => Ok(Some(s)),
      None => {
        self.buffer_write();
        self.buffer_read();
        let o2 = try!(self.get_reply_reader());
        match o2{
          Some(s) => Ok(Some(s)),
          None => Err("Error".to_str())
        }
      }
    }
  }

  pub fn connect(ip: &str, port: u16) -> RedisContext {
    RedisContext {
      err: 0,
      errstr: String::new(),
      tcpstream: match TcpStream::connect(ip, port) {
        Ok(s) => s,
        Err(e) => fail!(e.desc)
      },
      flags: 0,
      obuf: String::new(),
      reader: RedisReader::new()
    }
  }

  pub fn command(&mut self, command: &str) -> Result<Option<String>, String> {
    self.obuf = self.format_command(command);
    let r = try!(self.block_for_reply());

    match r {
      Some(s) => { println!("{}", s); Ok(Some(s)) }
      None => { println!("Error!"); Err("Error".to_str()) }
    }
  }
}

<commit_msg>building sanity<commit_after>#![crate_id = "rustyredis#0.1"]
#![desc = "A Rust client library for Redis based off hiredis"]
#![crate_type = "lib"]

use std::io::net::tcp::TcpStream;

enum Global {
  RedisReaderMaxBuf = 1024 * 16
}

#[deriving(Clone)]
pub enum RedisReply {
  RedisString(String),
  RedisInteger(int),
  RedisNil,
  RedisStatus(String),
  RedisError(String)
}

enum RedisError {
  RedisNoError,
  RedisIoError,
  RedisProcessError
}

struct RedisReadTask {
  kind: int,
  elm: int,
  idx: int,
  obj: String, // this prob isn't right
}

struct RedisReader {
  err: RedisError,
  errstr: String,
  buf: String,
  reply: RedisReply,
  pos: int,
  len: int,
  rstack: [RedisReadTask, ..9],
  ridx: int
}

pub struct RedisContext {
  err: RedisError,
  errstr: String,
  tcpstream: TcpStream,
  flags: int,
  obuf: String,
  reader: RedisReader
}

impl RedisReadTask {
  fn new() -> RedisReadTask {
    RedisReadTask {
      kind: -1,
      elm: -1,
      idx: -1,
      obj: String::new(),
    }
  }
}

impl RedisReader {
  fn process_item(&self) -> Result<(), String> {
    unimplemented!();
  }

  fn process_reply(&mut self) -> Result<Option<RedisReply>, String> {
    if self.len == 0 {
      return Ok(Some(RedisNil))
    }

    if self.ridx == -1 {
      self.ridx = 0;
    }

    while self.ridx >= 0 {
      match self.process_item(){
        Err(s) => { self.set_error(RedisProcessError, s.as_slice()); return Err(s) },
        _ => ()
      }
    }

    Ok(Some(self.reply.clone()))
  }

  fn feed(&mut self, buf: &mut [u8], len: uint){
    let mut i = 0;
    while i < len {
      let c = buf[i].to_ascii();
      self.buf.push_char(c.to_char());
      i = i + 1;
    }
    println!("{}", self.buf);
  }

  fn set_error(&mut self, err: RedisError, errstr: &str){
    self.err = err;
    self.errstr = errstr.to_str();
  }

  fn new() -> RedisReader {
    RedisReader {
      err: RedisNoError,
      errstr: String::new(),
      buf: String::new(),
      reply: RedisNil,
      pos: 0,
      len: 0,
      rstack: [RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new(),
               RedisReadTask::new()],
      ridx: -1
    }
  }
}

impl RedisContext {
  fn format_command(&self, format: &str) -> String {
    let mut argc: uint = 0;
    let mut c = String::new();
    let mut finalc = String::new();

    for arg in format.split(' '){
      let arglen = arg.len();
      c = c.append("$");
      c = c.append(arglen.to_str().as_slice());
      c = c.append("\r\n");
      c = c.append(arg);
      c = c.append("\r\n");
      argc = argc + 1;
    }
    finalc = finalc.append("*");
    finalc = finalc.append(argc.to_str().as_slice());
    finalc = finalc.append("\r\n");
    finalc = finalc.append(c.as_slice());
    finalc
  }

  fn set_error(&mut self, err: RedisError, errstr: &str){
    self.err = err;
    self.errstr = errstr.to_str();
  }

  fn get_reply_reader(&mut self) -> Result<Option<RedisReply>, String> {
    self.reader.process_reply()
  }

  fn buffer_write(&mut self) -> int {
    println!("{}", self.obuf);
    match self.tcpstream.write_str(self.obuf.as_slice()){
      Err(e) => { self.set_error(RedisIoError, e.desc ); 1 }
      _ => 0
    }
  }

  fn buffer_read(&mut self) -> int {
    let mut buf = [0, ..RedisReaderMaxBuf as uint];
    let res = self.tcpstream.read(buf);
    match res {
      Ok(s) => { self.reader.feed(buf, s); 0 },
      Err(e) => { self.set_error(RedisIoError, e.desc); 1 }
    }

  }

  fn block_for_reply(&mut self) -> Result<Option<RedisReply>, String> {
    let o = try!(self.get_reply_reader());
    match o {
      Some(s) => Ok(Some(s)),
      None => {
        self.buffer_write();
        self.buffer_read();
        let o2 = try!(self.get_reply_reader());
        match o2{
          Some(s) => Ok(Some(s)),
          None => Err("Error".to_str())
        }
      }
    }
  }

  pub fn connect(ip: &str, port: u16) -> RedisContext {
    RedisContext {
      err: RedisNoError,
      errstr: String::new(),
      tcpstream: match TcpStream::connect(ip, port) {
        Ok(s) => s,
        Err(e) => fail!(e.desc)
      },
      flags: 0,
      obuf: String::new(),
      reader: RedisReader::new()
    }
  }

  pub fn command(&mut self, command: &str) -> Result<Option<RedisReply>, String> {
    self.obuf = self.format_command(command);
    self.block_for_reply()
  }
}

<|endoftext|>


<commit_before>//! Defines the scene struct which contains the various objects defining the scene.
//! This includes the geometry, instances of the geometry, the camera and so on.

use std::sync::Arc;

use linalg::{Transform, Point, Vector, Ray};
use film::{Camera, Colorf};
use geometry::{Sphere, Plane, Instance};
use material::{Matte, SpecularMetal, Material};
use geometry::{Geometry, Intersection};
use integrator::{Whitted, Integrator};
use light;
use light::Light;

/// The scene containing the objects and camera configuration we'd like to render,
/// shared immutably among the ray tracing threads
pub struct Scene {
    pub camera: Arc<Camera>,
    /// TODO: Only one instance for now
    pub instances: Arc<Vec<Instance>>,
    pub integrator: Arc<Box<Integrator + Send + Sync>>,
    /// TODO: Only one light for now
    pub light: Arc<Box<Light + Send + Sync>>,
    sphere: Arc<Box<Geometry + Send + Sync>>,
}

impl Scene {
    /// Create our (currently) hard-coded scene, passing in the render target
    /// dimensions so we can set the projection matrix for the camera
    pub fn new(w: usize, h: usize) -> Scene {
        let sphere = Arc::new(Box::new(Sphere::new(2.0)) as Box<Geometry + Send + Sync>);
        let plane = Arc::new(Box::new(Plane) as Box<Geometry + Send + Sync>);
        let white_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 1.0, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let red_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 0.2, 0.2), 1.0)) as Box<Material + Send + Sync>);
        let blue_wall = Arc::new(Box::new(Matte::new(&Colorf::new(0.2, 0.2, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let instances = vec![
            // The reflective sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(SpecularMetal::new(&Colorf::new(0.155, 0.116, 0.138),
                                                 &Colorf::new(4.828, 3.122, 2.146)))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(-3.0, -4.0, 6.0))),
            // The blue matte sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(Matte::new(&Colorf::new(0.0, 0.0, 1.0), 0.8))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(3.0, -4.0, 3.0))),
            // The back wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 0.0, 10.0))
                          * Transform::scale(&Vector::broadcast(20.0))),
            // The left wall
            Instance::new(plane.clone(), red_wall.clone(), Transform::translate(&Vector::new(-6.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_y(90.0)),
            // The right wall
            Instance::new(plane.clone(), blue_wall.clone(), Transform::translate(&Vector::new(6.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_y(-90.0)),
            // The top wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 6.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_x(90.0)),
            // The bottom wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, -6.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_x(-90.0))
        ];
        Scene {
            camera: Arc::new(Camera::new(Transform::look_at(&Point::new(0.0, 0.0, -16.0),
                &Point::new(0.0, 0.0, 0.0), &Vector::new(0.0, 1.0, 0.0)), 40.0, (w, h))),
            instances: Arc::new(instances),
            integrator: Arc::new(Box::new(Whitted::new(8)) as Box<Integrator + Send + Sync>),
            light: Arc::new(Box::new(light::Point::new(&Point::new(0.0, 5.0, 4.5), &Colorf::broadcast(40.0)))
                            as Box<Light + Send + Sync>),
            sphere: sphere.clone(),
        }
    }
    /// Test the ray for intersections against the objects in the scene.
    /// Returns Some(Intersection) if an intersection was found and None if not.
    pub fn intersect(&self, ray: &mut Ray) -> Option<Intersection> {
        // We can always return the next hit found since the ray's max_t value is updated
        // after an intersection is found. Thus if we find another hit we know that one
        // occured before any previous ones. TODO: Replace with a BVH
        self.instances.iter().fold(None, |p, ref i|
                                    match i.intersect(ray) {
                                        Some(h) => Some(h),
                                        None => p,
                                    })
    }
}

<commit_msg>Make the closer sphere glass. It's all sorts of wrong though<commit_after>//! Defines the scene struct which contains the various objects defining the scene.
//! This includes the geometry, instances of the geometry, the camera and so on.

use std::sync::Arc;

use linalg::{Transform, Point, Vector, Ray};
use film::{Camera, Colorf};
use geometry::{Sphere, Plane, Instance};
use material::{Matte, SpecularMetal, Glass, Material};
use geometry::{Geometry, Intersection};
use integrator::{Whitted, Integrator};
use light;
use light::Light;

/// The scene containing the objects and camera configuration we'd like to render,
/// shared immutably among the ray tracing threads
pub struct Scene {
    pub camera: Arc<Camera>,
    /// TODO: Only one instance for now
    pub instances: Arc<Vec<Instance>>,
    pub integrator: Arc<Box<Integrator + Send + Sync>>,
    /// TODO: Only one light for now
    pub light: Arc<Box<Light + Send + Sync>>,
    sphere: Arc<Box<Geometry + Send + Sync>>,
}

impl Scene {
    /// Create our (currently) hard-coded scene, passing in the render target
    /// dimensions so we can set the projection matrix for the camera
    pub fn new(w: usize, h: usize) -> Scene {
        let sphere = Arc::new(Box::new(Sphere::new(2.0)) as Box<Geometry + Send + Sync>);
        let plane = Arc::new(Box::new(Plane) as Box<Geometry + Send + Sync>);
        let white_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 1.0, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let red_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 0.2, 0.2), 1.0)) as Box<Material + Send + Sync>);
        let blue_wall = Arc::new(Box::new(Matte::new(&Colorf::new(0.2, 0.2, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let instances = vec![
            // The reflective sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(SpecularMetal::new(&Colorf::new(0.155, 0.116, 0.138),
                                                 &Colorf::new(4.828, 3.122, 2.146)))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(-3.0, -4.0, 6.0))),
            // The blue matte sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(Glass::new(&Colorf::broadcast(1.0), &Colorf::broadcast(1.0), 1.52))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(3.0, -4.0, 3.0))),
            // The back wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 0.0, 10.0))
                          * Transform::scale(&Vector::broadcast(20.0))),
            // The left wall
            Instance::new(plane.clone(), red_wall.clone(), Transform::translate(&Vector::new(-6.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_y(90.0)),
            // The right wall
            Instance::new(plane.clone(), blue_wall.clone(), Transform::translate(&Vector::new(6.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_y(-90.0)),
            // The top wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 6.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_x(90.0)),
            // The bottom wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, -6.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_x(-90.0))
        ];
        Scene {
            camera: Arc::new(Camera::new(Transform::look_at(&Point::new(0.0, 0.0, -16.0),
                &Point::new(0.0, 0.0, 0.0), &Vector::new(0.0, 1.0, 0.0)), 40.0, (w, h))),
            instances: Arc::new(instances),
            integrator: Arc::new(Box::new(Whitted::new(8)) as Box<Integrator + Send + Sync>),
            light: Arc::new(Box::new(light::Point::new(&Point::new(0.0, 5.0, 4.5), &Colorf::broadcast(40.0)))
                            as Box<Light + Send + Sync>),
            sphere: sphere.clone(),
        }
    }
    /// Test the ray for intersections against the objects in the scene.
    /// Returns Some(Intersection) if an intersection was found and None if not.
    pub fn intersect(&self, ray: &mut Ray) -> Option<Intersection> {
        // We can always return the next hit found since the ray's max_t value is updated
        // after an intersection is found. Thus if we find another hit we know that one
        // occured before any previous ones. TODO: Replace with a BVH
        self.instances.iter().fold(None, |p, ref i|
                                    match i.intersect(ray) {
                                        Some(h) => Some(h),
                                        None => p,
                                    })
    }
}

<|endoftext|>


<commit_before>use std::vec;

#[deriving(Eq)]
pub enum Move {
    Up,
    Down,
    Left,
    Right
}

struct Snake {
    priv x            : uint,
    priv y            : uint,
    priv tail         : ~[Move],
    priv current_move : Move,
    priv next_move    : Move,
    priv move_delay   : f32,
    priv wait_time    : f32,
    score             : uint,
    dead              : bool
}

impl Snake {
    /// Initialise a snake with 3 segments starting with a specified start
    /// direction and speed
    pub fn init(x: uint, y: uint, start_dir: Move, move_delay: f32) -> Snake {
        Snake {
            x            : x,
            y            : y,
            tail         : box [start_dir, start_dir, start_dir],
            current_move : start_dir,
            next_move    : start_dir,
            move_delay   : move_delay,
            wait_time    : 0.,
            score        : 10,
            dead         : false
        }
    }

    /// Initialise a snake with 3 segments with default speed and direction
    pub fn init_with_defaults(x: uint, y: uint) -> Snake {
        Snake::init(x, y, RIGHT, 0.05)
    }

    /// Add a new segment to the end of the snake
    pub fn add_segment(&mut self) {
        let dir = *self.tail.last();
        self.tail.push(dir);
    }

    /// Update the snake's position based on the amount of time elapsed since
    /// the last update.
    pub fn update(&mut self, elapsed_time: f32) {
        self.wait_time += elapsed_time;
        if (self.wait_time >= self.move_delay) {
            self.wait_time -= self.move_delay;

            // Move the head based on the direction
            match self.next_move {
                Up    => self.y -= 1,
                Down  => self.y += 1,
                Left  => self.x -= 1,
                Right => self.x += 1
            }

            // Move the rest of the components
            for i in range(1, self.tail.len()).invert() {
                self.tail[i] = self.tail[i-1];
            }
            self.tail[0] = self.next_move;

            self.current_move = self.next_move;
        }
    }

    /// Checks for colision with the map edges and any obstacles in the map.
    /// # Arguments
    /// `map_width` the width of the map.
    /// `map_height` the height of the map.
    /// `walls` a vector of obstacles in the map.
    ///
    /// # Return
    /// `true` if the snake hits anything, `false` otherwise.
    pub fn check_collision(&self, map_width: uint, map_height: uint,
            walls: &[[uint,..2]]) -> bool
    {
        // Check map bounds
        if (self.x < 0 || self.y < 0 ||
                self.x >= map_width || self.y >= map_height)
        {
            return true;
        }

        // Check obstacles
        for wall in walls.iter() {
            if (self.x == wall[0] && self.y == wall[1]) {
                return true;
            }
        }

        return false;
    }

    /// Get the position of the snake's head.
    pub fn get_head(&self) -> [uint,..2] {
        [self.x, self.y]
    }

    /// Sets the snake's next move, if possible
    pub fn set_move(&mut self, next_move: Move) {
        match next_move {
            Up    => if self.current_move != Down  { self.next_move = Up;    },
            Down  => if self.current_move != Up    { self.next_move = Down;  },
            Left  => if self.current_move != Right { self.next_move = Left;  },
            Right => if self.current_move != Left  { self.next_move = Right; }
        }
    }

    /// Converts the tail of the snake to a vector of points.
    pub fn tail_to_points(&self) -> ~[[uint,..2]] {
        let mut acc = vec::with_capacity(self.tail.len());

        /* Note: segment directions point to the position of the next block, not
         * the position of next block to the segment. */
        let mut next = [self.x, self.y];
        for segment in self.tail.iter() {
            next =
                match *segment {
                    Up    => [next[0], next[1] + 1],
                    Down  => [next[0], next[1] - 1],
                    Left  => [next[0] + 1, next[1]],
                    Right => [next[0] - 1, next[1]]
                };
            acc.push(next);
        }
        return acc;
    }
}
<commit_msg>Add simple unit tests<commit_after>use std::vec;

#[deriving(Eq)]
pub enum Move {
    Up,
    Down,
    Left,
    Right
}

struct Snake {
    priv x            : uint,
    priv y            : uint,
    priv tail         : ~[Move],
    priv current_move : Move,
    priv next_move    : Move,
    priv move_delay   : f32,
    priv wait_time    : f32,
    score             : uint,
    dead              : bool
}

impl Snake {
    /// Initialise a snake with 3 segments starting with a specified start
    /// direction and speed
    pub fn init(x: uint, y: uint, start_dir: Move, move_delay: f32) -> Snake {
        Snake {
            x            : x,
            y            : y,
            tail         : box [start_dir, start_dir, start_dir],
            current_move : start_dir,
            next_move    : start_dir,
            move_delay   : move_delay,
            wait_time    : 0.,
            score        : 10,
            dead         : false
        }
    }

    /// Initialise a snake with 3 segments with default speed and direction
    pub fn init_with_defaults(x: uint, y: uint) -> Snake {
        Snake::init(x, y, RIGHT, 0.05)
    }

    /// Add a new segment to the end of the snake
    pub fn add_segment(&mut self) {
        let dir = *self.tail.last();
        self.tail.push(dir);
    }

    /// Update the snake's position based on the amount of time elapsed since
    /// the last update.
    pub fn update(&mut self, elapsed_time: f32) {
        self.wait_time += elapsed_time;
        if (self.wait_time >= self.move_delay) {
            self.wait_time -= self.move_delay;

            // Move the head based on the direction
            match self.next_move {
                Up    => self.y -= 1,
                Down  => self.y += 1,
                Left  => self.x -= 1,
                Right => self.x += 1
            }

            // Move the rest of the components
            for i in range(1, self.tail.len()).invert() {
                self.tail[i] = self.tail[i-1];
            }
            self.tail[0] = self.next_move;

            self.current_move = self.next_move;
        }
    }

    /// Checks for colision with the map edges and any obstacles in the map.
    /// # Arguments
    /// `map_width` the width of the map.
    /// `map_height` the height of the map.
    /// `walls` a vector of obstacles in the map.
    ///
    /// # Return
    /// `true` if the snake hits anything, `false` otherwise.
    pub fn check_collision(&self, map_width: uint, map_height: uint,
            walls: &[[uint,..2]]) -> bool
    {
        // Check map bounds
        if (self.x < 0 || self.y < 0 ||
                self.x >= map_width || self.y >= map_height)
        {
            return true;
        }

        // Check obstacles
        for wall in walls.iter() {
            if (self.x == wall[0] && self.y == wall[1]) {
                return true;
            }
        }

        return false;
    }

    /// Get the position of the snake's head.
    pub fn get_head(&self) -> [uint,..2] {
        [self.x, self.y]
    }

    /// Sets the snake's next move, if possible
    pub fn set_move(&mut self, next_move: Move) {
        match next_move {
            Up    => if self.current_move != Down  { self.next_move = Up;    },
            Down  => if self.current_move != Up    { self.next_move = Down;  },
            Left  => if self.current_move != Right { self.next_move = Left;  },
            Right => if self.current_move != Left  { self.next_move = Right; }
        }
    }

    /// Converts the tail of the snake to a vector of points.
    pub fn tail_to_points(&self) -> ~[[uint,..2]] {
        let mut acc = vec::with_capacity(self.tail.len());

        /* Note: segment directions point to the position of the next block, not
         * the position of next block to the segment. */
        let mut next = [self.x, self.y];
        for segment in self.tail.iter() {
            next =
                match *segment {
                    Up    => [next[0], next[1] + 1],
                    Down  => [next[0], next[1] - 1],
                    Left  => [next[0] + 1, next[1]],
                    Right => [next[0] - 1, next[1]]
                };
            acc.push(next);
        }
        return acc;
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_tail_to_points() {
        let snake = init(10, 10, RIGHT, 0.05);
        assert_eq!(snake.tail_to_points(), ~[[9, 10], [8, 10], [7,10]])
    }

    #[test]
    fn test_get_head() {
        let snake = init(10, 10, RIGHT, 0.05);
        assert_eq!(snake.get_head(), [10, 10]);
    }

    #[test]
    fn test_update_same_direction() {
        let mut snake = init(10, 10, RIGHT, 1.0);
        snake.update(1.0);
        assert_eq!(snake.get_head(), [11, 10]);
        assert_eq!(snake.tail_to_points(), ~[[10, 10], [9, 10], [8,10]]);
    }

    #[test]
    fn test_update_different_direction() {
        let mut snake = init(10, 10, RIGHT, 1.0);
        snake.set_move(DOWN);
        snake.update(1.0);
        assert_eq!(snake.get_head(), [10, 11]);
        assert_eq!(snake.tail_to_points(), ~[[10, 10], [9, 10], [8,10]]);
    }
}
<|endoftext|>


<commit_before>extern crate rand;

const ROWS: i8 = 9;
const COLS: i8 = 12;
const TILES: i8 = 108;
const PLAYERS: i8 = 4;

#[derive(RustcDecodable, RustcEncodable)]
pub struct Game {
    players: Vec<Player>,
    board: Board,
    turn: PlayerId,
    merge_decision: Option<PlayerId>
}

#[derive(RustcDecodable, RustcEncodable)]
struct Player {
    id: PlayerId,
    money: i32,
    shares: PlayerShares,
    tiles: Vec<Tile>
}

type PlayerId = i8;

#[derive(RustcDecodable, RustcEncodable)]
struct PlayerShares {
    luxor: i8,
    tower: i8,
    american: i8,
    festival: i8,
    worldwide: i8,
    continental: i8,
    imperial: i8
}

#[derive(RustcDecodable, RustcEncodable, Clone, Debug)]
struct Tile { row: i8, col: i8 }

#[derive(RustcDecodable, RustcEncodable)]
struct Board {
    slots: Vec<Slot>
}

#[derive(RustcDecodable, RustcEncodable)]
struct Slot {
    row: i8,
    col: i8,
    has_tile: bool,
    hotel: Option<Hotel>
}

enum Action {
    PlaceTile,
    HandleMergeStocks,
    BuyStocks,
    DrawTile,
    EndGame
}

pub struct PlaceTile {
    player: PlayerId,
    tile: Tile
}

pub struct HandleMergeStocks {
    hold: i8,
    sell: i8,
    trade: i8
}

type BuyStocks = PlayerShares;

#[derive(RustcDecodable, RustcEncodable)]
enum Hotel { Luxor, Tower, American, Festival, Worldwide, Continental, Imperial }

fn empty_shares() -> PlayerShares {
    PlayerShares { luxor: 0, tower: 0, american: 0, festival: 0, worldwide: 0, continental: 0, imperial: 0 }
}

fn new_player(id: PlayerId, tiles: Vec<Tile>) -> Player {
    Player { id: id, money: 6000, shares: empty_shares(), tiles: tiles }
}

fn choose_tiles(tiles: Vec<Tile>, count: usize) -> (Vec<Tile>, Vec<Tile>) {
    let mut remaining_tiles = tiles;
    let mut random_tiles = Vec::new();
    for _ in 0..count {
        let random_index = (rand::random::<i8>() as usize) % remaining_tiles.len();
        random_tiles.push(remaining_tiles.remove(random_index));
    }
    (random_tiles, remaining_tiles)
}

pub fn initial_state() -> Game {
    let mut slots: Vec<Slot> = (0..COLS)
        .flat_map(|col| {
            let rows = 0..ROWS;
            let res: Vec<Slot> = rows.map(|row| Slot { row: row, col: col, hotel: None, has_tile: false } ).collect();
            res
        }).collect();
    let tiles = (0..TILES).map(|i| Tile { row: i / COLS, col: i % ROWS }).collect();
    let (starting_tiles, remaining_tiles) = choose_tiles(tiles, PLAYERS as usize);
    let (tiles1, remaining_tiles1) = choose_tiles(remaining_tiles, 6 as usize);
    let (tiles2, remaining_tiles2) = choose_tiles(remaining_tiles1, 6 as usize);
    let (tiles3, remaining_tiles3) = choose_tiles(remaining_tiles2, 6 as usize);
    let (tiles4, _) = choose_tiles(remaining_tiles3, 6 as usize);
    let players = vec![
        new_player(1, tiles1),
        new_player(2, tiles2),
        new_player(3, tiles3),
        new_player(4, tiles4)];
    for tile in starting_tiles {
        let found_slot = slots.iter_mut().find(|slot| slot.row == tile.row && slot.col == tile.col);
        match found_slot {
            Some(slot) => {
                slot.has_tile = true;
            }
            None => panic!("No slot found!")
        }
    }
    Game {
        board: Board { slots: slots },
        players: players,
        turn: 1,
        merge_decision: None
    }
}

#[test]
fn players_start_with_six_tiles() {
    let state = initial_state();
    for player in state.players {
        assert_eq!(player.tiles.len(), 6);
    }
}

#[test]
fn players_start_with_6000_in_cash() {
    let state = initial_state();
    for player in state.players {
        assert_eq!(player.money, 6000);
    }
}

#[test]
fn players_start_with_zero_shares() {
    let state = initial_state();
    for player in state.players {
        assert_eq!(player.shares.luxor, 0);
        assert_eq!(player.shares.tower, 0);
        assert_eq!(player.shares.american, 0);
        assert_eq!(player.shares.festival, 0);
        assert_eq!(player.shares.worldwide, 0);
        assert_eq!(player.shares.continental, 0);
        assert_eq!(player.shares.imperial, 0);
    }
}

#[test]
fn game_starts_with_four_placed_tiles() {
    let state = initial_state();
    let board_tiles = state.board.slots.iter().filter(|s| s.has_tile).count();
    assert_eq!(board_tiles, 4)
}
<commit_msg>Clean up state handling<commit_after>extern crate rand;

const ROWS: u8 = 9;
const COLS: u8 = 12;
const TILES: u8 = 108;
const PLAYERS: u8 = 4;

#[derive(RustcDecodable, RustcEncodable)]
pub struct Game {
    players: Vec<Player>,
    board: Board,
    turn: PlayerId,
    merge_decision: Option<PlayerId>
}

#[derive(RustcDecodable, RustcEncodable)]
struct Player {
    id: PlayerId,
    money: i32,
    shares: PlayerShares,
    tiles: Vec<Tile>
}

type PlayerId = u8;

#[derive(RustcDecodable, RustcEncodable)]
struct PlayerShares {
    luxor: u8,
    tower: u8,
    american: u8,
    festival: u8,
    worldwide: u8,
    continental: u8,
    imperial: u8
}

#[derive(RustcDecodable, RustcEncodable, Clone, Debug)]
struct Tile { row: u8, col: u8 }

#[derive(RustcDecodable, RustcEncodable)]
struct Board {
    slots: Vec<Slot>
}

#[derive(RustcDecodable, RustcEncodable)]
struct Slot {
    row: u8,
    col: u8,
    has_tile: bool,
    hotel: Option<Hotel>
}

enum Action {
    PlaceTile,
    HandleMergeStocks,
    BuyStocks,
    DrawTile,
    EndGame
}

pub struct PlaceTile {
    player: PlayerId,
    tile: Tile
}

pub struct HandleMergeStocks {
    hold: u8,
    sell: u8,
    trade: u8
}

type BuyStocks = PlayerShares;

#[derive(RustcDecodable, RustcEncodable)]
enum Hotel { Luxor, Tower, American, Festival, Worldwide, Continental, Imperial }

fn empty_shares() -> PlayerShares {
    PlayerShares { luxor: 0, tower: 0, american: 0, festival: 0, worldwide: 0, continental: 0, imperial: 0 }
}

fn new_player(id: PlayerId, tiles: Vec<Tile>) -> Player {
    Player { id: id, money: 6000, shares: empty_shares(), tiles: tiles }
}

fn choose_tiles(tiles: Vec<Tile>, count: u8) -> (Vec<Tile>, Vec<Tile>) {
    let mut remaining_tiles = tiles;
    let mut random_tiles = Vec::new();
    for _ in 0..count {
        let random_index = (rand::random::<u8>() as usize) % remaining_tiles.len();
        random_tiles.push(remaining_tiles.remove(random_index));
    }
    (random_tiles, remaining_tiles)
}

fn new_players(tiles: Vec<Tile>) -> Vec<Player>{
    let init_players: Vec<Player> = Vec::new();
    let (players, _) = (0..PLAYERS)
        .fold( (init_players, tiles), | (mut v, remaining), i | {
            let (player_tiles, new_remaining) = choose_tiles(remaining, 6);
            let player = new_player(i, player_tiles);
            v.push(player);
            (v, new_remaining)
        });
    players
}

fn has_tile_on_slot(tiles: & Vec<Tile>, row: u8, col: u8) -> bool {
    tiles.iter().any(|t| t.row == row && t.col == col)
}

fn initial_slots(starting_tiles: Vec<Tile>) -> Vec<Slot> {
    let slots: Vec<Slot> = (0..COLS)
        .flat_map(|col| {
            let rows = 0..ROWS;
            let res: Vec<Slot> = rows.map(|row| {
                let has_tile = has_tile_on_slot(&starting_tiles, row, col);
                Slot { row: row, col: col, hotel: None, has_tile: has_tile }
            }).collect();
            res
        }).collect();
    slots
}

pub fn initial_state() -> Game {
    let all_tiles = (0..TILES).map(|i| Tile { row: i / COLS, col: i % ROWS }).collect();
    let (starting_tiles, remaining_tiles) = choose_tiles(all_tiles, PLAYERS);
    let players = new_players(remaining_tiles);
    let slots = initial_slots(starting_tiles);
    Game {
        board: Board { slots: slots },
        players: players,
        turn: 1,
        merge_decision: None
    }
}

#[test]
fn players_start_with_six_tiles() {
    let state = initial_state();
    for player in state.players {
        assert_eq!(player.tiles.len(), 6);
    }
}

#[test]
fn players_start_with_6000_in_cash() {
    let state = initial_state();
    for player in state.players {
        assert_eq!(player.money, 6000);
    }
}

#[test]
fn players_start_with_zero_shares() {
    let state = initial_state();
    for player in state.players {
        assert_eq!(player.shares.luxor, 0);
        assert_eq!(player.shares.tower, 0);
        assert_eq!(player.shares.american, 0);
        assert_eq!(player.shares.festival, 0);
        assert_eq!(player.shares.worldwide, 0);
        assert_eq!(player.shares.continental, 0);
        assert_eq!(player.shares.imperial, 0);
    }
}

#[test]
fn game_starts_with_four_placed_tiles() {
    let state = initial_state();
    let board_tiles = state.board.slots.iter().filter(|s| s.has_tile).count();
    assert_eq!(board_tiles, 4)
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::io;
use std::fs::File;

//use test::Bencher;

use blob::Blob;
use error::Error;
use value::Value;

#[test]
fn nbt_nonempty() {
    let mut nbt = Blob::new();
    nbt.insert("name", "Herobrine").unwrap();
    nbt.insert("health", 100i8).unwrap();
    nbt.insert("food", 20.0f32).unwrap();
    nbt.insert("emeralds", 12345i16).unwrap();
    nbt.insert("timestamp", 1424778774i32).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x08,
                0x00, 0x04,
                0x6e, 0x61, 0x6d, 0x65,
                0x00, 0x09,
                0x48, 0x65, 0x72, 0x6f, 0x62, 0x72, 0x69, 0x6e, 0x65,
            0x01,
                0x00, 0x06,
                0x68, 0x65, 0x61, 0x6c, 0x74, 0x68,
                0x64,
            0x05,
                0x00, 0x04,
                0x66, 0x6f, 0x6f, 0x64,
                0x41, 0xa0, 0x00, 0x00,
            0x02,
                0x00, 0x08,
                0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x64, 0x73,
                0x30, 0x39,
            0x03,
                0x00, 0x09,
                0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
                0x54, 0xec, 0x66, 0x16,
        0x00
    ];

    // Test correct length.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(bytes.len(), dst.len());

    // We can only test if the decoded bytes match, since the HashMap does
    // not guarantee order (and so encoding is likely to be different, but
    // still correct).
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_empty_nbtfile() {
    let nbt = Blob::new();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
        0x00
    ];

    // Test encoding.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(&dst, &bytes);

    // Test decoding.
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_nested_compound() {
    let mut inner = HashMap::new();
    inner.insert("test".to_string(), Value::Byte(123));
    let mut nbt = Blob::new();
    nbt.insert("inner", Value::Compound(inner)).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x0a,
                0x00, 0x05,
                0x69, 0x6e, 0x6e, 0x65, 0x72,
                0x01,
                0x00, 0x04,
                0x74, 0x65, 0x73, 0x74,
                0x7b,
            0x00,
        0x00
    ];

    // Test encoding.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(&dst, &bytes);

    // Test decoding.
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_empty_list() {
    let mut nbt = Blob::new();
    nbt.insert("list", Value::List(Vec::new())).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x09,
                0x00, 0x04,
                0x6c, 0x69, 0x73, 0x74,
                0x01,
                0x00, 0x00, 0x00, 0x00,
        0x00
    ];

    // Test encoding.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(&dst, &bytes);

    // Test decoding.
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_no_root() {
    let bytes = vec![0x00];
    // Will fail, because the root is not a compound.
    assert_eq!(Blob::from_reader(&mut io::Cursor::new(&bytes[..])),
            Err(Error::NoRootCompound));
}

#[test]
fn nbt_no_end_tag() {
    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x09,
                0x00, 0x04,
                0x6c, 0x69, 0x73, 0x74,
                0x01,
                0x00, 0x00, 0x00, 0x00
    ];

    // Will fail, because there is no end tag.
    assert_eq!(Blob::from_reader(&mut io::Cursor::new(&bytes[..])),
            Err(Error::IncompleteNbtValue));
}

#[test]
fn nbt_invalid_id() {
    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x0f, // No tag associated with 0x0f.
                0x00, 0x04,
                0x6c, 0x69, 0x73, 0x74,
                0x01,
        0x00
    ];
    assert_eq!(Blob::from_reader(&mut io::Cursor::new(&bytes[..])),
               Err(Error::InvalidTypeId(15)));
}

#[test]
fn nbt_invalid_list() {
    let mut nbt = Blob::new();
    let mut badlist = Vec::new();
    badlist.push(Value::Byte(1));
    badlist.push(Value::Short(1));
    // Will fail to insert, because the List is heterogeneous.
    assert_eq!(nbt.insert("list", Value::List(badlist)),
               Err(Error::HeterogeneousList));
}

#[test]
fn nbt_bad_compression() {
    // These aren't in the zlib or gzip format, so they'll fail.
    let bytes = vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
    assert!(Blob::from_gzip_reader(&mut io::Cursor::new(&bytes[..])).is_err());
    assert!(Blob::from_zlib_reader(&mut io::Cursor::new(&bytes[..])).is_err());
}

#[test]
fn nbt_compression() {
    // Create a non-trivial Blob.
    let mut nbt = Blob::new();
    nbt.insert("name", Value::String("Herobrine".to_string())).unwrap();
    nbt.insert("health", Value::Byte(100)).unwrap();
    nbt.insert("food", Value::Float(20.0)).unwrap();
    nbt.insert("emeralds", Value::Short(12345)).unwrap();
    nbt.insert("timestamp", Value::Int(1424778774)).unwrap();

    // Test zlib encoding/decoding.
    let mut zlib_dst = Vec::new();
    nbt.to_zlib_writer(&mut zlib_dst).unwrap();
    let zlib_file = Blob::from_zlib_reader(&mut io::Cursor::new(zlib_dst)).unwrap();
    assert_eq!(&nbt, &zlib_file);

    // Test gzip encoding/decoding.
    let mut gzip_dst = Vec::new();
    nbt.to_gzip_writer(&mut gzip_dst).unwrap();
    let gz_file = Blob::from_gzip_reader(&mut io::Cursor::new(gzip_dst)).unwrap();
    assert_eq!(&nbt, &gz_file);
}

#[test]
fn nbt_bigtest() {
    let mut bigtest_file = File::open("tests/big1.nbt").unwrap();
    let bigtest = Blob::from_gzip_reader(&mut bigtest_file).unwrap();
    // This is a pretty indirect way of testing correctness.
    let mut dst = Vec::new();
    bigtest.to_writer(&mut dst).unwrap();
    assert_eq!(1544, dst.len());
}

#[test]
fn nbt_arrays() {
    let mut arrays_file = File::open("tests/arrays.nbt").unwrap();
    let arrays = Blob::from_reader(&mut arrays_file).unwrap();
    match &arrays["ia"] {
        &Value::IntArray(ref arr) => assert_eq!(&[-2, -1, 0, 1, 2], &**arr),
        _ => panic!("ia was not TAG_IntArray"),
    }

    match &arrays["ba"] {
        &Value::ByteArray(ref arr) => assert_eq!(&[-2, -1, 0, 1, 2], &**arr),
        _ => panic!("ba was not TAG_ByteArray"),
    }

    match &arrays["la"] {
        &Value::LongArray(ref arr) => assert_eq!(&[-2, -1, 0, 1, 2], &**arr),
        _ => panic!("la was not TAG_LongArray"),
    }
}

//#[bench]
//fn nbt_bench_bigwrite(b: &mut Bencher) {
//    let mut file = File::open("tests/big1.nbt").unwrap();
//    let nbt = Blob::from_gzip(&mut file).unwrap();
//    b.iter(|| {
//        nbt.write(&mut io::sink())
//    });
//}

//#[bench]
//fn nbt_bench_smallwrite(b: &mut Bencher) {
//    let mut file = File::open("tests/small4.nbt").unwrap();
//    let nbt = Blob::from_reader(&mut file).unwrap();
//    b.iter(|| {
//        nbt.write(&mut io::sink())
//    });
//}
<commit_msg>Adds a roundtrip test for Blob (de)serialization using serde.<commit_after>use std::collections::HashMap;
use std::io;
use std::fs::File;

//use test::Bencher;

use blob::Blob;
use error::Error;
use value::Value;

#[test]
fn nbt_nonempty() {
    let mut nbt = Blob::new();
    nbt.insert("name", "Herobrine").unwrap();
    nbt.insert("health", 100i8).unwrap();
    nbt.insert("food", 20.0f32).unwrap();
    nbt.insert("emeralds", 12345i16).unwrap();
    nbt.insert("timestamp", 1424778774i32).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x08,
                0x00, 0x04,
                0x6e, 0x61, 0x6d, 0x65,
                0x00, 0x09,
                0x48, 0x65, 0x72, 0x6f, 0x62, 0x72, 0x69, 0x6e, 0x65,
            0x01,
                0x00, 0x06,
                0x68, 0x65, 0x61, 0x6c, 0x74, 0x68,
                0x64,
            0x05,
                0x00, 0x04,
                0x66, 0x6f, 0x6f, 0x64,
                0x41, 0xa0, 0x00, 0x00,
            0x02,
                0x00, 0x08,
                0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x64, 0x73,
                0x30, 0x39,
            0x03,
                0x00, 0x09,
                0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
                0x54, 0xec, 0x66, 0x16,
        0x00
    ];

    // Test correct length.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(bytes.len(), dst.len());

    // We can only test if the decoded bytes match, since the HashMap does
    // not guarantee order (and so encoding is likely to be different, but
    // still correct).
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_empty_nbtfile() {
    let nbt = Blob::new();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
        0x00
    ];

    // Test encoding.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(&dst, &bytes);

    // Test decoding.
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_nested_compound() {
    let mut inner = HashMap::new();
    inner.insert("test".to_string(), Value::Byte(123));
    let mut nbt = Blob::new();
    nbt.insert("inner", Value::Compound(inner)).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x0a,
                0x00, 0x05,
                0x69, 0x6e, 0x6e, 0x65, 0x72,
                0x01,
                0x00, 0x04,
                0x74, 0x65, 0x73, 0x74,
                0x7b,
            0x00,
        0x00
    ];

    // Test encoding.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(&dst, &bytes);

    // Test decoding.
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_empty_list() {
    let mut nbt = Blob::new();
    nbt.insert("list", Value::List(Vec::new())).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x09,
                0x00, 0x04,
                0x6c, 0x69, 0x73, 0x74,
                0x01,
                0x00, 0x00, 0x00, 0x00,
        0x00
    ];

    // Test encoding.
    let mut dst = Vec::new();
    nbt.to_writer(&mut dst).unwrap();
    assert_eq!(&dst, &bytes);

    // Test decoding.
    let mut src = io::Cursor::new(bytes);
    let file = Blob::from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
}

#[test]
fn nbt_no_root() {
    let bytes = vec![0x00];
    // Will fail, because the root is not a compound.
    assert_eq!(Blob::from_reader(&mut io::Cursor::new(&bytes[..])),
            Err(Error::NoRootCompound));
}

#[test]
fn nbt_no_end_tag() {
    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x09,
                0x00, 0x04,
                0x6c, 0x69, 0x73, 0x74,
                0x01,
                0x00, 0x00, 0x00, 0x00
    ];

    // Will fail, because there is no end tag.
    assert_eq!(Blob::from_reader(&mut io::Cursor::new(&bytes[..])),
            Err(Error::IncompleteNbtValue));
}

#[test]
fn nbt_invalid_id() {
    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x0f, // No tag associated with 0x0f.
                0x00, 0x04,
                0x6c, 0x69, 0x73, 0x74,
                0x01,
        0x00
    ];
    assert_eq!(Blob::from_reader(&mut io::Cursor::new(&bytes[..])),
               Err(Error::InvalidTypeId(15)));
}

#[test]
fn nbt_invalid_list() {
    let mut nbt = Blob::new();
    let mut badlist = Vec::new();
    badlist.push(Value::Byte(1));
    badlist.push(Value::Short(1));
    // Will fail to insert, because the List is heterogeneous.
    assert_eq!(nbt.insert("list", Value::List(badlist)),
               Err(Error::HeterogeneousList));
}

#[test]
fn nbt_bad_compression() {
    // These aren't in the zlib or gzip format, so they'll fail.
    let bytes = vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
    assert!(Blob::from_gzip_reader(&mut io::Cursor::new(&bytes[..])).is_err());
    assert!(Blob::from_zlib_reader(&mut io::Cursor::new(&bytes[..])).is_err());
}

#[test]
fn nbt_compression() {
    // Create a non-trivial Blob.
    let mut nbt = Blob::new();
    nbt.insert("name", Value::String("Herobrine".to_string())).unwrap();
    nbt.insert("health", Value::Byte(100)).unwrap();
    nbt.insert("food", Value::Float(20.0)).unwrap();
    nbt.insert("emeralds", Value::Short(12345)).unwrap();
    nbt.insert("timestamp", Value::Int(1424778774)).unwrap();

    // Test zlib encoding/decoding.
    let mut zlib_dst = Vec::new();
    nbt.to_zlib_writer(&mut zlib_dst).unwrap();
    let zlib_file = Blob::from_zlib_reader(&mut io::Cursor::new(zlib_dst)).unwrap();
    assert_eq!(&nbt, &zlib_file);

    // Test gzip encoding/decoding.
    let mut gzip_dst = Vec::new();
    nbt.to_gzip_writer(&mut gzip_dst).unwrap();
    let gz_file = Blob::from_gzip_reader(&mut io::Cursor::new(gzip_dst)).unwrap();
    assert_eq!(&nbt, &gz_file);
}

#[test]
fn nbt_bigtest() {
    let mut bigtest_file = File::open("tests/big1.nbt").unwrap();
    let bigtest = Blob::from_gzip_reader(&mut bigtest_file).unwrap();
    // This is a pretty indirect way of testing correctness.
    let mut dst = Vec::new();
    bigtest.to_writer(&mut dst).unwrap();
    assert_eq!(1544, dst.len());
}

#[test]
fn nbt_arrays() {
    let mut arrays_file = File::open("tests/arrays.nbt").unwrap();
    let arrays = Blob::from_reader(&mut arrays_file).unwrap();
    match &arrays["ia"] {
        &Value::IntArray(ref arr) => assert_eq!(&[-2, -1, 0, 1, 2], &**arr),
        _ => panic!("ia was not TAG_IntArray"),
    }

    match &arrays["ba"] {
        &Value::ByteArray(ref arr) => assert_eq!(&[-2, -1, 0, 1, 2], &**arr),
        _ => panic!("ba was not TAG_ByteArray"),
    }

    match &arrays["la"] {
        &Value::LongArray(ref arr) => assert_eq!(&[-2, -1, 0, 1, 2], &**arr),
        _ => panic!("la was not TAG_LongArray"),
    }
}

//#[bench]
//fn nbt_bench_bigwrite(b: &mut Bencher) {
//    let mut file = File::open("tests/big1.nbt").unwrap();
//    let nbt = Blob::from_gzip(&mut file).unwrap();
//    b.iter(|| {
//        nbt.write(&mut io::sink())
//    });
//}

//#[bench]
//fn nbt_bench_smallwrite(b: &mut Bencher) {
//    let mut file = File::open("tests/small4.nbt").unwrap();
//    let nbt = Blob::from_reader(&mut file).unwrap();
//    b.iter(|| {
//        nbt.write(&mut io::sink())
//    });
//}

#[test]
#[cfg(feature = "serde")]
fn serde_blob() {
    use de::from_reader;
    use ser::to_writer;

    let mut nbt = Blob::new();
    nbt.insert("name", "Herobrine").unwrap();
    nbt.insert("health", 100i8).unwrap();
    nbt.insert("food", 20.0f32).unwrap();
    nbt.insert("emeralds", 12345i16).unwrap();
    nbt.insert("timestamp", 1424778774i32).unwrap();

    let bytes = vec![
        0x0a,
            0x00, 0x00,
            0x08,
                0x00, 0x04,
                0x6e, 0x61, 0x6d, 0x65,
                0x00, 0x09,
                0x48, 0x65, 0x72, 0x6f, 0x62, 0x72, 0x69, 0x6e, 0x65,
            0x01,
                0x00, 0x06,
                0x68, 0x65, 0x61, 0x6c, 0x74, 0x68,
                0x64,
            0x05,
                0x00, 0x04,
                0x66, 0x6f, 0x6f, 0x64,
                0x41, 0xa0, 0x00, 0x00,
            0x02,
                0x00, 0x08,
                0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x64, 0x73,
                0x30, 0x39,
            0x03,
                0x00, 0x09,
                0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
                0x54, 0xec, 0x66, 0x16,
        0x00
    ];

    // Roundtrip.

    let mut src = io::Cursor::new(bytes.clone());
    let file: Blob = from_reader(&mut src).unwrap();
    assert_eq!(&file, &nbt);
    let mut dst = Vec::new();
    to_writer(&mut dst, &nbt, None).unwrap();
    // We can only test if the decoded bytes match, since the HashMap does
    // not guarantee order (and so encoding is likely to be different, but
    // still correct).
    assert_eq!(&bytes.len(), &dst.len());
}
<|endoftext|>


<commit_before>use traits::{AtEof,Compare,CompareResult,InputLength,InputIter,InputTake,Slice,FindSubstring,ParseTo};
use util::Offset;

use std::str::{self,FromStr,Chars,CharIndices};
use std::ops::{Range,RangeTo,RangeFrom,RangeFull};
use std::iter::Enumerate;
use std::slice::Iter;

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteStr<'a>(pub &'a str);

impl<'a> AtEof for CompleteStr<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteStr<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteStr<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteStr<'a> {
  type Item     = char;
  type RawItem  = char;
  type Iter     = CharIndices<'a>;
  type IterElem = Chars<'a>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteStr<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteStr(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteStr(s1), CompleteStr(s2)))
  }
}

impl<'a> InputLength for CompleteStr<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b str> for CompleteStr<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteStr<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteStr<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse().ok()
  }
}

impl<'a> Offset for CompleteStr<'a> {
  fn offset(&self, second:&CompleteStr<'a>) -> usize {
    self.0.offset(second.0)
  }
}

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteByteSlice<'a>(pub &'a [u8]);

impl<'a> AtEof for CompleteByteSlice<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteByteSlice<'a> {
  type Item     = &'a u8;
  type RawItem  = u8;
  type Iter     = Enumerate<Iter<'a, Self::RawItem>>;
  type IterElem = Iter<'a, Self::RawItem>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteByteSlice<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteByteSlice(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteByteSlice(s1), CompleteByteSlice(s2)))
  }
}

impl<'a> InputLength for CompleteByteSlice<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b [u8]> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> Compare<&'b str> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b [u8]> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b [u8]) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteByteSlice<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse_to()
  }
}

impl<'a> Offset for CompleteByteSlice<'a> {
  fn offset(&self, second:&CompleteByteSlice<'a>) -> usize {
    self.0.offset(second.0)
  }
}
<commit_msg>impl FindToken<Complete{Str,ByteSlice}> for u8<commit_after>use traits::{AtEof,Compare,CompareResult,InputLength,InputIter,InputTake,Slice,FindSubstring,FindToken,ParseTo};
use util::Offset;

use std::str::{self,FromStr,Chars,CharIndices};
use std::ops::{Range,RangeTo,RangeFrom,RangeFull};
use std::iter::Enumerate;
use std::slice::Iter;

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteStr<'a>(pub &'a str);

impl<'a> AtEof for CompleteStr<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteStr<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteStr<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteStr<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteStr(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteStr<'a> {
  type Item     = char;
  type RawItem  = char;
  type Iter     = CharIndices<'a>;
  type IterElem = Chars<'a>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteStr<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteStr(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteStr(s1), CompleteStr(s2)))
  }
}

impl<'a> InputLength for CompleteStr<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b str> for CompleteStr<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteStr<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a> FindToken<CompleteStr<'a>> for u8 {
  fn find_token(&self, input: CompleteStr<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteStr<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse().ok()
  }
}

impl<'a> Offset for CompleteStr<'a> {
  fn offset(&self, second:&CompleteStr<'a>) -> usize {
    self.0.offset(second.0)
  }
}

#[derive(Clone,Copy,Debug,PartialEq)]
pub struct CompleteByteSlice<'a>(pub &'a [u8]);

impl<'a> AtEof for CompleteByteSlice<'a> {
  fn at_eof(&self) -> bool { true }
}

impl<'a> Slice<Range<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:Range<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeTo<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeTo<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFrom<usize>> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFrom<usize>) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> Slice<RangeFull> for CompleteByteSlice<'a> {
  fn slice(&self, range:RangeFull) -> Self {
    CompleteByteSlice(self.0.slice(range))
  }
}

impl<'a> InputIter for CompleteByteSlice<'a> {
  type Item     = &'a u8;
  type RawItem  = u8;
  type Iter     = Enumerate<Iter<'a, Self::RawItem>>;
  type IterElem = Iter<'a, Self::RawItem>;

  fn iter_indices(&self)  -> Self::Iter {
    self.0.iter_indices()
  }
  fn iter_elements(&self) -> Self::IterElem {
    self.0.iter_elements()
  }
  fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
    self.0.position(predicate)
  }
  fn slice_index(&self, count:usize) -> Option<usize> {
    self.0.slice_index(count)
  }
}

impl<'a> InputTake for CompleteByteSlice<'a> {
  fn take(&self, count: usize)  -> Option<Self> {
    self.0.take(count).map(|s| CompleteByteSlice(s))
  }

  fn take_split(&self, count: usize) -> Option<(Self,Self)> {
    self.0.take_split(count).map(|(s1, s2)| (CompleteByteSlice(s1), CompleteByteSlice(s2)))
  }
}

impl<'a> InputLength for CompleteByteSlice<'a> {
  fn input_len(&self) -> usize {
    self.0.input_len()
  }
}

impl<'a,'b> Compare<&'b [u8]> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> Compare<&'b str> for CompleteByteSlice<'a> {
  fn compare(&self, t: &'b str) -> CompareResult {
    self.0.compare(t)
  }
  fn compare_no_case(&self, t: &'b str) -> CompareResult {
    self.0.compare_no_case(t)
  }
}

impl<'a,'b> FindSubstring<&'b [u8]> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b [u8]) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a,'b> FindSubstring<&'b str> for CompleteByteSlice<'a> {
  fn find_substring(&self, substr: &'b str) -> Option<usize> {
    self.0.find_substring(substr)
  }
}

impl<'a> FindToken<CompleteByteSlice<'a>> for u8 {
  fn find_token(&self, input: CompleteByteSlice<'a>) -> bool {
    self.find_token(input.0)
  }
}

impl<'a, R:FromStr> ParseTo<R> for CompleteByteSlice<'a> {
  fn parse_to(&self) -> Option<R> {
    self.0.parse_to()
  }
}

impl<'a> Offset for CompleteByteSlice<'a> {
  fn offset(&self, second:&CompleteByteSlice<'a>) -> usize {
    self.0.offset(second.0)
  }
}
<|endoftext|>