<commit_before>// CITA
// Copyright 2016-2017 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#![cfg_attr(test, feature(test))]
extern crate tx_pool;
extern crate test;
extern crate libproto;
extern crate util;
extern crate cita_crypto as crypto;

use crypto::{KeyPair, CreateKey};
use libproto::blockchain::{Transaction, UnverifiedTransaction, SignedTransaction};
use std::time::SystemTime;
use test::Bencher;
use tx_pool::pool::*;

#[bench]
fn bench_base(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut tx = Transaction::new();
    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
    }
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_base", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}

#[bench]
fn bench_enqueue(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut p = Pool::new(5000, 1000);
    let mut tx = Transaction::new();
    let keypair = KeyPair::gen_keypair();
    let pv = keypair.privkey();
    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
        tx.set_to("1234567".to_string());
        tx.set_nonce("0".to_string());
        tx.set_valid_until_block(99999);
        tx.set_quota(999999999);
        p.enqueue(tx.sign(*pv));
    }
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_enqueue", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}

#[bench]
fn bench_package(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut p = Pool::new(5000, 1000);
    let mut tx = Transaction::new();
    let keypair = KeyPair::gen_keypair();
    let pv = keypair.privkey();
    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
        tx.set_to("1234567".to_string());
        tx.set_nonce("0".to_string());
        tx.set_valid_until_block(99999);
        tx.set_quota(9999999999);
        p.enqueue(tx.sign(*pv));
    }
    p.package(666);
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_package", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}

#[bench]
fn bench_update(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut p = Pool::new(5000, 1000);
    let mut tx = Transaction::new();
    let keypair = KeyPair::gen_keypair();
    let pv = keypair.privkey();

    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
        tx.set_to("1234567".to_string());
        tx.set_nonce("0".to_string());
        tx.set_valid_until_block(99999);
        tx.set_quota(999999999);
        p.enqueue(tx.sign(*pv));
    }
    let txs = p.package(666);
    p.update(&txs);
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_update", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}
<commit_msg>fix make bench warning<commit_after>// CITA
// Copyright 2016-2017 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#![cfg_attr(test, feature(test))]
extern crate tx_pool;
extern crate test;
extern crate libproto;
extern crate util;
extern crate cita_crypto as crypto;

use crypto::{KeyPair, CreateKey};
use libproto::blockchain::Transaction;
use std::time::SystemTime;
use test::Bencher;
use tx_pool::pool::*;

#[bench]
fn bench_base(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut tx = Transaction::new();
    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
    }
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_base", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}

#[bench]
fn bench_enqueue(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut p = Pool::new(5000, 1000);
    let mut tx = Transaction::new();
    let keypair = KeyPair::gen_keypair();
    let pv = keypair.privkey();
    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
        tx.set_to("1234567".to_string());
        tx.set_nonce("0".to_string());
        tx.set_valid_until_block(99999);
        tx.set_quota(999999999);
        p.enqueue(tx.sign(*pv));
    }
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_enqueue", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}

#[bench]
fn bench_package(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut p = Pool::new(5000, 1000);
    let mut tx = Transaction::new();
    let keypair = KeyPair::gen_keypair();
    let pv = keypair.privkey();
    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
        tx.set_to("1234567".to_string());
        tx.set_nonce("0".to_string());
        tx.set_valid_until_block(99999);
        tx.set_quota(9999999999);
        p.enqueue(tx.sign(*pv));
    }
    p.package(666);
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_package", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}

#[bench]
fn bench_update(b: &mut Bencher) {
    let start = SystemTime::now();
    let mut p = Pool::new(5000, 1000);
    let mut tx = Transaction::new();
    let keypair = KeyPair::gen_keypair();
    let pv = keypair.privkey();

    for i in 0..10000 {
        tx.set_data(format!("{}", i).as_bytes().to_vec());
        tx.set_to("1234567".to_string());
        tx.set_nonce("0".to_string());
        tx.set_valid_until_block(99999);
        tx.set_quota(999999999);
        p.enqueue(tx.sign(*pv));
    }
    let txs = p.package(666);
    p.update(&txs);
    let sys_time = SystemTime::now();
    let diff = sys_time.duration_since(start).expect("SystemTime::duration_since failed");
    println!("pass");
    println!("test {:20} ... bench: {}.{} s/iter", "bench_update", diff.as_secs(), diff.subsec_nanos());
    b.iter(|| {});
}
<|endoftext|>


<commit_before>use console;
use pixset;
use units;
use vertex;

pub struct VertexData {
    data: Vec<vertex::Vertex>,
    size: units::Size2D,
}

// TODO remove Size
impl VertexData {
    pub fn new(size: units::Size2D) -> Self {
        let length = (size.width * size.height) as usize;
        let (lt, rt, rb, lb) = pixset::PIXSET.get(&pixset::Pix::Empty);
        let mut data: Vec<vertex::Vertex> = Vec::with_capacity(length * 4);

        for i in 0..length {
            let (x, y) = (i as i32 % size.width, i as i32 / size.width as i32);
            data.push(vertex::Vertex::new([-0.5, 0.5], lt, [x, y + 1]));
            data.push(vertex::Vertex::new([0.5, 0.5], rt, [x + 1, y + 1]));
            data.push(vertex::Vertex::new([0.5, -0.5], rb, [x + 1, y]));
            data.push(vertex::Vertex::new([-0.5, -0.5], lb, [x, y]));
        }

        VertexData {
            data: data,
            size: size,
        }
    }

    pub fn data(&self) -> &[vertex::Vertex] {
        &self.data[..]
    }

    // TODO have this take references? bench it?
    pub fn set(&mut self, screen_loc: units::ScreenTile2D, tile: console::Tile) {
        //let offset = ((self.size.width * screen_loc.y + screen_loc.x) * 4) as usize;
        let offset: usize = ((self.size.height - 1 - screen_loc.y) * self.size.width +
                             screen_loc.x) as usize * 4;
        let (lt, rt, rb, lb) = pixset::PIXSET.get(&tile.pix);

        self.data[offset].tileset_coords = lt;
        self.data[offset].foreground_color = tile.fg;
        self.data[offset].background_color = tile.bg;

        self.data[offset + 1].tileset_coords = rt;
        self.data[offset + 1].foreground_color = tile.fg;
        self.data[offset + 1].background_color = tile.bg;

        self.data[offset + 2].tileset_coords = rb;
        self.data[offset + 2].foreground_color = tile.fg;
        self.data[offset + 2].background_color = tile.bg;

        self.data[offset + 3].tileset_coords = lb;
        self.data[offset + 3].foreground_color = tile.fg;
        self.data[offset + 3].background_color = tile.bg;
    }
}
<commit_msg>chore(vertex_data): fix weird offset calc in set<commit_after>use console;
use pixset;
use units;
use vertex;

pub struct VertexData {
    data: Vec<vertex::Vertex>,
    size: units::Size2D,
}

// TODO remove Size
impl VertexData {
    pub fn new(size: units::Size2D) -> Self {
        let length = (size.width * size.height) as usize;
        let (lt, rt, rb, lb) = pixset::PIXSET.get(&pixset::Pix::Empty);
        let mut data: Vec<vertex::Vertex> = Vec::with_capacity(length * 4);
        let inv_y = size.height % size.width - 1;

        for i in 0..length {
            let (x, y) = (i as i32 % size.width, inv_y - i as i32 / size.width as i32);
            data.push(vertex::Vertex::new([-0.5, 0.5], lt, [x, y + 1]));
            data.push(vertex::Vertex::new([0.5, 0.5], rt, [x + 1, y + 1]));
            data.push(vertex::Vertex::new([0.5, -0.5], rb, [x + 1, y]));
            data.push(vertex::Vertex::new([-0.5, -0.5], lb, [x, y]));
        }

        VertexData {
            data: data,
            size: size,
        }
    }

    pub fn data(&self) -> &[vertex::Vertex] {
        &self.data[..]
    }

