<commit_before>use sign::{SignatureV2};
pub use reqwest::{Method, StatusCode};
use reqwest;
use xmlhelper::decode::{FromXMLStream, Stream};

error_chain! {
  foreign_links {
    Io(::std::io::Error);
    Request(reqwest::Error);
  }

  links {
    XmlDecode(::xmlhelper::decode::Error, ::xmlhelper::decode::ErrorKind);
    Sign(super::sign::Error, super::sign::ErrorKind);
  }

  errors {
    ErrorResponse(resp: ErrorResponse) {
      description("MWS request is unsuccessful")
      display("MWS request is unsuccessful: {:?}", resp)
    }
  }
}

#[derive(Debug)]
pub enum Response<T> where T: FromXMLStream<Stream<reqwest::Response>> {
  Success(T),
  Error(ErrorResponse),
}

#[derive(Debug)]
pub struct ErrorResponse {
  pub status: StatusCode,
  pub info: Option<ErrorResponseInfo>,
  pub raw: String
}

#[derive(Debug, Default)]
pub struct ErrorResponseInfo {
  pub errors: Vec<ErrorResponseError>,
  pub request_id: String
}

#[derive(Debug, Default, PartialEq)]
pub struct ErrorResponseError {
  pub error_type: String,
  pub code: String,
  pub message: String,
  pub detail: String
}

impl ErrorResponseInfo {
  fn from_xml_stream<R: ::std::io::Read>(s: &mut Stream<R>) -> ::xmlhelper::decode::Result<ErrorResponseInfo> {
    use xmlhelper::decode::{start_document, element, fold_elements, characters};
    start_document(s)?;
    element(s, "ErrorResponse", |s| {
      fold_elements(s, ErrorResponseInfo::default(), |s, resp| {
        match s.local_name() {
          "Error" => {
            let err = fold_elements(s, ErrorResponseError::default(), |s, err| {
              match s.local_name() {
                "Type" => {
                  err.error_type = characters(s)?;
                },
                "Code" => {
                  err.code = characters(s)?;
                },
                "Message" => {
                  err.message = characters(s)?;
                },
                "Detail" => {
                  err.detail = characters(s)?;
                },
                _ => {}
              }
              Ok(())
            })?;
            resp.errors.push(err);
          },
          "RequestID" => {
            resp.request_id = characters(s)?;
          },
          _ => {}
        }
        Ok(())
      })
    }).into()
  }
}

impl FromXMLStream<Stream<reqwest::Response>> for ErrorResponseInfo {
  fn from_xml(s: &mut Stream<reqwest::Response>) -> ::xmlhelper::decode::Result<ErrorResponseInfo> {
    ErrorResponseInfo::from_xml_stream(s)
  }
}

#[cfg(test)]
impl FromXMLStream<Stream<::std::io::Cursor<String>>> for ErrorResponseInfo {
  fn from_xml(s: &mut Stream<::std::io::Cursor<String>>) -> ::xmlhelper::decode::Result<ErrorResponseInfo> {
    ErrorResponseInfo::from_xml_stream(s)
  }
}

/// [Reference](http://docs.developer.amazonservices.com/en_CA/dev_guide/DG_Endpoints.html)
pub struct ClientOptions {
  /// Your software can access Amazon Marketplace Web Service (Amazon MWS) using region-specific endpoints.
  pub endpoint: String,

  /// Your seller or merchant identifier.
  pub seller_id: String,

  /// Represents the authorization of a specific developer of a web application by a specific Amazon seller.
  pub mws_auth_token: Option<String>,

  /// Your Amazon MWS account is identified by your access key Id, which Amazon MWS uses to look up your Secret Access Key.
  pub aws_access_key_id: String,
  pub secret_key: String,
}

pub struct Client {
  options: ClientOptions,
  http_client: reqwest::Client,
}

impl Client {
  pub fn new(options: ClientOptions) -> Result<Client> {
    Ok(Client {
      options: options,
      http_client: reqwest::Client::new()?,
    })
  }

  pub fn request<P, T>(&self, method: Method, path: &str, version: &str, action: &str, parameters: P) -> Result<Response<T>>
    where P: Into<Vec<(String, String)>>, T: FromXMLStream<Stream<reqwest::Response>>
  {
    let mut sign = SignatureV2::new(self.options.endpoint.clone(), self.options.aws_access_key_id.clone(), self.options.secret_key.clone());
    for (k, v) in parameters.into() {
      sign.add(&k, v);
    }
    let url = sign.generate_url(method.clone(), path, version, action)?.to_string();
    let resp = self.http_client.request(method, &url).send()?;
    let mut stream = Stream::new(resp);
    let v = T::from_xml(&mut stream)?;
    Ok(Response::Success(v))
  }

  #[cfg(test)]
  pub fn request_raw<P>(&self, method: Method, path: &str, version: &str, action: &str, parameters: P) -> Result<(StatusCode, String)>
    where P: Into<Vec<(String, String)>>
  {
    use std::io::Read;

    let mut sign = SignatureV2::new(self.options.endpoint.clone(), self.options.aws_access_key_id.clone(), self.options.secret_key.clone());
    for (k, v) in parameters.into() {
      sign.add(&k, v);
    }
    let url = sign.generate_url(method.clone(), path, version, action)?.to_string();
    let mut resp = self.http_client.request(method, &url).send()?;
    let mut s = String::new();
    resp.read_to_string(&mut s)?;
    Ok((resp.status().clone(), s))
  }
}

#[cfg(test)]
pub fn get_test_client() -> Client {
  use std::env;
  Client::new(ClientOptions {
    endpoint: env::var("Endpoint").expect("get Endpoint"),
    seller_id: env::var("SellerId").expect("get SellerId"),
    mws_auth_token: None,
    aws_access_key_id : env::var("AWSAccessKeyId").expect("get AWSAccessKeyId"),
    secret_key: env::var("SecretKey").expect("get SecretKey"),
  }).expect("create client")
}

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

  #[test]
  fn it_works() {
    dotenv().ok();
    let client = get_test_client();
    let (status, body) = client.request_raw(Method::Post, "/Orders/2013-09-01", "2013-09-01", "GetServiceStatus", vec![]).expect("send request");
    assert!(status.is_success());
    assert!(body.starts_with("<?xml"));

    use std::io::Cursor;
    let (status, body) = client.request_raw(Method::Post, "/Fake/2013-09-01", "2013-09-01", "GetServiceStatus", vec![]).expect("send request");
    assert!(!status.is_success());
    let source = Cursor::new(body);
    let mut s = Stream::new(source);
    let err_info = ErrorResponseInfo::from_xml(&mut s).expect("decode error response");
    assert_eq!(err_info.errors.len(), 1);
    assert_eq!(err_info.errors[0], ErrorResponseError {
      error_type: "Sender".to_string(), code: "InvalidAddress".to_string(), message: "Section Fake/2013-09-01 is invalid".to_string(), detail: "".to_string()
    });
  }
}<commit_msg>Handle client error response.<commit_after>use sign::{SignatureV2};
pub use reqwest::{Method, StatusCode};
use reqwest;
use xmlhelper::decode::{FromXMLStream, Stream};

error_chain! {
  foreign_links {
    Io(::std::io::Error);
    Request(reqwest::Error);
  }

  links {
    XmlDecode(::xmlhelper::decode::Error, ::xmlhelper::decode::ErrorKind);
    Sign(super::sign::Error, super::sign::ErrorKind);
  }

  errors {
    ErrorResponse(resp: ErrorResponse) {
      description("MWS request is unsuccessful")
      display("MWS request is unsuccessful: {:?}", resp)
    }
  }
}

#[derive(Debug)]
pub enum Response<T> where T: FromXMLStream<Stream<reqwest::Response>> {
  Success(T),
  Error(ErrorResponse),
}

#[derive(Debug)]
pub struct ErrorResponse {
  pub status: StatusCode,
  pub info: Option<ErrorResponseInfo>,
  pub raw: String
}

#[derive(Debug, Default)]
pub struct ErrorResponseInfo {
  pub errors: Vec<ErrorResponseError>,
  pub request_id: String
}

#[derive(Debug, Default, PartialEq)]
pub struct ErrorResponseError {
  pub error_type: String,
  pub code: String,
  pub message: String,
  pub detail: String
}

impl ErrorResponseInfo {
  fn from_xml_stream<R: ::std::io::Read>(s: &mut Stream<R>) -> ::xmlhelper::decode::Result<ErrorResponseInfo> {
    use xmlhelper::decode::{start_document, element, fold_elements, characters};
    start_document(s)?;
    element(s, "ErrorResponse", |s| {
      fold_elements(s, ErrorResponseInfo::default(), |s, resp| {
        match s.local_name() {
          "Error" => {
            let err = fold_elements(s, ErrorResponseError::default(), |s, err| {
              match s.local_name() {
                "Type" => {
                  err.error_type = characters(s)?;
                },
                "Code" => {
                  err.code = characters(s)?;
                },
                "Message" => {
                  err.message = characters(s)?;
                },
                "Detail" => {
                  err.detail = characters(s)?;
                },
                _ => {}
              }
              Ok(())
            })?;
            resp.errors.push(err);
          },
          "RequestID" => {
            resp.request_id = characters(s)?;
          },
          _ => {}
        }
        Ok(())
      })
    }).into()
  }
}

