<commit_before>// Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-test arcs no longer unwrap

extern crate sync;

use std::from_str::FromStr;
use std::iter::count;
use std::cmp::min;
use std::os;
use std::vec::from_elem;
use sync::Arc;
use sync::RWArc;

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

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

fn mult(v: RWArc<~[f64]>, out: RWArc<~[f64]>, f: fn(&~[f64], uint) -> f64) {
    let wait = Arc::new(());
    let len = out.read(|out| out.len());
    let chunk = len / 100 + 1;
    for chk in count(0, chunk) {
        if chk >= len {break;}
        let w = wait.clone();
        let v = v.clone();
        let out = out.clone();
        spawn(proc() {
            for i in range(chk, min(len, chk + chunk)) {
                let val = v.read(|v| f(v, i));
                out.write(|out| out[i] = val);
            }
            let _ = w;
        });
    }
    let _ = wait.unwrap();
}

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

fn mult_Av(v: RWArc<~[f64]>, out: RWArc<~[f64]>) {
    mult(v, out, mult_Av_impl);
}

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

fn mult_Atv(v: RWArc<~[f64]>, out: RWArc<~[f64]>) {
    mult(v, out, mult_Atv_impl);
}

fn mult_AtAv(v: RWArc<~[f64]>, out: RWArc<~[f64]>, tmp: RWArc<~[f64]>) {
    mult_Av(v, tmp.clone());
    mult_Atv(tmp, out);
}

fn main() {
    let args = os::args();
    let n = if os::getenv("RUST_BENCH").is_some() {
        5500
    } else if args.len() < 2 {
        2000
    } else {
        FromStr::from_str(args[1]).unwrap()
    };
    let u = RWArc::new(from_elem(n, 1.));
    let v = RWArc::new(from_elem(n, 1.));
    let tmp = RWArc::new(from_elem(n, 1.));
    for _ in range(0, 10) {
        mult_AtAv(u.clone(), v.clone(), tmp.clone());
        mult_AtAv(v.clone(), u.clone(), tmp.clone());
    }
    let u = u.unwrap();
    let v = v.unwrap();
    println!("{:.9f}", (dot(u,v) / dot(v,v)).sqrt());
}
<commit_msg>fix shootout-spectralnorm, broken since Arc cannot unwrap.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate sync;

use std::from_str::FromStr;
use std::iter::count;
use std::cmp::min;
use std::os;
use std::vec::from_elem;
use sync::RWArc;

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

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

