<commit_before>extern crate mio;
extern crate bytes;

use mio::*;
use mio::tcp::*;
use bytes::{ByteBuf, MutByteBuf};
use mio::util::Slab;
use std::io;
use std::net::{SocketAddr};
use std::str::FromStr;

const SERVER: Token = Token(0);

struct EchoConn {
    sock: TcpStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet
}

impl EchoConn {
    fn new(sock: TcpStream) -> EchoConn {
        EchoConn {
            sock: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            token: None,
            interest: EventSet::hup()
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>) -> io::Result<()> {
        let mut buf = self.buf.take().unwrap();

        match self.sock.try_write_buf(&mut buf) {
            Ok(None) => {
                print!("client flushing buf; WOULDBLOCK");

                self.buf = Some(buf);
                self.interest.insert(EventSet::writable());
            }
            Ok(Some(r)) => {
                print!("CONN : we wrote {} bytes!", r);

                self.mut_buf = Some(buf.flip());

                self.interest.insert(EventSet::readable());
                self.interest.remove(EventSet::writable());
            }
            Err(e) => print!("not implemented; client err={:?}", e),
        }

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

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap();

        match self.sock.try_read_buf(&mut buf) {
            Ok(None) => {
                panic!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                print!("CONN : we read {} bytes!", r);
                self.interest.remove(EventSet::readable());
                self.interest.insert(EventSet::writable());
            }
            Err(e) => {
                print!("not implemented; client err={:?}", e);
                self.interest.remove(EventSet::readable());
            }

        };

        // prepare to provide this to writable
        self.buf = Some(buf.flip());
        event_loop.reregister(&self.sock, self.token.unwrap(), self.interest,
                              PollOpt::edge())
    }
}

struct EchoServer {
    sock: TcpListener,
    conns: Slab<EchoConn>
}

impl EchoServer {
    fn accept(&mut self, event_loop: &mut EventLoop<Echo>) -> io::Result<()> {
        print!("server accepting socket");

        let sock = self.sock.accept().unwrap().unwrap();
        let conn = EchoConn::new(sock,);
        let tok = self.conns.insert(conn)
            .ok().expect("could not add connection to slab");

        // Register the connection
        self.conns[tok].token = Some(tok);
        event_loop.register_opt(&self.conns[tok].sock, tok, EventSet::readable(),
                                PollOpt::edge() | PollOpt::oneshot())
            .ok().expect("could not register socket with event loop");

        Ok(())
    }

    fn conn_readable(&mut self, event_loop: &mut EventLoop<Echo>,
                     tok: Token) -> io::Result<()> {
        print!("server conn readable; tok={:?}", tok);
        self.conn(tok).readable(event_loop)
    }

    fn conn_writable(&mut self, event_loop: &mut EventLoop<Echo>,
                     tok: Token) -> io::Result<()> {
        print!("server conn writable; tok={:?}", tok);
        self.conn(tok).writable(event_loop)
    }

    fn conn<'a>(&'a mut self, tok: Token) -> &'a mut EchoConn {
        &mut self.conns[tok]
    }
}

struct Echo {
    server: EchoServer,
}

impl Echo {
    fn new(sock: TcpListener) -> Echo {
        Echo {
            server: EchoServer {
                sock: sock,
                conns: Slab::new_starting_at(Token(2), 128)
            },
        }
    }
}

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

    fn ready(&mut self, event_loop: &mut EventLoop<Echo>, token: Token,
             events: EventSet) {
        print!("ready {:?} {:?}", token, events);
        if events.is_readable() {
            match token {
                SERVER => self.server.accept(event_loop).unwrap(),
                i => self.server.conn_readable(event_loop, i).unwrap()
            }
        }

        if events.is_writable() {
            match token {
                SERVER => panic!("received writable for token 0"),
                _ => self.server.conn_writable(event_loop, token).unwrap()
            };
        }
    }
}

pub fn localhost() -> SocketAddr {
    FromStr::from_str("127.0.0.1:7000").unwrap()
}

pub fn main () {
    let mut event_loop = EventLoop::new().unwrap();

    let addr = localhost ();
    let srv_sock = TcpListener::bind(&addr).unwrap();

    print!("listen for connections");
    event_loop.register_opt(&srv_sock, SERVER, EventSet::readable(),
                            PollOpt::edge() | PollOpt::oneshot()).unwrap();

    // Start the event loop
    event_loop.run(&mut Echo::new(srv_sock)).unwrap();
}
<commit_msg>More gracious end of connection<commit_after>extern crate mio;
extern crate bytes;

use mio::*;
use mio::tcp::*;
use bytes::{ByteBuf, MutByteBuf};
use mio::util::Slab;
use std::io;
use std::net::{SocketAddr};
use std::str::FromStr;

const SERVER: Token = Token(0);
type MyEventLoop = EventLoop<EchoServer>;

struct EchoConn {
    sock: TcpStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet
}

impl EchoConn {
    fn new(sock: TcpStream) -> EchoConn {
        EchoConn {
            sock: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            token: None,
            interest: EventSet::hup()
        }
    }

    fn writable(&mut self, event_loop: &mut MyEventLoop) -> io::Result<()> {
        let mut buf = self.buf.take().unwrap();

        match self.sock.try_write_buf(&mut buf) {
            Ok(None) => {
                self.buf = Some(buf);
                self.interest.insert(EventSet::writable());
            }
            Ok(Some(r)) => {
                let remaining = buf.remaining ();

                if remaining > 0 {
                    println!("we wrote {} bytes but {} remaining!", r, remaining);
                    self.interest.insert(EventSet::writable());
                }
                else {
                    println!("we wrote {} bytes, done", r);
                    self.mut_buf = Some(buf.flip());
                    self.interest.insert(EventSet::readable());
                    self.interest.remove(EventSet::writable());
                }
            }
            Err(e) => println!("not implemented; client err={:?}", e),
        }

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

    fn readable(&mut self, event_loop: &mut MyEventLoop) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap();

        match self.sock.try_read_buf(&mut buf) {
            Ok(None) => {
                panic!("we just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                println!("we read {} bytes!", r);
                if r == 0 {
                    println!("{:?}: end of connection", self.token.unwrap ());
                    self.interest.remove(EventSet::readable());
                }
                else {
                    self.interest.remove(EventSet::readable());
                    self.interest.insert(EventSet::writable());

                }
            }
            Err(e) => {
                println!("not implemented; client err={:?}", e);
                self.interest.remove(EventSet::readable());
            }
        };

        // prepare to provide this to writable
        self.buf = Some(buf.flip());
        event_loop.reregister(&self.sock, self.token.unwrap(), self.interest, PollOpt::edge())
    }
}

struct EchoServer {
    sock: TcpListener,
    conns: Slab<EchoConn>
}

impl EchoServer {
    fn new(sock: TcpListener) -> EchoServer {
        EchoServer {
            sock: sock,
            conns: Slab::new_starting_at(Token(2), 128)
        }
    }

    fn accept(&mut self, event_loop: &mut MyEventLoop) -> io::Result<()> {
        println!("server accepting socket");

        let sock = self.sock.accept().unwrap().unwrap();
        let conn = EchoConn::new(sock);
        let tok = self.conns.insert(conn).ok().expect("could not add connection to slab");
        println! ("assigned token {:?}", tok);

        // Register the connection
        self.conns[tok].token = Some(tok);
        event_loop.register_opt(&self.conns[tok].sock, tok, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot())
            .ok().expect("could not register socket with event loop");

        Ok(())
    }

    fn conn_readable(&mut self, event_loop: &mut MyEventLoop, tok: Token) -> io::Result<()> {
        println!("server conn readable; tok={:?}", tok);
        self.conn(tok).readable(event_loop)
    }

    fn conn_writable(&mut self, event_loop: &mut MyEventLoop, tok: Token) -> io::Result<()> {
        println!("server conn writable; tok={:?}", tok);
        self.conn(tok).writable(event_loop)
    }

    fn conn<'a>(&'a mut self, tok: Token) -> &'a mut EchoConn {
        &mut self.conns[tok]
    }
}

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

    fn ready(&mut self, event_loop: &mut MyEventLoop, token: Token, events: EventSet) {
        println!("ready {:?} {:?}", token, events);
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                i => self.conn_readable(event_loop, i).unwrap()
            }
        }

        if events.is_writable() {
            match token {
                SERVER => panic!("received writable for SERVER: impossible, can only accept connections"),
                _ => self.conn_writable(event_loop, token).unwrap()
            };
        }
    }
}

pub fn localhost() -> SocketAddr {
    FromStr::from_str("127.0.0.1:7000").unwrap()
}

pub fn main () {
    let mut event_loop = EventLoop::new().unwrap();

    let addr = localhost ();
    let srv_sock = TcpListener::bind(&addr).unwrap();

    println!("listen for connections");
    event_loop.register_opt(
        &srv_sock, SERVER,
        EventSet::readable(),
        PollOpt::edge() | PollOpt::oneshot()
    ).unwrap();

    // Start the event loop
    event_loop.run(&mut EchoServer::new(srv_sock)).unwrap();
}
<|endoftext|>


<commit_before>use std::process::Command;
use std::fs::File;
use std::io::Write;

#[derive(PartialEq)]
enum OpType {
	Word,
	Long,
}

#[derive(PartialEq, Clone)]
enum EaType {
    Any,
    Immidate,
    DataRegister,
    AddressRegister,
    Memory,
}

struct Op {
	name: &'static str,
	count: usize,
	ea_type: EaType,
}

impl Op {
	fn new(name: &'static str, count: usize, ea_type: EaType) -> Op {
		Op {
			name: name,
			count: count,
			ea_type: ea_type,
		}
	}
}

#[derive(Clone)]
struct CycleRule {
    count: usize,
    source: EaType,
    dest: EaType,
}

struct Instruction<'a> {
    name: &'static str,
    op_type: OpType,
    cycle_rules: &'a [CycleRule],
}

fn calculate_cycle_count(inst: &Instruction, src: &Op, dest: &Op) -> usize {
    let mut cycle_count = 0;

    for rule in inst.cycle_rules {
        if (src.ea_type == rule.source || rule.source == EaType::Any) &&
           (dest.ea_type == rule.dest || rule.dest == EaType::Any) {
            cycle_count = rule.count;
            break;
        }
    }

    cycle_count += src.count + dest.count;

    if inst.op_type == OpType::Long {
        if src.count != 0 {
            cycle_count += 4;
        }

        if dest.count != 0 {
            cycle_count += 4;
        }
    }

    cycle_count
}