impl FromXMLStream<Stream<reqwest::Response>> for ErrorResponseInfo {
  fn from_xml(s: &mut Stream<reqwest::Response>) -> ::xmlhelper::decode::Result<ErrorResponseInfo> {
    ErrorResponseInfo::from_xml_stream(s)
  }
}

impl FromXMLStream<Stream<::std::io::Cursor<String>>> for ErrorResponseInfo {
  fn from_xml(s: &mut Stream<::std::io::Cursor<String>>) -> ::xmlhelper::decode::Result<ErrorResponseInfo> {
    ErrorResponseInfo::from_xml_stream(s)
  }
}

/// [Reference](http://docs.developer.amazonservices.com/en_CA/dev_guide/DG_Endpoints.html)
pub struct ClientOptions {
  /// Your software can access Amazon Marketplace Web Service (Amazon MWS) using region-specific endpoints.
  pub endpoint: String,

  /// Your seller or merchant identifier.
  pub seller_id: String,

  /// Represents the authorization of a specific developer of a web application by a specific Amazon seller.
  pub mws_auth_token: Option<String>,

  /// Your Amazon MWS account is identified by your access key Id, which Amazon MWS uses to look up your Secret Access Key.
  pub aws_access_key_id: String,
  pub secret_key: String,
}

pub struct Client {
  options: ClientOptions,
  http_client: reqwest::Client,
}

impl Client {
  pub fn new(options: ClientOptions) -> Result<Client> {
    Ok(Client {
      options: options,
      http_client: reqwest::Client::new()?,
    })
  }

  pub fn request<P, T>(&self, method: Method, path: &str, version: &str, action: &str, parameters: P) -> Result<Response<T>>
    where P: Into<Vec<(String, String)>>, T: FromXMLStream<Stream<reqwest::Response>>
  {
    let mut sign = SignatureV2::new(self.options.endpoint.clone(), self.options.aws_access_key_id.clone(), self.options.secret_key.clone());
    for (k, v) in parameters.into() {
      sign.add(&k, v);
    }
    let url = sign.generate_url(method.clone(), path, version, action)?.to_string();
    let mut resp = self.http_client.request(method, &url).send()?;
    if resp.status().is_success() {
      let mut stream = Stream::new(resp);
      let v = T::from_xml(&mut stream)?;
      Ok(Response::Success(v))
    } else {
      use std::io::{Read, Cursor};

      let mut body = String::new();
      resp.read_to_string(&mut body)?;
      let mut s = Stream::new(Cursor::new(body.clone()));
      match ErrorResponseInfo::from_xml(&mut s) {
        Ok(info) => Ok(Response::Error(ErrorResponse {
          status: resp.status().clone(),
          raw: body,
          info: Some(info),
        })),
        Err(_) => Ok(Response::Error(ErrorResponse {
          status: resp.status().clone(),
          raw: body,
          info: None,
        })),
      }
    }
  }

  #[cfg(test)]
  pub fn request_raw<P>(&self, method: Method, path: &str, version: &str, action: &str, parameters: P) -> Result<(StatusCode, String)>
    where P: Into<Vec<(String, String)>>
  {
    use std::io::Read;

    let mut sign = SignatureV2::new(self.options.endpoint.clone(), self.options.aws_access_key_id.clone(), self.options.secret_key.clone());
    for (k, v) in parameters.into() {
      sign.add(&k, v);
    }
    let url = sign.generate_url(method.clone(), path, version, action)?.to_string();
    let mut resp = self.http_client.request(method, &url).send()?;
    let mut s = String::new();
    resp.read_to_string(&mut s)?;
    Ok((resp.status().clone(), s))
  }
}

#[cfg(test)]
pub fn get_test_client() -> Client {
  use std::env;
  Client::new(ClientOptions {
    endpoint: env::var("Endpoint").expect("get Endpoint"),
    seller_id: env::var("SellerId").expect("get SellerId"),
    mws_auth_token: None,
    aws_access_key_id : env::var("AWSAccessKeyId").expect("get AWSAccessKeyId"),
    secret_key: env::var("SecretKey").expect("get SecretKey"),
  }).expect("create client")
}

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

  #[test]
  fn it_works() {
    dotenv().ok();
    let client = get_test_client();
    let (status, body) = client.request_raw(Method::Post, "/Orders/2013-09-01", "2013-09-01", "GetServiceStatus", vec![]).expect("send request");
    assert!(status.is_success());
    assert!(body.starts_with("<?xml"));

    use std::io::Cursor;
    let (status, body) = client.request_raw(Method::Post, "/Fake/2013-09-01", "2013-09-01", "GetServiceStatus", vec![]).expect("send request");
    assert!(!status.is_success());
    let source = Cursor::new(body);
    let mut s = Stream::new(source);
    let err_info = ErrorResponseInfo::from_xml(&mut s).expect("decode error response");
    assert_eq!(err_info.errors.len(), 1);
    assert_eq!(err_info.errors[0], ErrorResponseError {
      error_type: "Sender".to_string(), code: "InvalidAddress".to_string(), message: "Section Fake/2013-09-01 is invalid".to_string(), detail: "".to_string()
    });
  }
}<|endoftext|>