    pub fn set(&mut self, screen_loc: units::ScreenTile2D, tile: console::Tile) {
        let offset = ((self.size.width * screen_loc.y + screen_loc.x) * 4) as usize;
        let (lt, rt, rb, lb) = pixset::PIXSET.get(&tile.pix);

        self.data[offset].tileset_coords = lt;
        self.data[offset].foreground_color = tile.fg;
        self.data[offset].background_color = tile.bg;

        self.data[offset + 1].tileset_coords = rt;
        self.data[offset + 1].foreground_color = tile.fg;
        self.data[offset + 1].background_color = tile.bg;

        self.data[offset + 2].tileset_coords = rb;
        self.data[offset + 2].foreground_color = tile.fg;
        self.data[offset + 2].background_color = tile.bg;

        self.data[offset + 3].tileset_coords = lb;
        self.data[offset + 3].foreground_color = tile.fg;
        self.data[offset + 3].background_color = tile.bg;
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

use core::num::{One, Zero};

pub struct Matrix2D<T> {
    m11: T, m12: T,
    m21: T, m22: T,
    m31: T, m32: T
}

pub impl<T:Copy + One + Zero> Matrix2D<T> {
    fn new(m11: T, m12: T, m21: T, m22: T, m31: T, m32: T) -> Matrix2D<T> {
        Matrix2D {
            m11: m11, m12: m12,
            m21: m21, m22: m22,
            m31: m31, m32: m32
        }
    }

    fn translate(&self, x: &T, y: &T) -> Matrix2D<T> {
        let (_0, _1) = (Zero::zero(), One::one());
        let matrix = Matrix2D::new(_1, _0,
                                   _0, _1,
                                   *x, *y);
        return matrix;  // FIXME: This does not multiply yet!!
    }

    fn identity() -> Matrix2D<T> {
        let (_0, _1) = (Zero::zero(), One::one());
        return Matrix2D::new(_1, _0,
                             _0, _1,
                             _0, _0);
    }
}

<commit_msg>Remove redundant constructor in Matrix2D.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

use core::num::{One, Zero};

pub struct Matrix2D<T> {
    m11: T, m12: T,
    m21: T, m22: T,
    m31: T, m32: T
}

pub impl<T:Add<T,T> + Copy + Mul<T,T> + One + Zero> Matrix2D<T> {
    fn new(m11: T, m12: T, m21: T, m22: T, m31: T, m32: T) -> Matrix2D<T> {
        Matrix2D {
            m11: m11, m12: m12,
            m21: m21, m22: m22,
            m31: m31, m32: m32
        }
    }

    fn mul(&self, m: &Matrix2D<T>) -> Matrix2D<T> {
        Matrix2D::new(m.m11*self.m11 + m.m12*self.m21,
                      m.m11*self.m12 + m.m12*self.m22,
                      m.m21*self.m11 + m.m22*self.m21,
                      m.m21*self.m12 + m.m22*self.m22,
                      m.m31*self.m11 + m.m32*self.m21 + self.m31,
                      m.m31*self.m12 + m.m32*self.m22 + self.m32)
    }

    fn translate(&self, x: T, y: T) -> Matrix2D<T> {
         let (_0, _1) = (Zero::zero(), One::one());
         let matrix = Matrix2D::new(_1, _0,
                                    _0, _1,
                                    x, y);
        return self.mul(&matrix);
    }

    fn scale(&self, x: T, y: T) -> Matrix2D<T> {
        Matrix2D::new(self.m11 * x, self.m12,
                      self.m21,     self.m22 * y,
                      self.m31,     self.m32)
    }

    fn identity() -> Matrix2D<T> {
        let (_0, _1) = (Zero::zero(), One::one());
        return Matrix2D::new(_1, _0,
                             _0, _1,
                             _0, _0);
    }

    fn to_array(&self) -> [T, ..6] {
        [
            self.m11, self.m12,
            self.m21, self.m22,
            self.m31, self.m32
        ]
    }

}

<|endoftext|>


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

mod tests;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Hand {
    pub cards: Vec<card::Card>,
}

impl Hand {
    pub fn new(mut cards: Vec<card::Card>) -> Hand {
        cards.sort();
        Hand {
            cards: cards,

        }
    }

    fn has_flush(&self) -> bool {
        let suit_mask: i64 = card::Suit::get_suit_mask(self.cards.first().unwrap().suit);
        for card in &self.cards[1..] {
            if (-suit_mask) & card.get_mask() != 0 {
                return false;
            }
        }
        true
    }

    fn has_straight(&self) -> bool {
        let mut ranks: i64 = 0;
        for card in &self.cards {
            ranks |= 1 << card.rank as u32;
        }

        let straight_matcher: i64 = 0b11111;
        let ace_low_matcher: i64 = 0b1000000001111;
        if ranks ^ ace_low_matcher == 0 {
            return true;
        }
        for i in 0..8 {
            if ranks ^ (straight_matcher << i) == 0 {
                return true;
            }
        }
        false
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum PokerRanking {
    HighCard,
    OnePair,
    TwoPair,
    Trips,
    Straight,
    Flush,
    FullHouse,
    Quads,
    StraightFlush,
}
<commit_msg>Pulled get_ranks_mask() into its own function<commit_after>use card;
use std::fmt;

mod tests;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Hand {
    pub cards: Vec<card::Card>,
}

impl Hand {
    pub fn new(mut cards: Vec<card::Card>) -> Hand {
        cards.sort();
        Hand {
            cards: cards,

        }
    }

    fn has_flush(&self) -> bool {
        let suit_mask: i64 = card::Suit::get_suit_mask(self.cards.first().unwrap().suit);
        for card in &self.cards[1..] {
            if (-suit_mask) & card.get_mask() != 0 {
                return false;
            }
        }
        true
    }

    fn has_straight(&self) -> bool {
        let ranks: i64 = self.get_ranks_mask();
        let straight_matcher: i64 = 0b11111;
        let ace_low_matcher: i64 = 0b1000000001111;
        if ranks ^ ace_low_matcher == 0 {
            return true;
        }
        for i in 0..8 {
            if ranks ^ (straight_matcher << i) == 0 {
                return true;
            }
        }
        false
    }

    fn get_ranks_mask(&self) -> i64 {
        let mut ranks: i64 = 0;
        for card in &self.cards {
            ranks |= 1 << card.rank as u32;
        }
        ranks
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum PokerRanking {
    HighCard,
    OnePair,
    TwoPair,
    Trips,
    Straight,
    Flush,
    FullHouse,
    Quads,
    StraightFlush,
}
<|endoftext|>


<commit_before>use std::io::{stdin, File};
use std::io::buffered::BufferedReader;
use std::str::{from_utf8};
use std::os;

fn print_usage () {
	println("A tool to keep your reading skills bright and shiny.");
	println("Usage: rustoleum [arguments] path/to/input/file");
	println("-i (I)nteractive mode");
	println("-wpm N Display N words per (m)inute (default: 300)");
	println("-wpl N Display N words per (l)ine (default: 1)");
	println("-h Display this (h)elp");
}

fn get_args_interactive () -> (uint, uint, Path) {
	let mut reader = BufferedReader::new(stdin());

	println("Input path to file to read: ");
	let input = reader.read_line().unwrap_or(~"data/example.txt");
	let p = Path::new(input.trim());

	println("Input WPM: ");
	let input = reader.read_line().unwrap();
	let WPM = from_str::<uint>(input.trim()).unwrap_or(300);

	println("Input the number of words to view at a time: ");
	let input = reader.read_line().unwrap();
	let WPL = from_str::<uint>(input.trim()).unwrap_or(1);

	(WPM, WPL, p)
}

fn get_vals (args: ~[~str]) -> (uint, uint, Path){
	if args.contains(&~"-i"){
		get_args_interactive()
	}  else {
		let fallbackfile = &~"data/example.txt";
		let path = args.tail().last_opt().unwrap_or(fallbackfile);
		let p = Path::new(path.as_slice());
		let WPM = from_str::<uint>(args[1 + args.position_elem(&~"-wpm").unwrap_or(-1)]).unwrap_or(300);
		let WPL = from_str::<uint>(args[1 + args.position_elem(&~"-wpl").unwrap_or(-1)]).unwrap_or(1);
		(WPM,WPL,p)
	}
}

fn print_file(WPM: uint, WPL: uint, p: Path){
	if p.exists(){
		let contents = File::open(&p).read_to_end();
		let mut string_iter = from_utf8(contents).words();
		let string_vec = string_iter.to_owned_vec();
		let sleep_time = (60000 / WPM * WPL) as u64;
		for words in string_vec.chunks(WPL) {
			println("\x1bc".into_owned().append(words.connect(" ")));
			std::io::timer::sleep(sleep_time);
		}
	} else {
		println("The path specified does not exist. Please specify a valid path, or run rustoleum -h for help.");
		println("Calling rustoleum with no arguments will display data/example.txt at 300 WPM, with 1 word per line.");
	}
}

fn main () {
	if os::args().contains(&~"-h"){
		print_usage();
	} else {
		let (WPM, WPL, p) = get_vals(os::args());
		print_file(WPM, WPL, p);
	}

}
<commit_msg>Abstracted get_arg function, because you should never have two lines of identical code.<commit_after>use std::io::{stdin, File};
use std::io::buffered::BufferedReader;
use std::str::{from_utf8};
use std::os;

fn print_usage () {
	println("A tool to keep your reading skills bright and shiny.");
	println("Usage: rustoleum [arguments] path/to/input/file");
	println("-i (I)nteractive mode");
	println("-wpm N Display N words per (m)inute (default: 300)");
	println("-wpl N Display N words per (l)ine (default: 1)");
	println("-h Display this (h)elp");
}

fn get_args_interactive () -> (uint, uint, Path) {
	let mut reader = BufferedReader::new(stdin());

	println("Input path to file to read: ");
	let input = reader.read_line().unwrap_or(~"data/example.txt");
	let p = Path::new(input.trim());

	println("Input WPM: ");
	let input = reader.read_line().unwrap();
	let WPM = from_str::<uint>(input.trim()).unwrap_or(300);

	println("Input the number of words to view at a time: ");
	let input = reader.read_line().unwrap();
	let WPL = from_str::<uint>(input.trim()).unwrap_or(1);

	(WPM, WPL, p)
}

fn get_vals (args: ~[~str]) -> (uint, uint, Path){
	if args.contains(&~"-i"){
		get_args_interactive()
	}  else {
		let fallbackfile = &~"data/example.txt";
		let path = args.tail().last_opt().unwrap_or(fallbackfile);
		let p = Path::new(path.as_slice());
		//let WPM = from_str::<uint>(args[1 + args.position_elem(&~"-wpm").unwrap_or(-1)]).unwrap_or(300);
		//let WPL = from_str::<uint>(args[1 + args.position_elem(&~"-wpl").unwrap_or(-1)]).unwrap_or(1);
		let WPM = get_arg(&args, &~"-wpm", 300);
		let WPL = get_arg(&args, &~"-wpl", 300);
		(WPM,WPL,p)
	}
}

fn get_arg (args: &~[~str], flag: &~str, default: uint) -> uint {
	from_str::<uint>(args[1 + args.position_elem(flag).unwrap_or(-1)]).unwrap_or(default)
}

fn print_file(WPM: uint, WPL: uint, p: Path){
	if p.exists(){
		let contents = File::open(&p).read_to_end();
		let mut string_iter = from_utf8(contents).words();
		let string_vec = string_iter.to_owned_vec();
		let sleep_time = (60000 / WPM * WPL) as u64;
		for words in string_vec.chunks(WPL) {
			println("\x1bc".into_owned().append(words.connect(" ")));
			std::io::timer::sleep(sleep_time);
		}
	} else {
		println("The path specified does not exist. Please specify a valid path, or run rustoleum -h for help.");
		println("Calling rustoleum with no arguments will display data/example.txt at 300 WPM, with 1 word per line.");
	}
}

fn main () {
	if os::args().contains(&~"-h"){
		print_usage();
	} else {
		let (WPM, WPL, p) = get_vals(os::args());
		print_file(WPM, WPL, p);
	}

}
<|endoftext|>


<commit_before>#![crate_name = "http"]

#![comment = "Rust HTTP server"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/chris-morgan/rust-http/doc/")]

#![deny(non_camel_case_types)]
//#[deny(missing_doc)];

#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(phase)]

#[phase(plugin, link)] extern crate log;
extern crate url = "url_";
extern crate time;
extern crate collections;
extern crate debug;

pub mod buffer;
pub mod client;
pub mod common;
pub mod connecter;
pub mod server;
pub mod method;
pub mod headers;
pub mod rfc2616;
#[path = "generated/status.rs"]
pub mod status;  // Getting an error? It's generated; use ``make`` or see the ``Makefile``

/// TODO: submit upstream
#[cfg(test)]
pub mod memstream;
<commit_msg>Upgrade to rust-url change: the url_ crate was renamed url.<commit_after>#![crate_name = "http"]

#![comment = "Rust HTTP server"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/chris-morgan/rust-http/doc/")]

#![deny(non_camel_case_types)]
//#[deny(missing_doc)];

#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(phase)]

#[phase(plugin, link)] extern crate log;
extern crate url;
extern crate time;
extern crate collections;
extern crate debug;

pub mod buffer;
pub mod client;
pub mod common;
pub mod connecter;
pub mod server;
pub mod method;
pub mod headers;
pub mod rfc2616;
#[path = "generated/status.rs"]
pub mod status;  // Getting an error? It's generated; use ``make`` or see the ``Makefile``

/// TODO: submit upstream
#[cfg(test)]
pub mod memstream;
<|endoftext|>


<commit_before>//! This module initializes a project.

use std::fs;
use std::io::{Result, Error, ErrorKind};

use git2::Repository;

/// Creates a folder. The folder must not exist or must be empty.
///
/// Impure.
pub fn make_project_folder(root: &str) -> Result<()> {
    // Make the folder - ignore error.
    let _ = fs::create_dir(root);

    // Check that the folder is empty
    fs::read_dir(root)
        .and_then(|iter| {
            let count = iter.count();
            if count == 0 {
                Ok(())
            } else {
                dir_not_empty_err(root, count)
            }
        })
}

fn dir_not_empty_err(root: &str, count: usize) -> Result<()> {
    Err(Error::new(ErrorKind::Other, format!("{} was not empty: {} files exist", root, count)))
}

/// Initializes a git repository at root.
///
/// Impure.
pub fn make_repository(root: &str) -> Result<()> {
    Ok(())
}<commit_msg>A bunch of error handling thats just too much<commit_after>//! This module initializes a project.

use std::{fs, io, error};

use git2::Repository;

#[derive(Debug)]
pub enum InitError<'a> {
    Io(io::Error),
    FolderNotEmpty(&'a str, usize),
    TodoErr
}

impl error::Error for InitError {
    fn description(&self) -> &str {
        match self {
            Io(err) => format!("IoError occurred: {}", err.description),
            FolderNotEmpty(root, count) => format!("{} was not empty: {} files exist", root, count),
            TodoErr => "TodoErr",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            Io(err) => Some(err),
            FolderNotEmpty(_, _) => None,
            TodoErr => None,
        }
    }
}

/// Creates a folder. The folder must not exist or must be empty.
///
/// Impure.
pub fn make_project_folder(root: &str) -> Result<(), InitError> {
    // Make the folder - ignore error.
    let _ = fs::create_dir(root);

    // Check that the folder is empty
    fs::read_dir(root)
        .map_err(|err| InitError::Io(err))
        .and_then(|iter| {
            let count = iter.count();
            if count == 0 {
                Ok(())
            } else {
                Err(InitError::FolderNotEmpty(root, count))
            }
        })
}

/// Initializes a git repository at root.
///
/// Impure.
pub fn make_repository(root: &str) -> Result<Repository, InitError> {
    unimplemented!()
}<|endoftext|>


<commit_before>use std::io;
use std::ops::{Deref, DerefMut};
use std::sync::Arc;

use futures::{Async, Poll, Stream, Sink, StartSend, AsyncSink};

use io::Io;

/// A reference counted buffer of bytes.
///
/// An `EasyBuf` is a representation of a byte buffer where sub-slices of it can
/// be handed out efficiently, each with a `'static` lifetime which keeps the
/// data alive. The buffer also supports mutation but may require bytes to be
/// copied to complete the operation.
#[derive(Clone)]
pub struct EasyBuf {
    buf: Arc<Vec<u8>>,
    start: usize,
    end: usize,
}

/// An RAII object returned from `get_mut` which provides mutable access to the
/// underlying `Vec<u8>`.
pub struct EasyBufMut<'a> {
    buf: &'a mut Vec<u8>,
    end: &'a mut usize,
}

impl EasyBuf {
    /// Creates a new EasyBuf with no data and the default capacity.
    pub fn new() -> EasyBuf {
        EasyBuf::with_capacity(8 * 1024)
    }

    /// Creates a new EasyBuf with `cap` capacity.
    pub fn with_capacity(cap: usize) -> EasyBuf {
        EasyBuf {
            buf: Arc::new(Vec::with_capacity(cap)),
            start: 0,
            end: 0,
        }
    }

    /// Changes the starting index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `start` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    fn set_start(&mut self, start: usize) -> &mut EasyBuf {
        assert!(start <= self.buf.as_ref().len());
        assert!(start <= self.end);
        self.start = start;
        self
    }

    /// Changes the end index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `end` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    fn set_end(&mut self, end: usize) -> &mut EasyBuf {
        assert!(end <= self.buf.len());
        assert!(self.start <= end);
        self.end = end;
        self
    }

    /// Returns the number of bytes contained in this `EasyBuf`.
    pub fn len(&self) -> usize {
        self.end - self.start
    }

    /// Returns the inner contents of this `EasyBuf` as a slice.
    pub fn as_slice(&self) -> &[u8] {
        self.as_ref()
    }

    /// Splits the buffer into two at the given index.
    ///
    /// Afterwards `self` contains elements `[0, at)`, and the returned `EasyBuf`
    /// contains elements `[at, len)`.
    ///
    /// This is an O(1) operation that just increases the reference count and
    /// sets a few indexes.
    ///
    /// # Panics
    ///
    /// Panics if `at > len`
    pub fn split_off(&mut self, at: usize) -> EasyBuf {
        let mut other = EasyBuf { buf: self.buf.clone(), ..*self };
        let idx = self.start + at;
        other.set_start(idx);
        self.set_end(idx);
        return other
    }

    /// Splits the buffer into two at the given index.
    ///
    /// Afterwards `self` contains elements `[at, len)`, and the returned `EasyBuf`
    /// contains elements `[0, at)`.
    ///
    /// This is an O(1) operation that just increases the reference count and
    /// sets a few indexes.
    ///
    /// # Panics
    ///
    /// Panics if `at > len`
    pub fn drain_to(&mut self, at: usize) -> EasyBuf {
        let mut other = EasyBuf { buf: self.buf.clone(), ..*self };
        let idx = self.start + at;
        other.set_end(idx);
        self.set_start(idx);
        return other
    }

    /// Returns a mutable reference to the underlying growable buffer of bytes.
    ///
    /// If this `EasyBuf` is the only instance pointing at the underlying buffer
    /// of bytes, a direct mutable reference will be returned. Otherwise the
    /// contents of this `EasyBuf` will be reallocated in a fresh `Vec<u8>`
    /// allocation with the same capacity as this allocation, and that
    /// allocation will be returned.
    ///
    /// This operation **is not O(1)** as it may clone the entire contents of
    /// this buffer.
    ///
    /// The returned `EasyBufMut` type implement `Deref` and `DerefMut` to
    /// `Vec<u8>` can the byte buffer can be manipulated using the standard
    /// `Vec<u8>` methods.
    pub fn get_mut(&mut self) -> EasyBufMut {
        // Fast path if we can get mutable access to our own current
        // buffer.
        //
        // TODO: this should be a match or an if-let
        if Arc::get_mut(&mut self.buf).is_some() {
            let buf = Arc::get_mut(&mut self.buf).unwrap();
            buf.drain(..self.start);
            self.start = 0;
            return EasyBufMut { buf: buf, end: &mut self.end }
        }

        // If we couldn't get access above then we give ourself a new buffer
        // here.
        let mut v = Vec::with_capacity(self.buf.capacity());
        v.extend_from_slice(self.as_ref());
        self.start = 0;
        self.buf = Arc::new(v);
        EasyBufMut {
            buf: Arc::get_mut(&mut self.buf).unwrap(),
            end: &mut self.end,
        }
    }
}

impl AsRef<[u8]> for EasyBuf {
    fn as_ref(&self) -> &[u8] {
        &self.buf[self.start..self.end]
    }
}

impl<'a> Deref for EasyBufMut<'a> {
    type Target = Vec<u8>;

    fn deref(&self) -> &Vec<u8> {
        self.buf
    }
}

impl<'a> DerefMut for EasyBufMut<'a> {
    fn deref_mut(&mut self) -> &mut Vec<u8> {
        self.buf
    }
}

impl From<Vec<u8>> for EasyBuf {
    fn from(vec: Vec<u8>) -> EasyBuf {
        let end = vec.len();
        EasyBuf {
            buf: Arc::new(vec),
            start: 0,
            end: end,
        }
    }
}

impl<'a> Drop for EasyBufMut<'a> {
    fn drop(&mut self) {
        *self.end = self.buf.len();
    }
}

/// Encoding and decoding of frames via buffers.
///
/// This trait is used when constructing an instance of `Framed`. It provides
/// two types: `In`, for decoded input frames, and `Out`, for outgoing frames
/// that need to be encoded. It also provides methods to actually perform the
/// encoding and decoding, which work with corresponding buffer types.
///
/// The trait itself is implemented on a type that can track state for decoding
/// or encoding, which is particularly useful for streaming parsers. In many
/// cases, though, this type will simply be a unit struct (e.g. `struct
/// HttpCodec`).
pub trait Codec {
    /// The type of decoded frames.
    type In;

    /// The type of frames to be encoded.
    type Out;

    /// Attempts to decode a frame from the provided buffer of bytes.
    ///
    /// This method is called by `Framed` whenever bytes are ready to be parsed.
    /// The provided buffer of bytes is what's been read so far, and this
    /// instance of `Decode` can determine whether an entire frame is in the
    /// buffer and is ready to be returned.
    ///
    /// If an entire frame is available, then this instance will remove those
    /// bytes from the buffer provided and return them as a decoded
    /// frame. Note that removing bytes from the provided buffer doesn't always
    /// necessarily copy the bytes, so this should be an efficient operation in
    /// most circumstances.
    ///
    /// If the bytes look valid, but a frame isn't fully available yet, then
    /// `Ok(None)` is returned. This indicates to the `Framed` instance that
    /// it needs to read some more bytes before calling this method again.
    ///
    /// Finally, if the bytes in the buffer are malformed then an error is
    /// returned indicating why. This informs `Framed` that the stream is now
    /// corrupt and should be terminated.
    fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<Self::In>, io::Error>;

    /// A default method available to be called when there are no more bytes
    /// available to be read from the underlying I/O.
    ///
    /// This method defaults to calling `decode` and returns an error if
    /// `Ok(None)` is returned. Typically this doesn't need to be implemented
    /// unless the framing protocol differs near the end of the stream.
    fn decode_eof(&mut self, buf: &mut EasyBuf) -> io::Result<Self::In> {
        match try!(self.decode(buf)) {
            Some(frame) => Ok(frame),
            None => Err(io::Error::new(io::ErrorKind::Other,
                                       "bytes remaining on stream")),
        }
    }

    /// Encodes a frame into the buffer provided.
    ///
    /// This method will encode `msg` into the byte buffer provided by `buf`.
    /// The `buf` provided is an internal buffer of the `Framed` instance and
    /// will be written out when possible.
    fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> io::Result<()>;
}

/// A unified `Stream` and `Sink` interface to an underlying `Io` object, using
/// the `Codec` trait to encode and decode frames.
///
/// You can acquire a `Framed` instance by using the `Io::framed` adapter.
pub struct Framed<T, C> {
    upstream: T,
    codec: C,
    eof: bool,
    is_readable: bool,
    rd: EasyBuf,
    wr: Vec<u8>,
}

impl<T: Io, C: Codec> Stream for Framed<T, C> {
    type Item = C::In;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<C::In>, io::Error> {
        loop {
            // If the read buffer has any pending data, then it could be
            // possible that `decode` will return a new frame. We leave it to
            // the decoder to optimize detecting that more data is required.
            if self.is_readable {
                if self.eof {
                    if self.rd.len() == 0 {
                        return Ok(None.into())
                    } else {
                        let frame = try!(self.codec.decode_eof(&mut self.rd));
                        return Ok(Async::Ready(Some(frame)))
                    }
                }
                trace!("attempting to decode a frame");
                if let Some(frame) = try!(self.codec.decode(&mut self.rd)) {
                    trace!("frame decoded from buffer");
                    return Ok(Async::Ready(Some(frame)));
                }
                self.is_readable = false;
            }

            assert!(!self.eof);

            // Otherwise, try to read more data and try again
            //
            // TODO: shouldn't read_to_end, that may read a lot
            let before = self.rd.len();
            let ret = self.upstream.read_to_end(&mut self.rd.get_mut());
            match ret {
                Ok(_n) => self.eof = true,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    if self.rd.len() == before {
                        return Ok(Async::NotReady)
                    }
                }
                Err(e) => return Err(e),
            }
            self.is_readable = true;
        }
    }
}

impl<T: Io, C: Codec> Sink for Framed<T, C> {
    type SinkItem = C::Out;
    type SinkError = io::Error;

    fn start_send(&mut self, item: C::Out) -> StartSend<C::Out, io::Error> {
        // If the buffer is already over 8KiB, then attempt to flush it. If after flushing it's
        // *still* over 8KiB, then apply backpressure (reject the send).
        if self.wr.len() > 8 * 1024 {
            try!(self.poll_complete());
            if self.wr.len() > 8 * 1024 {
                return Ok(AsyncSink::NotReady(item));
            }
        }

        try!(self.codec.encode(item, &mut self.wr));
        Ok(AsyncSink::Ready)
    }

    fn poll_complete(&mut self) -> Poll<(), io::Error> {
        trace!("flushing framed transport");

        while !self.wr.is_empty() {
            trace!("writing; remaining={}", self.wr.len());
            let n = try_nb!(self.upstream.write(&self.wr));
            if n == 0 {
                return Err(io::Error::new(io::ErrorKind::WriteZero,
                                          "failed to write frame to transport"));
            }
            self.wr.drain(..n);
        }

        // Try flushing the underlying IO
        try_nb!(self.upstream.flush());

        trace!("framed transport flushed");
        return Ok(Async::Ready(()));
    }
}

pub fn framed<T, C>(io: T, codec: C) -> Framed<T, C> {
    Framed {
        upstream: io,
        codec: codec,
        eof: false,
        is_readable: false,
        rd: EasyBuf::new(),
        wr: Vec::with_capacity(8 * 1024),
    }
}

impl<T, C> Framed<T, C> {

    /// Returns a reference to the underlying I/O stream wrapped by `Framed`.
    ///
    /// Note that care should be taken to not tamper with the underlying stream
    /// of data coming in as it may corrupt the stream of frames otherwise being
    /// worked with.
    pub fn get_ref(&self) -> &T {
        &self.upstream
    }

    /// Returns a mutable reference to the underlying I/O stream wrapped by
    /// `Framed`.
    ///
    /// Note that care should be taken to not tamper with the underlying stream
    /// of data coming in as it may corrupt the stream of frames otherwise being
    /// worked with.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.upstream
    }

    /// Consumes the `Framed`, returning its underlying I/O stream.
    ///
    /// Note that care should be taken to not tamper with the underlying stream
    /// of data coming in as it may corrupt the stream of frames otherwise being
    /// worked with.
    pub fn into_inner(self) -> T {
        self.upstream
    }
}
<commit_msg>Use `io::Result`<commit_after>use std::io;
use std::ops::{Deref, DerefMut};
use std::sync::Arc;

use futures::{Async, Poll, Stream, Sink, StartSend, AsyncSink};

use io::Io;

/// A reference counted buffer of bytes.
///
/// An `EasyBuf` is a representation of a byte buffer where sub-slices of it can
/// be handed out efficiently, each with a `'static` lifetime which keeps the
/// data alive. The buffer also supports mutation but may require bytes to be
/// copied to complete the operation.
#[derive(Clone)]
pub struct EasyBuf {
    buf: Arc<Vec<u8>>,
    start: usize,
    end: usize,
}

/// An RAII object returned from `get_mut` which provides mutable access to the
/// underlying `Vec<u8>`.
pub struct EasyBufMut<'a> {
    buf: &'a mut Vec<u8>,
    end: &'a mut usize,
}