fn mult(v: RWArc<~[f64]>, out: RWArc<~[f64]>, f: fn(&~[f64], uint) -> f64) {
    // We lanch in different tasks the work to be done.  To finish
    // this fuction, we need to wait for the completion of every
    // tasks.  To do that, we give to each tasks a wait_chan that we
    // drop at the end of the work.  At the end of this function, we
    // wait until the channel hang up.
    let (wait_port, wait_chan) = Chan::new();

    let len = out.read(|out| out.len());
    let chunk = len / 100 + 1;
    for chk in count(0, chunk) {
        if chk >= len {break;}
        let w = wait_chan.clone();
        let v = v.clone();
        let out = out.clone();
        spawn(proc() {
            for i in range(chk, min(len, chk + chunk)) {
                let val = v.read(|v| f(v, i));
                out.write(|out| out[i] = val);
            }
            drop(w)
        });
    }

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

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

fn mult_Av(v: RWArc<~[f64]>, out: RWArc<~[f64]>) {
    mult(v, out, mult_Av_impl);
}

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

fn mult_Atv(v: RWArc<~[f64]>, out: RWArc<~[f64]>) {
    mult(v, out, mult_Atv_impl);
}

fn mult_AtAv(v: RWArc<~[f64]>, out: RWArc<~[f64]>, tmp: RWArc<~[f64]>) {
    mult_Av(v, tmp.clone());
    mult_Atv(tmp, out);
}

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

    u.read(|u| v.read(|v| {
        println!("{:.9f}", (dot(*u, *v) / dot(*v, *v)).sqrt());
    }))
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2018-2020 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

use gtk::{
    ButtonExt,
    Inhibit,
    LabelExt,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::{Relm, Widget, timeout};
use relm_derive::{Msg, widget};

use self::Msg::*;

// Define the structure of the model.
pub struct Model {
    counter: i32,
}

// The messages that can be sent to the update function.
#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
    Show,
}

#[widget]
impl Widget for Win {
    // The initial model.
    fn model(relm: &Relm<Self>, _: ()) -> Model {
        timeout(relm.stream(), 1000, || Show);
        Model {
            counter: 0,
        }
    }

    // Update the model according to the message received.
    fn update(&mut self, event: Msg) {
        match event {
            Decrement => self.model.counter -= 1,
            Increment => self.model.counter += 1,
            Quit => gtk::main_quit(),
            Show => self.widgets.dec_button.set_visible(true),
        }
    }

    view! {
        gtk::Window {
            gtk::Box {
                // Set the orientation property of the Box.
                orientation: Vertical,
                // Create a Button inside the Box.
                gtk::Button {
                    // Send the message Increment when the button is clicked.
                    clicked => Increment,
                    // TODO: check if using two events of the same name work.
                    label: "+",
                },
                #[name="label"]
                gtk::Label {
                    // Bind the text property of the label to the counter attribute of the model.
                    text: &self.model.counter.to_string(),
                },
                #[name="dec_button"]
                gtk::Button {
                    clicked => Decrement,
                    label: "-",
                    visible: false,
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    Win::run(()).expect("Win::run failed");
}

#[cfg(test)]
mod tests {
    use gtk::LabelExt;

    use gtk_test::assert_text;
    use relm_test::click;

    use crate::Win;

    #[test]
    fn label_change() {
        let (_component, widgets) = relm::init_test::<Win>(()).expect("init_test failed");
        let dec_button = &widgets.dec_button;
        let label = &widgets.label;

        click(dec_button);
        assert_text!(label, -1);
        click(dec_button);
        assert_text!(label, -2);
    }
}
<commit_msg>Fix test in example<commit_after>/*
 * Copyright (c) 2018-2020 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

use gtk::{
    ButtonExt,
    Inhibit,
    LabelExt,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::{Relm, Widget, timeout};
use relm_derive::{Msg, widget};

use self::Msg::*;

// Define the structure of the model.
pub struct Model {
    counter: i32,
}

// The messages that can be sent to the update function.
#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
    Show,
}

#[widget]
impl Widget for Win {
    // The initial model.
    fn model(relm: &Relm<Self>, _: ()) -> Model {
        timeout(relm.stream(), 1000, || Show);
        Model {
            counter: 0,
        }
    }

    // Update the model according to the message received.
    fn update(&mut self, event: Msg) {
        match event {
            Decrement => self.model.counter -= 1,
            Increment => self.model.counter += 1,
            Quit => gtk::main_quit(),
            Show => self.widgets.dec_button.set_visible(true),
        }
    }

    view! {
        gtk::Window {
            gtk::Box {
                // Set the orientation property of the Box.
                orientation: Vertical,
                // Create a Button inside the Box.
                gtk::Button {
                    // Send the message Increment when the button is clicked.
                    clicked => Increment,
                    // TODO: check if using two events of the same name work.
                    label: "+",
                },
                #[name="label"]
                gtk::Label {
                    // Bind the text property of the label to the counter attribute of the model.
                    text: &self.model.counter.to_string(),
                },
                #[name="dec_button"]
                gtk::Button {
                    clicked => Decrement,
                    label: "-",
                    visible: false,
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    Win::run(()).expect("Win::run failed");
}

#[cfg(test)]
mod tests {
    use gtk::LabelExt;

    use gtk_test::assert_text;
    use relm_test::click;

    use crate::Win;

    #[test]
    fn label_change() {
        let (_component, _, widgets) = relm::init_test::<Win>(()).expect("init_test failed");
        let dec_button = &widgets.dec_button;
        let label = &widgets.label;

        click(dec_button);
        assert_text!(label, -1);
        click(dec_button);
        assert_text!(label, -2);
    }
}
<|endoftext|>


<commit_before>use hyper::Client;
use hyper::Result as HyperResult;
use hyper::client::Response as HyperResponse;
use hyper::header::{Headers, ContentType};
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::status::StatusCode;

use event::Event;
use types::Result;
use expected_version::ExpectedVersion;
use error::HesError;
use error::UserErrorKind;
use connection::ConnectionInfo;

use api::ESExpectedVersion;
use api::to_error::*;

pub struct Appender<'a> {
    connection_info: &'a ConnectionInfo,
}

impl<'a> Appender<'a> {
    pub fn new(connection_info: &'a ConnectionInfo) -> Appender {
        Appender { connection_info: connection_info }
    }

    pub fn append(&self, stream_name: &str, expected_version: ExpectedVersion, events: Vec<Event>) -> Result<()> {
        let client = Client::default();

        let result = client.post(&self.url(stream_name))
            .headers(build_headers(expected_version))
            .body(&request_body(events))
            .send();

        to_hes_result(result)
    }

    fn url(&self, stream_name: &str) -> String {
        format!("http://{}:{}/streams/{}",
                self.connection_info.host,
                self.connection_info.port,
                stream_name)
    }
}

fn build_headers(expected_version: ExpectedVersion) -> Headers {
    let mut headers = Headers::new();
    headers.set(
        ContentType(Mime(TopLevel::Application, SubLevel::Ext("vnd.eventstore.events+json".to_owned()), vec![]))
    );
    headers.set(ESExpectedVersion(expected_version.into()));

    headers
}

fn request_body(events: Vec<Event>) -> String {
    let events_as_json: Vec<String> = events.iter().map(|e| {
        format!(r#"{{
                      "eventType": "{}",
                      "eventId": "{}",
                      "data": {}
                    }}"#,
                e.event_type.to_string(),
                e.event_id.unwrap().hyphenated().to_string(), //TODO Eliminate `unwrap`.
                e.data.clone().unwrap()) //TODO Eliminate `clone` and deal with `unwrap`.
    }).collect::<_>();

    format!("[{}]", events_as_json.join(","))
}

fn to_hes_result(result: HyperResult<HyperResponse>) -> Result<()> {
    match result {
        Ok(response) => {
            match response.status {
                StatusCode::Created => Ok(()),
                _ => stream_deleted_error(response)
                    .and_then(event_number_mismatch_error)
                    .map_err(|kind| HesError::UserError(kind))
                    .and_then(default_error)
            }
        },
        Err(err) => Err(HesError::UserError(UserErrorKind::Http(err)))
    }
}
<commit_msg>Take event option keys into account turning it into JSON<commit_after>use hyper::Client;
use hyper::Result as HyperResult;
use hyper::client::Response as HyperResponse;
use hyper::header::{Headers, ContentType};
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::status::StatusCode;

use event::Event;
use types::Result;
use expected_version::ExpectedVersion;
use error::HesError;
use error::UserErrorKind;
use connection::ConnectionInfo;

use api::ESExpectedVersion;
use api::to_error::*;

pub struct Appender<'a> {
    connection_info: &'a ConnectionInfo,
}

impl<'a> Appender<'a> {
    pub fn new(connection_info: &'a ConnectionInfo) -> Appender {
        Appender { connection_info: connection_info }
    }

    pub fn append(&self, stream_name: &str, expected_version: ExpectedVersion, events: Vec<Event>) -> Result<()> {
        let client = Client::default();

        let result = client.post(&self.url(stream_name))
            .headers(build_headers(expected_version))
            .body(&request_body(events))
            .send();

        to_hes_result(result)
    }

    fn url(&self, stream_name: &str) -> String {
        format!("http://{}:{}/streams/{}",
                self.connection_info.host,
                self.connection_info.port,
                stream_name)
    }
}

fn build_headers(expected_version: ExpectedVersion) -> Headers {
    let mut headers = Headers::new();
    headers.set(
        ContentType(Mime(TopLevel::Application, SubLevel::Ext("vnd.eventstore.events+json".to_owned()), vec![]))
    );
    headers.set(ESExpectedVersion(expected_version.into()));

    headers
}

fn request_body(events: Vec<Event>) -> String {
    let events_as_json: Vec<String> = events.iter().map(|e| {
        let mut result: String = format!(r#"{{"eventType":"{}""#, e.event_type);

        if let Some(id) = e.event_id {
            let id_pair = &format!(r#","eventId":"{}""#, id);
            result.push_str(id_pair)
        }

        if let Some(ref data) = e.data {
            let data_pair = &format!(r#","data":{}"#, data);
            result.push_str(data_pair)
        }

        result.push_str(r#"}"#);

        result
    }).collect::<_>();

    format!("[{}]", events_as_json.join(","))
}

fn to_hes_result(result: HyperResult<HyperResponse>) -> Result<()> {
    match result {
        Ok(response) => {
            match response.status {
                StatusCode::Created => Ok(()),
                _ => stream_deleted_error(response)
                    .and_then(event_number_mismatch_error)
                    .map_err(|kind| HesError::UserError(kind))
                    .and_then(default_error)
            }
        },
        Err(err) => Err(HesError::UserError(UserErrorKind::Http(err)))
    }
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//
/*
Vikram Bhasin vb8nd and Justin Ingram jci5kb
*/

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use std::os::getcwd;
use extra::getopts;
use std::run::Process;
use std::run::ProcessOutput;
use std::run::ProcessOptions;
use std::option::{Option, None, Some};
use std::io::buffered::BufferedWriter;
use std::io::File;
use std::comm::Chan;
use std::io::signal::Listener;
use std::io::signal::{Interrupt};
use std::libc;

struct Shell {
    cmd_prompt: ~str,
    hist: ~[~str],
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {

        Shell {
            cmd_prompt: prompt_str.to_owned(),
            hist: ~[],
        }
    }

    fn listen(&mut self, list: Listener) {
	spawn(proc() {
	    loop {
		match list.port.recv() {
		    Interrupt => { }
		    _ => { println("THERE WAS DERP"); }
		}
	    }
	});
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        let mut x = Listener::new();
	let reg = x.register(Interrupt);

	if reg {
	    self.listen(x);
	} else {
	    println("Failed to register listener");
	}

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");
            self.hist.push(line);
            match program {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                "cd"	=>  { self.changeDir(cmd_line); }
                "history" =>{ self.history(); }
                "gcowsay" => { self.cowsay(cmd_line); }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            //Let's process the argv

            let endopt = argv.pop_opt();
            let end = match endopt {
		Some(stringy) => { stringy }
		None => { ~"" }
            };

            if end.eq(&~"&") {
		// println("Start in a new process" + end);

		if argv.contains(&~">") {
		    println("Contains >");
		}

		self.run_cmd(program, argv, true);
            } else {
		//println("No new process");
		if !end.eq(&~"") {
		    argv.push(end.to_owned());
		}

		if argv.contains(&~">") {
		    //println("Contains >");
		    let mut found = false;
		    let mut filename = ~"";
		    let mut x = 0;
		    for stringy in argv.clone().move_iter() {
			if stringy.eq(&~">") {
			    break;
			}
			x += 1;
		    }
		    match argv.get_opt(x+1) {
			Some(text) => { filename = text.to_owned(); }
			None => {}
		    }
		    argv.remove(x+1);
		    argv.remove(x);
		    self.run_cmd_out(program, argv, filename, false);
		} else {
		    self.run_cmd(program, argv, false);
		}
            }
        }
    }

    fn run_cmd_out(&mut self, program: &str, argv: &[~str], filename: &str, bg: bool) {
        if self.cmd_exists(program) {
	    // Old stuff

            //println("Run command hit");
            //println(program);

	    if !bg {
		// run::process_status(program, argv);
		let mut whichprocop = ProcessOptions::new();
		unsafe {
		    whichprocop.out_fd = Some(libc::fileno(libc::fopen(filename.to_c_str().unwrap(), "w".to_c_str().unwrap())));
		}

	    } else {
		//let f = self.makefunky(program, argv);
		//let (recvp, recvc): (Port<~str>, Chan<~str>) = Chan::new();
		//spawn(expr(f(program, argv)));

		let x = program.clone().to_owned();
		let y = argv.clone().to_owned();

		spawn(proc() {
		    let mut whichprocop = ProcessOptions::new();
		    match(Process::new(x, y, whichprocop)) {
			Some(mut process) => {
			    process.finish();
			}
			None => { println("ERROR"); }
		    }
		});
	    }

        } else {
            println!("{:s}: command not found", program);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str], bg: bool) {
        if self.cmd_exists(program) {
	    // Old stuff

            //println("Run command hit");
            //println(program);

	    if !bg {
		run::process_status(program, argv);
	    } else {
		//let f = self.makefunky(program, argv);
		//let (recvp, recvc): (Port<~str>, Chan<~str>) = Chan::new();
		//spawn(expr(f(program, argv)));

		let x = program.clone().to_owned();
		let y = argv.clone().to_owned();

		spawn(proc() {
		    let mut whichprocop = ProcessOptions::new();
		    match(Process::new(x, y, whichprocop)) {
			Some(mut process) => {
			    process.finish();
			}
			None => { println("ERROR"); }
		    }
		});
	    }

        } else {
            println!("{:s}: command not found", program);
        }
    }
    /*
    fn makefunky(&mut self, program: &str, argv: &[~str]) -> (proc(&str, &[~str])) {
	proc(program: &str, argv: &[~str]) {

	    // whichprocop.dir = self.cwdopt.as_ref();

	    let mut whichproc = Process::new(program, argv, whichprocop);
	    let mut process = whichproc.unwrap();

	    let mut procout = process.finish_with_output();
	    println(std::str::from_utf8(procout.output));
	}
    }
    */

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    //Justin's function for cd
    fn changeDir(&mut self, cmd_line: &str) {
	let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 1 {
            let pstring: ~str = argv.remove(1);

            //println!("You want to change cwd to {:s}", pstring);

            let npath = Path::new(pstring);

            let mut cpath = getcwd();
            cpath.push(npath);

            if cpath.exists() {
		let mut cpathforopt = cpath.clone();
		std::os::change_dir(&cpath);
		// self.cwd = cpath;
            } else {
		println("Path does not exist!");
            }

        }

        let x = getcwd();

        match x.as_str() {
	    Some(path_str) => {println!("{:s}", path_str); }
	    None	=> {println("Path not representable as string!"); }
        }
    }

    fn history(&mut self) {
	let mut n :int = 1;
	for stringy in self.hist.iter() {
	    let x = stringy.clone();
	    print("[" + n.to_str() + "]" + ~"\t" + x);
	    n += 1;
	}
    }

    fn cowsay(&mut self, cmd_line: &str) {
	let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
	let mut stringer = ~"";

	if argv.len() > 1 {
	    argv.remove(0);
	}

	for stringy in argv.iter() {
	    stringer = stringer + ~" " + stringy.to_owned();
	}

	println(" _______");
	println("< " + stringer + " >");
	println(" -------");
	println("        \\   ^__^");
	println("         \\  (oo)\\_______");
	println("            (__)\\       )\\/\\");
	println("                ||----w |");
	println("                ||     ||");
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {

    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>OUTPUT WORKS<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//
/*
Vikram Bhasin vb8nd and Justin Ingram jci5kb
*/

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use std::os::getcwd;
use extra::getopts;
use std::run::Process;
use std::run::ProcessOutput;
use std::run::ProcessOptions;
use std::option::{Option, None, Some};
use std::io::buffered::BufferedWriter;
use std::io::File;
use std::comm::Chan;
use std::io::signal::Listener;
use std::io::signal::{Interrupt};
use std::libc;

struct Shell {
    cmd_prompt: ~str,
    hist: ~[~str],
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {

        Shell {
            cmd_prompt: prompt_str.to_owned(),
            hist: ~[],
        }
    }

    fn listen(&mut self, list: Listener) {
	spawn(proc() {
	    loop {
		match list.port.recv() {
		    Interrupt => { }
		    _ => { println("THERE WAS DERP"); }
		}
	    }
	});
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        let mut x = Listener::new();
	let reg = x.register(Interrupt);

	if reg {
	    self.listen(x);
	} else {
	    println("Failed to register listener");
	}

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");
            self.hist.push(line);
            match program {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                "cd"	=>  { self.changeDir(cmd_line); }
                "history" =>{ self.history(); }
                "gcowsay" => { self.cowsay(cmd_line); }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            //Let's process the argv

            let endopt = argv.pop_opt();
            let end = match endopt {
		Some(stringy) => { stringy }
		None => { ~"" }
            };

            if end.eq(&~"&") {
		// println("Start in a new process" + end);

		if argv.contains(&~">") {
		    // println("Contains >");
		    if argv.contains(&~">") {
		    //println("Contains >");
		    let mut found = false;
		    let mut filename = ~"";
		    let mut x = 0;
		    for stringy in argv.clone().move_iter() {
			if stringy.eq(&~">") {
			    break;
			}
			x += 1;
		    }
		    match argv.get_opt(x+1) {
			Some(text) => { filename = text.to_owned(); }
			None => {}
		    }
		    argv.remove(x+1);
		    argv.remove(x);
		    self.run_cmd_out(program, argv, filename, true);
		} else {
		    self.run_cmd(program, argv, true);
		}
		}

		self.run_cmd(program, argv, true);
            } else {
		//println("No new process");
		if !end.eq(&~"") {
		    argv.push(end.to_owned());
		}

		if argv.contains(&~">") {
		    //println("Contains >");
		    let mut found = false;
		    let mut filename = ~"";
		    let mut x = 0;
		    for stringy in argv.clone().move_iter() {
			if stringy.eq(&~">") {
			    break;
			}
			x += 1;
		    }
		    match argv.get_opt(x+1) {
			Some(text) => { filename = text.to_owned(); }
			None => {}
		    }
		    argv.remove(x+1);
		    argv.remove(x);
		    self.run_cmd_out(program, argv, filename, false);
		} else {
		    self.run_cmd(program, argv, false);
		}
            }
        }
    }

    fn run_cmd_out(&mut self, program: &str, argv: &[~str], filename: &str, bg: bool) {
        if self.cmd_exists(program) {
	    // Old stuff

            //println("Run command hit");
            //println(program);

	    if !bg {
		// run::process_status(program, argv);
		let mut whichprocop = ProcessOptions::new();
		unsafe {
		    whichprocop.out_fd = Some(libc::fileno(libc::fopen(filename.to_c_str().unwrap(), "w".to_c_str().unwrap())));
		}
		match(Process::new(program, argv, whichprocop)) {
		    Some(mut process) => {
			process.finish();
		    }
		    None => { println("ERROR"); }
		}

	    } else {
		//let f = self.makefunky(program, argv);
		//let (recvp, recvc): (Port<~str>, Chan<~str>) = Chan::new();
		//spawn(expr(f(program, argv)));

		let x = program.clone().to_owned();
		let y = argv.clone().to_owned();
		let f = filename.clone().to_owned();

		spawn(proc() {
		    let mut whichprocop = ProcessOptions::new();
		    unsafe {
			whichprocop.out_fd = Some(libc::fileno(libc::fopen(f.to_c_str().unwrap(), "w".to_c_str().unwrap())));
		    }
		    match(Process::new(x, y, whichprocop)) {
			Some(mut process) => {
			    process.finish();
			}
			None => { println("ERROR"); }
		    }
		});
	    }

        } else {
            println!("{:s}: command not found", program);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str], bg: bool) {
        if self.cmd_exists(program) {
	    // Old stuff

            //println("Run command hit");
            //println(program);

	    if !bg {
		run::process_status(program, argv);
	    } else {
		//let f = self.makefunky(program, argv);
		//let (recvp, recvc): (Port<~str>, Chan<~str>) = Chan::new();
		//spawn(expr(f(program, argv)));

		let x = program.clone().to_owned();
		let y = argv.clone().to_owned();

		spawn(proc() {
		    let mut whichprocop = ProcessOptions::new();
		    match(Process::new(x, y, whichprocop)) {
			Some(mut process) => {
			    process.finish();
			}
			None => { println("ERROR"); }
		    }
		});
	    }

        } else {
            println!("{:s}: command not found", program);
        }
    }
    /*
    fn makefunky(&mut self, program: &str, argv: &[~str]) -> (proc(&str, &[~str])) {
	proc(program: &str, argv: &[~str]) {

	    // whichprocop.dir = self.cwdopt.as_ref();

	    let mut whichproc = Process::new(program, argv, whichprocop);
	    let mut process = whichproc.unwrap();

	    let mut procout = process.finish_with_output();
	    println(std::str::from_utf8(procout.output));
	}
    }
    */

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    //Justin's function for cd
    fn changeDir(&mut self, cmd_line: &str) {
	let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 1 {
            let pstring: ~str = argv.remove(1);

            //println!("You want to change cwd to {:s}", pstring);

            let npath = Path::new(pstring);

            let mut cpath = getcwd();
            cpath.push(npath);

            if cpath.exists() {
		let mut cpathforopt = cpath.clone();
		std::os::change_dir(&cpath);
		// self.cwd = cpath;
            } else {
		println("Path does not exist!");
            }

        }

        let x = getcwd();

        match x.as_str() {
	    Some(path_str) => {println!("{:s}", path_str); }
	    None	=> {println("Path not representable as string!"); }
        }
    }

    fn history(&mut self) {
	let mut n :int = 1;
	for stringy in self.hist.iter() {
	    let x = stringy.clone();
	    print("[" + n.to_str() + "]" + ~"\t" + x);
	    n += 1;
	}
    }

    fn cowsay(&mut self, cmd_line: &str) {
	let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
	let mut stringer = ~"";

	if argv.len() > 1 {
	    argv.remove(0);
	}

	for stringy in argv.iter() {
	    stringer = stringer + ~" " + stringy.to_owned();
	}

	println(" _______");
	println("< " + stringer + " >");
	println(" -------");
	println("        \\   ^__^");
	println("         \\  (oo)\\_______");
	println("            (__)\\       )\\/\\");
	println("                ||----w |");
	println("                ||     ||");
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {

    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                "cd"    =>  { self.run_cd(cmd_line); }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] = self.get_args(cmd_line);

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            self.run_cmd(program, argv);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str]) {
        if self.cmd_exists(program) {
            run::process_status(program, argv);
        } else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    fn run_cd(&mut self, cmd_line: &str) {
        let argv: ~[~str] = self.get_args(cmd_line);
        let pathOpt: Option<Path> = match argv.len() {
            1   =>  { os::homedir() }
            0   =>  { os::homedir() }
            _   =>  { Some(Path::new(argv[1])) }
        };

        match pathOpt {
            Some(path)   =>  {
                if path.is_dir() {
                    os::change_dir(&path);
                } else {
                    println!("Error: {:s} is not a directory", path.as_str().unwrap());
                }
            }
            None        =>  {
                println!("Error: Invalid path");
            }
        };
    }

    fn get_args(&mut self, cmd_line: &str) -> ~[~str] {
        return cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>Added history command.<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    cmd_history: ~[~str],
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            cmd_history: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""          =>  { continue; }
                "exit"      =>  { return; }
                "cd"        =>  { self.run_cd(cmd_line); }
                "history"   =>  { self.run_history(cmd_line); }
                _           =>  { self.run_cmdline(cmd_line); }
            }

            self.cmd_history.push(program.to_owned());
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] = self.get_args(cmd_line);

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            self.run_cmd(program, argv);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str]) {
        if self.cmd_exists(program) {
            run::process_status(program, argv);
        } else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    fn run_cd(&mut self, cmd_line: &str) {
        let argv: ~[~str] = self.get_args(cmd_line);
        let pathOpt: Option<Path> = match argv.len() {
            1   =>  { os::homedir() }
            0   =>  { os::homedir() }
            _   =>  { Some(Path::new(argv[1])) }
        };

        match pathOpt {
            Some(path)   =>  {
                if path.is_dir() {
                    os::change_dir(&path);
                } else {
                    println!("Error: {:s} is not a directory", path.as_str().unwrap());
                }
            }
            None        =>  {
                println!("Error: Invalid path");
            }
        };
    }

    fn run_history(&mut self, cmd_line: &str) {
        let argv: ~[~str] = self.get_args(cmd_line);
        if (argv.len() > 1) {
            println!("Error: history does not take options (sadly).");
        }
        else {
            let mut i = 1;
            for entry in self.cmd_history.iter() {
                println!("{:d} \t{:s}", i, entry.to_owned());
                i = i + 1;
            }
        }

    }

    fn get_args(&mut self, cmd_line: &str) -> ~[~str] {
        return cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


<commit_before>//! Generic WebSocket message stream.

pub mod frame;

mod message;

pub use self::message::Message;
pub use self::frame::CloseFrame;

use std::collections::VecDeque;
use std::io::{Read, Write, ErrorKind as IoErrorKind};
use std::mem::replace;

use error::{Error, Result};
use self::message::{IncompleteMessage, IncompleteMessageType};
use self::frame::{Frame, FrameSocket};
use self::frame::coding::{OpCode, Data as OpData, Control as OpCtl, CloseCode};
use util::NonBlockingResult;

/// Indicates a Client or Server role of the websocket
#[derive(Debug, Clone, Copy)]
pub enum Role {
    /// This socket is a server
    Server,
    /// This socket is a client
    Client,
}

/// WebSocket input-output stream.
///
/// This is THE structure you want to create to me able to talk the WebSocket protocol.
/// It may be created by calling `connect`, `accept` or `client` functions.
pub struct WebSocket<Stream> {
    /// Server or client?
    role: Role,
    /// The underlying socket.
    socket: FrameSocket<Stream>,
    /// The state of processing, either "active" or "closing".
    state: WebSocketState,
    /// Receive: an incomplete message being processed.
    incomplete: Option<IncompleteMessage>,
    /// Send: a data send queue.
    send_queue: VecDeque<Frame>,
    /// Send: an OOB pong message.
    pong: Option<Frame>,
}

impl<Stream> WebSocket<Stream> {
    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_raw_socket(stream: Stream, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::new(stream), role)
    }

    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_partially_read(stream: Stream, part: Vec<u8>, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::from_partially_read(stream, part), role)
    }

    /// Returns a shared reference to the inner stream.
    pub fn get_ref(&self) -> &Stream {
        self.socket.get_ref()
    }
    /// Returns a mutable reference to the inner stream.
    pub fn get_mut(&mut self) -> &mut Stream {
        self.socket.get_mut()
    }

    /// Convert a frame socket into a WebSocket.
    fn from_frame_socket(socket: FrameSocket<Stream>, role: Role) -> Self {
        WebSocket {
            role: role,
            socket: socket,
            state: WebSocketState::Active,
            incomplete: None,
            send_queue: VecDeque::new(),
            pong: None,
        }
    }
}

impl<Stream: Read + Write> WebSocket<Stream> {
    /// Read a message from stream, if possible.
    ///
    /// This function sends pong and close responses automatically.
    /// However, it never blocks on write.
    pub fn read_message(&mut self) -> Result<Message> {
        loop {
            // Since we may get ping or close, we need to reply to the messages even during read.
            // Thus we call write_pending() but ignore its blocking.
            self.write_pending().no_block()?;
            // If we get here, either write blocks or we have nothing to write.
            // Thus if read blocks, just let it return WouldBlock.
            let res = self.read_message_frame();
            if let Some(message) = self.translate_close(res)? {
                trace!("Received message {}", message);
                return Ok(message)
            }
        }
    }

    /// Send a message to stream, if possible.
    ///
    /// This function guarantees that the frame is queued regardless of any errors.
    /// There is no need to resend the frame. In order to handle WouldBlock or Incomplete,
    /// call write_pending() afterwards.
    pub fn write_message(&mut self, message: Message) -> Result<()> {
        let frame = {
            let opcode = match message {
                Message::Text(_) => OpData::Text,
                Message::Binary(_) => OpData::Binary,
            };
            Frame::message(message.into_data(), OpCode::Data(opcode), true)
        };
        self.send_queue.push_back(frame);
        self.write_pending()
    }

    /// Send ping.
    pub fn send_ping(&mut self, payload: Vec<u8>) -> Result<()> {
        self.send_queue.push_back(Frame::ping(payload));
        self.write_pending()
    }

    /// Close the connection.
    ///
    /// This function guarantees that the close frame will be queued.
    /// There is no need to call it again, just like write_message().
    pub fn close(&mut self, code: Option<CloseFrame>) -> Result<()> {
        if let WebSocketState::Active = self.state {
            self.state = WebSocketState::ClosedByUs;
            let frame = Frame::close(code);
            self.send_queue.push_back(frame);
        } else {
            // Already closed, nothing to do.
        }
        self.write_pending()
    }

    /// Flush the pending send queue.
    pub fn write_pending(&mut self) -> Result<()> {
        // First, make sure we have no pending frame sending.
        {
            let res = self.socket.write_pending();
            self.translate_close(res)?;
        }

        // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
        // response, unless it already received a Close frame. It SHOULD
        // respond with Pong frame as soon as is practical. (RFC 6455)
        if let Some(pong) = replace(&mut self.pong, None) {
            self.send_one_frame(pong)?;
        }
        // If we have any unsent frames, send them.
        while let Some(data) = self.send_queue.pop_front() {
            self.send_one_frame(data)?;
        }

        // If we're closing and there is nothing to send anymore, we should close the connection.
        if self.send_queue.is_empty() {
            if let WebSocketState::ClosedByPeer(ref mut frame) = self.state {
                // The underlying TCP connection, in most normal cases, SHOULD be closed
                // first by the server, so that it holds the TIME_WAIT state and not the
                // client (as this would prevent it from re-opening the connection for 2
                // maximum segment lifetimes (2MSL), while there is no corresponding
                // server impact as a TIME_WAIT connection is immediately reopened upon
                // a new SYN with a higher seq number). (RFC 6455)
                match self.role {
                    Role::Client => Ok(()),
                    Role::Server => Err(Error::ConnectionClosed(replace(frame, None))),
                }
            } else {
                Ok(())
            }
        } else {
            Ok(())
        }
    }

    /// Try to decode one message frame. May return None.
    fn read_message_frame(&mut self) -> Result<Option<Message>> {
        if let Some(mut frame) = self.socket.read_frame()? {

            // MUST be 0 unless an extension is negotiated that defines meanings
            // for non-zero values.  If a nonzero value is received and none of
            // the negotiated extensions defines the meaning of such a nonzero
            // value, the receiving endpoint MUST _Fail the WebSocket
            // Connection_.
            if frame.has_rsv1() || frame.has_rsv2() || frame.has_rsv3() {
                return Err(Error::Protocol("Reserved bits are non-zero".into()))
            }

            match self.role {
                Role::Server => {
                    if frame.is_masked() {
                        // A server MUST remove masking for data frames received from a client
                        // as described in Section 5.3. (RFC 6455)
                        frame.remove_mask()
                    } else {
                        // The server MUST close the connection upon receiving a
                        // frame that is not masked. (RFC 6455)
                        return Err(Error::Protocol("Received an unmasked frame from client".into()))
                    }
                }
                Role::Client => {
                    if frame.is_masked() {
                        // A client MUST close a connection if it detects a masked frame. (RFC 6455)
                        return Err(Error::Protocol("Received a masked frame from server".into()))
                    }
                }
            }

            match frame.opcode() {

                OpCode::Control(ctl) => {
                    (match ctl {
                        // All control frames MUST have a payload length of 125 bytes or less
                        // and MUST NOT be fragmented. (RFC 6455)
                        _ if !frame.is_final() => {
                            Err(Error::Protocol("Fragmented control frame".into()))
                        }
                        _ if frame.payload().len() > 125 => {
                            Err(Error::Protocol("Control frame too big".into()))
                        }
                        OpCtl::Close => {
                            self.do_close(frame.into_close()?)
                        }
                        OpCtl::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown control frame type {}", i).into()))
                        }
                        OpCtl::Ping | OpCtl::Pong if !self.state.is_active() => {
                            // No ping processing while closing.
                            Ok(())
                        }
                        OpCtl::Ping => {
                            self.do_ping(frame.into_data())
                        }
                        OpCtl::Pong => {
                            self.do_pong(frame.into_data())
                        }
                    }).map(|_| None)
                }

                OpCode::Data(_) if !self.state.is_active() => {
                    // No data processing while closing.
                    Ok(None)
                }

                OpCode::Data(data) => {
                    let fin = frame.is_final();
                    match data {
                        OpData::Continue => {
                            if let Some(ref mut msg) = self.incomplete {
                                // TODO if msg too big
                                msg.extend(frame.into_data())?;
                            } else {
                                return Err(Error::Protocol("Continue frame but nothing to continue".into()))
                            }
                            if fin {
                                Ok(Some(replace(&mut self.incomplete, None).unwrap().complete()?))
                            } else {
                                Ok(None)
                            }
                        }
                        c if self.incomplete.is_some() => {
                            Err(Error::Protocol(
                                format!("Received {} while waiting for more fragments", c).into()
                            ))
                        }
                        OpData::Text | OpData::Binary => {
                            let msg = {
                                let message_type = match data {
                                    OpData::Text => IncompleteMessageType::Text,
                                    OpData::Binary => IncompleteMessageType::Binary,
                                    _ => panic!("Bug: message is not text nor binary"),
                                };
                                let mut m = IncompleteMessage::new(message_type);
                                m.extend(frame.into_data())?;
                                m
                            };
                            if fin {
                                Ok(Some(msg.complete()?))
                            } else {
                                self.incomplete = Some(msg);
                                Ok(None)
                            }
                        }
                        OpData::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown data frame type {}", i).into()))
                        }
                    }
                }

            } // match opcode

        } else {
            Err(Error::Protocol("Connection reset without closing handshake".into()))
        }
    }

    /// Received a close frame.
    fn do_close(&mut self, close: Option<CloseFrame>) -> Result<()> {
        debug!("Received close frame: {:?}", close);
        match self.state {
            WebSocketState::Active => {
                let close_code = close.as_ref().map(|f| f.code);
                self.state = WebSocketState::ClosedByPeer(close.map(CloseFrame::into_owned));
                let reply = if let Some(code) = close_code {
                    if code.is_allowed() {
                        Frame::close(Some(CloseFrame {
                            code: CloseCode::Normal,
                            reason: "".into(),
                        }))
                    } else {
                        Frame::close(Some(CloseFrame {
                            code: CloseCode::Protocol,
                            reason: "Protocol violation".into()
                        }))
                    }
                } else {
                    Frame::close(None)
                };
                debug!("Replying to close with {:?}", reply);
                self.send_queue.push_back(reply);
                Ok(())
            }
            WebSocketState::ClosedByPeer(_) | WebSocketState::CloseAcknowledged(_) => {
                // It is already closed, just ignore.
                Ok(())
            }
            WebSocketState::ClosedByUs => {
                // We received a reply.
                let close = close.map(CloseFrame::into_owned);
                match self.role {
                    Role::Client => {
                        // Client waits for the server to close the connection.
                        self.state = WebSocketState::CloseAcknowledged(close);
                        Ok(())
                    }
                    Role::Server => {
                        // Server closes the connection.
                        Err(Error::ConnectionClosed(close))
                    }
                }
            }
        }
    }

    /// Received a ping frame.
    fn do_ping(&mut self, ping: Vec<u8>) -> Result<()> {
        // If an endpoint receives a Ping frame and has not yet sent Pong
        // frame(s) in response to previous Ping frame(s), the endpoint MAY
        // elect to send a Pong frame for only the most recently processed Ping
        // frame. (RFC 6455)
        // We do exactly that, keeping a "queue" from one and only Pong frame.
        self.pong = Some(Frame::pong(ping));
        Ok(())
    }

    /// Received a pong frame.
    fn do_pong(&mut self, _: Vec<u8>) -> Result<()> {
        // A Pong frame MAY be sent unsolicited.  This serves as a
        // unidirectional heartbeat.  A response to an unsolicited Pong frame is
        // not expected. (RFC 6455)
        // Due to this, we just don't check pongs right now.
        // TODO: check if there was a reply to our ping at all...
        Ok(())
    }

    /// Send a single pending frame.
    fn send_one_frame(&mut self, mut frame: Frame) -> Result<()> {
        match self.role {
            Role::Server => {
            }
            Role::Client => {
                // 5.  If the data is being sent by the client, the frame(s) MUST be
                // masked as defined in Section 5.3. (RFC 6455)
                frame.set_mask();
            }
        }
        let res = self.socket.write_frame(frame);
        self.translate_close(res)
    }

    /// Translate a "Connection reset by peer" into ConnectionClosed as needed.
    fn translate_close<T>(&mut self, res: Result<T>) -> Result<T> {
        match res {
            Err(Error::Io(err)) => Err({
                if err.kind() == IoErrorKind::ConnectionReset {
                    match self.state {
                        WebSocketState::ClosedByPeer(ref mut frame) =>
                            Error::ConnectionClosed(replace(frame, None)),
                        WebSocketState::CloseAcknowledged(ref mut frame) =>
                            Error::ConnectionClosed(replace(frame, None)),
                        _ => Error::Io(err),
                    }
                } else {
                    Error::Io(err)
                }
            }),
            x => x,
        }
    }

}

/// The current connection state.
enum WebSocketState {
    /// The connection is active.
    Active,
    /// We initiated a close handshake.
    ClosedByUs,
    /// The peer initiated a close handshake.
    ClosedByPeer(Option<CloseFrame<'static>>),
    /// The peer replied to our close handshake.
    CloseAcknowledged(Option<CloseFrame<'static>>),
}

impl WebSocketState {
    /// Tell if we're allowed to process normal messages.
    fn is_active(&self) -> bool {
        match *self {
            WebSocketState::Active => true,
            _ => false,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{WebSocket, Role, Message};

    use std::io;
    use std::io::Cursor;

    struct WriteMoc<Stream>(Stream);

    impl<Stream> io::Write for WriteMoc<Stream> {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            Ok(buf.len())
        }
        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    impl<Stream: io::Read> io::Read for WriteMoc<Stream> {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            self.0.read(buf)
        }
    }

    #[test]
    fn receive_messages() {
        let incoming = Cursor::new(vec![
            0x01, 0x07,
            0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20,
            0x80, 0x06,
            0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
            0x82, 0x03,
            0x01, 0x02, 0x03,
        ]);
        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client);
        assert_eq!(socket.read_message().unwrap(), Message::Text("Hello, World!".into()));
        assert_eq!(socket.read_message().unwrap(), Message::Binary(vec![0x01, 0x02, 0x03]));
    }

}
<commit_msg>improve doc in protocol/mod.rs<commit_after>//! Generic WebSocket message stream.

pub mod frame;

mod message;

pub use self::message::Message;
pub use self::frame::CloseFrame;

use std::collections::VecDeque;
use std::io::{Read, Write, ErrorKind as IoErrorKind};
use std::mem::replace;

use error::{Error, Result};
use self::message::{IncompleteMessage, IncompleteMessageType};
use self::frame::{Frame, FrameSocket};
use self::frame::coding::{OpCode, Data as OpData, Control as OpCtl, CloseCode};
use util::NonBlockingResult;

/// Indicates a Client or Server role of the websocket
#[derive(Debug, Clone, Copy)]
pub enum Role {
    /// This socket is a server
    Server,
    /// This socket is a client
    Client,
}

/// WebSocket input-output stream.
///
/// This is THE structure you want to create to be able to speak the WebSocket protocol.
/// It may be created by calling `connect`, `accept` or `client` functions.
pub struct WebSocket<Stream> {
    /// Server or client?
    role: Role,
    /// The underlying socket.
    socket: FrameSocket<Stream>,
    /// The state of processing, either "active" or "closing".
    state: WebSocketState,
    /// Receive: an incomplete message being processed.
    incomplete: Option<IncompleteMessage>,
    /// Send: a data send queue.
    send_queue: VecDeque<Frame>,
    /// Send: an OOB pong message.
    pong: Option<Frame>,
}

impl<Stream> WebSocket<Stream> {
    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_raw_socket(stream: Stream, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::new(stream), role)
    }

    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_partially_read(stream: Stream, part: Vec<u8>, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::from_partially_read(stream, part), role)
    }

    /// Returns a shared reference to the inner stream.
    pub fn get_ref(&self) -> &Stream {
        self.socket.get_ref()
    }
    /// Returns a mutable reference to the inner stream.
    pub fn get_mut(&mut self) -> &mut Stream {
        self.socket.get_mut()
    }

    /// Convert a frame socket into a WebSocket.
    fn from_frame_socket(socket: FrameSocket<Stream>, role: Role) -> Self {
        WebSocket {
            role: role,
            socket: socket,
            state: WebSocketState::Active,
            incomplete: None,
            send_queue: VecDeque::new(),
            pong: None,
        }
    }
}

impl<Stream: Read + Write> WebSocket<Stream> {
    /// Read a message from stream, if possible.
    ///
    /// This function sends pong and close responses automatically.
    /// However, it never blocks on write.
    pub fn read_message(&mut self) -> Result<Message> {
        loop {
            // Since we may get ping or close, we need to reply to the messages even during read.
            // Thus we call write_pending() but ignore its blocking.
            self.write_pending().no_block()?;
            // If we get here, either write blocks or we have nothing to write.
            // Thus if read blocks, just let it return WouldBlock.
            let res = self.read_message_frame();
            if let Some(message) = self.translate_close(res)? {
                trace!("Received message {}", message);
                return Ok(message)
            }
        }
    }

    /// Send a message to stream, if possible.
    ///
    /// This function guarantees that the frame is queued regardless of any errors.
    /// There is no need to resend the frame. In order to handle WouldBlock or Incomplete,
    /// call write_pending() afterwards.
    pub fn write_message(&mut self, message: Message) -> Result<()> {
        let frame = {
            let opcode = match message {
                Message::Text(_) => OpData::Text,
                Message::Binary(_) => OpData::Binary,
            };
            Frame::message(message.into_data(), OpCode::Data(opcode), true)
        };
        self.send_queue.push_back(frame);
        self.write_pending()
    }

    /// Send ping.
    pub fn send_ping(&mut self, payload: Vec<u8>) -> Result<()> {
        self.send_queue.push_back(Frame::ping(payload));
        self.write_pending()
    }

    /// Close the connection.
    ///
    /// This function guarantees that the close frame will be queued.
    /// There is no need to call it again, just like write_message().
    pub fn close(&mut self, code: Option<CloseFrame>) -> Result<()> {
        if let WebSocketState::Active = self.state {
            self.state = WebSocketState::ClosedByUs;
            let frame = Frame::close(code);
            self.send_queue.push_back(frame);
        } else {
            // Already closed, nothing to do.
        }
        self.write_pending()
    }

    /// Flush the pending send queue.
    pub fn write_pending(&mut self) -> Result<()> {
        // First, make sure we have no pending frame sending.
        {
            let res = self.socket.write_pending();
            self.translate_close(res)?;
        }

        // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
        // response, unless it already received a Close frame. It SHOULD
        // respond with Pong frame as soon as is practical. (RFC 6455)
        if let Some(pong) = replace(&mut self.pong, None) {
            self.send_one_frame(pong)?;
        }
        // If we have any unsent frames, send them.
        while let Some(data) = self.send_queue.pop_front() {
            self.send_one_frame(data)?;
        }

        // If we're closing and there is nothing to send anymore, we should close the connection.
        if self.send_queue.is_empty() {
            if let WebSocketState::ClosedByPeer(ref mut frame) = self.state {
                // The underlying TCP connection, in most normal cases, SHOULD be closed
                // first by the server, so that it holds the TIME_WAIT state and not the
                // client (as this would prevent it from re-opening the connection for 2
                // maximum segment lifetimes (2MSL), while there is no corresponding
                // server impact as a TIME_WAIT connection is immediately reopened upon
                // a new SYN with a higher seq number). (RFC 6455)
                match self.role {
                    Role::Client => Ok(()),
                    Role::Server => Err(Error::ConnectionClosed(replace(frame, None))),
                }
            } else {
                Ok(())
            }
        } else {
            Ok(())
        }
    }

    /// Try to decode one message frame. May return None.
    fn read_message_frame(&mut self) -> Result<Option<Message>> {
        if let Some(mut frame) = self.socket.read_frame()? {

            // MUST be 0 unless an extension is negotiated that defines meanings
            // for non-zero values.  If a nonzero value is received and none of
            // the negotiated extensions defines the meaning of such a nonzero
            // value, the receiving endpoint MUST _Fail the WebSocket
            // Connection_.
            if frame.has_rsv1() || frame.has_rsv2() || frame.has_rsv3() {
                return Err(Error::Protocol("Reserved bits are non-zero".into()))
            }

            match self.role {
                Role::Server => {
                    if frame.is_masked() {
                        // A server MUST remove masking for data frames received from a client
                        // as described in Section 5.3. (RFC 6455)
                        frame.remove_mask()
                    } else {
                        // The server MUST close the connection upon receiving a
                        // frame that is not masked. (RFC 6455)
                        return Err(Error::Protocol("Received an unmasked frame from client".into()))
                    }
                }
                Role::Client => {
                    if frame.is_masked() {
                        // A client MUST close a connection if it detects a masked frame. (RFC 6455)
                        return Err(Error::Protocol("Received a masked frame from server".into()))
                    }
                }
            }

            match frame.opcode() {

                OpCode::Control(ctl) => {
                    (match ctl {
                        // All control frames MUST have a payload length of 125 bytes or less
                        // and MUST NOT be fragmented. (RFC 6455)
                        _ if !frame.is_final() => {
                            Err(Error::Protocol("Fragmented control frame".into()))
                        }
                        _ if frame.payload().len() > 125 => {
                            Err(Error::Protocol("Control frame too big".into()))
                        }
                        OpCtl::Close => {
                            self.do_close(frame.into_close()?)
                        }
                        OpCtl::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown control frame type {}", i).into()))
                        }
                        OpCtl::Ping | OpCtl::Pong if !self.state.is_active() => {
                            // No ping processing while closing.
                            Ok(())
                        }
                        OpCtl::Ping => {
                            self.do_ping(frame.into_data())
                        }
                        OpCtl::Pong => {
                            self.do_pong(frame.into_data())
                        }
                    }).map(|_| None)
                }

                OpCode::Data(_) if !self.state.is_active() => {
                    // No data processing while closing.
                    Ok(None)
                }

                OpCode::Data(data) => {
                    let fin = frame.is_final();
                    match data {
                        OpData::Continue => {
                            if let Some(ref mut msg) = self.incomplete {
                                // TODO if msg too big
                                msg.extend(frame.into_data())?;
                            } else {
                                return Err(Error::Protocol("Continue frame but nothing to continue".into()))
                            }
                            if fin {
                                Ok(Some(replace(&mut self.incomplete, None).unwrap().complete()?))
                            } else {
                                Ok(None)
                            }
                        }
                        c if self.incomplete.is_some() => {
                            Err(Error::Protocol(
                                format!("Received {} while waiting for more fragments", c).into()
                            ))
                        }
                        OpData::Text | OpData::Binary => {
                            let msg = {
                                let message_type = match data {
                                    OpData::Text => IncompleteMessageType::Text,
                                    OpData::Binary => IncompleteMessageType::Binary,
                                    _ => panic!("Bug: message is not text nor binary"),
                                };
                                let mut m = IncompleteMessage::new(message_type);
                                m.extend(frame.into_data())?;
                                m
                            };
                            if fin {
                                Ok(Some(msg.complete()?))
                            } else {
                                self.incomplete = Some(msg);
                                Ok(None)
                            }
                        }
                        OpData::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown data frame type {}", i).into()))
                        }
                    }
                }

            } // match opcode

        } else {
            Err(Error::Protocol("Connection reset without closing handshake".into()))
        }
    }

    /// Received a close frame.
    fn do_close(&mut self, close: Option<CloseFrame>) -> Result<()> {
        debug!("Received close frame: {:?}", close);
        match self.state {
            WebSocketState::Active => {
                let close_code = close.as_ref().map(|f| f.code);
                self.state = WebSocketState::ClosedByPeer(close.map(CloseFrame::into_owned));
                let reply = if let Some(code) = close_code {
                    if code.is_allowed() {
                        Frame::close(Some(CloseFrame {
                            code: CloseCode::Normal,
                            reason: "".into(),
                        }))
                    } else {
                        Frame::close(Some(CloseFrame {
                            code: CloseCode::Protocol,
                            reason: "Protocol violation".into()
                        }))
                    }
                } else {
                    Frame::close(None)
                };
                debug!("Replying to close with {:?}", reply);
                self.send_queue.push_back(reply);
                Ok(())
            }
            WebSocketState::ClosedByPeer(_) | WebSocketState::CloseAcknowledged(_) => {
                // It is already closed, just ignore.
                Ok(())
            }
            WebSocketState::ClosedByUs => {
                // We received a reply.
                let close = close.map(CloseFrame::into_owned);
                match self.role {
                    Role::Client => {
                        // Client waits for the server to close the connection.
                        self.state = WebSocketState::CloseAcknowledged(close);
                        Ok(())
                    }
                    Role::Server => {
                        // Server closes the connection.
                        Err(Error::ConnectionClosed(close))
                    }
                }
            }
        }
    }

    /// Received a ping frame.
    fn do_ping(&mut self, ping: Vec<u8>) -> Result<()> {
        // If an endpoint receives a Ping frame and has not yet sent Pong
        // frame(s) in response to previous Ping frame(s), the endpoint MAY
        // elect to send a Pong frame for only the most recently processed Ping
        // frame. (RFC 6455)
        // We do exactly that, keeping a "queue" from one and only Pong frame.
        self.pong = Some(Frame::pong(ping));
        Ok(())
    }

    /// Received a pong frame.
    fn do_pong(&mut self, _: Vec<u8>) -> Result<()> {
        // A Pong frame MAY be sent unsolicited.  This serves as a
        // unidirectional heartbeat.  A response to an unsolicited Pong frame is
        // not expected. (RFC 6455)
        // Due to this, we just don't check pongs right now.
        // TODO: check if there was a reply to our ping at all...
        Ok(())
    }

    /// Send a single pending frame.
    fn send_one_frame(&mut self, mut frame: Frame) -> Result<()> {
        match self.role {
            Role::Server => {
            }
            Role::Client => {
                // 5.  If the data is being sent by the client, the frame(s) MUST be
                // masked as defined in Section 5.3. (RFC 6455)
                frame.set_mask();
            }
        }
        let res = self.socket.write_frame(frame);
        self.translate_close(res)
    }

    /// Translate a "Connection reset by peer" into ConnectionClosed as needed.
    fn translate_close<T>(&mut self, res: Result<T>) -> Result<T> {
        match res {
            Err(Error::Io(err)) => Err({
                if err.kind() == IoErrorKind::ConnectionReset {
                    match self.state {
                        WebSocketState::ClosedByPeer(ref mut frame) =>
                            Error::ConnectionClosed(replace(frame, None)),
                        WebSocketState::CloseAcknowledged(ref mut frame) =>
                            Error::ConnectionClosed(replace(frame, None)),
                        _ => Error::Io(err),
                    }
                } else {
                    Error::Io(err)
                }
            }),
            x => x,
        }
    }

}

/// The current connection state.
enum WebSocketState {
    /// The connection is active.
    Active,
    /// We initiated a close handshake.
    ClosedByUs,
    /// The peer initiated a close handshake.
    ClosedByPeer(Option<CloseFrame<'static>>),
    /// The peer replied to our close handshake.
    CloseAcknowledged(Option<CloseFrame<'static>>),
}

impl WebSocketState {
    /// Tell if we're allowed to process normal messages.
    fn is_active(&self) -> bool {
        match *self {
            WebSocketState::Active => true,
            _ => false,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{WebSocket, Role, Message};

    use std::io;
    use std::io::Cursor;

    struct WriteMoc<Stream>(Stream);

    impl<Stream> io::Write for WriteMoc<Stream> {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            Ok(buf.len())
        }
        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    impl<Stream: io::Read> io::Read for WriteMoc<Stream> {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            self.0.read(buf)
        }
    }

    #[test]
    fn receive_messages() {
        let incoming = Cursor::new(vec![
            0x01, 0x07,
            0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20,
            0x80, 0x06,
            0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
            0x82, 0x03,
            0x01, 0x02, 0x03,
        ]);
        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client);
        assert_eq!(socket.read_message().unwrap(), Message::Text("Hello, World!".into()));
        assert_eq!(socket.read_message().unwrap(), Message::Binary(vec![0x01, 0x02, 0x03]));
    }

}
<|endoftext|>


<commit_before>//! way-cooler registry.

use std::ops::Deref;
use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

use rustc_serialize::Decodable;
use rustc_serialize::json;
use rustc_serialize::json::{Json, ToJson};

mod types;
pub use self::types::{RegistryAccess, RegistryValue};

type RegMap = HashMap<String, RegistryValue>;

lazy_static! {
    /// Registry variable for the registry
    static ref REGISTRY: RwLock<RegMap> =
        RwLock::new(HashMap::new());
}

/// Error types that can happen
#[derive(Debug, PartialEq, Eq)]
pub enum RegistryError {
    /// The value in the registry could not be parsed
    InvalidJson,
    /// The registry key was not found
    KeyNotFound
}

/// Acquires a read lock on the registry.
fn read_lock<'a>() -> RwLockReadGuard<'a, RegMap> {
    REGISTRY.read().unwrap()
}

/// Acquires a write lock on the registry.
fn write_lock<'a>() -> RwLockWriteGuard<'a, RegMap> {
    REGISTRY.write().unwrap()
}

/// Gets a Json object from a registry key
pub fn get_json(name: &String) -> Option<Arc<Json>> {
    trace!("get_json: {}", name);
    let ref reg = *read_lock();
    if let Some(val) = reg.get(name) {
        Some(val.get_json())
    }
    else {
        None
    }
}

/// Gets an object from the regsitry, decoding its internal json
/// representation.
pub fn get<T: Decodable>(name: &String) -> Result<T, RegistryError> {
    let maybe_json = get_json(name);
    if let Some(json_arc) = maybe_json {
        let mut decoder = json::Decoder::new(json_arc.deref().to_json());
        match T::decode(&mut decoder) {
            Ok(val) => Ok(val),
            Err(e) => Err(RegistryError::InvalidJson)
        }
    }
    else {
        Err(RegistryError::KeyNotFound)
    }
}

/// Set a key in the registry to a particular value
pub fn set<T: ToJson>(key: String, val: T) {
    trace!("set: {}", key);
    let ref mut write_reg = *write_lock();
    let regvalue = RegistryValue::new(RegistryAccess::Public, val);
    write_reg.insert(key, regvalue);
}
<commit_msg>Add Borrow<T> types to registry key methods<commit_after>//! way-cooler registry.

use std::ops::Deref;
use std::cmp::Eq;
use std::fmt::Display;
use std::hash::Hash;
use std::borrow::Borrow;

use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

use rustc_serialize::{Decodable, json};
use rustc_serialize::json::{Json, ToJson};

mod types;
pub use self::types::{RegistryAccess, RegistryValue};

type RegMap = HashMap<String, RegistryValue>;

lazy_static! {
    /// Registry variable for the registry
    static ref REGISTRY: RwLock<RegMap> =
        RwLock::new(HashMap::new());
}

/// Error types that can happen
#[derive(Debug, PartialEq, Eq)]
pub enum RegistryError {
    /// The value in the registry could not be parsed
    InvalidJson,
    /// The registry key was not found
    KeyNotFound
}

/// Acquires a read lock on the registry.
fn read_lock<'a>() -> RwLockReadGuard<'a, RegMap> {
    REGISTRY.read().unwrap()
}

/// Acquires a write lock on the registry.
fn write_lock<'a>() -> RwLockWriteGuard<'a, RegMap> {
    REGISTRY.write().unwrap()
}

/// Gets a Json object from a registry key
pub fn get_json<K>(name: &K) -> Option<Arc<Json>>
where String: Borrow<K>, K: Hash + Eq + Display {
    trace!("get_json: {}", *name);
    let ref reg = *read_lock();
    if let Some(val) = reg.get(name) {
        Some(val.get_json())
    }
    else {
        None
    }
}

/// Gets an object from the regsitry, decoding its internal json
/// representation.
pub fn get<T, K>(name: &K) -> Result<T, RegistryError>
where T: Decodable, String: Borrow<K>, K: Hash + Eq + Display {
    let maybe_json = get_json(name);
    if let Some(json_arc) = maybe_json {
        let mut decoder = json::Decoder::new(json_arc.deref().to_json());
        match T::decode(&mut decoder) {
            Ok(val) => Ok(val),
            Err(e) => Err(RegistryError::InvalidJson)
        }
    }
    else {
        Err(RegistryError::KeyNotFound)
    }
}

/// Set a key in the registry to a particular value
pub fn set<T: ToJson>(key: String, val: T) {
    trace!("set: {}", key);
    let ref mut write_reg = *write_lock();
    let regvalue = RegistryValue::new(RegistryAccess::Public, val);
    write_reg.insert(key, regvalue);
}

/// Whether this map contains a key
pub fn contains_key<K>(key: &K) -> bool
where String: Borrow<K>, K: Hash + Eq + Display {
    trace!("contains_key: {}", *key);
    let ref read_reg = *read_lock();
    read_reg.contains_key(key)
}
<|endoftext|>


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

pub trait Pattern: Show {
  fn precedence(&self) -> uint;

  fn bracket(&self, outer_precedence: uint) -> String {
    if self.precedence() < outer_precedence {
      format!("({})", self)
    } else {
      format!("{}", self)
    }
  }

  fn inspect(&self) -> String {
    format!("/{}/", self)
  }
}

pub struct Empty;

impl Show for Empty {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "")
  }
}

impl Pattern for Empty {
  fn precedence(&self) -> uint { 3 }
}

pub struct Literal {
  pub character: char
}

impl Show for Literal {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    self.character.fmt(f)
  }
}

impl Pattern for Literal {
  fn precedence(&self) -> uint { 3 }
}

/// Concatenate node
pub struct Concatenate<S, T> {
  pub first: S,
  pub second: T
}

/// implement Show trait for Concatenate
impl<S: Show, T: Show> Show for Concatenate<S, T> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}|{}", self.first, self.second)
  }
}