<commit_before>use std::io::{BufRead, BufReader, Write};
use std::net::{Shutdown, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;

use command::Command;
use message::Message;
use server::Server;

use command::parse_command;

pub fn run(stream: TcpStream, server: &Arc<Mutex<Server>>) {
    println!("New client");
    Server::welcome_user(clone_stream(&stream));
    let mut client = Client::new(clone_stream(&stream));
    client.choose_username(server);
    Server::display_instructions(clone_stream(&stream));
    client.chat(server);
}

struct Client {
    username: String,
    stream: TcpStream,
}

impl Client {
    fn new(stream: TcpStream) -> Self {
        Client {
            username: "".to_string(),
            stream: stream,
        }
    }

    fn clone(&self) -> Self {
        Client {
            username: self.username.to_string(),
            stream: clone_stream(&self.stream),
        }
    }

    fn choose_username(&mut self, server: &Arc<Mutex<Server>>) {
        let mut reader = BufReader::new(clone_stream(&self.stream));
        let mut username = "".to_string();

        while self.username.len() == 0 {
            match reader.read_line(&mut username) {
                Ok(_) => {
                    username = username.trim().to_string().to_lowercase();

                    if server.lock().unwrap().add_user(username.to_string()) {
                        self.username = username.to_string();
                    }
                    else {
                        let mut stream = clone_stream(&self.stream);
                        let invalid_msg = "Invalid username. Please try again.\n".to_string();
                        stream.write(&invalid_msg.into_bytes())
                              .expect("Error writing to stream");
                        username = "".to_string();
                    }
                },
                Err(e) => println!("{}", e)
            }
        }
    }

    fn choose_chatroom(&self, server: &Arc<Mutex<Server>>, sndr: Sender<String>) -> usize {
        let mut stream = clone_stream(&self.stream);
        let msg = "Available rooms:\n".to_string();
        stream.write(&msg.into_bytes()).expect("Error writing to stream");

        server.lock().unwrap().display_rooms(clone_stream(&stream));

        let msg = "\nEnter the room number of the room you wish to join, \
                    or type \"new\".\n".to_string();
        stream.write(&msg.into_bytes()).expect("Error writing to stream");

        let mut reader = BufReader::new(clone_stream(&stream));
        let mut choice = "".to_string();
        loop {
            match reader.read_line(&mut choice) {
                Ok(_) => {
                    choice = choice.trim().to_string().to_lowercase();

                    if choice == "new".to_string() {
                        let msg = "Enter the name of your room: ".to_string();
                        stream.write(&msg.into_bytes()).expect("Error writing to stream");
                        let mut room_name = "".to_string();
                        if let Ok(_) = reader.read_line(&mut room_name) {
                            let mut server = server.lock().unwrap();
                            let room_num = server.create_room(room_name.trim().to_string());
                            server.join_room(room_num, self.username.to_string(),
                                             sndr.clone());
                            return room_num;
                        }
                    }
                    else if let Ok(room_num) = choice.parse() {
                        if server.lock().unwrap()
                                .join_room(room_num, self.username.to_string(),
                                           sndr.clone()) {
                            return room_num;
                        }
                    }
                    let msg = "Try again\n".to_string();
                    choice = "".to_string();
                    stream.write(&msg.into_bytes()).expect("Error writing to stream");
                },
                Err(e) => println!("{}", e)
            }
        }
    }

    fn chat(self, server: &Arc<Mutex<Server>>) {
        let (sndr, rcvr) = channel();
        let stream = clone_stream(&self.stream);
        thread::spawn(move|| {
            receive_messages(stream, rcvr);
        });
        &self.send_messages(server, sndr);
    }

    fn send_messages(&self, server: &Arc<Mutex<Server>>, sndr: Sender<String>) {
        loop {
            let _self = self.clone();
            let room_num = self.choose_chatroom(server, sndr.clone());
            let username = self.username.to_string();
            let reader = BufReader::new(clone_stream(&self.stream));
            let server = server.clone();
            let handle = thread::spawn(move|| {
                let mut lines = reader.lines();
                while let Some(Ok(line)) = lines.next() {
                    if line.len() > 0 {
                        if &line[0..1] == "/" {
                            _self.handle_command(room_num, line, &server);
                        }
                        else {
                            let msg = Message::new(username.to_string(),
                                                   room_num,
                                                   line.to_string());
                            server.lock().unwrap().send_message(msg);
                        }
                    }
                }
            });
            let _ = handle.join();
        }
    }

    fn handle_command(&self, room_id: usize, command: String, server: &Arc<Mutex<Server>>) {
        match parse_command(command) {
            Command::Quit => {
                let mut server = server.lock().unwrap();
                server.leave_room(room_id, self.username.to_string());
            },
            Command::Logoff => {
                let _ = self.stream.shutdown(Shutdown::Both);
            },
            _ => unimplemented!(),
        }
    }
}

fn receive_messages(stream: TcpStream, rcvr: Receiver<String>) {
    let mut stream = stream;
    loop {
        match rcvr.recv() {
            Ok(msg) => {
                stream.write(&msg.into_bytes())
                      .expect("Error writing to stream");
            },
            Err(e) => {
                println!("Error receiving message {}", e);
                break;
            }
        }
    }
}

fn clone_stream(stream: &TcpStream) -> TcpStream {
    stream.try_clone().expect("Error cloning stream")
}

#[cfg(test)]
mod client_tests {

}
<commit_msg>More work on quit and logoff<commit_after>use std::io::{BufRead, BufReader, Write};
use std::net::{Shutdown, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;

use command::Command;
use message::Message;
use server::Server;

use command::parse_command;

pub fn run(stream: TcpStream, server: &Arc<Mutex<Server>>) {
    println!("New client");
    Server::welcome_user(clone_stream(&stream));
    let mut client = Client::new(clone_stream(&stream));
    client.choose_username(server);
    Server::display_instructions(clone_stream(&stream));
    client.chat(server);
}

struct Client {
    username: String,
    stream: TcpStream,
    logged_on: bool,
    chatting: bool,
}

impl Client {
    fn new(stream: TcpStream) -> Self {
        Client {
            username: "".to_string(),
            stream: stream,
            logged_on: true,
            chatting: false,
        }
    }

    fn clone(&self) -> Self {
        Client {
            username: self.username.to_string(),
            stream: clone_stream(&self.stream),
            logged_on: self.logged_on,
            chatting: self.chatting,
        }
    }

    fn choose_username(&mut self, server: &Arc<Mutex<Server>>) {
        let mut reader = BufReader::new(clone_stream(&self.stream));
        let mut username = "".to_string();

        while self.username.len() == 0 {
            match reader.read_line(&mut username) {
                Ok(_) => {
                    username = username.trim().to_string().to_lowercase();

                    if server.lock().unwrap().add_user(username.to_string()) {
                        self.username = username.to_string();
                    }
                    else {
                        let mut stream = clone_stream(&self.stream);
                        let invalid_msg = "Invalid username. Please try again.\n".to_string();
                        stream.write(&invalid_msg.into_bytes())
                              .expect("Error writing to stream");
                        username = "".to_string();
                    }
                },
                Err(e) => println!("{}", e)
            }
        }
    }

    fn choose_chatroom(&self, server: &Arc<Mutex<Server>>, sndr: Sender<String>) -> usize {
        let mut stream = clone_stream(&self.stream);
        let msg = "Available rooms:\n".to_string();
        stream.write(&msg.into_bytes()).expect("Error writing to stream");

        server.lock().unwrap().display_rooms(clone_stream(&stream));

        let msg = "\nEnter the room number of the room you wish to join, \
                    or type \"new\".\n".to_string();
        stream.write(&msg.into_bytes()).expect("Error writing to stream");

        let mut reader = BufReader::new(clone_stream(&stream));
        let mut choice = "".to_string();
        loop {
            match reader.read_line(&mut choice) {
                Ok(_) => {
                    choice = choice.trim().to_string().to_lowercase();

                    if choice == "new".to_string() {
                        let msg = "Enter the name of your room: ".to_string();
                        stream.write(&msg.into_bytes()).expect("Error writing to stream");
                        let mut room_name = "".to_string();
                        if let Ok(_) = reader.read_line(&mut room_name) {
                            let mut server = server.lock().unwrap();
                            let room_num = server.create_room(room_name.trim().to_string());
                            server.join_room(room_num, self.username.to_string(),
                                             sndr.clone());
                            return room_num;
                        }
                    }
                    else if let Ok(room_num) = choice.parse() {
                        if server.lock().unwrap()
                                .join_room(room_num, self.username.to_string(),
                                           sndr.clone()) {
                            return room_num;
                        }
                    }
                    let msg = "Try again\n".to_string();
                    choice = "".to_string();
                    stream.write(&msg.into_bytes()).expect("Error writing to stream");
                },
                Err(e) => println!("{}", e)
            }
        }
    }

    fn chat(mut self, server: &Arc<Mutex<Server>>) {
        let (sndr, rcvr) = channel();
        let stream = clone_stream(&self.stream);
        thread::spawn(move|| {
            receive_messages(stream, rcvr);
        });
        &self.send_messages(server, sndr);
    }

    fn send_messages(&mut self, server: &Arc<Mutex<Server>>, sndr: Sender<String>) {
        while self.logged_on {
            let room_num = self.choose_chatroom(server, sndr.clone());
            self.chatting = true;

            let username = self.username.to_string();
            let reader = BufReader::new(clone_stream(&self.stream));
            let server = server.clone();
            let mut _self = self.clone();
            let handle = thread::spawn(move|| {
                let mut lines = reader.lines();
                while _self.chatting {
                    if let Some(Ok(line)) = lines.next() {
                        if line.len() <= 0 {continue;}
                        if &line[0..1] == "/" {
                            _self.handle_command(room_num, line, &server);
                        } else {
                            let msg = Message::new(username.to_string(),
                                                   room_num, line.to_string());
                            server.lock().unwrap().send_message(msg);
                        }
                    }
                }
            });
            let _ = handle.join();
        }
    }

    fn handle_command(&mut self, room_id: usize, command: String,
                      server: &Arc<Mutex<Server>>) {
        match parse_command(command) {
            Command::Quit => {
                self.chatting = false;
                let mut server = server.lock().unwrap();
                server.leave_room(room_id, self.username.to_string());
            },
            Command::Logoff => {
                self.logged_on = false;
                let _ = self.stream.shutdown(Shutdown::Both);
            },
            _ => unimplemented!(),
        }
    }
}

fn receive_messages(stream: TcpStream, rcvr: Receiver<String>) {
    let mut stream = stream;
    loop {
        match rcvr.recv() {
            Ok(msg) => {
                if let Ok(_) = stream.write(&msg.into_bytes()) {}
                else {return;}
            },
            Err(e) => {
                println!("Error receiving message {}", e);
                return;
            }
        }
    }
}

fn clone_stream(stream: &TcpStream) -> TcpStream {
    stream.try_clone().expect("Error cloning stream")
}

#[cfg(test)]
mod client_tests {

}
<|endoftext|>


<commit_before>use error::{Result, Error};
use utils;
use protocol;
use super::connection::KafkaConnection;
use super::codecs::*;
use std::collections::HashMap;
use std::io::Cursor;
use std::io::Read;

const CLIENTID: &'static str = "kafka-rust";
const DEFAULT_TIMEOUT: i32 = 120; // seconds

#[derive(Default)]
#[derive(Debug)]
pub struct KafkaClient {
    pub clientid: String,
    pub timeout: i32,
    pub hosts: Vec<String>,
    pub correlation: i32,
    pub conns: HashMap<String, KafkaConnection>,
    pub topic_partitions: HashMap<String, Vec<i32>>,
    pub topic_brokers: HashMap<String, String>
}

impl KafkaClient {
    pub fn new(hosts: &Vec<String>) -> KafkaClient {
        KafkaClient { hosts: hosts.to_vec(), clientid: CLIENTID.to_string(),
                      timeout: DEFAULT_TIMEOUT, ..KafkaClient::default()}
    }

    fn get_conn(& mut self, host: &str) -> Result<KafkaConnection> {
        match self.conns.get(host) {
            Some (conn) => return conn.clone(),
            None => {}
        }
        // TODO
        // Keeping this out here since get is causing ownership issues
        // Will refactor once I know better
        self.conns.insert(host.to_string(),
                          try!(KafkaConnection::new(host, self.timeout)));
        self.get_conn(host)
    }

    fn next_id(&mut self) -> i32{
        self.correlation = (self.correlation + 1) % (1i32 << 30);
        self.correlation
    }

    pub fn load_metadata_all(&mut self) -> Result<()>{
        self.reset_metadata();
        self.load_metadata(&vec!())
    }

    pub fn load_metadata (&mut self, topics: &Vec<String>) -> Result<()>{
        let resp = try!(self.get_metadata(topics));

        let mut brokers: HashMap<i32, String> = HashMap::new();
        for broker in resp.brokers {
            brokers.insert(broker.nodeid, format!("{}:{}", broker.host, broker.port));
        }

        self.topic_brokers.clear();
        for topic in resp.topics {
            self.topic_partitions.insert(topic.topic.clone(), vec!());

            for partition in topic.partitions {
                match brokers.get(&partition.leader) {
                    Some(broker) => {
                        self.topic_partitions.get_mut(&topic.topic).unwrap().push(partition.id);
                        self.topic_brokers.insert(
                            format!("{}-{}", topic.topic, partition.id),
                            broker.clone());
                    },
                    None => {}
                }
            }
        }
        Ok(())
    }

    pub fn reset_metadata(&mut self) {
        self.topic_partitions.clear();
        self.topic_brokers.clear();
    }

    fn get_metadata(&mut self, topics: &Vec<String>) -> Result<protocol::MetadataResponse> {
        let correlation = self.next_id();
        for host in self.hosts.to_vec() {
            let req = protocol::MetadataRequest::new(correlation, &self.clientid, topics);
            match self.get_conn(&host) {
                Ok(mut conn) => if self.send_request(&mut conn, req).is_ok() {
                    return self.get_response::<protocol::MetadataResponse>(&mut conn);
                },
                Err(_) => {}
            }
        }

        Err(Error::NoHostReachable)
    }

    pub fn fetch_offsets(&mut self) {
        // TODO - Implement method to fetch offsets for more than 1 topic

    }

    pub fn fetch_topic_offset(&mut self, topic: &String) -> Result<Vec<(String, Vec<utils::PartitionOffset>)>> {
        // Doing it like this because HashMap will not return borrow of self otherwise
        let partitions = self.topic_partitions
                             .get(topic)
                             .unwrap_or(&vec!())
                             .clone();

        // Maybe TODO: Can this be simplified without complexifying?
        let mut brokers: HashMap<String, Vec<i32>> = HashMap:: new();
        for p in partitions {
            let key = format!("{}-{}", topic, p);
            match self.topic_brokers.get(&key) {
                Some(broker) => {
                    if !brokers.contains_key(broker) {brokers.insert(broker.clone(), Vec::new());}
                    brokers.get_mut(broker).unwrap().push(p);
                },
                None => {}
            }
        }

        let mut res: Vec<utils::PartitionOffset> = vec!();
        for (host, partitions) in brokers.iter() {
            let v = vec!(utils::TopicPartitions{
                topic: topic.clone(),
                partitions: partitions.to_vec()
                });
            for tpo in try!(self.fetch_offset(&v, host)) {
                res.push(utils::PartitionOffset{partition: tpo.partition, offset: tpo.offset});
            }
        }
        Ok(vec!((topic.clone(), res)))
    }

    fn fetch_offset(&mut self, topic_partitions: &Vec<utils::TopicPartitions>, host: &String)
                            -> Result<Vec<utils::TopicPartitionOffset>> {
        let correlation = self.next_id();
        let req = protocol::OffsetRequest::new_latest(topic_partitions, correlation, &self.clientid);

        let resp = try!(self.send_receive::<protocol::OffsetRequest, protocol::OffsetResponse>(&host, req));

        Ok(resp.get_offsets())

    }

    fn get_broker(&mut self, topic: &String, partition: i32) -> Option<String> {
        let key = format!("{}-{}", topic, partition);
        match self.topic_brokers.get(&key) {
            Some(broker) => {
                Some(broker.clone())
            },
            None => None
        }
    }

    pub fn fetch_messages(&mut self, topic: &String, partition: i32, offset: i64) -> Result<Vec<utils::OffsetMessage>>{

        let host = self.get_broker(topic, partition).unwrap();

        let correlation = self.next_id();
        let req = protocol::FetchRequest::new_single(topic, partition, offset, correlation, &self.clientid);

        let resp = try!(self.send_receive::<protocol::FetchRequest, protocol::FetchResponse>(&host, req));
        Ok(resp.get_messages())
    }

    pub fn send_message(&mut self, topic: &String, partition: i32, required_acks: i16,
                      timeout: i32, message: &Vec<u8>) -> Result<protocol::ProduceResponse> {

        let host = self.get_broker(topic, partition).unwrap();

        let correlation = self.next_id();
        let req = protocol::ProduceRequest::new_single(topic, partition, required_acks,
            timeout, message, correlation, &self.clientid);

        self.send_receive::<protocol::ProduceRequest, protocol::ProduceResponse>(&host, req)

    }

    fn send_receive<T: ToByte, V: FromByte>(&mut self, host: &str, req: T) -> Result<V::R> {
        let mut conn = try!(self.get_conn(&host));
        try!(self.send_request(&mut conn, req));
        self.get_response::<V>(&mut conn)
    }

    fn send_request<T: ToByte>(&self, conn: &mut KafkaConnection, request: T) -> Result<usize>{
        let mut buffer = vec!();
        request.encode(&mut buffer);

        let mut s = vec!();
        (buffer.len() as i32).encode(&mut s);
        for byte in buffer.iter() { s.push(*byte); }

        conn.send(&s)
    }

    fn get_response<T: FromByte>(&self, conn:&mut KafkaConnection) -> Result<T::R>{
        let mut v: Vec<u8> = vec!();
        let _ = conn.read(4, &mut v);
        let size = i32::decode_new(&mut Cursor::new(v)).unwrap();

        let mut resp: Vec<u8> = vec!();
        let _ = try!(conn.read(size as u64, &mut resp));

        T::decode_new(&mut Cursor::new(resp))
    }

}
<commit_msg>Minor change<commit_after>use error::{Result, Error};
use utils;
use protocol;
use connection::KafkaConnection;
use codecs::{ToByte, FromByte};
use std::collections::HashMap;
use std::io::Cursor;
use std::io::Read;

const CLIENTID: &'static str = "kafka-rust";
const DEFAULT_TIMEOUT: i32 = 120; // seconds

#[derive(Default)]
#[derive(Debug)]
pub struct KafkaClient {
    pub clientid: String,
    pub timeout: i32,
    pub hosts: Vec<String>,
    pub correlation: i32,
    pub conns: HashMap<String, KafkaConnection>,
    pub topic_partitions: HashMap<String, Vec<i32>>,
    pub topic_brokers: HashMap<String, String>
}

impl KafkaClient {
    pub fn new(hosts: &Vec<String>) -> KafkaClient {
        KafkaClient { hosts: hosts.to_vec(), clientid: CLIENTID.to_string(),
                      timeout: DEFAULT_TIMEOUT, ..KafkaClient::default()}
    }

    fn get_conn(& mut self, host: &str) -> Result<KafkaConnection> {
        match self.conns.get(host) {
            Some (conn) => return conn.clone(),
            None => {}
        }
        // TODO
        // Keeping this out here since get is causing ownership issues
        // Will refactor once I know better
        self.conns.insert(host.to_string(),
                          try!(KafkaConnection::new(host, self.timeout)));
        self.get_conn(host)
    }

    fn next_id(&mut self) -> i32{
        self.correlation = (self.correlation + 1) % (1i32 << 30);
        self.correlation
    }

    pub fn load_metadata_all(&mut self) -> Result<()>{
        self.reset_metadata();
        self.load_metadata(&vec!())
    }

    pub fn load_metadata (&mut self, topics: &Vec<String>) -> Result<()>{
        let resp = try!(self.get_metadata(topics));

        let mut brokers: HashMap<i32, String> = HashMap::new();
        for broker in resp.brokers {
            brokers.insert(broker.nodeid, format!("{}:{}", broker.host, broker.port));
        }

        self.topic_brokers.clear();
        for topic in resp.topics {
            self.topic_partitions.insert(topic.topic.clone(), vec!());

            for partition in topic.partitions {
                match brokers.get(&partition.leader) {
                    Some(broker) => {
                        self.topic_partitions.get_mut(&topic.topic).unwrap().push(partition.id);
                        self.topic_brokers.insert(
                            format!("{}-{}", topic.topic, partition.id),
                            broker.clone());
                    },
                    None => {}
                }
            }
        }
        Ok(())
    }

    pub fn reset_metadata(&mut self) {
        self.topic_partitions.clear();
        self.topic_brokers.clear();
    }

    fn get_metadata(&mut self, topics: &Vec<String>) -> Result<protocol::MetadataResponse> {
        let correlation = self.next_id();
        for host in self.hosts.to_vec() {
            let req = protocol::MetadataRequest::new(correlation, &self.clientid, topics);
            match self.get_conn(&host) {
                Ok(mut conn) => if self.send_request(&mut conn, req).is_ok() {
                    return self.get_response::<protocol::MetadataResponse>(&mut conn);
                },
                Err(_) => {}
            }
        }

        Err(Error::NoHostReachable)
    }

    pub fn fetch_offsets(&mut self) {
        // TODO - Implement method to fetch offsets for more than 1 topic

    }

    pub fn fetch_topic_offset(&mut self, topic: &String) -> Result<Vec<(String, Vec<utils::PartitionOffset>)>> {
        // Doing it like this because HashMap will not return borrow of self otherwise
        let partitions = self.topic_partitions
                             .get(topic)
                             .unwrap_or(&vec!())
                             .clone();

        // Maybe TODO: Can this be simplified without complexifying?
        let mut brokers: HashMap<String, Vec<i32>> = HashMap:: new();
        for p in partitions {
            let key = format!("{}-{}", topic, p);
            match self.topic_brokers.get(&key) {
                Some(broker) => {
                    if !brokers.contains_key(broker) {brokers.insert(broker.clone(), Vec::new());}
                    brokers.get_mut(broker).unwrap().push(p);
                },
                None => {}
            }
        }

        let mut res: Vec<utils::PartitionOffset> = vec!();
        for (host, partitions) in brokers.iter() {
            let v = vec!(utils::TopicPartitions{
                topic: topic.clone(),
                partitions: partitions.to_vec()
                });
            for tpo in try!(self.fetch_offset(&v, host)) {
                res.push(utils::PartitionOffset{partition: tpo.partition, offset: tpo.offset});
            }
        }
        Ok(vec!((topic.clone(), res)))
    }

    fn fetch_offset(&mut self, topic_partitions: &Vec<utils::TopicPartitions>, host: &String)
                            -> Result<Vec<utils::TopicPartitionOffset>> {
        let correlation = self.next_id();
        let req = protocol::OffsetRequest::new_latest(topic_partitions, correlation, &self.clientid);

        let resp = try!(self.send_receive::<protocol::OffsetRequest, protocol::OffsetResponse>(&host, req));

        Ok(resp.get_offsets())

    }

    fn get_broker(&mut self, topic: &String, partition: i32) -> Option<String> {
        let key = format!("{}-{}", topic, partition);
        match self.topic_brokers.get(&key) {
            Some(broker) => {
                Some(broker.clone())
            },
            None => None
        }
    }

    pub fn fetch_messages(&mut self, topic: &String, partition: i32, offset: i64) -> Result<Vec<utils::OffsetMessage>>{

        let host = self.get_broker(topic, partition).unwrap();

        let correlation = self.next_id();
        let req = protocol::FetchRequest::new_single(topic, partition, offset, correlation, &self.clientid);

        let resp = try!(self.send_receive::<protocol::FetchRequest, protocol::FetchResponse>(&host, req));
        Ok(resp.get_messages())
    }

    pub fn send_message(&mut self, topic: &String, partition: i32, required_acks: i16,
                      timeout: i32, message: &Vec<u8>) -> Result<protocol::ProduceResponse> {

        let host = self.get_broker(topic, partition).unwrap();

        let correlation = self.next_id();
        let req = protocol::ProduceRequest::new_single(topic, partition, required_acks,
            timeout, message, correlation, &self.clientid);

        self.send_receive::<protocol::ProduceRequest, protocol::ProduceResponse>(&host, req)

    }

    fn send_receive<T: ToByte, V: FromByte>(&mut self, host: &str, req: T) -> Result<V::R> {
        let mut conn = try!(self.get_conn(&host));
        try!(self.send_request(&mut conn, req));
        self.get_response::<V>(&mut conn)
    }

    fn send_request<T: ToByte>(&self, conn: &mut KafkaConnection, request: T) -> Result<usize>{
        let mut buffer = vec!();
        request.encode(&mut buffer);

        let mut s = vec!();
        (buffer.len() as i32).encode(&mut s);
        for byte in buffer.iter() { s.push(*byte); }

        conn.send(&s)
    }

    fn get_response<T: FromByte>(&self, conn:&mut KafkaConnection) -> Result<T::R>{
        let mut v: Vec<u8> = vec!();
        let _ = conn.read(4, &mut v);
        let size = i32::decode_new(&mut Cursor::new(v)).unwrap();

        let mut resp: Vec<u8> = vec!();
        let _ = try!(conn.read(size as u64, &mut resp));

        T::decode_new(&mut Cursor::new(resp))
    }

}
<|endoftext|>


<commit_before>use super::request::*;

use std::cmp;
use std::cmp::Ordering;

#[derive(Debug)]
pub struct HSB {
    pub hue: u8,
    pub saturation: u8,
    pub brightness: u8,
}

pub struct RGB {
    pub red: u8,
    pub green: u8,
    pub blue: u8,
}

impl HSB {
    fn new(h: u8, s: u8, b: u8) -> HSB {
        HSB {
            hue: h,
            saturation: s,
            brightness: b,
        }
    }
}

const WORDSIZE: f32 = 65535.0;

// LIFX uses HSB aka HSV, not HSL.

pub fn hue_degrees_to_word(degrees: u8) -> [u8; 2] {
    let f = degrees as f32 / 360.0 * WORDSIZE;
    let b = RequestBin::u16_to_u8_array(f as u16);
    [b[0], b[1]]
}

pub fn saturation_percent_to_word(percent: u8) -> [u8; 2] {
    let f = percent as f32 / 100.0 * WORDSIZE;
    let b = RequestBin::u16_to_u8_array(f as u16);
    [b[1], b[1]]
}

pub fn brightness_percent_to_word(percent: u8) -> [u8; 2] {
    saturation_percent_to_word(percent)
}

pub fn rgb_to_hsv(rgb: RGB) -> HSB {
    let r1 = rgb.red as f32 / 255.0;
    let g1 = rgb.green as f32 / 255.0;
    let b1 = rgb.blue as f32 / 255.0;

    let mut floats: Vec<f32> = vec![r1, g1, b1];
    floats.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
    let cmax = floats[2];
    let cmin = floats[0];
    let d = cmax - cmin;

    // Hue.
    let h = match cmax {
        _ if r1 == cmax => (((g1 - b1) / d) % 6.0) * 60.0,
        _ if g1 == cmax => (((b1 - r1) / d) + 2.0) * 60.0,
        _ if b1 == cmax => (((r1 - g1) / d) + 4.0) * 60.0,
        _ => 0.0,
    };

    // Saturation.
    let s = match cmax {
        0.0 => 0.0,
        _ => d / cmax,
    };

    // Value / brightness.
    let v = cmax;

    HSB {
        hue: h as u8,
        saturation: (s * 100.0) as u8,
        brightness: (v * 100.0) as u8,
    }
}

#[cfg(test)]
mod tests {

    use colour::*;

    #[test]
    fn test_hue_degrees_to_word() {
        assert_eq!([0x55, 0x55], hue_degrees_to_word(120));
    }

    #[test]
    fn test_saturation_percent_to_word() {
        assert_eq!([0x7F, 0x7F], saturation_percent_to_word(50));
    }

    #[test]
    fn test_rgb_to_hsv() {
        struct test {
            rgb: RGB,
            hsb: HSB,
        };

        let tests = vec![
                        test {
                             rgb: RGB { // olive
                                 red: 128,
                                 green: 128,
                                 blue: 0,
                             },
                             hsb: HSB {
                                 hue: 60,
                                 saturation: 100,
                                 brightness: 50,
                             },
                         },
                         test {
                             rgb: RGB { // chartreuse
                                 red: 127,
                                 green: 255,
                                 blue: 0,
                             },
                             hsb: HSB {
                                 hue: 90,
                                 saturation: 100,
                                 brightness: 100,
                             },
                         },
        ];

        for t in tests {
            let res = rgb_to_hsv(t.rgb);
            assert_eq!(res.hue, t.hsb.hue);
            assert_eq!(res.saturation, t.hsb.saturation);
            assert_eq!(res.brightness, t.hsb.brightness);
        }
    }
}

pub const BEIGE: HSB = HSB {
    hue: 60,
    saturation: 56,
    brightness: 91,
};
pub const BLUE: HSB = HSB {
    hue: 240,
    saturation: 100,
    brightness: 50,
};
pub const CHARTREUSE: HSB = HSB {
    hue: 90,
    saturation: 100,
    brightness: 50,
};
pub const CORAL: HSB = HSB {
    hue: 916,
    saturation: 100,
    brightness: 66,
};
pub const CORNFLOWER: HSB = HSB {
    hue: 219,
    saturation: 79,
    brightness: 66,
};
pub const CRIMSON: HSB = HSB {
    hue: 348,
    saturation: 83,
    brightness: 47,
};
pub const DEEP_SKY_BLUE: HSB = HSB {
    hue: 195,
    saturation: 100,
    brightness: 50,
};
pub const GREEN: HSB = HSB {
    hue: 120,
    saturation: 100,
    brightness: 50,
};
pub const RED: HSB = HSB {
    hue: 0,
    saturation: 100,
    brightness: 50,
};
pub const SLATE_GRAY: HSB = HSB {
    hue: 210,
    saturation: 13,
    brightness: 50,
};
<commit_msg>Fix test.<commit_after>use super::request::*;

use std::cmp;
use std::cmp::Ordering;

#[derive(Debug)]
pub struct HSB {
    pub hue: u8,
    pub saturation: u8,
    pub brightness: u8,
}

pub struct RGB {
    pub red: u8,
    pub green: u8,
    pub blue: u8,
}

impl HSB {
    fn new(h: u8, s: u8, b: u8) -> HSB {
        HSB {
            hue: h,
            saturation: s,
            brightness: b,
        }
    }
}

const WORDSIZE: f32 = 65535.0;

// LIFX uses HSB aka HSV, not HSL.

pub fn hue_degrees_to_word(degrees: u8) -> [u8; 2] {
    let f = degrees as f32 / 360.0 * WORDSIZE;
    let b = RequestBin::u16_to_u8_array(f as u16);
    [b[0], b[1]]
}

pub fn saturation_percent_to_word(percent: u8) -> [u8; 2] {
    let f = percent as f32 / 100.0 * WORDSIZE;
    let b = RequestBin::u16_to_u8_array(f as u16);
    [b[0], b[1]]
}

pub fn brightness_percent_to_word(percent: u8) -> [u8; 2] {
    saturation_percent_to_word(percent)
}

pub fn rgb_to_hsv(rgb: RGB) -> HSB {
    let r1 = rgb.red as f32 / 255.0;
    let g1 = rgb.green as f32 / 255.0;
    let b1 = rgb.blue as f32 / 255.0;

    let mut floats: Vec<f32> = vec![r1, g1, b1];
    floats.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
    let cmax = floats[2];
    let cmin = floats[0];
    let d = cmax - cmin;

    // Hue.
    let h = match cmax {
        _ if r1 == cmax => (((g1 - b1) / d) % 6.0) * 60.0,
        _ if g1 == cmax => (((b1 - r1) / d) + 2.0) * 60.0,
        _ if b1 == cmax => (((r1 - g1) / d) + 4.0) * 60.0,
        _ => 0.0,
    };

    // Saturation.
    let s = match cmax {
        0.0 => 0.0,
        _ => d / cmax,
    };

    // Value / brightness.
    let v = cmax;

    HSB {
        hue: h as u8,
        saturation: (s * 100.0) as u8,
        brightness: (v * 100.0) as u8,
    }
}

#[cfg(test)]
mod tests {

    use colour::*;

    #[test]
    fn test_hue_degrees_to_word() {
        assert_eq!([0x55, 0x55], hue_degrees_to_word(120));
    }

    #[test]
    fn test_saturation_percent_to_word() {
        assert_eq!([0x7F, 0xFF], saturation_percent_to_word(50));
    }

    #[test]
    fn test_rgb_to_hsv() {
        struct test {
            rgb: RGB,
            hsb: HSB,
        };

        let tests = vec![
                        test {
                             rgb: RGB { // olive
                                 red: 128,
                                 green: 128,
                                 blue: 0,
                             },
                             hsb: HSB {
                                 hue: 60,
                                 saturation: 100,
                                 brightness: 50,
                             },
                         },
                         test {
                             rgb: RGB { // chartreuse
                                 red: 127,
                                 green: 255,
                                 blue: 0,
                             },
                             hsb: HSB {
                                 hue: 90,
                                 saturation: 100,
                                 brightness: 100,
                             },
                         },
        ];

        for t in tests {
            let res = rgb_to_hsv(t.rgb);
            assert_eq!(res.hue, t.hsb.hue);
            assert_eq!(res.saturation, t.hsb.saturation);
            assert_eq!(res.brightness, t.hsb.brightness);
        }
    }
}

pub const BEIGE: HSB = HSB {
    hue: 60,
    saturation: 56,
    brightness: 91,
};
pub const BLUE: HSB = HSB {
    hue: 240,
    saturation: 100,
    brightness: 50,
};
pub const CHARTREUSE: HSB = HSB {
    hue: 90,
    saturation: 100,
    brightness: 50,
};
pub const CORAL: HSB = HSB {
    hue: 916,
    saturation: 100,
    brightness: 66,
};
pub const CORNFLOWER: HSB = HSB {
    hue: 219,
    saturation: 79,
    brightness: 66,
};
pub const CRIMSON: HSB = HSB {
    hue: 348,
    saturation: 83,
    brightness: 47,
};
pub const DEEP_SKY_BLUE: HSB = HSB {
    hue: 195,
    saturation: 100,
    brightness: 50,
};
pub const GREEN: HSB = HSB {
    hue: 120,
    saturation: 100,
    brightness: 50,
};
pub const RED: HSB = HSB {
    hue: 0,
    saturation: 100,
    brightness: 50,
};
pub const SLATE_GRAY: HSB = HSB {
    hue: 210,
    saturation: 13,
    brightness: 50,
};
<|endoftext|>


<commit_before>use hyper::client::RequestBuilder;
use json;
use std::io::Read;
use mustache;
use nickel::{Response, MiddlewareResult, MediaType};
use hyper::server::request;
use hyper::header::Cookie;
use std::ops::Deref;
use mustache::MapBuilder;

pub fn json_for_request(rb: RequestBuilder) -> Result<json::JsonValue, String> {
    let mut res = match rb.send() {
        Ok(val) => val,
        Err(_) => {
            return Err("Can't connect to TfL".to_string());
        }
    };
    let mut buffer: String = String::new();
    res.read_to_string(&mut buffer).expect("can't read");
    let obj = match json::parse(&buffer) {
        Ok(val) => val,
        Err(_) => {
            return Err(format!("Bad json: {} ", buffer));
        }
    };
    return Ok(obj);
}

pub fn render_to_response<'a, D>(mut response: Response<'a, D>,
                                 path: &str,
                                 data: &mustache::Data)
                                 -> MiddlewareResult<'a, D> {
    let template = mustache::compile_path(path).expect("working template");
    let mut buffer: Vec<u8> = vec![];
    template.render_data(&mut buffer, data);
    response.set(MediaType::Html);
    response.send(buffer)
}