fn main() {
	let dest_types = [Op::new("d0", 0, EaType::DataRegister),
	                  Op::new("a0", 0, EaType::AddressRegister) ,
	                  Op::new("(a0)", 4, EaType::Memory) ,
					  Op::new("(a0)+", 4, EaType::Memory) ,
					  Op::new("-(a0)", 6, EaType::Memory),
					  Op::new("2(a0)", 8, EaType::Memory),
					  Op::new("2(a0,d0)", 10, EaType::Memory),
					  Op::new("$4.W", 8, EaType::Memory),
					  Op::new("$4.L", 12, EaType::Memory)];

	let src_types = [Op::new("d0", 0, EaType::DataRegister),
	                 Op::new("a0", 0, EaType::AddressRegister),
	                 Op::new("(a0)", 4, EaType::Memory),
					 Op::new("(a0)+", 4, EaType::Memory),
					 Op::new("-(a0)", 6, EaType::Memory),
					 Op::new("2(a0)", 8, EaType::Memory),
					 Op::new("2(a0,d0)", 10, EaType::Memory),
					 Op::new("$4.W", 8, EaType::Memory),
					 Op::new("$4.L", 12, EaType::Memory),
					 Op::new("2(pc)", 8, EaType::Memory),
					 Op::new("2(pc,d0)", 10, EaType::Memory),
					 Op::new("#2", 4, EaType::Immidate)];

	let mut compile_status = Vec::new();

	let filename = "temp.s";

	let dst_print = [" Dn ", " An ", " (An) ", " (An)+ ", " -(An) ", " d(An) ", " d(An,Dn) ", " xxx.W ", " xxx.L "];
	let src_print = ["| Dn       ",
					 "| An       ",
					 "| (An)     ",
					 "| (An)+    ",
					 "| -(An)    ",
					 "| d(An)    ",
					 "| d(An,Dn) ",
					 "| xxx.W    ",
					 "| xxx.L    ",
					 "| d(Pc)    ",
					 "| d(Pc,Dn) ",
					 "| #xxx     "];

    let instructions = [
        /*
        Instruction {
            name: "clr.w",
            op_type: OpType::Word,
            cycle_rules: &[
                CycleRule { count: 4, source: EaType::DataRegister, dest: EaType::Any },
                CycleRule { count: 8, source: EaType::DataRegister, dest: EaType::Memory },
            ]
        },
        */
        Instruction {
            name: "add.w",
            op_type: OpType::Word,
            cycle_rules: &[
                CycleRule { count: 4, source: EaType::Immidate, dest: EaType::DataRegister },
                CycleRule { count: 8, source: EaType::Immidate, dest: EaType::Memory },
                CycleRule { count: 8, source: EaType::Any, dest: EaType::AddressRegister },
                CycleRule { count: 4, source: EaType::Any, dest: EaType::DataRegister },
                CycleRule { count: 8, source: EaType::DataRegister, dest: EaType::Memory },
            ]
        },
        Instruction {
            name: "add.l",
            op_type: OpType::Long,
            cycle_rules: &[
                CycleRule { count: 8, source: EaType::Immidate, dest: EaType::DataRegister },
                CycleRule { count: 8, source: EaType::Immidate, dest: EaType::Memory },
                CycleRule { count: 8, source: EaType::Any, dest: EaType::AddressRegister },
                CycleRule { count: 6, source: EaType::Any, dest: EaType::DataRegister },
                CycleRule { count: 12, source: EaType::DataRegister, dest: EaType::Memory },
            ]
        },
        /*
        Instruction {
            name: "and.l",
            op_type: OpType::Word,
            cycle_rules: &[
                CycleRule { count: 6, source: EaType::Any, dest: EaType::DataRegister },
                CycleRule { count: 12, source: EaType::DataRegister, dest: EaType::Memory },
            ]
        }
        */
    ];

	for inst in &instructions {
		compile_status.clear();
		for src in &src_types {
			for dst in &dest_types {

				{
					let mut file = File::create(filename).unwrap();
					write!(file, " {} {},{}", inst.name, src.name, dst.name).unwrap();
				}

				let output = Command::new("vasmm68k_mot").arg("-quiet").arg(filename).output().expect("failed to execute process");

				if output.status.success() {
                    compile_status.push(Some(calculate_cycle_count(&inst, &src, &dst)));
				} else {
					compile_status.push(None);
				}
			}
		}

		// print header
        print!("| {name:<width$}", name=inst.name, width=9);

		for dst in &dst_print {
			print!("|{}", dst);
		}

		println!("|");
		println!("|----------|----|----|------|-------|-------|-------|----------|-------|-------|");

		let mut index = 0;

		for src in &src_print {
			print!("{}", src);

			for dest_name in &dst_print {
				if let Some(cycle_count) = compile_status[index] {
					print!("|{number:^width$}", number=cycle_count, width=dest_name.len());
				} else {
					print!("|{number:^width$}", number="*", width=dest_name.len());
				}
				index += 1;
			}

			println!("|");
		}

		println!("");
	}
}
<commit_msg>Rustfmt<commit_after>use std::process::Command;
use std::fs::File;
use std::io::Write;

#[derive(PartialEq)]
enum OpType {
    Word,
    Long,
}

#[derive(PartialEq, Clone)]
enum EaType {
    Any,
    Immidate,
    DataRegister,
    AddressRegister,
    Memory,
}

struct Op {
    name: &'static str,
    count: usize,
    ea_type: EaType,
}

impl Op {
    fn new(name: &'static str, count: usize, ea_type: EaType) -> Op {
        Op {
            name: name,
            count: count,
            ea_type: ea_type,
        }
    }
}

#[derive(Clone)]
struct CycleRule {
    count: usize,
    source: EaType,
    dest: EaType,
}

struct Instruction<'a> {
    name: &'static str,
    op_type: OpType,
    cycle_rules: &'a [CycleRule],
}

fn calculate_cycle_count(inst: &Instruction, src: &Op, dest: &Op) -> usize {
    let mut cycle_count = 0;

    for rule in inst.cycle_rules {
        if (src.ea_type == rule.source || rule.source == EaType::Any) &&
           (dest.ea_type == rule.dest || rule.dest == EaType::Any) {
            cycle_count = rule.count;
            break;
        }
    }

    cycle_count += src.count + dest.count;

    if inst.op_type == OpType::Long {
        if src.count != 0 {
            cycle_count += 4;
        }

        if dest.count != 0 {
            cycle_count += 4;
        }
    }

    cycle_count
}

fn main() {
    let dest_types = [Op::new("d0", 0, EaType::DataRegister),
                      Op::new("a0", 0, EaType::AddressRegister),
                      Op::new("(a0)", 4, EaType::Memory),
                      Op::new("(a0)+", 4, EaType::Memory),
                      Op::new("-(a0)", 6, EaType::Memory),
                      Op::new("2(a0)", 8, EaType::Memory),
                      Op::new("2(a0,d0)", 10, EaType::Memory),
                      Op::new("$4.W", 8, EaType::Memory),
                      Op::new("$4.L", 12, EaType::Memory)];

    let src_types = [Op::new("d0", 0, EaType::DataRegister),
                     Op::new("a0", 0, EaType::AddressRegister),
                     Op::new("(a0)", 4, EaType::Memory),
                     Op::new("(a0)+", 4, EaType::Memory),
                     Op::new("-(a0)", 6, EaType::Memory),
                     Op::new("2(a0)", 8, EaType::Memory),
                     Op::new("2(a0,d0)", 10, EaType::Memory),
                     Op::new("$4.W", 8, EaType::Memory),
                     Op::new("$4.L", 12, EaType::Memory),
                     Op::new("2(pc)", 8, EaType::Memory),
                     Op::new("2(pc,d0)", 10, EaType::Memory),
                     Op::new("#2", 4, EaType::Immidate)];

    let mut compile_status = Vec::new();

    let filename = "temp.s";

    let dst_print = [" Dn ",
                     " An ",
                     " (An) ",
                     " (An)+ ",
                     " -(An) ",
                     " d(An) ",
                     " d(An,Dn) ",
                     " xxx.W ",
                     " xxx.L "];
    let src_print = ["| Dn       ",
                     "| An       ",
                     "| (An)     ",
                     "| (An)+    ",
                     "| -(An)    ",
                     "| d(An)    ",
                     "| d(An,Dn) ",
                     "| xxx.W    ",
                     "| xxx.L    ",
                     "| d(Pc)    ",
                     "| d(Pc,Dn) ",
                     "| #xxx     "];

    let instructions = [// Instruction {
                        // name: "clr.w",
                        // op_type: OpType::Word,
                        // cycle_rules: &[
                        // CycleRule { count: 4, source: EaType::DataRegister, dest: EaType::Any },
                        // CycleRule { count: 8, source: EaType::DataRegister, dest: EaType::Memory },
                        // ]
                        // },
                        //
                        Instruction {
                            name: "add.w",
                            op_type: OpType::Word,
                            cycle_rules: &[CycleRule {
                                               count: 4,
                                               source: EaType::Immidate,
                                               dest: EaType::DataRegister,
                                           },
                                           CycleRule {
                                               count: 8,
                                               source: EaType::Immidate,
                                               dest: EaType::Memory,
                                           },
                                           CycleRule {
                                               count: 8,
                                               source: EaType::Any,
                                               dest: EaType::AddressRegister,
                                           },
                                           CycleRule {
                                               count: 4,
                                               source: EaType::Any,
                                               dest: EaType::DataRegister,
                                           },
                                           CycleRule {
                                               count: 8,
                                               source: EaType::DataRegister,
                                               dest: EaType::Memory,
                                           }],
                        },
                        Instruction {
                            name: "add.l",
                            op_type: OpType::Long,
                            cycle_rules: &[CycleRule {
                                               count: 8,
                                               source: EaType::Immidate,
                                               dest: EaType::DataRegister,
                                           },
                                           CycleRule {
                                               count: 8,
                                               source: EaType::Immidate,
                                               dest: EaType::Memory,
                                           },
                                           CycleRule {
                                               count: 8,
                                               source: EaType::Any,
                                               dest: EaType::AddressRegister,
                                           },
                                           CycleRule {
                                               count: 6,
                                               source: EaType::Any,
                                               dest: EaType::DataRegister,
                                           },
                                           CycleRule {
                                               count: 12,
                                               source: EaType::DataRegister,
                                               dest: EaType::Memory,
                                           }],
                        } /* Instruction {
                           * name: "and.l",
                           * op_type: OpType::Word,
                           * cycle_rules: &[
                           * CycleRule { count: 6, source: EaType::Any, dest: EaType::DataRegister },
                           * CycleRule { count: 12, source: EaType::DataRegister, dest: EaType::Memory },
                           * ]
                           * }
                           * */];

    for inst in &instructions {
        compile_status.clear();
        for src in &src_types {
            for dst in &dest_types {

                {
                    let mut file = File::create(filename).unwrap();
                    write!(file, " {} {},{}", inst.name, src.name, dst.name).unwrap();
                }

                let output = Command::new("vasmm68k_mot")
                    .arg("-quiet")
                    .arg(filename)
                    .output()
                    .expect("failed to execute process");

                if output.status.success() {
                    compile_status.push(Some(calculate_cycle_count(&inst, &src, &dst)));
                } else {
                    compile_status.push(None);
                }
            }
        }

        // print header
        print!("| {name:<width$}", name = inst.name, width = 9);

        for dst in &dst_print {
            print!("|{}", dst);
        }

        println!("|");
        println!("|----------|----|----|------|-------|-------|-------|----------|-------|-------|");

        let mut index = 0;

        for src in &src_print {
            print!("{}", src);

            for dest_name in &dst_print {
                if let Some(cycle_count) = compile_status[index] {
                    print!("|{number:^width$}",
                           number = cycle_count,
                           width = dest_name.len());
                } else {
                    print!("|{number:^width$}", number = "*", width = dest_name.len());
                }
                index += 1;
            }

            println!("|");
        }

        println!("");
    }
}
<|endoftext|>