impl<S, T> Pattern for Concatenate<S, T>
  where S: Show + Pattern, T: Show + Pattern {
  fn precedence(&self) -> uint { 1 }
}

#[cfg(test)]
mod test {
  use super::Pattern;
  use super::Empty;
  use super::Literal;
  use super::Concatenate;

  #[test]
  fn test_empty() {
    assert_eq!(Empty.precedence(), 3);
    assert_eq!(Empty.to_string().as_slice(), "");
  }

  #[test]
  fn test_literal() {
    let literal = Literal { character: 'a' };

    assert_eq!(literal.precedence(), 3);
    assert_eq!(literal.to_string().as_slice(), "a");
  }

  #[test]
  fn test_concatenate() {
    let literal = Literal { character: 'a' };
    let concat = Concatenate { first: Empty, second: literal };

    assert_eq!(concat.precedence(), 1);
    assert_eq!(concat.to_string().as_slice(), "|a");
  }
}
<commit_msg>add choose and typo fixed<commit_after>use std::fmt;
use std::fmt::Show;

pub trait Pattern: Show {
  fn precedence(&self) -> uint;

  fn bracket(&self, outer_precedence: uint) -> String {
    if self.precedence() < outer_precedence {
      format!("({})", self)
    } else {
      format!("{}", self)
    }
  }