pub static KEY: &'static str = "favourites";

pub fn favourites(req: &request::Request) -> json::JsonValue {
    let all_cookies = req.headers.get::<Cookie>().unwrap().deref();
    let raw = all_cookies.iter().find(|k| k.name == KEY);
    match raw {
        Some(val) => {
            match json::parse(&val.value) {
                Ok(val) => val,
                Err(_) => json::JsonValue::new_object(),  // assume junk
            }
        }
        None => json::JsonValue::new_object(),
    }
}

pub fn mustache_favourites(req: &request::Request) -> mustache::Data {
    let favourites = favourites(req);
    MapBuilder::new()
        .insert_vec("favourites", |vecbuilder| {
            let mut vecb = vecbuilder;
            for fav in favourites.entries() {
                vecb = vecb.push_map(|mapbuilder| {
                    mapbuilder.insert_str("key", fav.0)
                        .insert_str("value", fav.1)
                });
            }
            vecb
        })
        .build()
}
<commit_msg>Cope when there's no favourite cookie<commit_after>use hyper::client::RequestBuilder;
use json;
use std::io::Read;
use mustache;
use nickel::{Response, MiddlewareResult, MediaType};
use hyper::server::request;
use hyper::header::Cookie;
use std::ops::Deref;
use mustache::MapBuilder;