<commit_before>extern crate bencode;
extern crate rand;
extern crate bittorrent;
extern crate hyper;

use std::env;
use std::io::Read;
use std::collections::HashMap;
use bencode::{deserialize, deserialize_file, Bencode, TypedMethods};
use rand::{Rng, thread_rng};
use bittorrent::querystring::QueryString;
use bittorrent::metadata::{MetadataDict, Metadata};
use hyper::Client;
use hyper::header::Connection;

const PEER_ID_LENGTH:usize = 20;
const PEER_ID_PREFIX:&'static str = "ABT:";

fn gen_rand_peer_id (prefix: &str) -> String {
    let rand_length = PEER_ID_LENGTH - prefix.len();
    let rand = thread_rng().gen_ascii_chars()
                           .take(rand_length)
                           .collect::<String>();

    prefix.to_string() + &rand
}

fn ping_tracker (announce: String, args: Vec<(&str, String)>) -> Option<HashMap<String, Bencode>> {
    let req_addr = announce + "?" + &QueryString::from(args).query_string();
    let client = Client::new();
    let mut res = client.get(&req_addr)
                        .header(Connection::close())
                        .send().unwrap();
    let mut body = Vec::new();
    res.read_to_end(&mut body).unwrap();

    println!("dict: {:?}", body.iter().map(|a| *a as char).collect::<Vec<char>>());
    println!("{}", body.iter().map(|a| *a as char).collect::<String>());

    match deserialize(body) {
        Some(a) => match a.first() {
            Some(&Bencode::Dict(ref a)) => Some(a.to_owned()),
            _ => None
        },
        _ => None
    }
}

fn init (metadata: Metadata, listen_port: u32, bytes_dled: u32) {
    let peer_id = gen_rand_peer_id(PEER_ID_PREFIX);
    let bytes_left = metadata.get_total_length() - bytes_dled;

    let response = ping_tracker(metadata.announce, vec![
                                ("info_hash", metadata.info_hash),
                                ("peer_id", peer_id),
                                ("port", listen_port.to_string()),
                                ("uploaded", 0.to_string()),
                                ("downloaded", bytes_dled.to_string()),
                                ("left", bytes_left.to_string()),
                                ("compact", 1.to_string()),
                                ("event", "started".to_string())
                                ]);

    let tracker_resp = match response {
        Some(a) => a,
        None => panic!("no valid bencode response from tracker")
    };

    let peers = tracker_resp.get_owned_string("peers").unwrap();
    let peers6 = tracker_resp.get_owned_string("peers6").unwrap();

    let peers_bytes = peers.chars().map(|x| x as u8).collect::<Vec<u8>>();

    let addresses = (0..peers_bytes.len()/6).map(|x| {
        let ip_start = x * 6;
        let ip_end = ip_start + 4;
        //returns a 2-ple of addresses (as string) and port (as u32)
        ((&peers_bytes[ip_start..ip_end]).iter()
                                            .map(|y| y.to_string())
                                            .collect::<Vec<String>>()
                                            .join("."),
            peers_bytes[ip_end] as u32 + peers_bytes[ip_end+1] as u32)
    }).collect::<Vec<(String, u32)>>();

    println!("{:?}", addresses);
}

fn main () {
    let path = env::args().nth(1)
                          .unwrap_or_else(||panic!("no path to torrent provided"));

    let content = deserialize_file(path).unwrap_or_else(||panic!("unable to parse bencoded metadata"));

    let metadata = match content.first() {
        Some(&Bencode::Dict(ref dict)) => dict.to_metadata(),
        _ => panic!("no valid information in torrent file")
    }.unwrap();

    //println!("{:?}", metadata);
    init(metadata, 6888, 0);
}
<commit_msg>adding get_peers function<commit_after>extern crate bencode;
extern crate rand;
extern crate bittorrent;
extern crate hyper;

use std::env;
use std::io::Read;
use std::collections::HashMap;
use bencode::{deserialize, deserialize_file, Bencode, TypedMethods};
use rand::{Rng, thread_rng};
use bittorrent::querystring::QueryString;
use bittorrent::metadata::{MetadataDict, Metadata};
use hyper::Client;
use hyper::header::Connection;

const PEER_ID_LENGTH:usize = 20;
const PEER_ID_PREFIX:&'static str = "ABT:";

fn gen_rand_peer_id (prefix: &str) -> String {
    let rand_length = PEER_ID_LENGTH - prefix.len();
    let rand = thread_rng().gen_ascii_chars()
                           .take(rand_length)
                           .collect::<String>();

    prefix.to_string() + &rand
}

fn ping_tracker (announce: String, args: Vec<(&str, String)>) -> Option<HashMap<String, Bencode>> {
    let req_addr = announce + "?" + &QueryString::from(args).query_string();
    let client = Client::new();
    let mut res = client.get(&req_addr)
                        .header(Connection::close())
                        .send().unwrap();
    let mut body = Vec::new();
    res.read_to_end(&mut body).unwrap();

    println!("dict: {:?}", body.iter().map(|a| *a as char).collect::<Vec<char>>());
    println!("{}", body.iter().map(|a| *a as char).collect::<String>());

    match deserialize(body) {
        Some(a) => match a.first() {
            Some(&Bencode::Dict(ref a)) => Some(a.to_owned()),
            _ => None
        },
        _ => None
    }
}

fn get_peers <T> (tracker_response: &T) -> Vec<(String, u32)> where T:TypedMethods {
    let peers = tracker_response.get_owned_string("peers").unwrap();
    //for now keep the bottom unused value, it's for ipv6. which maybe will be addressed
    let peers6 = tracker_response.get_owned_string("peers6").unwrap();
    let peers_bytes = peers.chars().map(|x| x as u8).collect::<Vec<u8>>();

    (0..peers_bytes.len()/6).map(|x| {
        let ip_start = x * 6;
        let ip_end = ip_start + 4;
        //returns a 2-ple of addresses (as string) and port (as u32)
        ((&peers_bytes[ip_start..ip_end]).iter()
                                            .map(|y| y.to_string())
                                            .collect::<Vec<String>>()
                                            .join("."),
            peers_bytes[ip_end] as u32 + peers_bytes[ip_end+1] as u32)
    }).collect::<Vec<(String, u32)>>()
}

fn init (metadata: Metadata, listen_port: u32, bytes_dled: u32) {
    let peer_id = gen_rand_peer_id(PEER_ID_PREFIX);
    let bytes_left = metadata.get_total_length() - bytes_dled;

    let response = ping_tracker(metadata.announce, vec![
                                ("info_hash", metadata.info_hash),
                                ("peer_id", peer_id),
                                ("port", listen_port.to_string()),
                                ("uploaded", 0.to_string()),
                                ("downloaded", bytes_dled.to_string()),
                                ("left", bytes_left.to_string()),
                                ("compact", 1.to_string()),
                                ("event", "started".to_string())
                                ]);

    let tracker_resp = match response {
        Some(a) => a,
        None => panic!("no valid bencode response from tracker")
    };

    let peers = get_peers(&tracker_resp);

    println!("{:?}", peers);
}

fn main () {
    let path = env::args().nth(1)
                          .unwrap_or_else(||panic!("no path to torrent provided"));

    let content = deserialize_file(path).unwrap_or_else(||panic!("unable to parse bencoded metadata"));

    let metadata = match content.first() {
        Some(&Bencode::Dict(ref dict)) => dict.to_metadata(),
        _ => panic!("no valid information in torrent file")
    }.unwrap();

    //println!("{:?}", metadata);
    init(metadata, 6888, 0);
}
<|endoftext|>


<commit_before>use std::net::TcpStream;
use std::io::prelude::*;

fn main() {
	let mut connection = TcpStream::connect("127.0.0.1:6667").unwrap();
	let _ = connection.write(b"Hello World\n");
	let mut bytes = connection.bytes();
	const COMMAND_BUF_SIZE: usize = 4096;
	let mut command_buf: [u8; COMMAND_BUF_SIZE] = [0; COMMAND_BUF_SIZE];
	let mut buf_ind = 0;
	let mut command_end = false;
	loop {
		match bytes.next() {
			Some(x) => {
				let next_char = x.unwrap();
				command_buf[buf_ind] = next_char;
				if command_end && next_char == 10 {
					parse_command(&command_buf[0..(buf_ind-2)]);
					buf_ind = 0;
					command_end = false;
				} else if next_char == 102 {
					command_end = true;
				} else {
					command_end = false;
				}
				buf_ind = buf_ind + 1;
				if buf_ind >= COMMAND_BUF_SIZE {
					buf_ind = 0;
				}
			},
			None => break,
		}
	}
}

fn parse_command(command: &[u8]) {
	println!("Command Complete");
}
<commit_msg>Create str from command arr<commit_after>use std::net::TcpStream;
use std::io::prelude::*;
use std::str;

fn main() {
	let mut connection = TcpStream::connect("127.0.0.1:6667").unwrap();
	let _ = connection.write(b"Hello World\n");
	let mut bytes = connection.bytes();
	const COMMAND_BUF_SIZE: usize = 4096;
	let mut command_buf: [u8; COMMAND_BUF_SIZE] = [0; COMMAND_BUF_SIZE];
	let mut buf_ind = 0;
	let mut command_end = false;
	loop {
		match bytes.next() {
			Some(x) => {
				let next_char = x.unwrap();
				command_buf[buf_ind] = next_char;
				buf_ind = buf_ind + 1;
				if command_end && next_char == 10 {
					parse_command(&command_buf[0..(buf_ind-2)]);
					buf_ind = 0;
					command_end = false;
				} else if next_char == 102 {
					command_end = true;
				} else {
					command_end = false;
				}
				if buf_ind >= COMMAND_BUF_SIZE {
					buf_ind = 0;
				}
			},
			None => break,
		}
	}
}

fn parse_command(command: &[u8]) {
	println!("{}", str::from_utf8(command).unwrap());
}
<|endoftext|>