impl EasyBuf {
    /// Creates a new EasyBuf with no data and the default capacity.
    pub fn new() -> EasyBuf {
        EasyBuf::with_capacity(8 * 1024)
    }

    /// Creates a new EasyBuf with `cap` capacity.
    pub fn with_capacity(cap: usize) -> EasyBuf {
        EasyBuf {
            buf: Arc::new(Vec::with_capacity(cap)),
            start: 0,
            end: 0,
        }
    }

    /// Changes the starting index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `start` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    fn set_start(&mut self, start: usize) -> &mut EasyBuf {
        assert!(start <= self.buf.as_ref().len());
        assert!(start <= self.end);
        self.start = start;
        self
    }

    /// Changes the end index of this window to the index specified.
    ///
    /// Returns the windows back to chain multiple calls to this method.
    ///
    /// # Panics
    ///
    /// This method will panic if `end` is out of bounds for the underlying
    /// slice or if it comes after the `end` configured in this window.
    fn set_end(&mut self, end: usize) -> &mut EasyBuf {
        assert!(end <= self.buf.len());
        assert!(self.start <= end);
        self.end = end;
        self
    }

    /// Returns the number of bytes contained in this `EasyBuf`.
    pub fn len(&self) -> usize {
        self.end - self.start
    }

    /// Returns the inner contents of this `EasyBuf` as a slice.
    pub fn as_slice(&self) -> &[u8] {
        self.as_ref()
    }

    /// Splits the buffer into two at the given index.
    ///
    /// Afterwards `self` contains elements `[0, at)`, and the returned `EasyBuf`
    /// contains elements `[at, len)`.
    ///
    /// This is an O(1) operation that just increases the reference count and
    /// sets a few indexes.
    ///
    /// # Panics
    ///
    /// Panics if `at > len`
    pub fn split_off(&mut self, at: usize) -> EasyBuf {
        let mut other = EasyBuf { buf: self.buf.clone(), ..*self };
        let idx = self.start + at;
        other.set_start(idx);
        self.set_end(idx);
        return other
    }

    /// Splits the buffer into two at the given index.
    ///
    /// Afterwards `self` contains elements `[at, len)`, and the returned `EasyBuf`
    /// contains elements `[0, at)`.
    ///
    /// This is an O(1) operation that just increases the reference count and
    /// sets a few indexes.
    ///
    /// # Panics
    ///
    /// Panics if `at > len`
    pub fn drain_to(&mut self, at: usize) -> EasyBuf {
        let mut other = EasyBuf { buf: self.buf.clone(), ..*self };
        let idx = self.start + at;
        other.set_end(idx);
        self.set_start(idx);
        return other
    }

    /// Returns a mutable reference to the underlying growable buffer of bytes.
    ///
    /// If this `EasyBuf` is the only instance pointing at the underlying buffer
    /// of bytes, a direct mutable reference will be returned. Otherwise the
    /// contents of this `EasyBuf` will be reallocated in a fresh `Vec<u8>`
    /// allocation with the same capacity as this allocation, and that
    /// allocation will be returned.
    ///
    /// This operation **is not O(1)** as it may clone the entire contents of
    /// this buffer.
    ///
    /// The returned `EasyBufMut` type implement `Deref` and `DerefMut` to
    /// `Vec<u8>` can the byte buffer can be manipulated using the standard
    /// `Vec<u8>` methods.
    pub fn get_mut(&mut self) -> EasyBufMut {
        // Fast path if we can get mutable access to our own current
        // buffer.
        //
        // TODO: this should be a match or an if-let
        if Arc::get_mut(&mut self.buf).is_some() {
            let buf = Arc::get_mut(&mut self.buf).unwrap();
            buf.drain(..self.start);
            self.start = 0;
            return EasyBufMut { buf: buf, end: &mut self.end }
        }

        // If we couldn't get access above then we give ourself a new buffer
        // here.
        let mut v = Vec::with_capacity(self.buf.capacity());
        v.extend_from_slice(self.as_ref());
        self.start = 0;
        self.buf = Arc::new(v);
        EasyBufMut {
            buf: Arc::get_mut(&mut self.buf).unwrap(),
            end: &mut self.end,
        }
    }
}