pub fn json_for_request(rb: RequestBuilder) -> Result<json::JsonValue, String> {
    let mut res = match rb.send() {
        Ok(val) => val,
        Err(_) => {
            return Err("Can't connect to TfL".to_string());
        }
    };
    let mut buffer: String = String::new();
    res.read_to_string(&mut buffer).expect("can't read");
    let obj = match json::parse(&buffer) {
        Ok(val) => val,
        Err(_) => {
            return Err(format!("Bad json: {} ", buffer));
        }
    };
    return Ok(obj);
}

pub fn render_to_response<'a, D>(mut response: Response<'a, D>,
                                 path: &str,
                                 data: &mustache::Data)
                                 -> MiddlewareResult<'a, D> {
    let template = mustache::compile_path(path).expect("working template");
    let mut buffer: Vec<u8> = vec![];
    template.render_data(&mut buffer, data);
    response.set(MediaType::Html);
    response.send(buffer)
}

pub static KEY: &'static str = "favourites";

pub fn favourites(req: &request::Request) -> json::JsonValue {
    let raw_cookies = req.headers.get::<Cookie>();
    let all_cookies = match raw_cookies {
        Some(val) => val.deref(),
        None => return json::JsonValue::new_object()
    };
    let raw = all_cookies.iter().find(|k| k.name == KEY);
    match raw {
        Some(val) => {
            match json::parse(&val.value) {
                Ok(val) => val,
                Err(_) => json::JsonValue::new_object(),  // assume junk
            }
        }
        None => json::JsonValue::new_object(),
    }
}