<commit_before>use alga::general::{Real, SupersetOf};
use nalgebra::{self, Matrix4, Point2, Point3, Scalar, Unit, Vector3, Vector4};
use num::Float;
use std::cmp;
use std::ops;

pub type UScalar = u32;
pub type FScalar = f32;

pub type UPoint2 = Point2<UScalar>;
pub type UPoint3 = Point3<UScalar>;
pub type UVector3 = Vector3<UScalar>;

pub type FPoint2 = Point2<FScalar>;
pub type FPoint3 = Point3<FScalar>;
pub type FVector3 = Vector3<FScalar>;
pub type FVector4 = Vector4<FScalar>;
pub type FMatrix4 = Matrix4<FScalar>;

pub type FRay3 = Ray3<FScalar>;

pub struct Ray3<T>
    where T: Scalar
{
    pub position: Point3<T>,
    pub direction: Unit<Vector3<T>>,
}

impl<T> Ray3<T>
    where T: Real + Scalar
{
    pub fn new(position: Point3<T>, direction: Vector3<T>) -> Self {
        Ray3 {
            position: position,
            direction: Unit::new_normalize(direction),
        }
    }
}

pub trait Matrix4Ext<T>
    where T: Scalar
{
    fn to_array(&self) -> [[T; 4]; 4];
}

impl<T> Matrix4Ext<T> for Matrix4<T>
    where T: Scalar
{
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn to_array(&self) -> [[T; 4]; 4] {
        [[self[0],  self[1],  self[2],  self[3]],
         [self[4],  self[5],  self[6],  self[7]],
         [self[8],  self[9],  self[10], self[11]],
         [self[12], self[13], self[14], self[15]]]
    }
}

// TODO: The `FromSpace` and `IntoSpace` traits may not be useful. Instead, the
//       `nalgebra::convert` function can be used directly.
pub trait FromSpace<T> {
    fn from_space(value: T) -> Self;
}

impl<T, U> FromSpace<Point2<U>> for Point2<T>
    where T: SupersetOf<U> + Scalar,
          U: Scalar
{
    fn from_space(point: Point2<U>) -> Self {
        nalgebra::convert(point)
    }
}

impl<T, U> FromSpace<Point3<U>> for Point3<T>
    where T: SupersetOf<U> + Scalar,
          U: Scalar
{
    fn from_space(point: Point3<U>) -> Self {
        nalgebra::convert(point)
    }
}

impl<T, U> FromSpace<Vector3<U>> for Vector3<T>
    where T: SupersetOf<U> + Scalar,
          U: Scalar
{
    fn from_space(vector: Vector3<U>) -> Self {
        nalgebra::convert(vector)
    }
}

pub trait IntoSpace<T> {
    fn into_space(self) -> T;
}

impl<T, U> IntoSpace<U> for T
    where U: FromSpace<T>
{
    fn into_space(self) -> U {
        U::from_space(self)
    }
}

pub trait Clamp<T>
    where T: PartialOrd
{
    fn clamp(&self, min: T, max: T) -> Self;
}

impl<T> Clamp<T> for Point3<T>
    where T: PartialOrd + Scalar
{
    fn clamp(&self, min: T, max: T) -> Self {
        use nalgebra::clamp;

        Point3::new(clamp(self.x, min, max), clamp(self.y, min, max), clamp(self.z, min, max))
    }
}

pub trait Mask<T>
    where T: ops::BitAnd<Output = T>
{
    fn mask(&self, value: T) -> Self;
}

impl<T> Mask<T> for Point3<T>
    where T: ops::BitAnd<Output = T> + Scalar
{
    fn mask(&self, value: T) -> Self {
        Point3::new(self.x & value, self.y & value, self.z & value)
    }
}

pub trait UpperBound {
    fn upper_bound(&self, other: &Self) -> Self;
}

impl<T> UpperBound for Point3<T>
    where T: Ord + Scalar
{
    fn upper_bound(&self, other: &Self) -> Self {
        Point3::new(cmp::max(self.x, other.x),
                    cmp::max(self.y, other.y),
                    cmp::max(self.y, other.y))
    }
}

pub trait LowerBound {
    fn lower_bound(&self, other: &Self) -> Self;
}

impl<T> LowerBound for Point3<T>
    where T: Ord + Scalar
{
    fn lower_bound(&self, other: &Self) -> Self {
        Point3::new(cmp::min(self.x, other.x),
                    cmp::min(self.y, other.y),
                    cmp::min(self.y, other.y))
    }
}

pub trait Interpolate<F>: Sized
    where F: Float
{
    fn lerp(&self, other: &Self, f: F) -> Self;

    fn midpoint(&self, other: &Self) -> Self {
        self.lerp(other, F::one() / (F::one() + F::one()))
    }
}

impl<T, F> Interpolate<F> for (T, T, T)
    where T: SupersetOf<F> + Scalar,
          F: SupersetOf<T> + Float
{
    fn lerp(&self, other: &Self, f: F) -> Self {
        (lerp(self.0, other.0, f), lerp(self.1, other.1, f), lerp(self.2, other.2, f))
    }
}

impl<T, F> Interpolate<F> for Point3<T>
    where T: SupersetOf<F> + Scalar,
          F: SupersetOf<T> + Float
{
    fn lerp(&self, other: &Self, f: F) -> Self {
        Point3::new(lerp(self.x, other.x, f), lerp(self.y, other.y, f), lerp(self.z, other.z, f))
    }
}

pub fn lerp<T, F>(a: T, b: T, f: F) -> T
    where T: SupersetOf<F> + Scalar,
          F: SupersetOf<T> + Float
{
    use nalgebra::{convert, clamp};

    let f = clamp(f, F::zero(), F::one());
    let af = convert::<T, F>(a) * (F::one() - f);
    let bf = convert::<T, F>(b) * f;
    convert::<F, T>(af + bf)
}

#[cfg(test)]
mod tests {
    use super::*;
}
<commit_msg>Add simple `Ray3` constructors.<commit_after>use alga::general::{Real, SupersetOf};
use nalgebra::{self, Matrix4, Point2, Point3, Scalar, Unit, Vector3, Vector4};
use num::Float;
use std::cmp;
use std::ops;

pub type UScalar = u32;
pub type FScalar = f32;

pub type UPoint2 = Point2<UScalar>;
pub type UPoint3 = Point3<UScalar>;
pub type UVector3 = Vector3<UScalar>;

pub type FPoint2 = Point2<FScalar>;
pub type FPoint3 = Point3<FScalar>;
pub type FVector3 = Vector3<FScalar>;
pub type FVector4 = Vector4<FScalar>;
pub type FMatrix4 = Matrix4<FScalar>;

pub type FRay3 = Ray3<FScalar>;

pub struct Ray3<T>
    where T: Scalar
{
    pub position: Point3<T>,
    pub direction: Unit<Vector3<T>>,
}

impl<T> Ray3<T>
    where T: Real + Scalar
{
    pub fn new(position: Point3<T>, direction: Vector3<T>) -> Self {
        Ray3 {
            position: position,
            direction: Unit::new_normalize(direction),
        }
    }

    pub fn x() -> Self {
        Ray3::new(Point3::origin(), Vector3::x())
    }

    pub fn y() -> Self {
        Ray3::new(Point3::origin(), Vector3::y())
    }

    pub fn z() -> Self {
        Ray3::new(Point3::origin(), Vector3::z())
    }
}

pub trait Matrix4Ext<T>
    where T: Scalar
{
    fn to_array(&self) -> [[T; 4]; 4];
}

impl<T> Matrix4Ext<T> for Matrix4<T>
    where T: Scalar
{
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn to_array(&self) -> [[T; 4]; 4] {
        [[self[0],  self[1],  self[2],  self[3]],
         [self[4],  self[5],  self[6],  self[7]],
         [self[8],  self[9],  self[10], self[11]],
         [self[12], self[13], self[14], self[15]]]
    }
}

// TODO: The `FromSpace` and `IntoSpace` traits may not be useful. Instead, the
//       `nalgebra::convert` function can be used directly.
pub trait FromSpace<T> {
    fn from_space(value: T) -> Self;
}

impl<T, U> FromSpace<Point2<U>> for Point2<T>
    where T: SupersetOf<U> + Scalar,
          U: Scalar
{
    fn from_space(point: Point2<U>) -> Self {
        nalgebra::convert(point)
    }
}

impl<T, U> FromSpace<Point3<U>> for Point3<T>
    where T: SupersetOf<U> + Scalar,
          U: Scalar
{
    fn from_space(point: Point3<U>) -> Self {
        nalgebra::convert(point)
    }
}

impl<T, U> FromSpace<Vector3<U>> for Vector3<T>
    where T: SupersetOf<U> + Scalar,
          U: Scalar
{
    fn from_space(vector: Vector3<U>) -> Self {
        nalgebra::convert(vector)
    }
}

pub trait IntoSpace<T> {
    fn into_space(self) -> T;
}

impl<T, U> IntoSpace<U> for T
    where U: FromSpace<T>
{
    fn into_space(self) -> U {
        U::from_space(self)
    }
}

pub trait Clamp<T>
    where T: PartialOrd
{
    fn clamp(&self, min: T, max: T) -> Self;
}

impl<T> Clamp<T> for Point3<T>
    where T: PartialOrd + Scalar
{
    fn clamp(&self, min: T, max: T) -> Self {
        use nalgebra::clamp;

        Point3::new(clamp(self.x, min, max), clamp(self.y, min, max), clamp(self.z, min, max))
    }
}

pub trait Mask<T>
    where T: ops::BitAnd<Output = T>
{
    fn mask(&self, value: T) -> Self;
}

impl<T> Mask<T> for Point3<T>
    where T: ops::BitAnd<Output = T> + Scalar
{
    fn mask(&self, value: T) -> Self {
        Point3::new(self.x & value, self.y & value, self.z & value)
    }
}

pub trait UpperBound {
    fn upper_bound(&self, other: &Self) -> Self;
}

impl<T> UpperBound for Point3<T>
    where T: Ord + Scalar
{
    fn upper_bound(&self, other: &Self) -> Self {
        Point3::new(cmp::max(self.x, other.x),
                    cmp::max(self.y, other.y),
                    cmp::max(self.y, other.y))
    }
}

pub trait LowerBound {
    fn lower_bound(&self, other: &Self) -> Self;
}

impl<T> LowerBound for Point3<T>
    where T: Ord + Scalar
{
    fn lower_bound(&self, other: &Self) -> Self {
        Point3::new(cmp::min(self.x, other.x),
                    cmp::min(self.y, other.y),
                    cmp::min(self.y, other.y))
    }
}

pub trait Interpolate<F>: Sized
    where F: Float
{
    fn lerp(&self, other: &Self, f: F) -> Self;

    fn midpoint(&self, other: &Self) -> Self {
        self.lerp(other, F::one() / (F::one() + F::one()))
    }
}