  fn inspect(&self) -> String {
    format!("/{}/", self)
  }
}

pub struct Empty;

impl Show for Empty {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "")
  }
}

impl Pattern for Empty {
  fn precedence(&self) -> uint { 3 }
}

pub struct Literal {
  pub character: char
}

impl Show for Literal {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    self.character.fmt(f)
  }
}

impl Pattern for Literal {
  fn precedence(&self) -> uint { 3 }
}

/// Concatenate node
pub struct Concatenate<S, T> {
  pub first: S,
  pub second: T
}

/// implement Show trait for Concatenate
impl<S: Show, T: Show> Show for Concatenate<S, T> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}{}", self.first, self.second)
  }
}

impl<S, T> Pattern for Concatenate<S, T>
  where S: Show + Pattern, T: Show + Pattern {
  fn precedence(&self) -> uint { 1 }
}

pub struct Choose<S, T> {
  pub first: S,
  pub second: T
}

impl<S, T> Show for Choose<S, T>
  where S: Show, T: Show {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}|{}", self.first, self.second)
  }
}

impl<S, T> Pattern for Choose<S, T>
  where S: Show + Pattern, T: Show + Pattern {
  fn precedence(&self) -> uint { 0 }
}

#[cfg(test)]
mod test {
  use super::Pattern;
  use super::Empty;
  use super::Literal;
  use super::Concatenate;
  use super::Choose;