pub fn mustache_favourites(req: &request::Request) -> mustache::Data {
    let favourites = favourites(req);
    MapBuilder::new()
        .insert_vec("favourites", |vecbuilder| {
            let mut vecb = vecbuilder;
            for fav in favourites.entries() {
                vecb = vecb.push_map(|mapbuilder| {
                    mapbuilder.insert_str("key", fav.0)
                        .insert_str("value", fav.1)
                });
            }
            vecb
        })
        .build()
}
<|endoftext|>


<commit_before>use crate::de::{DeError, DeEvent, Deserializer, XmlRead};
use crate::{events::BytesStart, reader::Decoder};
use serde::de::{self, DeserializeSeed};

#[derive(Debug)]
enum Names {
    Unknown,
    Peek(String),
}

impl Names {
    fn is_valid(&self, decoder: Decoder, start: &BytesStart) -> Result<bool, DeError> {
        #[cfg(not(feature = "encoding"))]
        let name = decoder.decode(start.name())?;
        #[cfg(feature = "encoding")]
        let name = decoder.decode(start.name());
        let res = match self {
            Names::Unknown => true,
            Names::Peek(n) => &**n == &*name,
        };
        Ok(res)
    }
}

/// A SeqAccess
pub struct SeqAccess<'de, 'a, R>
where
    R: XmlRead<'de>,
{
    de: &'a mut Deserializer<'de, R>,
    names: Names,
}