impl<T, F> Interpolate<F> for (T, T, T)
    where T: SupersetOf<F> + Scalar,
          F: SupersetOf<T> + Float
{
    fn lerp(&self, other: &Self, f: F) -> Self {
        (lerp(self.0, other.0, f), lerp(self.1, other.1, f), lerp(self.2, other.2, f))
    }
}

impl<T, F> Interpolate<F> for Point3<T>
    where T: SupersetOf<F> + Scalar,
          F: SupersetOf<T> + Float
{
    fn lerp(&self, other: &Self, f: F) -> Self {
        Point3::new(lerp(self.x, other.x, f), lerp(self.y, other.y, f), lerp(self.z, other.z, f))
    }
}

pub fn lerp<T, F>(a: T, b: T, f: F) -> T
    where T: SupersetOf<F> + Scalar,
          F: SupersetOf<T> + Float
{
    use nalgebra::{convert, clamp};

    let f = clamp(f, F::zero(), F::one());
    let af = convert::<T, F>(a) * (F::one() - f);
    let bf = convert::<T, F>(b) * f;
    convert::<F, T>(af + bf)
}

#[cfg(test)]
mod tests {
    use super::*;
}
<|endoftext|>


<commit_before>//!
//! Desync pipes provide a way to generate and process streams via a `Desync` object
//!
//! Pipes are an excellent way to interface `Desync` objects and the futures library. Piping
//! a stream into a `Desync` object is equivalent to spawning it with an executor, except
//! without the need to dedicate a thread to running it.
//!
//! There are two kinds of pipe. The `pipe_in` function creates a pipe that processes each
//! value made available from a stream on a desync object as they arrive, producing no
//! results. This is useful for cases where a `Desync` object is being used as the endpoint
//! for some data processing (for example, to insert the results of an operation into an
//! asynchronous database object).
//!
//! The `pipe` function pipes data through an object. For every input value, it produces
//! an output value. This is good for creating streams that perform some kind of asynchronous
//! processing operation or that need to access data from inside a `Desync` object.
//!
//! Here's an example of using `pipe_in` to store data in a `HashSet`:
//!
//! ```
//! # extern crate futures;
//! # extern crate desync;
//! # use std::thread;
//! # use std::time::Duration;
//! # use std::collections::HashSet;
//! # use std::sync::*;
//! #
//! use futures::sync::mpsc;
//! use futures::executor;
//! use desync::*;
//!
//! let desync_hashset      = Arc::new(Desync::new(HashSet::new()));
//! let (sender, receiver)  = mpsc::channel(5);
//!
//! pipe_in(Arc::clone(&desync_hashset), receiver, |hashset, value| { value.map(|value| hashset.insert(value)); });
//!
//! let mut sender = executor::spawn(sender);
//! sender.wait_send("Test".to_string());
//! sender.wait_send("Another value".to_string());
//! #
//! # thread::sleep(Duration::from_millis(5));
//! # assert!(desync_hashset.sync(|hashset| hashset.contains(&("Test".to_string()))))
//! ```
//!

use super::desync::*;

use futures::*;
use futures::executor;
use futures::executor::Spawn;

use std::sync::*;
use std::result::Result;
use std::collections::VecDeque;

lazy_static! {
    /// The shared queue where we monitor for updates to the active pipe streams
    static ref PIPE_MONITOR: PipeMonitor = PipeMonitor::new();
}

///
/// Pipes a stream into a desync object. Whenever an item becomes available on the stream, the
/// processing function is called asynchronously with the item that was received.
///
/// This takes a weak reference to the passed in `Desync` object, so the pipe will stop if it's
/// the only thing referencing this object.
///
/// Piping a stream to a `Desync` like this will cause it to start executing: ie, this is
/// similar to calling `executor::spawn(stream)`, except that the stream will immediately
/// start draining into the `Desync` object.
///
pub fn pipe_in<Core, S, ProcessFn>(desync: Arc<Desync<Core>>, stream: S, process: ProcessFn)
where   Core:       'static+Send,
        S:          'static+Send+Stream,
        S::Item:    Send,
        S::Error:   Send,
        ProcessFn:  'static+Send+FnMut(&mut Core, Result<S::Item, S::Error>) -> () {

    // Need a mutable version of the stream
    let mut stream = stream;

    // We stop processing once the desync object is no longer used anywhere else
    let desync = Arc::downgrade(&desync);

    // Wrap the process fn up so we can call it asynchronously
    // (it doesn't really need to be in a mutex as it's only called by our object but we need to make it pass Rust's checks and we don't have a way to specify this at the moment)
    let process = Arc::new(Mutex::new(process));

    // Monitor the stream
    PIPE_MONITOR.monitor(move || {
        loop {
            let desync      = desync.upgrade();

            if let Some(desync) = desync {
                // Read the current status of the stream
                let process     = Arc::clone(&process);
                let next        = stream.poll();

                match next {
                    // Just wait if the stream is not ready
                    Ok(Async::NotReady) => { return Ok(Async::NotReady); },

                    // Stop processing when the stream is finished
                    Ok(Async::Ready(None)) => { return Ok(Async::Ready(())); }

                    // Stream returned a value
                    Ok(Async::Ready(Some(next))) => {
                        // Process the value on the stream
                        desync.sync(move |core| {
                            let mut process = process.lock().unwrap();
                            let process     = &mut *process;
                            process(core, Ok(next));
                        });
                    },

                    // Stream returned an error
                    Err(e) => {
                        // Process the error on the stream
                        desync.sync(move |core| {
                            let mut process = process.lock().unwrap();
                            let process     = &mut *process;
                            process(core, Err(e));
                        });
                    },
                }
            } else {
                // The desync target is no longer available - indicate that we've completed monitoring
                return Ok(Async::Ready(()));
            }
        }
    });
}

///
/// Pipes a stream into this object. Whenever an item becomes available on the stream, the
/// processing function is called asynchronously with the item that was received. The
/// return value is placed onto the output stream.
///
/// Unlike `pipe_in`, this keeps a strong reference to the `Desync` object so the processing
/// will continue so long as the input stream has data and the output stream is not dropped.
///
/// The input stream will start executing and reading values immediately when this is called.
/// Dropping the output stream will cause the pipe to be closed (the input stream will be
/// dropped and no further processing will occur).
///
pub fn pipe<Core, S, Output, OutputErr, ProcessFn>(desync: Arc<Desync<Core>>, stream: S, process: ProcessFn) -> impl Stream<Item=Output, Error=OutputErr>
where   Core:       'static+Send,
        S:          'static+Send+Stream,
        S::Item:    Send,
        S::Error:   Send,
        Output:     'static+Send,
        OutputErr:  'static+Send,
        ProcessFn:  'static+Send+FnMut(&mut Core, Result<S::Item, S::Error>) -> Result<Output, OutputErr> {

    // Fetch the input stream and prepare the process function for async calling
    let mut input_stream    = stream;
    let process             = Arc::new(Mutex::new(process));

    // Create the output stream
    let output_stream   = PipeStream::new();
    let stream_core     = Arc::clone(&output_stream.core);
    let stream_core     = Arc::downgrade(&stream_core);

    // Monitor the input stream and pass data to the output stream
    PIPE_MONITOR.monitor(move || {
        loop {
            let stream_core = stream_core.upgrade();

            if let Some(stream_core) = stream_core {
                // Read the current status of the stream
                let process         = Arc::clone(&process);
                let next            = input_stream.poll();
                let mut next_item;

                // Work out what the next item to pass to the process function should be
                match next {
                    // Just wait if the stream is not ready
                    Ok(Async::NotReady) => { return Ok(Async::NotReady); },

                    // Stop processing when the input stream is finished
                    Ok(Async::Ready(None)) => {
                        // Mark the target stream as closed
                        let mut stream_core = stream_core.lock().unwrap();
                        stream_core.closed = true;
                        stream_core.notify.take().map(|notify| notify.notify());

                        // Pipe has finished
                        return Ok(Async::Ready(()));
                    }

                    // Stream returned a value
                    Ok(Async::Ready(Some(next))) => next_item = Ok(next),

                    // Stream returned an error
                    Err(e) => next_item = Err(e),
                }

                // Send the next item to be processed
                desync.sync(move |core| {
                    // Process the next item
                    let mut process     = process.lock().unwrap();
                    let process         = &mut *process;
                    let next_item       = process(core, next_item);

                    // Send to the pipe stream
                    let mut stream_core = stream_core.lock().unwrap();

                    stream_core.pending.push_back(next_item);
                    stream_core.notify.take().map(|notify| notify.notify());
                });

            } else {
                // We stop processing once nothing is reading from the target stream
                return Ok(Async::Ready(()));
            }
        }
    });

    // The pipe stream is the result
    output_stream
}

///
/// The shared data for a pipe stream
///
struct PipeStreamCore<Item, Error>  {
    /// The pending data for this stream
    pending: VecDeque<Result<Item, Error>>,

    /// True if the input stream has closed (the stream is closed once this is true and there are no more pending items)
    closed: bool,

    /// The task to notify when the stream changes
    notify: Option<task::Task>
}

///
/// A stream generated by a pipe
///
struct PipeStream<Item, Error> {
    core: Arc<Mutex<PipeStreamCore<Item, Error>>>
}

impl<Item, Error> PipeStream<Item, Error> {
    ///
    /// Creates a new, empty, pipestream
    ///
    pub fn new() -> PipeStream<Item, Error> {
        PipeStream {
            core: Arc::new(Mutex::new(PipeStreamCore {
                pending:    VecDeque::new(),
                closed:     false,
                notify:     None
            }))
        }
    }
}

impl<Item, Error> Drop for PipeStream<Item, Error> {
    fn drop(&mut self) {
        let mut core = self.core.lock().unwrap();

        // Flush the pending queue
        core.pending = VecDeque::new();

        // TODO: wake the monitor and stop listening to the source stream
        // (Right now this will happen next time the source stream produces data)
    }
}

impl<Item, Error> Stream for PipeStream<Item, Error> {
    type Item   = Item;
    type Error  = Error;

    fn poll(&mut self) -> Poll<Option<Item>, Error> {
        // Fetch the core
        let mut core = self.core.lock().unwrap();

        if let Some(item) = core.pending.pop_front() {
            // Value waiting at the start of the stream
            match item {
                Ok(item)    => Ok(Async::Ready(Some(item))),
                Err(erm)    => Err(erm)
            }
        } else if core.closed {
            // No more data will be returned from this stream
            Ok(Async::Ready(None))
        } else {
            // Stream not ready
            core.notify = Some(task::current());

            Ok(Async::NotReady)
        }
    }
}

///
/// The main polling component for that implements the stream pipes
///
struct PipeMonitor {
}

///
/// Provides the 'Notify' interface for a polling function with a particular ID
///
struct PipeNotify<PollFn: Send> {
    next_poll: Arc<Desync<Option<Spawn<PollFn>>>>
}