  #[test]
  fn test_empty() {
    assert_eq!(Empty.precedence(), 3);
    assert_eq!(Empty.to_string().as_slice(), "");
  }

  #[test]
  fn test_literal() {
    let literal = Literal { character: 'a' };

    assert_eq!(literal.precedence(), 3);
    assert_eq!(literal.to_string().as_slice(), "a");
  }

  #[test]
  fn test_concatenate() {
    let literal = Literal { character: 'a' };
    let concat = Concatenate { first: Empty, second: literal };

    assert_eq!(concat.precedence(), 1);
    assert_eq!(concat.to_string().as_slice(), "a");
  }

  #[test]
  fn test_choose() {
    let literal = Literal { character: 'a' };
    let choose = Choose { first: Empty, second: literal };

    assert_eq!(choose.precedence(), 0);
    assert_eq!(choose.to_string().as_slice(), "|a");
  }
}
<|endoftext|>


<commit_before>//! Defines the renderable trait.
//! A renderable object holds the buffer that is written to wlc_pixel_write.
//! The buffer can only be modified by casting the type to a `Drawable`.

use rustwlc::{Geometry, WlcOutput};
use rustwlc::render::{write_pixels, wlc_pixel_format};
use cairo::{self, Context, ImageSurface, Operator};
use super::draw::BaseDraw;