impl AsRef<[u8]> for EasyBuf {
    fn as_ref(&self) -> &[u8] {
        &self.buf[self.start..self.end]
    }
}

impl<'a> Deref for EasyBufMut<'a> {
    type Target = Vec<u8>;

    fn deref(&self) -> &Vec<u8> {
        self.buf
    }
}

impl<'a> DerefMut for EasyBufMut<'a> {
    fn deref_mut(&mut self) -> &mut Vec<u8> {
        self.buf
    }
}

impl From<Vec<u8>> for EasyBuf {
    fn from(vec: Vec<u8>) -> EasyBuf {
        let end = vec.len();
        EasyBuf {
            buf: Arc::new(vec),
            start: 0,
            end: end,
        }
    }
}

impl<'a> Drop for EasyBufMut<'a> {
    fn drop(&mut self) {
        *self.end = self.buf.len();
    }
}

/// Encoding and decoding of frames via buffers.
///
/// This trait is used when constructing an instance of `Framed`. It provides
/// two types: `In`, for decoded input frames, and `Out`, for outgoing frames
/// that need to be encoded. It also provides methods to actually perform the
/// encoding and decoding, which work with corresponding buffer types.
///
/// The trait itself is implemented on a type that can track state for decoding
/// or encoding, which is particularly useful for streaming parsers. In many
/// cases, though, this type will simply be a unit struct (e.g. `struct
/// HttpCodec`).
pub trait Codec {
    /// The type of decoded frames.
    type In;

    /// The type of frames to be encoded.
    type Out;

    /// Attempts to decode a frame from the provided buffer of bytes.
    ///
    /// This method is called by `Framed` whenever bytes are ready to be parsed.
    /// The provided buffer of bytes is what's been read so far, and this
    /// instance of `Decode` can determine whether an entire frame is in the
    /// buffer and is ready to be returned.
    ///
    /// If an entire frame is available, then this instance will remove those
    /// bytes from the buffer provided and return them as a decoded
    /// frame. Note that removing bytes from the provided buffer doesn't always
    /// necessarily copy the bytes, so this should be an efficient operation in
    /// most circumstances.
    ///
    /// If the bytes look valid, but a frame isn't fully available yet, then
    /// `Ok(None)` is returned. This indicates to the `Framed` instance that
    /// it needs to read some more bytes before calling this method again.
    ///
    /// Finally, if the bytes in the buffer are malformed then an error is
    /// returned indicating why. This informs `Framed` that the stream is now
    /// corrupt and should be terminated.
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>>;

    /// A default method available to be called when there are no more bytes
    /// available to be read from the underlying I/O.
    ///
    /// This method defaults to calling `decode` and returns an error if
    /// `Ok(None)` is returned. Typically this doesn't need to be implemented
    /// unless the framing protocol differs near the end of the stream.
    fn decode_eof(&mut self, buf: &mut EasyBuf) -> io::Result<Self::In> {
        match try!(self.decode(buf)) {
            Some(frame) => Ok(frame),
            None => Err(io::Error::new(io::ErrorKind::Other,
                                       "bytes remaining on stream")),
        }
    }

    /// Encodes a frame into the buffer provided.
    ///
    /// This method will encode `msg` into the byte buffer provided by `buf`.
    /// The `buf` provided is an internal buffer of the `Framed` instance and
    /// will be written out when possible.
    fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> io::Result<()>;
}