impl PipeMonitor {
    ///
    /// Creates a new poll thread
    ///
    pub fn new() -> PipeMonitor {
        PipeMonitor {
        }
    }

    ///
    /// Performs a polling operation on a poll
    ///
    fn poll<PollFn>(this_poll: &mut Option<Spawn<PollFn>>, next_poll: Arc<Desync<Option<Spawn<PollFn>>>>)
    where PollFn: 'static+Send+Future<Item=(), Error=()> {
        // If the polling function exists...
        if let Some(mut poll) = this_poll.take() {
            // Create a notification
            let notify = PipeNotify {
                next_poll: next_poll
            };
            let notify = Arc::new(notify);

            // Poll the function
            let poll_result = poll.poll_future_notify(&notify, 0);

            // Keep the polling function alive if it has not finished yet
            if poll_result != Ok(Async::Ready(())) {
                // The take() call means that the polling won't continue unless we pass it forward like this
                *this_poll = Some(poll);
            }
        }
    }

    ///
    /// Adds a polling function to the current thread. It will be called using the futures
    /// notification system (ie, can call things like the stream poll function)
    ///
    pub fn monitor<PollFn>(&self, poll_fn: PollFn)
    where PollFn: 'static+Send+FnMut() -> Poll<(), ()> {
        // Turn the polling function into a future (it will complete when monitoring is complete)
        let poll_fn     = future::poll_fn(poll_fn);

        // Spawn it with an executor
        let poll_fn     = executor::spawn(poll_fn);

        // Create a desync object for polling
        let poll_fn     = Arc::new(Desync::new(Some(poll_fn)));
        let next_poll   = Arc::clone(&poll_fn);

        // Perform the initial polling
        poll_fn.sync(move |poll_fn| Self::poll(poll_fn, next_poll));
    }
}

impl<PollFn> executor::Notify for PipeNotify<PollFn>
where PollFn: 'static+Send+Future<Item=(), Error=()> {
    fn notify(&self, _id: usize) {
        // Poll the future whenever we're notified
        let next_poll = Arc::clone(&self.next_poll);
        self.next_poll.async(move |poll_fn| PipeMonitor::poll(poll_fn, next_poll));
    }
}
<commit_msg>Start to put in some support for backpressure from the pipe<commit_after>//!
//! Desync pipes provide a way to generate and process streams via a `Desync` object
//!
//! Pipes are an excellent way to interface `Desync` objects and the futures library. Piping
//! a stream into a `Desync` object is equivalent to spawning it with an executor, except
//! without the need to dedicate a thread to running it.
//!
//! There are two kinds of pipe. The `pipe_in` function creates a pipe that processes each
//! value made available from a stream on a desync object as they arrive, producing no
//! results. This is useful for cases where a `Desync` object is being used as the endpoint
//! for some data processing (for example, to insert the results of an operation into an
//! asynchronous database object).
//!
//! The `pipe` function pipes data through an object. For every input value, it produces
//! an output value. This is good for creating streams that perform some kind of asynchronous
//! processing operation or that need to access data from inside a `Desync` object.
//!
//! Here's an example of using `pipe_in` to store data in a `HashSet`:
//!
//! ```
//! # extern crate futures;
//! # extern crate desync;
//! # use std::thread;
//! # use std::time::Duration;
//! # use std::collections::HashSet;
//! # use std::sync::*;
//! #
//! use futures::sync::mpsc;
//! use futures::executor;
//! use desync::*;
//!
//! let desync_hashset      = Arc::new(Desync::new(HashSet::new()));
//! let (sender, receiver)  = mpsc::channel(5);
//!
//! pipe_in(Arc::clone(&desync_hashset), receiver, |hashset, value| { value.map(|value| hashset.insert(value)); });
//!
//! let mut sender = executor::spawn(sender);
//! sender.wait_send("Test".to_string());
//! sender.wait_send("Another value".to_string());
//! #
//! # thread::sleep(Duration::from_millis(5));
//! # assert!(desync_hashset.sync(|hashset| hashset.contains(&("Test".to_string()))))
//! ```
//!

use super::desync::*;

use futures::*;
use futures::executor;
use futures::executor::Spawn;

use std::sync::*;
use std::result::Result;
use std::collections::VecDeque;

lazy_static! {
    /// The shared queue where we monitor for updates to the active pipe streams
    static ref PIPE_MONITOR: PipeMonitor = PipeMonitor::new();
}

/// The maximum number of items to queue on a pipe stream before we stop accepting new input
const PIPE_BACKPRESSURE_COUNT: usize = 10;

///
/// Pipes a stream into a desync object. Whenever an item becomes available on the stream, the
/// processing function is called asynchronously with the item that was received.
///
/// This takes a weak reference to the passed in `Desync` object, so the pipe will stop if it's
/// the only thing referencing this object.
///
/// Piping a stream to a `Desync` like this will cause it to start executing: ie, this is
/// similar to calling `executor::spawn(stream)`, except that the stream will immediately
/// start draining into the `Desync` object.
///
pub fn pipe_in<Core, S, ProcessFn>(desync: Arc<Desync<Core>>, stream: S, process: ProcessFn)
where   Core:       'static+Send,
        S:          'static+Send+Stream,
        S::Item:    Send,
        S::Error:   Send,
        ProcessFn:  'static+Send+FnMut(&mut Core, Result<S::Item, S::Error>) -> () {

    // Need a mutable version of the stream
    let mut stream = stream;

    // We stop processing once the desync object is no longer used anywhere else
    let desync = Arc::downgrade(&desync);

    // Wrap the process fn up so we can call it asynchronously
    // (it doesn't really need to be in a mutex as it's only called by our object but we need to make it pass Rust's checks and we don't have a way to specify this at the moment)
    let process = Arc::new(Mutex::new(process));

    // Monitor the stream
    PIPE_MONITOR.monitor(move || {
        loop {
            let desync      = desync.upgrade();

            if let Some(desync) = desync {
                // Read the current status of the stream
                let process     = Arc::clone(&process);
                let next        = stream.poll();

                match next {
                    // Just wait if the stream is not ready
                    Ok(Async::NotReady) => { return Ok(Async::NotReady); },

                    // Stop processing when the stream is finished
                    Ok(Async::Ready(None)) => { return Ok(Async::Ready(())); }

                    // Stream returned a value
                    Ok(Async::Ready(Some(next))) => {
                        // Process the value on the stream
                        desync.sync(move |core| {
                            let mut process = process.lock().unwrap();
                            let process     = &mut *process;
                            process(core, Ok(next));
                        });
                    },

                    // Stream returned an error
                    Err(e) => {
                        // Process the error on the stream
                        desync.sync(move |core| {
                            let mut process = process.lock().unwrap();
                            let process     = &mut *process;
                            process(core, Err(e));
                        });
                    },
                }
            } else {
                // The desync target is no longer available - indicate that we've completed monitoring
                return Ok(Async::Ready(()));
            }
        }
    });
}

///
/// Pipes a stream into this object. Whenever an item becomes available on the stream, the
/// processing function is called asynchronously with the item that was received. The
/// return value is placed onto the output stream.
///
/// Unlike `pipe_in`, this keeps a strong reference to the `Desync` object so the processing
/// will continue so long as the input stream has data and the output stream is not dropped.
///
/// The input stream will start executing and reading values immediately when this is called.
/// Dropping the output stream will cause the pipe to be closed (the input stream will be
/// dropped and no further processing will occur).
///
pub fn pipe<Core, S, Output, OutputErr, ProcessFn>(desync: Arc<Desync<Core>>, stream: S, process: ProcessFn) -> impl Stream<Item=Output, Error=OutputErr>
where   Core:       'static+Send,
        S:          'static+Send+Stream,
        S::Item:    Send,
        S::Error:   Send,
        Output:     'static+Send,
        OutputErr:  'static+Send,
        ProcessFn:  'static+Send+FnMut(&mut Core, Result<S::Item, S::Error>) -> Result<Output, OutputErr> {

    // Fetch the input stream and prepare the process function for async calling
    let mut input_stream    = stream;
    let process             = Arc::new(Mutex::new(process));

    // Create the output stream
    let output_stream   = PipeStream::new();
    let stream_core     = Arc::clone(&output_stream.core);
    let stream_core     = Arc::downgrade(&stream_core);

    // Monitor the input stream and pass data to the output stream
    PIPE_MONITOR.monitor(move || {
        loop {
            let stream_core = stream_core.upgrade();

            if let Some(stream_core) = stream_core {
                // Read the current status of the stream
                let process         = Arc::clone(&process);
                let next            = input_stream.poll();
                let mut next_item;

                // Work out what the next item to pass to the process function should be
                match next {
                    // Just wait if the stream is not ready
                    Ok(Async::NotReady) => { return Ok(Async::NotReady); },

                    // Stop processing when the input stream is finished
                    Ok(Async::Ready(None)) => {
                        // Mark the target stream as closed
                        let mut stream_core = stream_core.lock().unwrap();
                        stream_core.closed = true;
                        stream_core.notify.take().map(|notify| notify.notify());

                        // Pipe has finished
                        return Ok(Async::Ready(()));
                    }

                    // Stream returned a value
                    Ok(Async::Ready(Some(next))) => next_item = Ok(next),

                    // Stream returned an error
                    Err(e) => next_item = Err(e),
                }

                // Send the next item to be processed
                desync.sync(move |core| {
                    // Process the next item
                    let mut process     = process.lock().unwrap();
                    let process         = &mut *process;
                    let next_item       = process(core, next_item);

                    // Send to the pipe stream
                    let mut stream_core = stream_core.lock().unwrap();

                    stream_core.pending.push_back(next_item);
                    stream_core.notify.take().map(|notify| notify.notify());
                });

            } else {
                // We stop processing once nothing is reading from the target stream
                return Ok(Async::Ready(()));
            }
        }
    });

    // The pipe stream is the result
    output_stream
}

///
/// The shared data for a pipe stream
///
struct PipeStreamCore<Item, Error>  {
    /// The pending data for this stream
    pending: VecDeque<Result<Item, Error>>,

    /// True if the input stream has closed (the stream is closed once this is true and there are no more pending items)
    closed: bool,

    /// The task to notify when the stream changes
    notify: Option<task::Task>,

    /// The task to notify when we reduce the amount of pending data
    backpressure_release_notify: Option<task::Task>
}

///
/// A stream generated by a pipe
///
struct PipeStream<Item, Error> {
    core: Arc<Mutex<PipeStreamCore<Item, Error>>>
}

impl<Item, Error> PipeStream<Item, Error> {
    ///
    /// Creates a new, empty, pipestream
    ///
    pub fn new() -> PipeStream<Item, Error> {
        PipeStream {
            core: Arc::new(Mutex::new(PipeStreamCore {
                pending:                        VecDeque::new(),
                closed:                         false,
                notify:                         None,
                backpressure_release_notify:    None
            }))
        }
    }
}