/// Something that can be rendered by wlc.
/// At minimum, it must store a buffer of bytes to write to wlc,
/// a geometry to tell wlc where to place the bytes,
/// and the `WlcOutput` that it will be rendered on.
pub trait Renderable {
    /// Makes a new `Renderable`
    ///
    /// Allowed to return `None` so that a needless allocation doesn't occur
    /// (e.g when the geometry is 0).
    fn new(geometry: Geometry, output: WlcOutput) -> Option<Self>
        where Self: :: std::marker::Sized;

    /// Gets the underlying `ImageSurface` used by the `Renderable` to render
    /// to wlc.
    ///
    /// Is mutable to ensure no other threads are touching the data.
    fn get_surface(&mut self) -> &mut ImageSurface;

    /// Gets the geometry for where the buffer should be rendered on the output.
    fn get_geometry(&self) -> Geometry;

    // TODO Why can't I just use reallocate_buffer here?

    /// Sets the geometry for where the buffer should be render on the output.
    fn set_geometry(&mut self, geometry: Geometry);

    /// Gets the output that this will be rendered on.
    fn get_output(&self) -> WlcOutput;

    /// Reallocates the buffer based on the new geometry.
    ///
    /// Allowed to return `None` so that a needless allocation doesn't occur
    /// (e.g when the geometry is 0).
    fn reallocate_buffer(self, geometry: Geometry) -> Option<Self>
        where Self: ::std::marker::Sized;