/// A unified `Stream` and `Sink` interface to an underlying `Io` object, using
/// the `Codec` trait to encode and decode frames.
///
/// You can acquire a `Framed` instance by using the `Io::framed` adapter.
pub struct Framed<T, C> {
    upstream: T,
    codec: C,
    eof: bool,
    is_readable: bool,
    rd: EasyBuf,
    wr: Vec<u8>,
}

impl<T: Io, C: Codec> Stream for Framed<T, C> {
    type Item = C::In;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<C::In>, io::Error> {
        loop {
            // If the read buffer has any pending data, then it could be
            // possible that `decode` will return a new frame. We leave it to
            // the decoder to optimize detecting that more data is required.
            if self.is_readable {
                if self.eof {
                    if self.rd.len() == 0 {
                        return Ok(None.into())
                    } else {
                        let frame = try!(self.codec.decode_eof(&mut self.rd));
                        return Ok(Async::Ready(Some(frame)))
                    }
                }
                trace!("attempting to decode a frame");
                if let Some(frame) = try!(self.codec.decode(&mut self.rd)) {
                    trace!("frame decoded from buffer");
                    return Ok(Async::Ready(Some(frame)));
                }
                self.is_readable = false;
            }

            assert!(!self.eof);

            // Otherwise, try to read more data and try again
            //
            // TODO: shouldn't read_to_end, that may read a lot
            let before = self.rd.len();
            let ret = self.upstream.read_to_end(&mut self.rd.get_mut());
            match ret {
                Ok(_n) => self.eof = true,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    if self.rd.len() == before {
                        return Ok(Async::NotReady)
                    }
                }
                Err(e) => return Err(e),
            }
            self.is_readable = true;
        }
    }
}

impl<T: Io, C: Codec> Sink for Framed<T, C> {
    type SinkItem = C::Out;
    type SinkError = io::Error;

    fn start_send(&mut self, item: C::Out) -> StartSend<C::Out, io::Error> {
        // If the buffer is already over 8KiB, then attempt to flush it. If after flushing it's
        // *still* over 8KiB, then apply backpressure (reject the send).
        if self.wr.len() > 8 * 1024 {
            try!(self.poll_complete());
            if self.wr.len() > 8 * 1024 {
                return Ok(AsyncSink::NotReady(item));
            }
        }

        try!(self.codec.encode(item, &mut self.wr));
        Ok(AsyncSink::Ready)
    }

    fn poll_complete(&mut self) -> Poll<(), io::Error> {
        trace!("flushing framed transport");

        while !self.wr.is_empty() {
            trace!("writing; remaining={}", self.wr.len());
            let n = try_nb!(self.upstream.write(&self.wr));
            if n == 0 {
                return Err(io::Error::new(io::ErrorKind::WriteZero,
                                          "failed to write frame to transport"));
            }
            self.wr.drain(..n);
        }

        // Try flushing the underlying IO
        try_nb!(self.upstream.flush());

        trace!("framed transport flushed");
        return Ok(Async::Ready(()));
    }
}

pub fn framed<T, C>(io: T, codec: C) -> Framed<T, C> {
    Framed {
        upstream: io,
        codec: codec,
        eof: false,
        is_readable: false,
        rd: EasyBuf::new(),
        wr: Vec::with_capacity(8 * 1024),
    }
}

impl<T, C> Framed<T, C> {

    /// Returns a reference to the underlying I/O stream wrapped by `Framed`.
    ///
    /// Note that care should be taken to not tamper with the underlying stream
    /// of data coming in as it may corrupt the stream of frames otherwise being
    /// worked with.
    pub fn get_ref(&self) -> &T {
        &self.upstream
    }

    /// Returns a mutable reference to the underlying I/O stream wrapped by
    /// `Framed`.
    ///
    /// Note that care should be taken to not tamper with the underlying stream
    /// of data coming in as it may corrupt the stream of frames otherwise being
    /// worked with.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.upstream
    }

    /// Consumes the `Framed`, returning its underlying I/O stream.
    ///
    /// Note that care should be taken to not tamper with the underlying stream
    /// of data coming in as it may corrupt the stream of frames otherwise being
    /// worked with.
    pub fn into_inner(self) -> T {
        self.upstream
    }
}
<|endoftext|>


<commit_before>use std::error::Error;

use rotor::{Machine, Scope, EarlyScope, Loop, LoopInstance, SpawnError};

/// Convenience enhancements to the main loop creator
pub trait LoopExt<M> {
    /// This method is useful for things that have a state machine and an
    /// accessor to it.
    ///
    /// Function looks a little bit complicated with generic params. But it
    /// solves very useful pattern in easier way.
    ///
    /// Examples:
    ///
    /// * `rotor_dns::create_resolve()`
    /// * `rotor_carbon::connect_ip()`
    ///
    /// Usage is simple (carbon example):
    /// ```ignore
    /// let sink = loop_inst.add_and_fetch(Fsm::Carbon, |scope| {
    ///     connect_ip(addr, scope)
    /// });
    /// ```
    /// Compare it to *traditional* way:
    /// ```ignore
    /// let mut sink_opt = None;
    /// loop_creator.add_machine_with(|scope| {
    ///     let (fsm, sink) = connect_ip(addr, scope).unwrap();
    ///     sink_opt = Some(sink);
    ///     Ok(Fsm::Carbon(fsm))
    /// }).unwrap();
    /// let sink = sink_opt.unwrap();
    /// ```
    ///
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut EarlyScope) -> Result<(N, T), E>;
}

/// Convenience enhancements to the main loop creator instance
pub trait LoopInstanceExt<M: Machine> {
    /// This method is useful for things that have a state machine and an
    /// accessor to it.
    ///
    /// Function looks a little bit complicated with generic params. But it
    /// solves very useful pattern in easier way.
    ///
    /// Examples:
    ///
    /// * `rotor_dns::create_resolve()`
    /// * `rotor_carbon::connect_ip()`
    ///
    /// Usage is simple (carbon example):
    /// ```ignore
    /// let sink = loop_inst.add_and_fetch(Fsm::Carbon, |scope| {
    ///     connect_ip(addr, scope)
    /// });
    /// ```
    /// Compare it to *traditional* way:
    /// ```ignore
    /// let mut sink_opt = None;
    /// loop_creator.add_machine_with(|scope| {
    ///     let (fsm, sink) = connect_ip(addr, scope).unwrap();
    ///     sink_opt = Some(sink);
    ///     Ok(Fsm::Carbon(fsm))
    /// }).unwrap();
    /// let sink = sink_opt.unwrap();
    /// ```
    ///
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut Scope<M::Context>) -> Result<(N, T), E>;
}

impl<C, M: Machine<Context=C>> LoopExt<M> for Loop<C, M> {
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut EarlyScope) -> Result<(N, T), E>
    {
        let mut result_opt = None;
        try!(self.add_machine_with(|scope| {
            let (fsm, value) = try!(fun(scope));
            result_opt = Some(value);
            Ok(fsm_wrapper(fsm))
        }));
        Ok(result_opt.unwrap())
    }
}

impl<C, M: Machine<Context=C>> LoopInstanceExt<M> for LoopInstance<C, M> {
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut Scope<M::Context>) -> Result<(N, T), E>
    {
        let mut result_opt = None;
        try!(self.add_machine_with(|scope| {
            let (fsm, value) = try!(fun(scope));
            result_opt = Some(value);
            Ok(fsm_wrapper(fsm))
        }));
        Ok(result_opt.unwrap())
    }
}
<commit_msg>Fix formatting and add some words to docs<commit_after>//! The traits which make main loop construction nicer
use std::error::Error;

use rotor::{Machine, Scope, EarlyScope, Loop, LoopInstance, SpawnError};

/// Convenience enhancements to the main loop creator
pub trait LoopExt<M> {
    /// This method is useful for things that have a state machine and an
    /// accessor to it.
    ///
    /// Function looks a little bit complicated with generic params. But it
    /// solves very useful pattern in easier way.
    ///
    /// Examples:
    ///
    /// * `rotor_dns::create_resolve()`
    /// * `rotor_carbon::connect_ip()`
    ///
    /// Usage is simple (carbon example):
    ///
    /// ```ignore
    /// let sink = loop_inst.add_and_fetch(Fsm::Carbon, |scope| {
    ///     connect_ip(addr, scope)
    /// });
    /// ```
    ///
    /// Compare it to *traditional* way:
    ///
    /// ```ignore
    /// let mut sink_opt = None;
    /// loop_creator.add_machine_with(|scope| {
    ///     let (fsm, sink) = connect_ip(addr, scope).unwrap();
    ///     sink_opt = Some(sink);
    ///     Ok(Fsm::Carbon(fsm))
    /// }).unwrap();
    /// let sink = sink_opt.unwrap();
    /// ```
    ///
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut EarlyScope) -> Result<(N, T), E>;
}

/// Convenience enhancements to the main loop creator instance
pub trait LoopInstanceExt<M: Machine> {
    /// This method is useful for things that have a state machine and an
    /// accessor to it.
    ///
    /// Function looks a little bit complicated with generic params. But it
    /// solves very useful pattern in easier way.
    ///
    /// Examples:
    ///
    /// * `rotor_dns::create_resolve()`
    /// * `rotor_carbon::connect_ip()`
    ///
    /// Usage is simple (carbon example):
    ///
    /// ```ignore
    /// let sink = loop_inst.add_and_fetch(Fsm::Carbon, |scope| {
    ///     connect_ip(addr, scope)
    /// });
    /// ```
    ///
    /// Compare it to *traditional* way:
    ///
    /// ```ignore
    /// let mut sink_opt = None;
    /// loop_creator.add_machine_with(|scope| {
    ///     let (fsm, sink) = connect_ip(addr, scope).unwrap();
    ///     sink_opt = Some(sink);
    ///     Ok(Fsm::Carbon(fsm))
    /// }).unwrap();
    /// let sink = sink_opt.unwrap();
    /// ```
    ///
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut Scope<M::Context>) -> Result<(N, T), E>;
}

impl<C, M: Machine<Context=C>> LoopExt<M> for Loop<C, M> {
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut EarlyScope) -> Result<(N, T), E>
    {
        let mut result_opt = None;
        try!(self.add_machine_with(|scope| {
            let (fsm, value) = try!(fun(scope));
            result_opt = Some(value);
            Ok(fsm_wrapper(fsm))
        }));
        Ok(result_opt.unwrap())
    }
}

impl<C, M: Machine<Context=C>> LoopInstanceExt<M> for LoopInstance<C, M> {
    fn add_and_fetch<F, W, T, E, N>(&mut self, fsm_wrapper: W, fun: F)
        -> Result<T, SpawnError<()>>
        where E: Error + 'static,
              W: FnOnce(N) -> M,
              F: FnOnce(&mut Scope<M::Context>) -> Result<(N, T), E>
    {
        let mut result_opt = None;
        try!(self.add_machine_with(|scope| {
            let (fsm, value) = try!(fun(scope));
            result_opt = Some(value);
            Ok(fsm_wrapper(fsm))
        }));
        Ok(result_opt.unwrap())
    }
}
<|endoftext|>