impl<Item, Error> Drop for PipeStream<Item, Error> {
    fn drop(&mut self) {
        let mut core = self.core.lock().unwrap();

        // Flush the pending queue
        core.pending = VecDeque::new();

        // TODO: wake the monitor and stop listening to the source stream
        // (Right now this will happen next time the source stream produces data)
    }
}

impl<Item, Error> Stream for PipeStream<Item, Error> {
    type Item   = Item;
    type Error  = Error;

    fn poll(&mut self) -> Poll<Option<Item>, Error> {
        // Fetch the core
        let mut core = self.core.lock().unwrap();

        if let Some(item) = core.pending.pop_front() {
            // Value waiting at the start of the stream
            core.backpressure_release_notify.take().map(|notify| notify.notify());

            match item {
                Ok(item)    => Ok(Async::Ready(Some(item))),
                Err(erm)    => Err(erm)
            }
        } else if core.closed {
            // No more data will be returned from this stream
            Ok(Async::Ready(None))
        } else {
            // Stream not ready
            core.notify = Some(task::current());

            Ok(Async::NotReady)
        }
    }
}

///
/// The main polling component for that implements the stream pipes
///
struct PipeMonitor {
}

///
/// Provides the 'Notify' interface for a polling function with a particular ID
///
struct PipeNotify<PollFn: Send> {
    next_poll: Arc<Desync<Option<Spawn<PollFn>>>>
}

impl PipeMonitor {
    ///
    /// Creates a new poll thread
    ///
    pub fn new() -> PipeMonitor {
        PipeMonitor {
        }
    }

    ///
    /// Performs a polling operation on a poll
    ///
    fn poll<PollFn>(this_poll: &mut Option<Spawn<PollFn>>, next_poll: Arc<Desync<Option<Spawn<PollFn>>>>)
    where PollFn: 'static+Send+Future<Item=(), Error=()> {
        // If the polling function exists...
        if let Some(mut poll) = this_poll.take() {
            // Create a notification
            let notify = PipeNotify {
                next_poll: next_poll
            };
            let notify = Arc::new(notify);

            // Poll the function
            let poll_result = poll.poll_future_notify(&notify, 0);

            // Keep the polling function alive if it has not finished yet
            if poll_result != Ok(Async::Ready(())) {
                // The take() call means that the polling won't continue unless we pass it forward like this
                *this_poll = Some(poll);
            }
        }
    }

    ///
    /// Adds a polling function to the current thread. It will be called using the futures
    /// notification system (ie, can call things like the stream poll function)
    ///
    pub fn monitor<PollFn>(&self, poll_fn: PollFn)
    where PollFn: 'static+Send+FnMut() -> Poll<(), ()> {
        // Turn the polling function into a future (it will complete when monitoring is complete)
        let poll_fn     = future::poll_fn(poll_fn);

        // Spawn it with an executor
        let poll_fn     = executor::spawn(poll_fn);

        // Create a desync object for polling
        let poll_fn     = Arc::new(Desync::new(Some(poll_fn)));
        let next_poll   = Arc::clone(&poll_fn);

        // Perform the initial polling
        poll_fn.sync(move |poll_fn| Self::poll(poll_fn, next_poll));
    }
}

impl<PollFn> executor::Notify for PipeNotify<PollFn>
where PollFn: 'static+Send+Future<Item=(), Error=()> {
    fn notify(&self, _id: usize) {
        // Poll the future whenever we're notified
        let next_poll = Arc::clone(&self.next_poll);
        self.next_poll.async(move |poll_fn| PipeMonitor::poll(poll_fn, next_poll));
    }
}
<|endoftext|>


<commit_before>/// A macro for extracting the successful type of a `Poll<T, E>`.
///
/// This macro bakes propagation of both errors and `NotReady` signals by
/// returning early.
#[macro_export]
macro_rules! try_ready {
    ($e:expr) => (match $e {
        Ok($crate::Async::Ready(t)) => t,
        Ok($crate::Async::NotReady) => return Ok($crate::Async::NotReady),
        Err(e) => return Err(From::from(e)),
    })
}

/// Return type of the `Future::poll` method, indicates whether a future's value
/// is ready or not.
///
/// * `Ok(Async::Ready(t))` means that a future has successfully resolved
/// * `Ok(Async::NotReady)` means that a future is not ready to complete yet
/// * `Err(e)` means that a future has completed with the given failure
pub type Poll<T, E> = Result<Async<T>, E>;

/// Return type of future, indicating whether a value is ready or not.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Async<T> {
    /// Represents that a value is immediately ready.
    Ready(T),

    /// Represents that a value is not ready yet, but may be so later.
    NotReady,
}

impl<T> Async<T> {
    /// Change the success type of this `Async` value with the closure provided
    pub fn map<F, U>(self, f: F) -> Async<U>
        where F: FnOnce(T) -> U
    {
        match self {
            Async::Ready(t) => Async::Ready(f(t)),
            Async::NotReady => Async::NotReady,
        }
    }

    /// Returns whether this is `Async::Ready`
    pub fn is_ready(&self) -> bool {
        match *self {
            Async::Ready(_) => true,
            Async::NotReady => false,
        }
    }

    /// Returns whether this is `Async::NotReady`
    pub fn is_not_ready(&self) -> bool {
        !self.is_ready()
    }
}

impl<T> From<T> for Async<T> {
    fn from(t: T) -> Async<T> {
        Async::Ready(t)
    }
}

/// The result of an asynchronous attempt to send a value to a sink.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AsyncSink<T> {
    /// The `start_send` attempt succeeded, so the sending process has
    /// *started*; you muse use `Sink::poll_complete` to drive the send
    /// to completion.
    Ready,

    /// The `start_send` attempt failed due to the sink being full. The value
    /// being sent is returned, and the current `Task` will be autoamtically
    /// notified again once the sink has room.
    NotReady(T),
}

impl<T> AsyncSink<T> {
    /// Returns whether this is `AsyncSink::Ready`
    pub fn is_ready(&self) -> bool {
        match *self {
            AsyncSink::Ready => true,
            AsyncSink::NotReady(_) => false,
        }
    }

    /// Returns whether this is `AsyncSink::NotReady`
    pub fn is_not_ready(&self) -> bool {
        !self.is_ready()
    }
}

/// Return type of the `Sink::start_send` method, indicating the outcome of a
/// send attempt. See `AsyncSink` for more details.
pub type StartSend<T, E> = Result<AsyncSink<T>, E>;
<commit_msg>Fix AsyncSink doc typo<commit_after>/// A macro for extracting the successful type of a `Poll<T, E>`.
///
/// This macro bakes propagation of both errors and `NotReady` signals by
/// returning early.
#[macro_export]
macro_rules! try_ready {
    ($e:expr) => (match $e {
        Ok($crate::Async::Ready(t)) => t,
        Ok($crate::Async::NotReady) => return Ok($crate::Async::NotReady),
        Err(e) => return Err(From::from(e)),
    })
}

/// Return type of the `Future::poll` method, indicates whether a future's value
/// is ready or not.
///
/// * `Ok(Async::Ready(t))` means that a future has successfully resolved
/// * `Ok(Async::NotReady)` means that a future is not ready to complete yet
/// * `Err(e)` means that a future has completed with the given failure
pub type Poll<T, E> = Result<Async<T>, E>;

/// Return type of future, indicating whether a value is ready or not.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Async<T> {
    /// Represents that a value is immediately ready.
    Ready(T),

    /// Represents that a value is not ready yet, but may be so later.
    NotReady,
}

impl<T> Async<T> {
    /// Change the success type of this `Async` value with the closure provided
    pub fn map<F, U>(self, f: F) -> Async<U>
        where F: FnOnce(T) -> U
    {
        match self {
            Async::Ready(t) => Async::Ready(f(t)),
            Async::NotReady => Async::NotReady,
        }
    }

    /// Returns whether this is `Async::Ready`
    pub fn is_ready(&self) -> bool {
        match *self {
            Async::Ready(_) => true,
            Async::NotReady => false,
        }
    }

    /// Returns whether this is `Async::NotReady`
    pub fn is_not_ready(&self) -> bool {
        !self.is_ready()
    }
}

impl<T> From<T> for Async<T> {
    fn from(t: T) -> Async<T> {
        Async::Ready(t)
    }
}

/// The result of an asynchronous attempt to send a value to a sink.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AsyncSink<T> {
    /// The `start_send` attempt succeeded, so the sending process has
    /// *started*; you muse use `Sink::poll_complete` to drive the send
    /// to completion.
    Ready,

    /// The `start_send` attempt failed due to the sink being full. The value
    /// being sent is returned, and the current `Task` will be automatically
    /// notified again once the sink has room.
    NotReady(T),
}

impl<T> AsyncSink<T> {
    /// Returns whether this is `AsyncSink::Ready`
    pub fn is_ready(&self) -> bool {
        match *self {
            AsyncSink::Ready => true,
            AsyncSink::NotReady(_) => false,
        }
    }

    /// Returns whether this is `AsyncSink::NotReady`
    pub fn is_not_ready(&self) -> bool {
        !self.is_ready()
    }
}

/// Return type of the `Sink::start_send` method, indicating the outcome of a
/// send attempt. See `AsyncSink` for more details.
pub type StartSend<T, E> = Result<AsyncSink<T>, E>;
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust 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 crate::rustc::hir::def::Def;
use crate::rustc::hir::*;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array};
use crate::syntax::ptr::P;
use crate::utils::sugg::Sugg;
use if_chain::if_chain;

use crate::rustc_errors::Applicability;
use crate::utils::paths::*;
use crate::utils::{match_def_path, match_type, span_lint_and_then};

/// **What it does:** Checks for expressions that could be replaced by the question mark operator
///
/// **Why is this bad?** Question mark usage is more idiomatic
///
/// **Known problems:** None
///
/// **Example:**
/// ```rust
/// if option.is_none() {
///     return None;
/// }
/// ```
///
/// Could be written:
///
/// ```rust
/// option?;
/// ```
declare_clippy_lint! {
    pub QUESTION_MARK,
    style,
    "checks for expressions that could be replaced by the question mark operator"
}

#[derive(Copy, Clone)]
pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(QUESTION_MARK)
    }
}