impl<'a, 'de, R> SeqAccess<'de, 'a, R>
where
    R: XmlRead<'de>,
{
    /// Get a new SeqAccess
    pub fn new(de: &'a mut Deserializer<'de, R>) -> Result<Self, DeError> {
        let decoder = de.reader.decoder();
        let names = if de.has_value_field {
            Names::Unknown
        } else {
            if let DeEvent::Start(e) = de.peek()? {
                #[cfg(not(feature = "encoding"))]
                let name = decoder.decode(e.name())?.to_owned();
                #[cfg(feature = "encoding")]
                let name = decoder.decode(e.name()).into_owned();
                Names::Peek(name)
            } else {
                Names::Unknown
            }
        };
        Ok(SeqAccess { de, names })
    }
}

impl<'de, 'a, R> de::SeqAccess<'de> for SeqAccess<'de, 'a, R>
where
    R: XmlRead<'de>,
{
    type Error = DeError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeError>
    where
        T: DeserializeSeed<'de>,
    {
        let decoder = self.de.reader.decoder();
        match self.de.peek()? {
            DeEvent::Eof | DeEvent::End(_) => Ok(None),
            DeEvent::Start(e) if !self.names.is_valid(decoder, e)? => Ok(None),
            _ => seed.deserialize(&mut *self.de).map(Some),
        }
    }
}
<commit_msg>Do not decode tags because all of them in the same encoding and we need only compare them<commit_after>use crate::de::{DeError, DeEvent, Deserializer, XmlRead};
use crate::events::BytesStart;
use serde::de::{self, DeserializeSeed};

#[derive(Debug)]
enum Names {
    Unknown,
    Peek(Vec<u8>),
}

impl Names {
    fn is_valid(&self, start: &BytesStart) -> bool {
        match self {
            Names::Unknown => true,
            Names::Peek(n) => n == start.name(),
        }
    }
}

/// A SeqAccess
pub struct SeqAccess<'de, 'a, R>
where
    R: XmlRead<'de>,
{
    de: &'a mut Deserializer<'de, R>,
    names: Names,
}

impl<'a, 'de, R> SeqAccess<'de, 'a, R>
where
    R: XmlRead<'de>,
{
    /// Get a new SeqAccess
    pub fn new(de: &'a mut Deserializer<'de, R>) -> Result<Self, DeError> {
        let names = if de.has_value_field {
            Names::Unknown
        } else {
            if let DeEvent::Start(e) = de.peek()? {
                Names::Peek(e.name().to_vec())
            } else {
                Names::Unknown
            }
        };
        Ok(SeqAccess { de, names })
    }
}

impl<'de, 'a, R> de::SeqAccess<'de> for SeqAccess<'de, 'a, R>
where
    R: XmlRead<'de>,
{
    type Error = DeError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeError>
    where
        T: DeserializeSeed<'de>,
    {
        match self.de.peek()? {
            DeEvent::Eof | DeEvent::End(_) => Ok(None),
            DeEvent::Start(e) if !self.names.is_valid(e) => Ok(None),
            _ => seed.deserialize(&mut *self.de).map(Some),
        }
    }
}
<|endoftext|>


<commit_before>//! All VST plugin editor related functionality.

use libc::c_void;

/// Implemented by plugin editors.
pub trait Editor {
    /// Get the size of the editor window.
    fn size(&self) -> (i32, i32);

    /// Get the coordinates of the editor window.
    fn position(&self) -> (i32, i32);

    /// Editor idle call. Called by host.
    fn idle(&mut self);

    /// Called when the editor window is closed.
    fn close(&mut self);

    /// Called when the editor window is opened. `window` is a platform dependant window pointer
    /// (e.g. `HWND` on Windows, `WindowRef` on OSX, `Window` on X11/Linux).
    fn open(&mut self, window: *mut c_void);

    /// Return whether the window is currently open.
    fn is_open(&mut self) -> bool;

    /// Set the knob mode for this editor (if supported by host).
    ///
    /// Return true if the knob mode was set.
    fn set_knob_mode(&mut self, mode: KnobMode) -> bool;

    /// Recieve key up event. Return true if the key was used.
    fn key_up(&mut self, keycode: KeyCode) -> bool;

    /// Receive key down event. Return true if the key was used.
    fn key_down(&mut self, keycode: KeyCode) -> bool;
}

/// Rectangle used to specify dimensions of editor window.
#[doc(hidden)]
pub struct Rect {
    /// Y value in pixels of top side.
    pub top: i16,
    /// X value in pixels of left side.
    pub left: i16,
    /// Y value in pixels of bottom side.
    pub bottom: i16,
    /// X value in pixels of right side.
    pub right: i16
}

/// A platform independent key code. Includes modifier keys.
pub struct KeyCode {
    /// ASCII character for key pressed (if applicable).
    pub character: char,
    /// Key pressed. See `enums::Key`.
    pub key: Key,
    /// Modifier key bitflags. See `enums::flags::modifier_key`.
    pub modifier: u8
}

/// Allows host to set how a parameter knob works.
#[repr(usize)]
#[derive(Copy, Clone, Debug)]
#[allow(missing_docs)]
pub enum KnobMode {
    Circular,
    CircularRelative,
    Linear
}
impl_clike!(KnobMode);

/// Platform independent key codes.
#[allow(missing_docs)]
#[repr(usize)]
#[derive(Debug, Copy, Clone)]
pub enum Key {
	Back = 1,
	Tab,
	Clear,
	Return,
	Pause,
	Escape,
	Space,
	Next,
	End,
	Home,
	Left,
	Up,
	Right,
	Down,
	PageUp,
	PageDown,
	Select,
	Print,
	Enter,
	Snapshot,
	Insert,
	Delete,
	Help,
	Numpad0,
	Numpad1,
	Numpad2,
	Numpad3,
	Numpad4,
	Numpad5,
	Numpad6,
	Numpad7,
	Numpad8,
	Numpad9,
	Multiply,
	Add,
	Separator,
	Subtract,
	Decimal,
	Divide,
	F1,
	F2,
	F3,
	F4,
	F5,
	F6,
	F7,
	F8,
	F9,
	F10,
	F11,
	F12,
	Numlock,
	Scroll,
	Shift,
	Control,
	Alt,
	Equals
}
impl_clike!(Key);
<commit_msg>Add default implementations for some editor methods<commit_after>//! All VST plugin editor related functionality.