<commit_before>use std::os;
use std::collections::HashMap;
use std::io;
use std::io::fs::PathExtensions;
use std::borrow::ToOwned;

use vobject::{Component,Property,parse_component,write_component};
use email::rfc5322::Rfc5322Parser;
use uuid::Uuid;

macro_rules! main_try {
    ($result: expr, $errmsg: expr) => (
        match $result {
            Ok(m) => m,
            Err(e) => {
                println!("{}: {}", $errmsg, e);
                os::set_exit_status(1);
                return;
            }
        }
    )
}

fn get_env() -> HashMap<String, String> {
    let mut env = HashMap::new();
    env.extend(os::env().into_iter().filter(|&(ref key, ref value)| {
        (key.as_slice() == "EDITOR" || key.as_slice().starts_with("MATES_")) &&
            value.len() > 0
    }));
    env
}

fn expect_env<'a>(env: &'a HashMap<String, String>, key: &str) -> &'a String {
    env.get(key).expect(
        format!("The {} environment variable must be set.", key).as_slice()
    )
}

fn build_index(outfile: &Path, dir: &Path) -> io::IoResult<()> {
    if !dir.is_dir() {
        return Err(io::IoError {
            kind: io::MismatchedFileTypeForOperation,
            desc: "MATES_DIR must be a directory.",
            detail: None
        });
    };

    let mut outf = io::File::create(outfile);
    let entries = try!(io::fs::readdir(dir));
    let mut errors = false;

    for entry in entries.iter() {
        if !entry.is_file() {
            continue;
        }

        println!("Processing {}", entry.display());
        let contact = match Contact::from_file(entry.clone()) {
            Ok(x) => x,
            Err(e) => {
                println!("Error while reading {}: {}", entry.display(), e);
                errors = true;
                continue
            }
        };

        match index_item_from_contact(&contact) {
            Ok(index_string) => {
                try!(outf.write_str(index_string.as_slice()));
            },
            Err(e) => {
                println!("Error while indexing {}: {}", entry.display(), e);
                errors = true;
                continue
            }
        };
    };

    if errors {
        Err(io::IoError {
            kind: io::OtherIoError,
            desc: "Several errors happened while generating the index.",
            detail: None
        })
    } else {
        Ok(())
    }
}

fn index_item_from_contact(contact: &Contact) -> io::IoResult<String> {
    let name = match contact.component.single_prop("FN") {
        Some(name) => name.value_as_string(),
        None => return Err(io::IoError {
            kind: io::OtherIoError,
            desc: "No name found.",
            detail: None
        })
    };

    let emails = contact.component.all_props("EMAIL");
    let mut rv = String::new();
    for email in emails.iter() {
        rv.push_str(format!("{}\t{}\t{}\n", email.value_as_string(), name, contact.path.display()).as_slice());
    };
    Ok(rv)
}

pub fn cli_main() {
    let env = get_env();
    let mut args = os::args().into_iter();
    let program = args.next().unwrap_or("mates".to_string());

    let help = format!("Usage: {} COMMAND
Commands:
    index:
        Rewrite/create the index.
    mutt-query <query>:
        Search for contact, output is usable for mutt's query_command.
    file-query <query>:
        Search for contact, return just the filename.
    email-query <query>:
        Search for contact, return \"name <email>\".
    add:
        Take mail from stdin, add sender to contacts. Print filename.
    edit <file-or-query>:
        Open contact (given by filepath or search-string) in $MATES_EDITOR. If
        the file is cleared, the contact is removed.", program);

    let print_help = |&:| {
        println!("{}", help);
    };

    let command = args.next().unwrap_or("".to_string());

    match command.as_slice() {
        "index" => {
            let index_file = expect_env(&env, "MATES_INDEX");
            let mates_dir = expect_env(&env, "MATES_DIR");
            println!("Rebuilding index file \"{}\"...", index_file);
            main_try!(build_index(
                &Path::new(index_file.as_slice()),
                &Path::new(mates_dir.as_slice())
            ), "Failed to build index");
        },
        "mutt-query" => {
            let query = args.next().unwrap_or("".to_string());
            main_try!(mutt_query(&env, query.as_slice()), "Failed to execute grep");
        },
        "file-query" => {
            let query = args.next().unwrap_or("".to_string());
            main_try!(file_query(&env, query.as_slice()), "Failed to execute grep");
        },
        "email-query" => {
            let query = args.next().unwrap_or("".to_string());
            main_try!(email_query(&env, query.as_slice()), "Failed to execute grep");
        },
        "add" => {
            let index_file = Path::new(expect_env(&env, "MATES_INDEX"));
            let mates_dir = Path::new(expect_env(&env, "MATES_DIR"));
            let contact = main_try!(add_contact(&mates_dir), "Failed to add contact");
            println!("{}", contact.path.display());

            let mut index_fp = main_try!(io::File::open_mode(
                &index_file,
                io::Append,
                io::Write),
                "Failed to open index"
            );

            let index_entry = main_try!(index_item_from_contact(&contact), "Failed to generate index");
            main_try!(index_fp.write_str(index_entry.as_slice()), "Failed to write to index");
        },
        "edit" => {
            let query = args.next().unwrap_or("".to_string());
            let mates_dir = expect_env(&env, "MATES_DIR");
            main_try!(edit_contact(&env, query.as_slice(), mates_dir.as_slice()),
                      "Failed to edit contact");
        },
        _ => {
            print_help();
            if command != "help" && command != "--help" && command != "-h" {
                os::set_exit_status(1);
            }
        }
    };
}

fn add_contact(contact_dir: &Path) -> io::IoResult<Contact> {
    let stdin = try!(io::stdin().lock().read_to_string());
    let from_header = match read_sender_from_email(stdin.as_slice()) {
        Some(x) => x,
        None => return Err(io::IoError {
            kind: io::InvalidInput,
            desc: "Couldn't find From-header in email.",
            detail: None
        })
    };
    let (fullname, email) = parse_from_header(&from_header);
    let contact = Contact::generate(fullname, email, contact_dir);
    try!(contact.write_create());
    Ok(contact)
}

/// Return a tuple (fullname, email)
fn parse_from_header<'a>(s: &'a String) -> (Option<&'a str>, Option<&'a str>) {
    let mut split = s.rsplitn(1, ' ');
    let email = match split.next() {
        Some(x) => Some(x.trim_left_matches('<').trim_right_matches('>')),
        None => Some(s.as_slice())
    };
    let name = split.next();
    (name, email)
}

/// Given an email, return value of From header.
fn read_sender_from_email(email: &str) -> Option<String> {
    let mut parser = Rfc5322Parser::new(email);
    while !parser.eof() {
        match parser.consume_header() {
            Some(header) => {
                if header.name == "From" {
                    return header.get_value()
                };
            },
            None => return None
        };
    };
    None
}

fn edit_contact(env: &HashMap<String, String>, query: &str, mates_dir: &str) -> Result<(), String> {
    let editor_cmd = match env.get("MATES_EDITOR") {
        Some(x) => x.as_slice(),
        None => match env.get("EDITOR") {
            Some(x) => x.as_slice(),
            None => return Err("Either MATES_EDITOR or EDITOR has to be set.".to_string())
        }
    };

    let results = {
        if Path::new(mates_dir).join(query).exists() {
            vec![query.to_string()]
        } else {
            let results_iter = match index_query(env, query) {
                Ok(x) => x,
                Err(e) => return Err(format!("Error while fetching index: {}", e))
            };

            results_iter.filter_map(|x| {
                if x.filepath.len() > 0 {
                    Some(x.filepath)
                } else {
                    None
                }}).collect()
        }
    };

    if results.len() < 1 {
        return Err("No such contact.".to_string());
    } else if results.len() > 1 {
        for fname in results.iter() {
            println!("{}", fname);
        };
        return Err("Ambiguous query.".to_string());
    }

    let fpath = results[0].as_slice();
    let mut process = match io::Command::new("sh")
        .arg("-c")
        // clear stdin, http://unix.stackexchange.com/a/77593
        .arg(format!("$0 -- \"$1\" < $2"))
        .arg(editor_cmd.as_slice())
        .arg(fpath)
        .arg("/dev/tty")
        .stdin(io::process::InheritFd(0))
        .stdout(io::process::InheritFd(1))
        .stderr(io::process::InheritFd(2))
        .spawn() {
            Ok(x) => x,
            Err(e) => return Err(format!("Error while invoking editor: {}", e))
        };

    match process.wait() {
        Ok(_) => (),
        Err(e) => return Err(format!("Error while invoking editor: {}", e))
    };

    if match io::File::open(&Path::new(fpath)).read_to_string() {
        Ok(x) => x,
        Err(e) => return Err(format!("File can't be read after user edited it: {}", e))
    }.as_slice().trim().len() == 0 {
        return Err(format!("Contact emptied, file removed."));
    };

    Ok(())
}

fn mutt_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<()> {
    println!("");  // For some reason mutt requires an empty line
    for item in try!(index_query(env, query)) {
        if item.email.len() > 0 && item.name.len() > 0 {
            println!("{}\t{}\t{}", item.email, item.name, item.filepath);
        };
    };
    Ok(())
}

fn file_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<()> {
    for item in try!(index_query(env, query)) {
        if item.filepath.len() > 0 {
            println!("{}", item.filepath)
        };
    };
    Ok(())
}

fn email_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<()> {
    for item in try!(index_query(env, query)) {
        if item.name.len() > 0 && item.email.len() > 0 {
            println!("{} <{}>", item.name, item.email);
        };
    };
    Ok(())
}

fn index_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<IndexIterator<'a>> {
    let default_grep = "grep".to_owned();
    let grep_cmd = match env.get("MATES_GREP") {
        Some(x) => x,
        None => &default_grep
    };

    let index_path = Path::new(expect_env(env, "MATES_INDEX"));
    let mut process = try!(io::Command::new(grep_cmd.as_slice())
        .arg(query.as_slice())
        .stderr(io::process::InheritFd(2))
        .spawn());

    {
        let mut index_fp = try!(io::File::open(&index_path));
        let mut stdin = process.stdin.take().unwrap();
        try!(stdin.write_str(try!(index_fp.read_to_string()).as_slice()));
    }

    let stream = match process.stdout.as_mut() {
        Some(x) => x,
        None => return Err(io::IoError {
            kind: io::IoUnavailable,
            desc: "Failed to get stdout from grep process.",
            detail: None
        })
    };

    let output = try!(stream.read_to_string());
    Ok(IndexIterator::new(&output))
}

struct IndexItem<'a> {
    pub email: String,
    pub name: String,
    pub filepath: String
}

impl<'a> IndexItem<'a> {
    fn new(line: String) -> IndexItem<'a> {
        let mut parts = line.split('\t');

        IndexItem {
            email: parts.next().unwrap_or("").to_string(),
            name: parts.next().unwrap_or("").to_string(),
            filepath: parts.next().unwrap_or("").to_string()
        }
    }
}

struct IndexIterator<'a> {
    linebuffer: Vec<String>
}

impl<'a> IndexIterator<'a> {
    fn new(output: &String) -> IndexIterator<'a> {