impl Pass {
    /// Check if the given expression on the given context matches the following structure:
    ///
    /// ```ignore
    /// if option.is_none() {
    ///    return None;
    /// }
    /// ```
    ///
    /// If it matches, it will suggest to use the question mark operator instead
    fn check_is_none_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr) {
        if_chain! {
            if let ExprKind::If(ref if_expr, ref body, _) = expr.node;
            if let ExprKind::MethodCall(ref segment, _, ref args) = if_expr.node;
            if segment.ident.name == "is_none";
            if Self::expression_returns_none(cx, body);
            if let Some(subject) = args.get(0);
            if Self::is_option(cx, subject);

            then {
                span_lint_and_then(
                    cx,
                    QUESTION_MARK,
                    expr.span,
                    "this block may be rewritten with the `?` operator",
                    |db| {
                        let receiver_str = &Sugg::hir(cx, subject, "..");

                        db.span_suggestion_with_applicability(
                            expr.span,
                            "replace_it_with",
                            format!("{}?;", receiver_str),
                            Applicability::MaybeIncorrect, // snippet
                        );
                    }
                )
            }
        }
    }

    fn is_option(cx: &LateContext<'_, '_>, expression: &Expr) -> bool {
        let expr_ty = cx.tables.expr_ty(expression);

        match_type(cx, expr_ty, &OPTION)
    }

    fn expression_returns_none(cx: &LateContext<'_, '_>, expression: &Expr) -> bool {
        match expression.node {
            ExprKind::Block(ref block, _) => {
                if let Some(return_expression) = Self::return_expression(block) {
                    return Self::expression_returns_none(cx, &return_expression);
                }

                false
            },
            ExprKind::Ret(Some(ref expr)) => Self::expression_returns_none(cx, expr),
            ExprKind::Path(ref qp) => {
                if let Def::VariantCtor(def_id, _) = cx.tables.qpath_def(qp, expression.hir_id) {
                    return match_def_path(cx.tcx, def_id, &OPTION_NONE);
                }

                false
            },
            _ => false,
        }
    }

    fn return_expression(block: &Block) -> Option<P<Expr>> {
        // Check if last expression is a return statement. Then, return the expression
        if_chain! {
            if block.stmts.len() == 1;
            if let Some(expr) = block.stmts.iter().last();
            if let StmtKind::Semi(ref expr, _) = expr.node;
            if let ExprKind::Ret(ref ret_expr) = expr.node;
            if let &Some(ref ret_expr) = ret_expr;

            then {
                return Some(ret_expr.clone());
            }
        }

        // Check if the block has an implicit return expression
        if let Some(ref ret_expr) = block.expr {
            return Some(ret_expr.clone());
        }

        None
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        Self::check_is_none_and_early_return_none(cx, expr);
    }
}
<commit_msg>question_mark: Lint only early returns<commit_after>// Copyright 2014-2018 The Rust 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 crate::rustc::hir::def::Def;
use crate::rustc::hir::*;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array};
use crate::syntax::ptr::P;
use crate::utils::sugg::Sugg;
use if_chain::if_chain;

use crate::rustc_errors::Applicability;
use crate::utils::paths::*;
use crate::utils::{match_def_path, match_type, span_lint_and_then};

/// **What it does:** Checks for expressions that could be replaced by the question mark operator
///
/// **Why is this bad?** Question mark usage is more idiomatic
///
/// **Known problems:** None
///
/// **Example:**
/// ```rust
/// if option.is_none() {
///     return None;
/// }
/// ```
///
/// Could be written:
///
/// ```rust
/// option?;
/// ```
declare_clippy_lint! {
    pub QUESTION_MARK,
    style,
    "checks for expressions that could be replaced by the question mark operator"
}

#[derive(Copy, Clone)]
pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(QUESTION_MARK)
    }
}

impl Pass {
    /// Check if the given expression on the given context matches the following structure:
    ///
    /// ```ignore
    /// if option.is_none() {
    ///    return None;
    /// }
    /// ```
    ///
    /// If it matches, it will suggest to use the question mark operator instead
    fn check_is_none_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr) {
        if_chain! {
            if let ExprKind::If(ref if_expr, ref body, _) = expr.node;
            if let ExprKind::MethodCall(ref segment, _, ref args) = if_expr.node;
            if segment.ident.name == "is_none";
            if Self::expression_returns_none(cx, body);
            if let Some(subject) = args.get(0);
            if Self::is_option(cx, subject);

            then {
                span_lint_and_then(
                    cx,
                    QUESTION_MARK,
                    expr.span,
                    "this block may be rewritten with the `?` operator",
                    |db| {
                        let receiver_str = &Sugg::hir(cx, subject, "..");

                        db.span_suggestion_with_applicability(
                            expr.span,
                            "replace_it_with",
                            format!("{}?;", receiver_str),
                            Applicability::MaybeIncorrect, // snippet
                        );
                    }
                )
            }
        }
    }

    fn is_option(cx: &LateContext<'_, '_>, expression: &Expr) -> bool {
        let expr_ty = cx.tables.expr_ty(expression);

        match_type(cx, expr_ty, &OPTION)
    }

    fn expression_returns_none(cx: &LateContext<'_, '_>, expression: &Expr) -> bool {
        match expression.node {
            ExprKind::Block(ref block, _) => {
                if let Some(return_expression) = Self::return_expression(block) {
                    return Self::expression_returns_none(cx, &return_expression);
                }

                false
            },
            ExprKind::Ret(Some(ref expr)) => Self::expression_returns_none(cx, expr),
            ExprKind::Path(ref qp) => {
                if let Def::VariantCtor(def_id, _) = cx.tables.qpath_def(qp, expression.hir_id) {
                    return match_def_path(cx.tcx, def_id, &OPTION_NONE);
                }

                false
            },
            _ => false,
        }
    }

    fn return_expression(block: &Block) -> Option<P<Expr>> {
        // Check if last expression is a return statement. Then, return the expression
        if_chain! {
            if block.stmts.len() == 1;
            if let Some(expr) = block.stmts.iter().last();
            if let StmtKind::Semi(ref expr, _) = expr.node;
            if let ExprKind::Ret(ref ret_expr) = expr.node;
            if let &Some(ref ret_expr) = ret_expr;

            then {
                return Some(ret_expr.clone());
            }
        }

        // Check for `return` without a semicolon.
        if_chain! {
            if block.stmts.len() == 0;
            if let Some(ExprKind::Ret(Some(ret_expr))) = block.expr.as_ref().map(|e| &e.node);
            then {
                return Some(ret_expr.clone());
            }
        }

        None
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        Self::check_is_none_and_early_return_none(cx, expr);
    }
}
<|endoftext|>


<commit_before>use std::io::Read;

use crate::common::LineIter;

fn parse_bit(bit: char) -> usize {
    if bit == '1' {
        1
    } else {
        0
    }
}

pub fn part1(input: &mut dyn Read) -> String {
    let mut reader = LineIter::new(input);

    let mut totals: Vec<usize> = reader.next().unwrap().chars().map(parse_bit).collect();

    let mut count = 1;

    while let Some(line) = reader.next() {
        line.chars()
            .map(parse_bit)
            .zip(totals.iter_mut())
            .for_each(|(b, t)| *t += b);

        count += 1;
    }

    let bitmask = (1 << totals.len()) - 1;

    let gamma = totals.into_iter().fold(0, |mut current, total| {
        current <<= 1;
        if total > count / 2 {
            current |= 1;
        };

        current
    });

    let epsilon = (!gamma) & bitmask;

    (gamma * epsilon).to_string()
}

fn find_remaining(mut strings: Vec<Vec<u8>>, most: bool) -> u32 {
    let comp: fn(usize, usize) -> bool = if most {
        |occurrences, len| occurrences * 2 >= len
    } else {
        |occurrences, len| occurrences * 2 < len
    };

    for pos in 0..strings[0].len() {
        if strings.len() == 1 {
            break;
        }

        let occurrences = strings.iter().filter(|b| b[pos] == b'1').count();

        let keep = if comp(occurrences, strings.len()) {
            b'1'
        } else {
            b'0'
        };

        strings.retain(|s| s[pos] == keep);
    }

    strings[0]
        .iter()
        .fold(0, |n, &b| (n << 1) | (b - b'0') as u32)
}

pub fn part2(input: &mut dyn Read) -> String {
    let mut strings = Vec::new();
    let mut reader = LineIter::new(input);

    while let Some(line) = reader.next() {
        strings.push(line.as_bytes().to_owned());
    }

    let oxygen = find_remaining(strings.clone(), true);
    let co2 = find_remaining(strings, false);

    (oxygen * co2).to_string()
}

#[cfg(test)]
mod tests {
    use crate::test_implementation;

    use super::*;

    const SAMPLE: &[u8] = include_bytes!("samples/03.txt");

    #[test]
    fn sample_part1() {
        test_implementation(part1, SAMPLE, 198);
    }

    #[test]
    fn sample_part2() {
        test_implementation(part2, SAMPLE, 230)
    }
}
<commit_msg>Less allocations in day 3 part 2<commit_after>use std::io::Read;

use crate::common::LineIter;

fn parse_bit(bit: char) -> usize {
    if bit == '1' {
        1
    } else {
        0
    }
}

pub fn part1(input: &mut dyn Read) -> String {
    let mut reader = LineIter::new(input);

    let mut totals: Vec<usize> = reader.next().unwrap().chars().map(parse_bit).collect();

    let mut count = 1;

    while let Some(line) = reader.next() {
        line.chars()
            .map(parse_bit)
            .zip(totals.iter_mut())
            .for_each(|(b, t)| *t += b);

        count += 1;
    }

    let bitmask = (1 << totals.len()) - 1;

    let gamma = totals.into_iter().fold(0, |mut current, total| {
        current <<= 1;
        if total > count / 2 {
            current |= 1;
        };

        current
    });

    let epsilon = (!gamma) & bitmask;

    (gamma * epsilon).to_string()
}

fn find_remaining(mut strings: Vec<u32>, most: bool, len: usize) -> u32 {
    for pos in 1..=len {
        if strings.len() == 1 {
            break;
        }

        let bit = 1 << (len - pos);

        let occurrences = strings.iter().filter(|&&b| (b & bit) == bit).count();

        let keep = if (occurrences * 2 < strings.len()) ^ most {
            bit
        } else {
            0
        };

        strings.retain(|&b| (b & bit) == keep);
    }

    strings[0]
}

pub fn part2(input: &mut dyn Read) -> String {
    let mut strings = Vec::new();
    let mut reader = LineIter::new(input);
    let mut len = None;

    while let Some(line) = reader.next() {
        strings.push(u32::from_str_radix(line, 2).unwrap());
        len = Some(line.len());
    }

    let len = len.unwrap();

    let oxygen = find_remaining(strings.clone(), true, len);
    let co2 = find_remaining(strings, false, len);

    (oxygen * co2).to_string()
}

#[cfg(test)]
mod tests {
    use crate::test_implementation;

    use super::*;

    const SAMPLE: &[u8] = include_bytes!("samples/03.txt");

    #[test]
    fn sample_part1() {
        test_implementation(part1, SAMPLE, 198);
    }

    #[test]
    fn sample_part2() {
        test_implementation(part2, SAMPLE, 230)
    }
}
<|endoftext|>