use libc::c_void;

/// Implemented by plugin editors.
#[allow(unused_variables)]
pub trait Editor {
    /// Get the size of the editor window.
    fn size(&self) -> (i32, i32);

    /// Get the coordinates of the editor window.
    fn position(&self) -> (i32, i32);

    /// Editor idle call. Called by host.
    fn idle(&mut self) {}

    /// Called when the editor window is closed.
    fn close(&mut self) {}

    /// Called when the editor window is opened. `window` is a platform dependant window pointer
    /// (e.g. `HWND` on Windows, `WindowRef` on OSX, `Window` on X11/Linux).
    fn open(&mut self, window: *mut c_void);

    /// Return whether the window is currently open.
    fn is_open(&mut self) -> bool;

    /// Set the knob mode for this editor (if supported by host).
    ///
    /// Return true if the knob mode was set.
    fn set_knob_mode(&mut self, mode: KnobMode) -> bool { false }

    /// Recieve key up event. Return true if the key was used.
    fn key_up(&mut self, keycode: KeyCode) -> bool { false }

    /// Receive key down event. Return true if the key was used.
    fn key_down(&mut self, keycode: KeyCode) -> bool { false }
}

/// Rectangle used to specify dimensions of editor window.
#[doc(hidden)]
pub struct Rect {
    /// Y value in pixels of top side.
    pub top: i16,
    /// X value in pixels of left side.
    pub left: i16,
    /// Y value in pixels of bottom side.
    pub bottom: i16,
    /// X value in pixels of right side.
    pub right: i16
}

/// A platform independent key code. Includes modifier keys.
pub struct KeyCode {
    /// ASCII character for key pressed (if applicable).
    pub character: char,
    /// Key pressed. See `enums::Key`.
    pub key: Key,
    /// Modifier key bitflags. See `enums::flags::modifier_key`.
    pub modifier: u8
}

/// Allows host to set how a parameter knob works.
#[repr(usize)]
#[derive(Copy, Clone, Debug)]
#[allow(missing_docs)]
pub enum KnobMode {
    Circular,
    CircularRelative,
    Linear
}
impl_clike!(KnobMode);

/// Platform independent key codes.
#[allow(missing_docs)]
#[repr(usize)]
#[derive(Debug, Copy, Clone)]
pub enum Key {
	Back = 1,
	Tab,
	Clear,
	Return,
	Pause,
	Escape,
	Space,
	Next,
	End,
	Home,
	Left,
	Up,
	Right,
	Down,
	PageUp,
	PageDown,
	Select,
	Print,
	Enter,
	Snapshot,
	Insert,
	Delete,
	Help,
	Numpad0,
	Numpad1,
	Numpad2,
	Numpad3,
	Numpad4,
	Numpad5,
	Numpad6,
	Numpad7,
	Numpad8,
	Numpad9,
	Multiply,
	Add,
	Separator,
	Subtract,
	Decimal,
	Divide,
	F1,
	F2,
	F3,
	F4,
	F5,
	F6,
	F7,
	F8,
	F9,
	F10,
	F11,
	F12,
	Numlock,
	Scroll,
	Shift,
	Control,
	Alt,
	Equals
}
impl_clike!(Key);
<|endoftext|>


<commit_before>use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use game;
use game::Direction;

pub struct Engine {
    event_pump: sdl2::EventPump,
    renderer: sdl2::render::Renderer<'static>,
    game_state: game::GameState,
}

impl Engine {
    pub fn run(&mut self) -> Result<(), String> {
        let mut framecounter = 0;
        loop {
            for event in self.event_pump.poll_iter() {
                match event {
                    Event::Quit { .. } |
                    Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return Ok(()),
                    Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
                        self.game_state.set_snake_dir(Direction::Up)
                    }
                    Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
                        self.game_state.set_snake_dir(Direction::Down)
                    }
                    Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
                        self.game_state.set_snake_dir(Direction::Left)
                    }
                    Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
                        self.game_state.set_snake_dir(Direction::Right)
                    }
                    _ => (),
                }
            }
            if framecounter % 10 == 0 {
                self.game_state.update();
            }
            self.render()?;
            framecounter += 1;
        }
    }

    fn render(&mut self) -> Result<(), String> {
        self.renderer.set_draw_color(Color::RGB(0, 0, 0));
        self.renderer.clear();
        let scale: u32 = 8;
        for ((y, x), &tile) in self.game_state.tiles().indexed_iter() {
            let color = match tile {
                game::Tile::Floor => Color::RGB(0, 0, 255),
                game::Tile::Wall => Color::RGB(255, 0, 0),
                game::Tile::Food => Color::RGB(255, 255, 0),
                game::Tile::Snake(_) => Color::RGB(0, 255, 0),
            };
            self.renderer.set_draw_color(color);
            self.renderer
                .fill_rect(sdl2::rect::Rect::new(x as i32 * scale as i32,
                                                 y as i32 * scale as i32,
                                                 scale,
                                                 scale))?;
        }
        self.renderer.present();

        Ok(())
    }
}

pub fn init() -> Result<Engine, String> {
    let sdl = sdl2::init()?;
    let video = sdl.video()?;
    let event_pump = sdl.event_pump()?;
    let window = video.window("Snake", 640, 480)
        .build()
        .or_else(|e| Err(format!("{}", e)))?;
    let renderer = window.renderer()
        .present_vsync()
        .build()
        .or_else(|e| Err(format!("{}", e)))?;
    let game_state = game::GameState::new();

    Ok(Engine {
           event_pump: event_pump,
           renderer: renderer,
           game_state: game_state,
       })
}
<commit_msg>Fullscreen support (toggle with F key)<commit_after>use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use sdl2::video::FullscreenType;
use game;
use game::Direction;

pub struct Engine {
    event_pump: sdl2::EventPump,
    renderer: sdl2::render::Renderer<'static>,
    game_state: game::GameState,
}

impl Engine {
    pub fn run(&mut self) -> Result<(), String> {
        let mut framecounter = 0;
        loop {
            for event in self.event_pump.poll_iter() {
                match event {
                    Event::Quit { .. } => return Ok(()),
                    Event::KeyDown { keycode: Some(keycode), repeat: false, .. } => {
                        match keycode {
                            Keycode::Escape => return Ok(()),
                            Keycode::F => {
                                {
                                    let mut window = self.renderer.window_mut().unwrap();
                                    let new_fullscreen_state = match window.fullscreen_state() {
                                        FullscreenType::Off => FullscreenType::Desktop,
                                        _ => FullscreenType::Off,
                                    };
                                    window.set_fullscreen(new_fullscreen_state)?;
                                }
                                self.renderer
                                    .set_logical_size(640, 480)
                                    .or_else(|e| Err(format!("{}", e)))?;
                            }
                            Keycode::Up => self.game_state.set_snake_dir(Direction::Up),
                            Keycode::Down => self.game_state.set_snake_dir(Direction::Down),
                            Keycode::Left => self.game_state.set_snake_dir(Direction::Left),
                            Keycode::Right => self.game_state.set_snake_dir(Direction::Right),
                            _ => {}
                        }
                    }
                    _ => {}
                }
            }
            if framecounter % 10 == 0 {
                self.game_state.update();
            }
            self.render()?;
            framecounter += 1;
        }
    }

    fn render(&mut self) -> Result<(), String> {
        self.renderer.set_draw_color(Color::RGB(0, 0, 0));
        self.renderer.clear();
        let scale: u32 = 8;
        for ((y, x), &tile) in self.game_state.tiles().indexed_iter() {
            let color = match tile {
                game::Tile::Floor => Color::RGB(0, 0, 255),
                game::Tile::Wall => Color::RGB(255, 0, 0),
                game::Tile::Food => Color::RGB(255, 255, 0),
                game::Tile::Snake(_) => Color::RGB(0, 255, 0),
            };
            self.renderer.set_draw_color(color);
            self.renderer
                .fill_rect(sdl2::rect::Rect::new(x as i32 * scale as i32,
                                                 y as i32 * scale as i32,
                                                 scale,
                                                 scale))?;
        }
        self.renderer.present();

        Ok(())
    }
}

pub fn init() -> Result<Engine, String> {
    let sdl = sdl2::init()?;
    let video = sdl.video()?;
    let event_pump = sdl.event_pump()?;
    let window = video.window("Snake", 640, 480)
        .build()
        .or_else(|e| Err(format!("{}", e)))?;
    let renderer = window.renderer()
        .present_vsync()
        .build()
        .or_else(|e| Err(format!("{}", e)))?;
    let game_state = game::GameState::new();

    Ok(Engine {
           event_pump: event_pump,
           renderer: renderer,
           game_state: game_state,
       })
}
<|endoftext|>