        let rv = output.split('\n').map(|x: &str| x.to_string()).collect();
        IndexIterator {
            linebuffer: rv
        }
    }
}

impl<'a> Iterator for IndexIterator<'a> {
    type Item = IndexItem<'a>;

    fn next(&mut self) -> Option<IndexItem<'a>> {
        match self.linebuffer.pop() {
            Some(x) => Some(IndexItem::new(x)),
            None => None
        }
    }
}

struct Contact {
    pub component: Component,
    pub path: Path
}

impl Contact {
    pub fn from_file(path: Path) -> io::IoResult<Contact> {
        let mut contact_file = try!(io::File::open(&path));
        let contact_string = try!(contact_file.read_to_string());
        let item = match parse_component(contact_string.as_slice()) {
            Ok(x) => x,
            Err(e) => return Err(io::IoError {
                kind: io::OtherIoError,
                desc: "Error while parsing contact",
                detail: Some(e)
            })
        };
        Ok(Contact { component: item, path: path })
    }

    pub fn generate(fullname: Option<&str>, email: Option<&str>, dir: &Path) -> Contact {
        let (uid, contact_path) = {
            let mut uid;
            let mut contact_path;
            loop {
                uid = Uuid::new_v4().to_simple_string();
                contact_path = dir.join(Path::new(format!("{}.vcf", uid)));
                if !contact_path.exists() {
                    break
                }
            };
            (uid, contact_path)
        };
        Contact { path: contact_path, component: generate_component(uid, fullname, email) }
    }

    pub fn write_create(&self) -> io::IoResult<()> {
        let string = write_component(&self.component);
        let mut fp = try!(io::File::create(&self.path));
        fp.write_str(string.as_slice())
    }
}

fn generate_component(uid: String, fullname: Option<&str>, email: Option<&str>) -> Component {
    let mut comp = Component::new("VCARD");

    match fullname {
        Some(x) => comp.all_props_mut("FN").push(Property::new(x)),
        None => ()
    };

    match email {
        Some(x) => comp.all_props_mut("EMAIL").push(Property::new(x)),
        None => ()
    };
    comp.all_props_mut("UID").push(Property::new(uid.as_slice()));
    comp
}
<commit_msg>less verbosity<commit_after>use std::os;
use std::collections::HashMap;
use std::io;
use std::io::fs::PathExtensions;
use std::borrow::ToOwned;

use vobject::{Component,Property,parse_component,write_component};
use email::rfc5322::Rfc5322Parser;
use uuid::Uuid;

macro_rules! main_try {
    ($result: expr, $errmsg: expr) => (
        match $result {
            Ok(m) => m,
            Err(e) => {
                println!("{}: {}", $errmsg, e);
                os::set_exit_status(1);
                return;
            }
        }
    )
}

fn get_env() -> HashMap<String, String> {
    let mut env = HashMap::new();
    env.extend(os::env().into_iter().filter(|&(ref key, ref value)| {
        (key.as_slice() == "EDITOR" || key.as_slice().starts_with("MATES_")) &&
            value.len() > 0
    }));
    env
}

fn expect_env<'a>(env: &'a HashMap<String, String>, key: &str) -> &'a String {
    env.get(key).expect(
        format!("The {} environment variable must be set.", key).as_slice()
    )
}

fn build_index(outfile: &Path, dir: &Path) -> io::IoResult<()> {
    if !dir.is_dir() {
        return Err(io::IoError {
            kind: io::MismatchedFileTypeForOperation,
            desc: "MATES_DIR must be a directory.",
            detail: None
        });
    };

    let mut outf = io::File::create(outfile);
    let entries = try!(io::fs::readdir(dir));
    let mut errors = false;

    for entry in entries.iter() {
        if !entry.is_file() {
            continue;
        }

        let contact = match Contact::from_file(entry.clone()) {
            Ok(x) => x,
            Err(e) => {
                println!("Error while reading {}: {}", entry.display(), e);
                errors = true;
                continue
            }
        };

        match index_item_from_contact(&contact) {
            Ok(index_string) => {
                try!(outf.write_str(index_string.as_slice()));
            },
            Err(e) => {
                println!("Error while indexing {}: {}", entry.display(), e);
                errors = true;
                continue
            }
        };
    };

    if errors {
        Err(io::IoError {
            kind: io::OtherIoError,
            desc: "Several errors happened while generating the index.",
            detail: None
        })
    } else {
        Ok(())
    }
}

fn index_item_from_contact(contact: &Contact) -> io::IoResult<String> {
    let name = match contact.component.single_prop("FN") {
        Some(name) => name.value_as_string(),
        None => return Err(io::IoError {
            kind: io::OtherIoError,
            desc: "No name found.",
            detail: None
        })
    };

    let emails = contact.component.all_props("EMAIL");
    let mut rv = String::new();
    for email in emails.iter() {
        rv.push_str(format!("{}\t{}\t{}\n", email.value_as_string(), name, contact.path.display()).as_slice());
    };
    Ok(rv)
}

pub fn cli_main() {
    let env = get_env();
    let mut args = os::args().into_iter();
    let program = args.next().unwrap_or("mates".to_string());

    let help = format!("Usage: {} COMMAND
Commands:
    index:
        Rewrite/create the index.
    mutt-query <query>:
        Search for contact, output is usable for mutt's query_command.
    file-query <query>:
        Search for contact, return just the filename.
    email-query <query>:
        Search for contact, return \"name <email>\".
    add:
        Take mail from stdin, add sender to contacts. Print filename.
    edit <file-or-query>:
        Open contact (given by filepath or search-string) in $MATES_EDITOR. If
        the file is cleared, the contact is removed.", program);

    let print_help = |&:| {
        println!("{}", help);
    };

    let command = args.next().unwrap_or("".to_string());

    match command.as_slice() {
        "index" => {
            let index_file = expect_env(&env, "MATES_INDEX");
            let mates_dir = expect_env(&env, "MATES_DIR");
            println!("Rebuilding index file \"{}\"...", index_file);
            main_try!(build_index(
                &Path::new(index_file.as_slice()),
                &Path::new(mates_dir.as_slice())
            ), "Failed to build index");
        },
        "mutt-query" => {
            let query = args.next().unwrap_or("".to_string());
            main_try!(mutt_query(&env, query.as_slice()), "Failed to execute grep");
        },
        "file-query" => {
            let query = args.next().unwrap_or("".to_string());
            main_try!(file_query(&env, query.as_slice()), "Failed to execute grep");
        },
        "email-query" => {
            let query = args.next().unwrap_or("".to_string());
            main_try!(email_query(&env, query.as_slice()), "Failed to execute grep");
        },
        "add" => {
            let index_file = Path::new(expect_env(&env, "MATES_INDEX"));
            let mates_dir = Path::new(expect_env(&env, "MATES_DIR"));
            let contact = main_try!(add_contact(&mates_dir), "Failed to add contact");
            println!("{}", contact.path.display());

            let mut index_fp = main_try!(io::File::open_mode(
                &index_file,
                io::Append,
                io::Write),
                "Failed to open index"
            );

            let index_entry = main_try!(index_item_from_contact(&contact), "Failed to generate index");
            main_try!(index_fp.write_str(index_entry.as_slice()), "Failed to write to index");
        },
        "edit" => {
            let query = args.next().unwrap_or("".to_string());
            let mates_dir = expect_env(&env, "MATES_DIR");
            main_try!(edit_contact(&env, query.as_slice(), mates_dir.as_slice()),
                      "Failed to edit contact");
        },
        _ => {
            print_help();
            if command != "help" && command != "--help" && command != "-h" {
                os::set_exit_status(1);
            }
        }
    };
}

fn add_contact(contact_dir: &Path) -> io::IoResult<Contact> {
    let stdin = try!(io::stdin().lock().read_to_string());
    let from_header = match read_sender_from_email(stdin.as_slice()) {
        Some(x) => x,
        None => return Err(io::IoError {
            kind: io::InvalidInput,
            desc: "Couldn't find From-header in email.",
            detail: None
        })
    };
    let (fullname, email) = parse_from_header(&from_header);
    let contact = Contact::generate(fullname, email, contact_dir);
    try!(contact.write_create());
    Ok(contact)
}

/// Return a tuple (fullname, email)
fn parse_from_header<'a>(s: &'a String) -> (Option<&'a str>, Option<&'a str>) {
    let mut split = s.rsplitn(1, ' ');
    let email = match split.next() {
        Some(x) => Some(x.trim_left_matches('<').trim_right_matches('>')),
        None => Some(s.as_slice())
    };
    let name = split.next();
    (name, email)
}

/// Given an email, return value of From header.
fn read_sender_from_email(email: &str) -> Option<String> {
    let mut parser = Rfc5322Parser::new(email);
    while !parser.eof() {
        match parser.consume_header() {
            Some(header) => {
                if header.name == "From" {
                    return header.get_value()
                };
            },
            None => return None
        };
    };
    None
}

fn edit_contact(env: &HashMap<String, String>, query: &str, mates_dir: &str) -> Result<(), String> {
    let editor_cmd = match env.get("MATES_EDITOR") {
        Some(x) => x.as_slice(),
        None => match env.get("EDITOR") {
            Some(x) => x.as_slice(),
            None => return Err("Either MATES_EDITOR or EDITOR has to be set.".to_string())
        }
    };

    let results = {
        if Path::new(mates_dir).join(query).exists() {
            vec![query.to_string()]
        } else {
            let results_iter = match index_query(env, query) {
                Ok(x) => x,
                Err(e) => return Err(format!("Error while fetching index: {}", e))
            };

            results_iter.filter_map(|x| {
                if x.filepath.len() > 0 {
                    Some(x.filepath)
                } else {
                    None
                }}).collect()
        }
    };

    if results.len() < 1 {
        return Err("No such contact.".to_string());
    } else if results.len() > 1 {
        for fname in results.iter() {
            println!("{}", fname);
        };
        return Err("Ambiguous query.".to_string());
    }

    let fpath = results[0].as_slice();
    let mut process = match io::Command::new("sh")
        .arg("-c")
        // clear stdin, http://unix.stackexchange.com/a/77593
        .arg(format!("$0 -- \"$1\" < $2"))
        .arg(editor_cmd.as_slice())
        .arg(fpath)
        .arg("/dev/tty")
        .stdin(io::process::InheritFd(0))
        .stdout(io::process::InheritFd(1))
        .stderr(io::process::InheritFd(2))
        .spawn() {
            Ok(x) => x,
            Err(e) => return Err(format!("Error while invoking editor: {}", e))
        };

    match process.wait() {
        Ok(_) => (),
        Err(e) => return Err(format!("Error while invoking editor: {}", e))
    };

    if match io::File::open(&Path::new(fpath)).read_to_string() {
        Ok(x) => x,
        Err(e) => return Err(format!("File can't be read after user edited it: {}", e))
    }.as_slice().trim().len() == 0 {
        return Err(format!("Contact emptied, file removed."));
    };

    Ok(())
}

fn mutt_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<()> {
    println!("");  // For some reason mutt requires an empty line
    for item in try!(index_query(env, query)) {
        if item.email.len() > 0 && item.name.len() > 0 {
            println!("{}\t{}\t{}", item.email, item.name, item.filepath);
        };
    };
    Ok(())
}