    fn enable_cairo(mut self) -> Result<BaseDraw<Self>, cairo::Status>
        where Self: ::std::marker::Sized
    {
        let cairo = Context::new(&*self.get_surface());
        match cairo.status() {
            cairo::Status::Success => {},
            err => return Err(err)
        }
        cairo.set_operator(Operator::Source);
        match cairo.status() {
            cairo::Status::Success => {},
            err => return Err(err)
        }
        Ok(BaseDraw::new(self, cairo))
    }

    /// Renders the data buffer at the internal geometry.
    ///
    /// Automatically ensures that the buffer does not clip the sides
    fn render(&mut self) {
        let output_res = self.get_output().get_resolution()
            .expect("Output had no resolution");
        let mut geometry = self.get_geometry();
        let surface = self.get_surface();
        let buffer = surface.get_data()
            .expect("Could not get surface buffer");

        // If the buffer would clip the side, keep it within the bounds
        // This is done because wlc wraps if it goes beyond, which we don't
        // want for the borders.
        if geometry.origin.x + geometry.size.w as i32 > output_res.w as i32 {
            let offset = (geometry.origin.x + geometry.size.w as i32) - output_res.w as i32;
            geometry.origin.x -= offset as i32;
        }
        if geometry.origin.y + geometry.size.h as i32 > output_res.h as i32 {
            let offset = (geometry.origin.y + geometry.size.h as i32) - output_res.h as i32;
            geometry.origin.y -= offset as i32;
        }
        if geometry.origin.x < 0 {
            geometry.origin.x = 0;
        }
        if geometry.origin.y < 0 {
            geometry.origin.y = 0;
        }
        write_pixels(wlc_pixel_format::WLC_RGBA8888, geometry, &buffer);
    }
}
<commit_msg>Removed TODO<commit_after>//! Defines the renderable trait.
//! A renderable object holds the buffer that is written to wlc_pixel_write.
//! The buffer can only be modified by casting the type to a `Drawable`.