fn file_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<()> {
    for item in try!(index_query(env, query)) {
        if item.filepath.len() > 0 {
            println!("{}", item.filepath)
        };
    };
    Ok(())
}

fn email_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<()> {
    for item in try!(index_query(env, query)) {
        if item.name.len() > 0 && item.email.len() > 0 {
            println!("{} <{}>", item.name, item.email);
        };
    };
    Ok(())
}

fn index_query<'a>(env: &HashMap<String, String>, query: &str) -> io::IoResult<IndexIterator<'a>> {
    let default_grep = "grep".to_owned();
    let grep_cmd = match env.get("MATES_GREP") {
        Some(x) => x,
        None => &default_grep
    };

    let index_path = Path::new(expect_env(env, "MATES_INDEX"));
    let mut process = try!(io::Command::new(grep_cmd.as_slice())
        .arg(query.as_slice())
        .stderr(io::process::InheritFd(2))
        .spawn());

    {
        let mut index_fp = try!(io::File::open(&index_path));
        let mut stdin = process.stdin.take().unwrap();
        try!(stdin.write_str(try!(index_fp.read_to_string()).as_slice()));
    }

    let stream = match process.stdout.as_mut() {
        Some(x) => x,
        None => return Err(io::IoError {
            kind: io::IoUnavailable,
            desc: "Failed to get stdout from grep process.",
            detail: None
        })
    };

    let output = try!(stream.read_to_string());
    Ok(IndexIterator::new(&output))
}

struct IndexItem<'a> {
    pub email: String,
    pub name: String,
    pub filepath: String
}

impl<'a> IndexItem<'a> {
    fn new(line: String) -> IndexItem<'a> {
        let mut parts = line.split('\t');

        IndexItem {
            email: parts.next().unwrap_or("").to_string(),
            name: parts.next().unwrap_or("").to_string(),
            filepath: parts.next().unwrap_or("").to_string()
        }
    }
}

struct IndexIterator<'a> {
    linebuffer: Vec<String>
}

impl<'a> IndexIterator<'a> {
    fn new(output: &String) -> IndexIterator<'a> {

        let rv = output.split('\n').map(|x: &str| x.to_string()).collect();
        IndexIterator {
            linebuffer: rv
        }
    }
}

impl<'a> Iterator for IndexIterator<'a> {
    type Item = IndexItem<'a>;

    fn next(&mut self) -> Option<IndexItem<'a>> {
        match self.linebuffer.pop() {
            Some(x) => Some(IndexItem::new(x)),
            None => None
        }
    }
}

struct Contact {
    pub component: Component,
    pub path: Path
}

impl Contact {
    pub fn from_file(path: Path) -> io::IoResult<Contact> {
        let mut contact_file = try!(io::File::open(&path));
        let contact_string = try!(contact_file.read_to_string());
        let item = match parse_component(contact_string.as_slice()) {
            Ok(x) => x,
            Err(e) => return Err(io::IoError {
                kind: io::OtherIoError,
                desc: "Error while parsing contact",
                detail: Some(e)
            })
        };
        Ok(Contact { component: item, path: path })
    }

    pub fn generate(fullname: Option<&str>, email: Option<&str>, dir: &Path) -> Contact {
        let (uid, contact_path) = {
            let mut uid;
            let mut contact_path;
            loop {
                uid = Uuid::new_v4().to_simple_string();
                contact_path = dir.join(Path::new(format!("{}.vcf", uid)));
                if !contact_path.exists() {
                    break
                }
            };
            (uid, contact_path)
        };
        Contact { path: contact_path, component: generate_component(uid, fullname, email) }
    }

    pub fn write_create(&self) -> io::IoResult<()> {
        let string = write_component(&self.component);
        let mut fp = try!(io::File::create(&self.path));
        fp.write_str(string.as_slice())
    }
}

fn generate_component(uid: String, fullname: Option<&str>, email: Option<&str>) -> Component {
    let mut comp = Component::new("VCARD");

    match fullname {
        Some(x) => comp.all_props_mut("FN").push(Property::new(x)),
        None => ()
    };

    match email {
        Some(x) => comp.all_props_mut("EMAIL").push(Property::new(x)),
        None => ()
    };
    comp.all_props_mut("UID").push(Property::new(uid.as_slice()));
    comp
}
<|endoftext|>


<commit_before>use ctxt::Context;
use mir::*;
use mir::Instr::*;
use mir::Opnd::*;

pub fn dump<'a, 'ast>(ctxt: &'a Context<'a, 'ast>, fct: &'a Mir) {
    Dumper::new(ctxt, fct).dump();
}

struct Dumper<'a, 'ast: 'a> {
    ctxt: &'a Context<'a, 'ast>,
    fct: &'a Mir,
}

impl<'a, 'ast> Dumper<'a, 'ast> {
    fn new(ctxt: &'a Context<'a, 'ast>, fct: &'a Mir) -> Dumper<'a, 'ast> {
        Dumper {
            ctxt: ctxt,
            fct: fct
        }
    }

    fn dump(&self) {
        println!("fct ({} block(s), {} var(s))", self.fct.blocks.len(), self.fct.vars.len());

        for var in &self.fct.vars {
            let name = self.ctxt.interner.str(var.name);
            println!("\t%{}:{} id={}", name, var.data_type.to_string(), var.id.to_string());
        }

        for block in &self.fct.blocks {
            let block = block.clone();
            self.dump_block(&block.borrow());
        }
    }

    fn dump_block(&self, block: &Block) {
        println!("\tblock {}: ({} instruction(s))",
            block.id.to_string(), block.instructions.len());

        for instr in &block.instructions {
            print!("\t\t");
            self.dump_instr(instr);
        }
    }

    fn dump_instr(&self, instr: &Instr) {
        match *instr {
            InstrRet(Some(opnd)) => println!("ret {}", self.opnd(opnd)),
            InstrRet(None) => println!("ret"),
            InstrGoto(block) => println!("goto -> block {}", block.to_string()),
            InstrTest(ref instr) =>
                println!("test {} -> block {} -> block {}", self.opnd(instr.opnd),
                    instr.true_block.to_string(), instr.false_block.to_string()),
            InstrAssign(ref instr) => println!("{} = {}",
                self.opnd(instr.dest), self.opnd(instr.src)),
            InstrUn(ref instr) => println!("{} = {} {}",
                self.opnd(instr.dest), instr.op.as_str(), self.opnd(instr.src)),
            InstrBin(ref instr) => println!("{} = {} {} {}", self.opnd(instr.dest),
                self.opnd(instr.lhs), instr.op.as_str(), self.opnd(instr.rhs)),
            InstrPhi(ref instr) => {
                let dest = OpndVar(instr.var_id, instr.dest);
                print!("{} = phi(", self.opnd(dest));
                let mut first = true;

                for opnd in &instr.opnds {
                    if !first { print!(", "); }
                    let opnd = OpndVar(instr.var_id, *opnd);
                    print!("{}", self.opnd(opnd));
                    first = false;
                }

                println!(") (backup {})", instr.backup);
            },
            InstrStr(ref instr) => println!("{} = str {:?}",
                self.opnd(instr.dest), instr.value),
            _ => panic!("unknown instruction")
        }
    }

    fn opnd(&self, opnd: Opnd) -> String {
        match opnd {
            OpndReg(ind) => format!("%reg{}", ind),
            OpndInt(val) => format!("{}", val),
            OpndBool(val) => format!("{}", val),
            OpndVar(id, ssa) => {
                let var = &self.fct.vars[id.0];
                let name = self.ctxt.interner.str(var.name);

                format!("%{}.{}", name, ssa)
            }
        }
    }
}
<commit_msg>MIR: renamed fct to mir<commit_after>use ctxt::Context;
use mir::*;
use mir::Instr::*;
use mir::Opnd::*;

pub fn dump<'a, 'ast>(ctxt: &'a Context<'a, 'ast>, mir: &'a Mir) {
    Dumper::new(ctxt, mir).dump();
}

struct Dumper<'a, 'ast: 'a> {
    ctxt: &'a Context<'a, 'ast>,
    mir: &'a Mir,
}

impl<'a, 'ast> Dumper<'a, 'ast> {
    fn new(ctxt: &'a Context<'a, 'ast>, mir: &'a Mir) -> Dumper<'a, 'ast> {
        Dumper {
            ctxt: ctxt,
            mir: mir
        }
    }

    fn dump(&self) {
        println!("fct ({} block(s), {} var(s))", self.mir.blocks.len(), self.mir.vars.len());

        for var in &self.mir.vars {
            let name = self.ctxt.interner.str(var.name);
            println!("\t%{}:{} id={}", name, var.data_type.to_string(), var.id.to_string());
        }

        for block in &self.mir.blocks {
            let block = block.clone();
            self.dump_block(&block.borrow());
        }
    }

    fn dump_block(&self, block: &Block) {
        println!("\tblock {}: ({} instruction(s))",
            block.id.to_string(), block.instructions.len());

        for instr in &block.instructions {
            print!("\t\t");
            self.dump_instr(instr);
        }
    }

    fn dump_instr(&self, instr: &Instr) {
        match *instr {
            InstrRet(Some(opnd)) => println!("ret {}", self.opnd(opnd)),
            InstrRet(None) => println!("ret"),
            InstrGoto(block) => println!("goto -> block {}", block.to_string()),
            InstrTest(ref instr) =>
                println!("test {} -> block {} -> block {}", self.opnd(instr.opnd),
                    instr.true_block.to_string(), instr.false_block.to_string()),
            InstrAssign(ref instr) => println!("{} = {}",
                self.opnd(instr.dest), self.opnd(instr.src)),
            InstrUn(ref instr) => println!("{} = {} {}",
                self.opnd(instr.dest), instr.op.as_str(), self.opnd(instr.src)),
            InstrBin(ref instr) => println!("{} = {} {} {}", self.opnd(instr.dest),
                self.opnd(instr.lhs), instr.op.as_str(), self.opnd(instr.rhs)),
            InstrPhi(ref instr) => {
                let dest = OpndVar(instr.var_id, instr.dest);
                print!("{} = phi(", self.opnd(dest));
                let mut first = true;

                for opnd in &instr.opnds {
                    if !first { print!(", "); }
                    let opnd = OpndVar(instr.var_id, *opnd);
                    print!("{}", self.opnd(opnd));
                    first = false;
                }

                println!(") (backup {})", instr.backup);
            },
            InstrStr(ref instr) => println!("{} = str {:?}",
                self.opnd(instr.dest), instr.value),
            _ => panic!("unknown instruction")
        }
    }

    fn opnd(&self, opnd: Opnd) -> String {
        match opnd {
            OpndReg(ind) => format!("%reg{}", ind),
            OpndInt(val) => format!("{}", val),
            OpndBool(val) => format!("{}", val),
            OpndVar(id, ssa) => {
                let var = &self.mir.vars[id.0];
                let name = self.ctxt.interner.str(var.name);

                format!("%{}.{}", name, ssa)
            }
        }
    }
}
<|endoftext|>