use rustwlc::{Geometry, WlcOutput};
use rustwlc::render::{write_pixels, wlc_pixel_format};
use cairo::{self, Context, ImageSurface, Operator};
use super::draw::BaseDraw;

/// Something that can be rendered by wlc.
/// At minimum, it must store a buffer of bytes to write to wlc,
/// a geometry to tell wlc where to place the bytes,
/// and the `WlcOutput` that it will be rendered on.
pub trait Renderable {
    /// Makes a new `Renderable`
    ///
    /// Allowed to return `None` so that a needless allocation doesn't occur
    /// (e.g when the geometry is 0).
    fn new(geometry: Geometry, output: WlcOutput) -> Option<Self>
        where Self: :: std::marker::Sized;

    /// Gets the underlying `ImageSurface` used by the `Renderable` to render
    /// to wlc.
    ///
    /// Is mutable to ensure no other threads are touching the data.
    fn get_surface(&mut self) -> &mut ImageSurface;

    /// Gets the geometry for where the buffer should be rendered on the output.
    fn get_geometry(&self) -> Geometry;

    /// Sets the geometry for where the buffer should be render on the output.
    fn set_geometry(&mut self, geometry: Geometry);

    /// Gets the output that this will be rendered on.
    fn get_output(&self) -> WlcOutput;

    /// Reallocates the buffer based on the new geometry.
    ///
    /// Allowed to return `None` so that a needless allocation doesn't occur
    /// (e.g when the geometry is 0).
    fn reallocate_buffer(self, geometry: Geometry) -> Option<Self>
        where Self: ::std::marker::Sized;

    fn enable_cairo(mut self) -> Result<BaseDraw<Self>, cairo::Status>
        where Self: ::std::marker::Sized
    {
        let cairo = Context::new(&*self.get_surface());
        match cairo.status() {
            cairo::Status::Success => {},
            err => return Err(err)
        }
        cairo.set_operator(Operator::Source);
        match cairo.status() {
            cairo::Status::Success => {},
            err => return Err(err)
        }
        Ok(BaseDraw::new(self, cairo))
    }

    /// Renders the data buffer at the internal geometry.
    ///
    /// Automatically ensures that the buffer does not clip the sides
    fn render(&mut self) {
        let output_res = self.get_output().get_resolution()
            .expect("Output had no resolution");
        let mut geometry = self.get_geometry();
        let surface = self.get_surface();
        let buffer = surface.get_data()
            .expect("Could not get surface buffer");

        // If the buffer would clip the side, keep it within the bounds
        // This is done because wlc wraps if it goes beyond, which we don't
        // want for the borders.
        if geometry.origin.x + geometry.size.w as i32 > output_res.w as i32 {
            let offset = (geometry.origin.x + geometry.size.w as i32) - output_res.w as i32;
            geometry.origin.x -= offset as i32;
        }
        if geometry.origin.y + geometry.size.h as i32 > output_res.h as i32 {
            let offset = (geometry.origin.y + geometry.size.h as i32) - output_res.h as i32;
            geometry.origin.y -= offset as i32;
        }
        if geometry.origin.x < 0 {
            geometry.origin.x = 0;
        }
        if geometry.origin.y < 0 {
            geometry.origin.y = 0;
        }
        write_pixels(wlc_pixel_format::WLC_RGBA8888, geometry, &buffer);
    }
}
<|endoftext|>