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

extern crate capnp;
extern crate rand;

use std::{mem, io};

use capnp::{message, serialize, serialize_packed};
use capnp::traits::Owned;

pub mod common;

pub mod carsales_capnp {
  include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs"));
}
pub mod carsales;

pub mod catrank_capnp {
  include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs"));
}
pub mod catrank;

pub mod eval_capnp {
  include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs"));
}

pub mod eval;

trait TestCase {
    type Request: for<'a> Owned<'a>;
    type Response: for<'a> Owned<'a>;
    type Expectation;

    fn setup_request(&self, &mut common::FastRand, <Self::Request as Owned>::Builder) -> Self::Expectation;
    fn handle_request(&self, <Self::Request as Owned>::Reader, <Self::Response as Owned>::Builder)
                      -> ::capnp::Result<()>;
    fn check_response(&self, <Self::Response as Owned>::Reader, Self::Expectation) -> ::capnp::Result<()>;
}

trait Serialize {
    fn read_message<R>(
        &self,
        read: &mut R,
        options: message::ReaderOptions)
                       -> ::capnp::Result<message::Reader<::capnp::serialize::OwnedSegments>>
        where R: io::BufRead;

    fn write_message<W, A>(&self, write: &mut W, message: &message::Builder<A>) -> ::capnp::Result<()>
        where W: io::Write, A: message::Allocator;
}

struct NoCompression;

impl Serialize for NoCompression {
    fn read_message<R>(&self, read: &mut R,
                       options: message::ReaderOptions)
                       -> ::capnp::Result<message::Reader<::capnp::serialize::OwnedSegments>>
        where R: io::BufRead
    {
        serialize::read_message(read, options)
    }

    fn write_message<W, A>(&self, write: &mut W, message: &message::Builder<A>) -> ::capnp::Result<()>
        where W: io::Write, A: message::Allocator {
        serialize::write_message(write, message).map_err(|e| e.into())
    }
}

struct Packed;

impl Serialize for Packed {
    fn read_message<R>(&self, read: &mut R,
                       options: message::ReaderOptions)
                       -> ::capnp::Result<message::Reader<::capnp::serialize::OwnedSegments>>
        where R: io::BufRead
    {
        serialize_packed::read_message(read, options)
    }

    fn write_message<W, A>(&self, write: &mut W, message: &message::Builder<A>) -> ::capnp::Result<()>
        where W: io::Write, A: message::Allocator {
        serialize_packed::write_message(write, message).map_err(|e| e.into())
    }
}

trait Scratch<'a> {
    type Allocator: message::Allocator;

    fn get_builders(&'a mut self) -> (message::Builder<Self::Allocator>, message::Builder<Self::Allocator>);
}

const SCRATCH_SIZE: usize = 128 * 1024;

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

impl <'a> Scratch<'a> for NoScratch {
    type Allocator = message::HeapAllocator;

    fn get_builders(&'a mut self) -> (message::Builder<Self::Allocator>, message::Builder<Self::Allocator>) {
        (message::Builder::new_default(), message::Builder::new_default())
    }
}

pub struct UseScratch {
    _owned_space: ::std::vec::Vec<::std::vec::Vec<capnp::Word>>,
    scratch_space: ::std::vec::Vec<message::ScratchSpace<'static>>,
}

impl UseScratch {
    pub fn new() -> UseScratch {
        let mut owned = Vec::new();
        let mut scratch = Vec::new();
        for _ in 0..6 {
            let mut words = capnp::Word::allocate_zeroed_vec(SCRATCH_SIZE);
            scratch.push(message::ScratchSpace::new(
                unsafe { mem::transmute(&mut words[..]) }));
            owned.push(words);
        }
        UseScratch {
            _owned_space: owned,
            scratch_space: scratch,
        }
    }
}

impl <'a> Scratch<'a> for UseScratch {
    type Allocator = message::ScratchSpaceHeapAllocator<'a, 'a>;

    fn get_builders(&'a mut self) -> (message::Builder<Self::Allocator>, message::Builder<Self::Allocator>) {
        (message::Builder::new(message::ScratchSpaceHeapAllocator::new(
            unsafe { mem::transmute(&mut self.scratch_space[0]) })),
         message::Builder::new(message::ScratchSpaceHeapAllocator::new(
             unsafe { mem::transmute(&mut self.scratch_space[1]) })))

    }
}

fn pass_by_object<S, T>(testcase: T, mut reuse: S, iters: u64) -> ::capnp::Result<()>
    where S: for<'a> Scratch<'a>, T: TestCase,
{
    let mut rng = common::FastRand::new();
    for _ in 0..iters {
        let (mut message_req, mut message_res) = reuse.get_builders();

        let expected = testcase.setup_request(
            &mut rng,
            message_req.init_root());

        testcase.handle_request(
            message_req.get_root_as_reader()?,
            message_res.init_root())?;

        testcase.check_response(
            message_res.get_root_as_reader()?,
            expected)?;
    }
    Ok(())
}

fn pass_by_bytes<C, S, T>(testcase: T, mut reuse: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    let mut request_bytes: ::std::vec::Vec<u8> =
        ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
    let mut response_bytes: ::std::vec::Vec<u8> =
        ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
    let mut rng = common::FastRand::new();
    for _ in 0..iters {
        let (mut message_req, mut message_res) = reuse.get_builders();

        let expected = {
            let request = message_req.init_root();
            testcase.setup_request(&mut rng, request)
        };

        {
            let response = message_res.init_root();

            {
                let mut writer: &mut [u8] = &mut request_bytes;
                compression.write_message(&mut writer, &mut message_req)?;
            }

            let mut request_bytes1: &[u8] = &request_bytes;
            let message_reader = compression.read_message(
                &mut request_bytes1,
                Default::default())?;

            let request_reader = message_reader.get_root()?;
            testcase.handle_request(request_reader, response)?;
        }

        {
            let mut writer: &mut [u8] = &mut response_bytes;
            compression.write_message(&mut writer, &mut message_res)?;
        }

        let mut response_bytes1: &[u8] = &response_bytes;
        let message_reader = compression.read_message(
            &mut response_bytes1,
            Default::default())?;

        let response_reader = message_reader.get_root()?;
        testcase.check_response(response_reader, expected)?;
    }
    Ok(())
}

fn server<C, S, T, R, W>(testcase: T, mut reuse: S, compression: C, iters: u64, mut input: R, mut output: W)
                         -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, R: io::Read, W: io::Write,
{
    let mut out_buffered = io::BufWriter::new(&mut output);
    let mut in_buffered = io::BufReader::new(&mut input);
    for _ in 0..iters {
        use std::io::Write;
        let (mut message_res, _) = reuse.get_builders();

        {
            let response = message_res.init_root();
            let message_reader = compression.read_message(
                &mut in_buffered,
                capnp::message::DEFAULT_READER_OPTIONS)?;
            let request_reader = message_reader.get_root()?;
            testcase.handle_request(request_reader, response)?;
        }

        compression.write_message(&mut out_buffered, &mut message_res)?;
        out_buffered.flush()?;
    }
    Ok(())
}

fn sync_client<C, S, T>(testcase: T, mut reuse: S, compression: C, iters: u64)
                        -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    let mut out_stream: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(1) };
    let mut in_stream: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(0) };
    let mut in_buffered = io::BufReader::new(&mut in_stream);
    let mut out_buffered = io::BufWriter::new(&mut out_stream);
    let mut rng = common::FastRand::new();
    for _ in 0..iters {
        use std::io::Write;
        let (mut message_req, _) = reuse.get_builders();

        let expected = {
            let request = message_req.init_root();
            testcase.setup_request(&mut rng, request)
        };
        compression.write_message(&mut out_buffered, &mut message_req)?;
        out_buffered.flush()?;

        let message_reader = compression.read_message(
            &mut in_buffered,
            Default::default())?;
        let response_reader = message_reader.get_root()?;
        testcase.check_response(response_reader, expected)?;
    }
    Ok(())
}

fn pass_by_pipe<C, S, T>(testcase: T, reuse: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    use std::{process, env};

    let mut args: Vec<String> = env::args().collect();
    args[2] = "client".to_string();

    let mut command = process::Command::new(&args[0]);
    command.args(&args[1..args.len()]);
    command.stdin(process::Stdio::piped());
    command.stdout(process::Stdio::piped());
    command.stderr(process::Stdio::null());
    match command.spawn() {
        Ok(ref mut p) => {
            let child_std_out = p.stdout.take().unwrap();
            let child_std_in = p.stdin.take().unwrap();
            server(testcase, reuse, compression, iters, child_std_out, child_std_in)?;
            println!("{}", p.wait().unwrap());
            Ok(())
        }
        Err(e) => {
            println!("could not start process: {}", e);
            Ok(())
        }
    }
}

pub enum Mode {
    Object,
    Bytes,
    Client,
    Server,
    Pipe,
}

impl Mode {
    pub fn parse(s: &str) -> ::capnp::Result<Mode> {
        match s {
            "object" => Ok(Mode::Object),
            "bytes" => Ok(Mode::Bytes),
            "client" => Ok(Mode::Client),
            "server" => Ok(Mode::Server),
            "pipe" => Ok(Mode::Pipe),
            s => Err(::capnp::Error::failed(format!("unrecognized mode: {}", s))),
        }
    }
}

fn do_testcase<C, S, T>(testcase: T, mode: Mode, reuse: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    match mode {
        Mode::Object => pass_by_object(testcase, reuse, iters),
        Mode::Bytes => pass_by_bytes(testcase, reuse, compression, iters),
        Mode::Client => sync_client(testcase, reuse, compression, iters),
        Mode::Server => {
            let input: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(1) };
            let output: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(0) };
            server(testcase, reuse, compression, iters, input, output)
        }
        Mode::Pipe => pass_by_pipe(testcase, reuse, compression, iters),
    }
}

fn do_testcase1<C, S>(case: &str, mode: Mode, scratch: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>,
{
    match case {
        "carsales" => do_testcase(carsales::CarSales, mode, scratch, compression, iters),
        "catrank" => do_testcase(catrank::CatRank, mode, scratch, compression, iters),
        "eval" => do_testcase(eval::Eval, mode, scratch, compression, iters),
        s => Err(::capnp::Error::failed(format!("unrecognized test case: {}", s))),
    }
}

fn do_testcase2<C>(case: &str, mode: Mode, scratch: &str, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize,
{
    match scratch {
        "no-reuse" => do_testcase1(case, mode, NoScratch, compression, iters),
        "reuse" => do_testcase1(case, mode, UseScratch::new(), compression, iters),
        s => Err(::capnp::Error::failed(format!("unrecognized reuse option: {}", s))),
    }
}

fn try_main() -> ::capnp::Result<()> {
    let args: Vec<String> = ::std::env::args().collect();

    assert!(args.len() == 6,
            "USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT",
            args[0]);

    let iters = match args[5].parse::<u64>() {
        Ok(n) => n,
        Err(_) =>
            return Err(::capnp::Error::failed(format!("Could not parse a u64 from: {}", args[5]))),
    };

    let mode = Mode::parse(&*args[2])?;

    match &*args[4] {
        "none" => do_testcase2(&*args[1], mode, &*args[3], NoCompression, iters),
        "packed" => do_testcase2(&*args[1], mode, &*args[3], Packed, iters),
        s => Err(::capnp::Error::failed(format!("unrecognized compression: {}", s))),
    }
}

pub fn main() {
    match try_main() {
        Ok(()) => (),
        Err(e) => {
            panic!("error: {:?}", e);
        }
    }
}
<commit_msg>modernize some archaic vector construction<commit_after>// Copyright (c) 2013-2017 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

extern crate capnp;
extern crate rand;

use std::{mem, io};

use capnp::{message, serialize, serialize_packed};
use capnp::traits::Owned;

pub mod common;

pub mod carsales_capnp {
  include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs"));
}
pub mod carsales;

pub mod catrank_capnp {
  include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs"));
}
pub mod catrank;

pub mod eval_capnp {
  include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs"));
}

pub mod eval;

trait TestCase {
    type Request: for<'a> Owned<'a>;
    type Response: for<'a> Owned<'a>;
    type Expectation;

    fn setup_request(&self, &mut common::FastRand, <Self::Request as Owned>::Builder) -> Self::Expectation;
    fn handle_request(&self, <Self::Request as Owned>::Reader, <Self::Response as Owned>::Builder)
                      -> ::capnp::Result<()>;
    fn check_response(&self, <Self::Response as Owned>::Reader, Self::Expectation) -> ::capnp::Result<()>;
}

trait Serialize {
    fn read_message<R>(
        &self,
        read: &mut R,
        options: message::ReaderOptions)
                       -> ::capnp::Result<message::Reader<::capnp::serialize::OwnedSegments>>
        where R: io::BufRead;

    fn write_message<W, A>(&self, write: &mut W, message: &message::Builder<A>) -> ::capnp::Result<()>
        where W: io::Write, A: message::Allocator;
}

struct NoCompression;

impl Serialize for NoCompression {
    fn read_message<R>(&self, read: &mut R,
                       options: message::ReaderOptions)
                       -> ::capnp::Result<message::Reader<::capnp::serialize::OwnedSegments>>
        where R: io::BufRead
    {
        serialize::read_message(read, options)
    }

    fn write_message<W, A>(&self, write: &mut W, message: &message::Builder<A>) -> ::capnp::Result<()>
        where W: io::Write, A: message::Allocator {
        serialize::write_message(write, message).map_err(|e| e.into())
    }
}

struct Packed;

impl Serialize for Packed {
    fn read_message<R>(&self, read: &mut R,
                       options: message::ReaderOptions)
                       -> ::capnp::Result<message::Reader<::capnp::serialize::OwnedSegments>>
        where R: io::BufRead
    {
        serialize_packed::read_message(read, options)
    }

    fn write_message<W, A>(&self, write: &mut W, message: &message::Builder<A>) -> ::capnp::Result<()>
        where W: io::Write, A: message::Allocator {
        serialize_packed::write_message(write, message).map_err(|e| e.into())
    }
}

trait Scratch<'a> {
    type Allocator: message::Allocator;

    fn get_builders(&'a mut self) -> (message::Builder<Self::Allocator>, message::Builder<Self::Allocator>);
}

const SCRATCH_SIZE: usize = 128 * 1024;

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

impl <'a> Scratch<'a> for NoScratch {
    type Allocator = message::HeapAllocator;

    fn get_builders(&'a mut self) -> (message::Builder<Self::Allocator>, message::Builder<Self::Allocator>) {
        (message::Builder::new_default(), message::Builder::new_default())
    }
}

pub struct UseScratch {
    _owned_space: ::std::vec::Vec<::std::vec::Vec<capnp::Word>>,
    scratch_space: ::std::vec::Vec<message::ScratchSpace<'static>>,
}

impl UseScratch {
    pub fn new() -> UseScratch {
        let mut owned = Vec::new();
        let mut scratch = Vec::new();
        for _ in 0..6 {
            let mut words = capnp::Word::allocate_zeroed_vec(SCRATCH_SIZE);
            scratch.push(message::ScratchSpace::new(
                unsafe { mem::transmute(&mut words[..]) }));
            owned.push(words);
        }
        UseScratch {
            _owned_space: owned,
            scratch_space: scratch,
        }
    }
}

impl <'a> Scratch<'a> for UseScratch {
    type Allocator = message::ScratchSpaceHeapAllocator<'a, 'a>;

    fn get_builders(&'a mut self) -> (message::Builder<Self::Allocator>, message::Builder<Self::Allocator>) {
        (message::Builder::new(message::ScratchSpaceHeapAllocator::new(
            unsafe { mem::transmute(&mut self.scratch_space[0]) })),
         message::Builder::new(message::ScratchSpaceHeapAllocator::new(
             unsafe { mem::transmute(&mut self.scratch_space[1]) })))

    }
}

fn pass_by_object<S, T>(testcase: T, mut reuse: S, iters: u64) -> ::capnp::Result<()>
    where S: for<'a> Scratch<'a>, T: TestCase,
{
    let mut rng = common::FastRand::new();
    for _ in 0..iters {
        let (mut message_req, mut message_res) = reuse.get_builders();

        let expected = testcase.setup_request(
            &mut rng,
            message_req.init_root());

        testcase.handle_request(
            message_req.get_root_as_reader()?,
            message_res.init_root())?;

        testcase.check_response(
            message_res.get_root_as_reader()?,
            expected)?;
    }
    Ok(())
}

fn pass_by_bytes<C, S, T>(testcase: T, mut reuse: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    let mut request_bytes = vec![0u8; SCRATCH_SIZE * 8];
    let mut response_bytes = vec![0u8; SCRATCH_SIZE * 8];
    let mut rng = common::FastRand::new();
    for _ in 0..iters {
        let (mut message_req, mut message_res) = reuse.get_builders();

        let expected = {
            let request = message_req.init_root();
            testcase.setup_request(&mut rng, request)
        };

        {
            let response = message_res.init_root();

            {
                let mut writer: &mut [u8] = &mut request_bytes;
                compression.write_message(&mut writer, &mut message_req)?;
            }

            let mut request_bytes1: &[u8] = &request_bytes;
            let message_reader = compression.read_message(
                &mut request_bytes1,
                Default::default())?;

            let request_reader = message_reader.get_root()?;
            testcase.handle_request(request_reader, response)?;
        }

        {
            let mut writer: &mut [u8] = &mut response_bytes;
            compression.write_message(&mut writer, &mut message_res)?;
        }

        let mut response_bytes1: &[u8] = &response_bytes;
        let message_reader = compression.read_message(
            &mut response_bytes1,
            Default::default())?;

        let response_reader = message_reader.get_root()?;
        testcase.check_response(response_reader, expected)?;
    }
    Ok(())
}

fn server<C, S, T, R, W>(testcase: T, mut reuse: S, compression: C, iters: u64, mut input: R, mut output: W)
                         -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, R: io::Read, W: io::Write,
{
    let mut out_buffered = io::BufWriter::new(&mut output);
    let mut in_buffered = io::BufReader::new(&mut input);
    for _ in 0..iters {
        use std::io::Write;
        let (mut message_res, _) = reuse.get_builders();

        {
            let response = message_res.init_root();
            let message_reader = compression.read_message(
                &mut in_buffered,
                capnp::message::DEFAULT_READER_OPTIONS)?;
            let request_reader = message_reader.get_root()?;
            testcase.handle_request(request_reader, response)?;
        }

        compression.write_message(&mut out_buffered, &mut message_res)?;
        out_buffered.flush()?;
    }
    Ok(())
}

fn sync_client<C, S, T>(testcase: T, mut reuse: S, compression: C, iters: u64)
                        -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    let mut out_stream: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(1) };
    let mut in_stream: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(0) };
    let mut in_buffered = io::BufReader::new(&mut in_stream);
    let mut out_buffered = io::BufWriter::new(&mut out_stream);
    let mut rng = common::FastRand::new();
    for _ in 0..iters {
        use std::io::Write;
        let (mut message_req, _) = reuse.get_builders();

        let expected = {
            let request = message_req.init_root();
            testcase.setup_request(&mut rng, request)
        };
        compression.write_message(&mut out_buffered, &mut message_req)?;
        out_buffered.flush()?;

        let message_reader = compression.read_message(
            &mut in_buffered,
            Default::default())?;
        let response_reader = message_reader.get_root()?;
        testcase.check_response(response_reader, expected)?;
    }
    Ok(())
}

fn pass_by_pipe<C, S, T>(testcase: T, reuse: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    use std::{process, env};

    let mut args: Vec<String> = env::args().collect();
    args[2] = "client".to_string();

    let mut command = process::Command::new(&args[0]);
    command.args(&args[1..args.len()]);
    command.stdin(process::Stdio::piped());
    command.stdout(process::Stdio::piped());
    command.stderr(process::Stdio::null());
    match command.spawn() {
        Ok(ref mut p) => {
            let child_std_out = p.stdout.take().unwrap();
            let child_std_in = p.stdin.take().unwrap();
            server(testcase, reuse, compression, iters, child_std_out, child_std_in)?;
            println!("{}", p.wait().unwrap());
            Ok(())
        }
        Err(e) => {
            println!("could not start process: {}", e);
            Ok(())
        }
    }
}

pub enum Mode {
    Object,
    Bytes,
    Client,
    Server,
    Pipe,
}

impl Mode {
    pub fn parse(s: &str) -> ::capnp::Result<Mode> {
        match s {
            "object" => Ok(Mode::Object),
            "bytes" => Ok(Mode::Bytes),
            "client" => Ok(Mode::Client),
            "server" => Ok(Mode::Server),
            "pipe" => Ok(Mode::Pipe),
            s => Err(::capnp::Error::failed(format!("unrecognized mode: {}", s))),
        }
    }
}

fn do_testcase<C, S, T>(testcase: T, mode: Mode, reuse: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase,
{
    match mode {
        Mode::Object => pass_by_object(testcase, reuse, iters),
        Mode::Bytes => pass_by_bytes(testcase, reuse, compression, iters),
        Mode::Client => sync_client(testcase, reuse, compression, iters),
        Mode::Server => {
            let input: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(1) };
            let output: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(0) };
            server(testcase, reuse, compression, iters, input, output)
        }
        Mode::Pipe => pass_by_pipe(testcase, reuse, compression, iters),
    }
}

fn do_testcase1<C, S>(case: &str, mode: Mode, scratch: S, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize, S: for<'a> Scratch<'a>,
{
    match case {
        "carsales" => do_testcase(carsales::CarSales, mode, scratch, compression, iters),
        "catrank" => do_testcase(catrank::CatRank, mode, scratch, compression, iters),
        "eval" => do_testcase(eval::Eval, mode, scratch, compression, iters),
        s => Err(::capnp::Error::failed(format!("unrecognized test case: {}", s))),
    }
}

fn do_testcase2<C>(case: &str, mode: Mode, scratch: &str, compression: C, iters: u64) -> ::capnp::Result<()>
    where C: Serialize,
{
    match scratch {
        "no-reuse" => do_testcase1(case, mode, NoScratch, compression, iters),
        "reuse" => do_testcase1(case, mode, UseScratch::new(), compression, iters),
        s => Err(::capnp::Error::failed(format!("unrecognized reuse option: {}", s))),
    }
}

fn try_main() -> ::capnp::Result<()> {
    let args: Vec<String> = ::std::env::args().collect();

    assert!(args.len() == 6,
            "USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT",
            args[0]);

    let iters = match args[5].parse::<u64>() {
        Ok(n) => n,
        Err(_) =>
            return Err(::capnp::Error::failed(format!("Could not parse a u64 from: {}", args[5]))),
    };

    let mode = Mode::parse(&*args[2])?;

    match &*args[4] {
        "none" => do_testcase2(&*args[1], mode, &*args[3], NoCompression, iters),
        "packed" => do_testcase2(&*args[1], mode, &*args[3], Packed, iters),
        s => Err(::capnp::Error::failed(format!("unrecognized compression: {}", s))),
    }
}

pub fn main() {
    match try_main() {
        Ok(()) => (),
        Err(e) => {
            panic!("error: {:?}", e);
        }
    }
}
<|endoftext|>


<commit_before>//! Compound data types.

#![allow(non_snake_case)]

use Result;
use band::{Atom, Band, Blob};
use primitive::*;

macro_rules! itemize(
    ($code:item) => ($code);
);

macro_rules! compound(
    ($structure:ident { $($field:ident [$($kind:tt)+] $(|$this:ident| $body:block)*,)+ }) => (
        declare!($structure { $($field $($kind)+,)+ });
        implement!($structure { $($field [$($kind)+] $(|$this| $body)*,)+ });
    );
);

macro_rules! declare(
    ($structure:ident { $($field:ident $kind:ty,)+ }) => (
        itemize! {
            #[derive(Debug, Default)]
            pub struct $structure { $(pub $field: $kind,)+ }
        }
    );
);

macro_rules! implement(
    ($structure:ident { $($field:ident [$($kind:tt)+] $(|$this:ident| $body:block)*,)+ }) => (
        impl Blob for $structure {
            fn read<T: Band>(&mut self, band: &mut T) -> Result<()> {
                $(self.$field = read!($structure, self, band, $($kind)+ $(|$this| $body)*);)+
                Ok(())
            }
        }
    );
);

macro_rules! read(
    ($structure:ident, $this:ident, $band:ident, USHORT) => ({
        try!(Atom::read($band))
    });
    ($structure:ident, $this:ident, $band:ident, SHORT) => ({
        try!(Atom::read($band))
    });
    ($structure:ident, $this:ident, $band:ident, ULONG) => ({
        try!(Atom::read($band))
    });
    ($structure:ident, $this:ident, $band:ident, Fixed) => ({
        try!(Atom::read($band))
    });
    ($structure:ident, $this:ident, $band:ident, LONGDATETIME) => ({
        try!(Atom::read($band))
    });
    ($structure:ident, $this:ident, $band:ident, Vec<USHORT> |$that:ident| $body:block) => ({
        #[allow(unused_variables)]
        fn count($that: &$structure) -> usize $body
        let _ = count($this);
        vec![]
    });
    ($structure:ident, $this:ident, $band:ident, Vec<SHORT> |$that:ident| $body:block) => ({
        #[allow(unused_variables)]
        fn count($that: &$structure) -> usize $body
        let _ = count($this);
        vec![]
    });
);

compound!(OffsetTable {
    version       [Fixed ],
    numTables     [USHORT],
    searchRange   [USHORT],
    entrySelector [USHORT],
    rangeShift    [USHORT],
});

compound!(TableRecord {
    tag      [ULONG],
    checkSum [ULONG],
    offset   [ULONG],
    length   [ULONG],
});

compound!(CharMapHeader {
    version   [USHORT],
    numTables [USHORT],
});

compound!(EncodingRecord {
    platformID [USHORT],
    encodingID [USHORT],
    offset     [ULONG ],
});

compound!(CharMapFormat4 {
    format        [USHORT     ],
    length        [USHORT     ],
    language      [USHORT     ],
    segCountX2    [USHORT     ],
    searchRange   [USHORT     ],
    entrySelector [USHORT     ],
    rangeShift    [USHORT     ],
    endCount      [Vec<USHORT>] |this| { 0 },
    reservedPad   [USHORT     ],
    startCount    [Vec<USHORT>] |this| { 0 },
    idDelta       [Vec<SHORT> ] |this| { 0 },
    idRangeOffset [Vec<USHORT>] |this| { 0 },
    glyphIdArray  [Vec<USHORT>] |this| { 0 },
});

compound!(CharMapFormat6 {
    format       [USHORT     ],
    length       [USHORT     ],
    language     [USHORT     ],
    firstCode    [USHORT     ],
    entryCount   [USHORT     ],
    glyphIdArray [Vec<USHORT>] |this| { 0 },
});

compound!(FontHeader {
    version            [Fixed       ],
    fontRevision       [Fixed       ],
    checkSumAdjustment [ULONG       ],
    magicNumber        [ULONG       ],
    flags              [USHORT      ],
    unitsPerEm         [USHORT      ],
    created            [LONGDATETIME],
    modified           [LONGDATETIME],
    xMin               [SHORT       ],
    yMin               [SHORT       ],
    xMax               [SHORT       ],
    yMax               [SHORT       ],
    macStyle           [USHORT      ],
    lowestRecPPEM      [USHORT      ],
    fontDirectionHint  [SHORT       ],
    indexToLocFormat   [SHORT       ],
    glyphDataFormat    [SHORT       ],
});

pub enum MaxProfile {
    Version05(MaxProfileVersion05),
    Version10(MaxProfileVersion10),
}

compound!(MaxProfileVersion05 {
    version   [Fixed ],
    numGlyphs [USHORT],
});

compound!(MaxProfileVersion10 {
    version               [Fixed ],
    numGlyphs             [USHORT],
    maxPoints             [USHORT],
    maxContours           [USHORT],
    maxCompositePoints    [USHORT],
    maxCompositeContours  [USHORT],
    maxZones              [USHORT],
    maxTwilightPoints     [USHORT],
    maxStorage            [USHORT],
    maxFunctionDefs       [USHORT],
    maxInstructionDefs    [USHORT],
    maxStackElements      [USHORT],
    maxSizeOfInstructions [USHORT],
    maxComponentElements  [USHORT],
    maxComponentDepth     [USHORT],
});

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

    #[test]
    fn offset_table_read() {
        use band::Blob;
        use compound::OffsetTable;

        let mut file = tests::open("SourceSerifPro-Regular.otf");
        let mut table = OffsetTable::default();
        table.read(&mut file).unwrap();

        assert_eq!(table.version.0, 0x4f54544f);
        assert_eq!(table.numTables, 12);
        assert_eq!(table.searchRange, 8 * 16);
        assert_eq!(table.entrySelector, 3);
        assert_eq!(table.rangeShift, table.numTables * 16 - table.searchRange);
    }

    #[test]
    fn char_map_read() {
        use band::Blob;
        use compound::{CharMapHeader, EncodingRecord};
        use std::io::{Seek, SeekFrom};

        let mut file = tests::open("SourceSerifPro-Regular.otf");
        file.seek(SeekFrom::Start(15668)).unwrap();
        let mut header = CharMapHeader::default();
        header.read(&mut file).unwrap();

        assert_eq!(header.version, 0);
        assert_eq!(header.numTables, 3);

        let (platforms, encodings) = ([0, 1, 3], [3, 0, 1]);
        for i in 0..3 {
            let mut record = EncodingRecord::default();
            record.read(&mut file).unwrap();

            assert_eq!(record.platformID, platforms[i]);
            assert_eq!(record.encodingID, encodings[i]);
        }
    }
}
<commit_msg>Simplify read!<commit_after>//! Compound data types.

#![allow(non_snake_case)]

use Result;
use band::{Atom, Band, Blob};
use primitive::*;

macro_rules! itemize(
    ($code:item) => ($code);
);

macro_rules! compound(
    ($structure:ident { $($field:ident [$($kind:tt)+] $(|$this:ident| $body:block)*,)+ }) => (
        declare!($structure { $($field $($kind)+,)+ });
        implement!($structure { $($field [$($kind)+] $(|$this| $body)*,)+ });
    );
);

macro_rules! declare(
    ($structure:ident { $($field:ident $kind:ty,)+ }) => (
        itemize! {
            #[derive(Debug, Default)]
            pub struct $structure { $(pub $field: $kind,)+ }
        }
    );
);

macro_rules! implement(
    ($structure:ident { $($field:ident [$($kind:tt)+] $(|$this:ident| $body:block)*,)+ }) => (
        impl Blob for $structure {
            fn read<T: Band>(&mut self, band: &mut T) -> Result<()> {
                $(self.$field = read!($structure, self, band, $($kind)+ $(|$this| $body)*);)+
                Ok(())
            }
        }
    );
);

macro_rules! read(
    ($structure:ident, $this:ident, $band:ident, Vec<$kind:ty> |$that:ident| $body:block) => ({
        #[allow(unused_variables)]
        fn count($that: &$structure) -> usize $body
        let _ = count($this);
        vec![]
    });
    ($structure:ident, $this:ident, $band:ident, $kind:ty) => ({
        try!(Atom::read($band))
    });
);

compound!(OffsetTable {
    version       [Fixed ],
    numTables     [USHORT],
    searchRange   [USHORT],
    entrySelector [USHORT],
    rangeShift    [USHORT],
});

compound!(TableRecord {
    tag      [ULONG],
    checkSum [ULONG],
    offset   [ULONG],
    length   [ULONG],
});

compound!(CharMapHeader {
    version   [USHORT],
    numTables [USHORT],
});

compound!(EncodingRecord {
    platformID [USHORT],
    encodingID [USHORT],
    offset     [ULONG ],
});

compound!(CharMapFormat4 {
    format        [USHORT     ],
    length        [USHORT     ],
    language      [USHORT     ],
    segCountX2    [USHORT     ],
    searchRange   [USHORT     ],
    entrySelector [USHORT     ],
    rangeShift    [USHORT     ],
    endCount      [Vec<USHORT>] |this| { 0 },
    reservedPad   [USHORT     ],
    startCount    [Vec<USHORT>] |this| { 0 },
    idDelta       [Vec<SHORT> ] |this| { 0 },
    idRangeOffset [Vec<USHORT>] |this| { 0 },
    glyphIdArray  [Vec<USHORT>] |this| { 0 },
});

compound!(CharMapFormat6 {
    format       [USHORT     ],
    length       [USHORT     ],
    language     [USHORT     ],
    firstCode    [USHORT     ],
    entryCount   [USHORT     ],
    glyphIdArray [Vec<USHORT>] |this| { 0 },
});

compound!(FontHeader {
    version            [Fixed       ],
    fontRevision       [Fixed       ],
    checkSumAdjustment [ULONG       ],
    magicNumber        [ULONG       ],
    flags              [USHORT      ],
    unitsPerEm         [USHORT      ],
    created            [LONGDATETIME],
    modified           [LONGDATETIME],
    xMin               [SHORT       ],
    yMin               [SHORT       ],
    xMax               [SHORT       ],
    yMax               [SHORT       ],
    macStyle           [USHORT      ],
    lowestRecPPEM      [USHORT      ],
    fontDirectionHint  [SHORT       ],
    indexToLocFormat   [SHORT       ],
    glyphDataFormat    [SHORT       ],
});

pub enum MaxProfile {
    Version05(MaxProfileVersion05),
    Version10(MaxProfileVersion10),
}

compound!(MaxProfileVersion05 {
    version   [Fixed ],
    numGlyphs [USHORT],
});

compound!(MaxProfileVersion10 {
    version               [Fixed ],
    numGlyphs             [USHORT],
    maxPoints             [USHORT],
    maxContours           [USHORT],
    maxCompositePoints    [USHORT],
    maxCompositeContours  [USHORT],
    maxZones              [USHORT],
    maxTwilightPoints     [USHORT],
    maxStorage            [USHORT],
    maxFunctionDefs       [USHORT],
    maxInstructionDefs    [USHORT],
    maxStackElements      [USHORT],
    maxSizeOfInstructions [USHORT],
    maxComponentElements  [USHORT],
    maxComponentDepth     [USHORT],
});

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

    #[test]
    fn offset_table_read() {
        use band::Blob;
        use compound::OffsetTable;

        let mut file = tests::open("SourceSerifPro-Regular.otf");
        let mut table = OffsetTable::default();
        table.read(&mut file).unwrap();

        assert_eq!(table.version.0, 0x4f54544f);
        assert_eq!(table.numTables, 12);
        assert_eq!(table.searchRange, 8 * 16);
        assert_eq!(table.entrySelector, 3);
        assert_eq!(table.rangeShift, table.numTables * 16 - table.searchRange);
    }

    #[test]
    fn char_map_read() {
        use band::Blob;
        use compound::{CharMapHeader, EncodingRecord};
        use std::io::{Seek, SeekFrom};

        let mut file = tests::open("SourceSerifPro-Regular.otf");
        file.seek(SeekFrom::Start(15668)).unwrap();
        let mut header = CharMapHeader::default();
        header.read(&mut file).unwrap();

        assert_eq!(header.version, 0);
        assert_eq!(header.numTables, 3);

        let (platforms, encodings) = ([0, 1, 3], [3, 0, 1]);
        for i in 0..3 {
            let mut record = EncodingRecord::default();
            record.read(&mut file).unwrap();

            assert_eq!(record.platformID, platforms[i]);
            assert_eq!(record.encodingID, encodings[i]);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Rouille developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::io::Write;
use std::thread;

use time;

use Request;

/// RAII guard that ensures that a log entry corresponding to a request will be written.
///
/// # Example
///
/// ```no_run
/// rouille::start_server("localhost:80", move |request| {
///     let _entry = rouille::LogEntry::start(std::io::stdout(), request);
///
///     // process the request here
///
/// # panic!()
/// }); // <-- the log entry is written at the end of this block
/// ```
///
pub struct LogEntry<W> where W: Write {
    line: String,
    output: W,
    start_time: u64,
}

impl<'a, W> LogEntry<W> where W: Write {
    /// Starts a `LogEntry`.
    pub fn start(output: W, rq: &Request) -> LogEntry<W> {
        LogEntry {
            line: format!("{} {}", rq.method(), rq.raw_url()),
            output: output,
            start_time: time::precise_time_ns(),
        }
    }
}

impl<W> Drop for LogEntry<W> where W: Write {
    fn drop(&mut self) {
        write!(self.output, "{} - ", self.line).unwrap();

        if thread::panicking() {
            write!(self.output, " - PANIC!").unwrap();

        } else {
            let elapsed = time::precise_time_ns() - self.start_time;
            format_time(self.output.by_ref(), elapsed);
        }

        writeln!(self.output, "").unwrap();
    }
}

fn format_time<W>(mut out: W, time: u64) where W: Write {
    if time < 1_000 {
        write!(out, "{}ns", time).unwrap()
    } else if time < 1_000_000 {
        write!(out, "{:.1}us", time as f64 / 1_000.0).unwrap()
    } else if time < 1_000_000_000 {
        write!(out, "{:.1}ms", time as f64 / 1_000_000.0).unwrap()
    } else {
        write!(out, "{:.1}s", time as f64 / 1_000_000_000.0).unwrap()
    }
}
<commit_msg>Use std::time::Instant instead of time::precise_time_ns<commit_after>// Copyright (c) 2016 The Rouille developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::io::Write;
use std::thread;
use std::time::Duration;
use std::time::Instant;

use Request;

/// RAII guard that ensures that a log entry corresponding to a request will be written.
///
/// # Example
///
/// ```no_run
/// rouille::start_server("localhost:80", move |request| {
///     let _entry = rouille::LogEntry::start(std::io::stdout(), request);
///
///     // process the request here
///
/// # panic!()
/// }); // <-- the log entry is written at the end of this block
/// ```
///
pub struct LogEntry<W> where W: Write {
    line: String,
    output: W,
    start_time: Instant,
}

impl<'a, W> LogEntry<W> where W: Write {
    /// Starts a `LogEntry`.
    pub fn start(output: W, rq: &Request) -> LogEntry<W> {
        LogEntry {
            line: format!("{} {}", rq.method(), rq.raw_url()),
            output: output,
            start_time: Instant::now(),
        }
    }
}

impl<W> Drop for LogEntry<W> where W: Write {
    fn drop(&mut self) {
        write!(self.output, "{} - ", self.line).unwrap();

        if thread::panicking() {
            write!(self.output, " - PANIC!").unwrap();

        } else {
            format_time(self.output.by_ref(), self.start_time.elapsed());
        }

        writeln!(self.output, "").unwrap();
    }
}

fn format_time<W>(mut out: W, duration: Duration) where W: Write {
    let secs_part = match duration.as_secs().checked_mul(1_000_000_000) {
        Some(v) => v,
        None => {
            write!(out, "{}s", duration.as_secs() as f64).unwrap();
            return;
        }
    };

    let duration_in_ns = secs_part + duration.subsec_nanos() as u64;

    if duration_in_ns < 1_000 {
        write!(out, "{}ns", duration_in_ns).unwrap()
    } else if duration_in_ns < 1_000_000 {
        write!(out, "{:.1}us", duration_in_ns as f64 / 1_000.0).unwrap()
    } else if duration_in_ns < 1_000_000_000 {
        write!(out, "{:.1}ms", duration_in_ns as f64 / 1_000_000.0).unwrap()
    } else {
        write!(out, "{:.1}s", duration_in_ns as f64 / 1_000_000_000.0).unwrap()
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ops::*;

#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
pub struct Checked<T>(pub Option<T>);

impl<T> Checked<T> {
    pub fn new(x: T) -> Checked<T> {
        Checked(Some(x))
    }
}

impl<T: fmt::Debug> fmt::Debug for Checked<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            Some(ref x) => x.fmt(f),
            None => "overflow".fmt(f),
        }
    }
}

impl<T: fmt::Display> fmt::Display for Checked<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            Some(ref x) => x.fmt(f),
            None => "overflow".fmt(f),
        }
    }
}

impl<T> From<T> for Checked<T> {
    fn from(x: T) -> Checked<T> {
        Checked(Some(x))
    }
}

impl<T> From<Option<T>> for Checked<T> {
    fn from(x: Option<T>) -> Checked<T> {
        Checked(x)
    }
}

// I'd like to
// impl<T, U> From<U> where T: From<U> for Checked<T>
// in the obvious way, but that "conflicts" with the default impl From<T> for T.
// This would subsume both the above Froms.

macro_rules! sh_impl {
    ($t:ident, $f:ident) => {
        impl Shl<Checked<$f>> for Checked<$t> {
            type Output = Checked<$t>;

            fn shl(self, other: Checked<$f>) -> Checked<$t> {
                match (self.0, other.0) {
                    (Some(x), Some(y)) => Checked(x.checked_shl(y)),
                    _ => Checked(None),
                }
            }
        }

        impl Shl<$f> for Checked<$t> {
            type Output = Checked<$t>;

            fn shl(self, other: $f) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(x.checked_shl(other)),
                    None => Checked(None),
                }
            }
        }

        impl ShlAssign<$f> for Checked<$t> {
            fn shl_assign(&mut self, other: $f) {
                *self = *self << other;
            }
        }

        impl Shr<Checked<$f>> for Checked<$t> {
            type Output = Checked<$t>;

            fn shr(self, other: Checked<$f>) -> Checked<$t> {
                match (self.0, other.0) {
                    (Some(x), Some(y)) => Checked(x.checked_shr(y)),
                    _ => Checked(None),
                }
            }
        }

        impl Shr<$f> for Checked<$t> {
            type Output = Checked<$t>;

            fn shr(self, other: $f) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(x.checked_shr(other)),
                    None => Checked(None),
                }
            }
        }

        impl ShrAssign<$f> for Checked<$t> {
            fn shr_assign(&mut self, other: $f) {
                *self = *self >> other;
            }
        }
    };
}

macro_rules! sh_impl_all {
    ($($t:ident)*) => ($(
        // When checked_shX is added for other shift sizes, uncomment some of these.
        // sh_impl! { $t, u8 }
        // sh_impl! { $t, u16 }
        sh_impl! { $t, u32 }
        //sh_impl! { $t, u64 }
        //sh_impl! { $t, usize }

        //sh_impl! { $t, i8 }
        //sh_impl! { $t, i16 }
        //sh_impl! { $t, i32 }
        //sh_impl! { $t, i64 }
        //sh_impl! { $t, isize }
    )*)
}

sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
    (impl $imp:ident, $method:ident for $t:ty) => {
        impl<'a> $imp for &'a $t {
            type Output = <$t as $imp>::Output;

            fn $method(self) -> <$t as $imp>::Output {
                $imp::$method(*self)
            }
        }
    }
}

// implements binary operators "&T op U", "T op &U", "&T op &U"
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
        impl<'a> $imp<$u> for &'a $t {
            type Output = <$t as $imp<$u>>::Output;

            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
                $imp::$method(*self, other)
            }
        }

        impl<'a> $imp<&'a $u> for $t {
            type Output = <$t as $imp<$u>>::Output;

            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
                $imp::$method(self, *other)
            }
        }

        impl<'a, 'b> $imp<&'a $u> for &'b $t {
            type Output = <$t as $imp<$u>>::Output;

            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
                $imp::$method(*self, *other)
            }
        }
    }
}

macro_rules! checked_impl {
    ($($t:ty)*) => {
        $(
            impl Add for Checked<$t> {
                type Output = Checked<$t>;

                fn add(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(x.checked_add(y)),
                        _ => Checked(None),
                    }
                }
            }

            impl Add<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn add(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(x.checked_add(other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl Add, add for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl Add, add for Checked<$t>, $t }

            impl AddAssign for Checked<$t> {
                fn add_assign(&mut self, other: Checked<$t>) {
                    *self = *self + other;
                }
            }

            impl AddAssign<$t> for Checked<$t> {
                fn add_assign(&mut self, other: $t) {
                    *self = *self + other;
                }
            }

            impl Sub for Checked<$t> {
                type Output = Checked<$t>;

                fn sub(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(x.checked_sub(y)),
                        _ => Checked(None),
                    }
                }
            }

            impl Sub<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn sub(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(x.checked_sub(other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl Sub, sub for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl Sub, sub for Checked<$t>, $t }

            impl SubAssign for Checked<$t> {
                fn sub_assign(&mut self, other: Checked<$t>) {
                    *self = *self - other;
                }
            }

            impl SubAssign<$t> for Checked<$t> {
                fn sub_assign(&mut self, other: $t) {
                    *self = *self - other;
                }
            }

            impl Mul for Checked<$t> {
                type Output = Checked<$t>;

                fn mul(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(x.checked_mul(y)),
                        _ => Checked(None),
                    }
                }
            }

            impl Mul<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn mul(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(x.checked_mul(other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl Mul, mul for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl Mul, mul for Checked<$t>, $t }

            impl MulAssign for Checked<$t> {
                fn mul_assign(&mut self, other: Checked<$t>) {
                    *self = *self * other;
                }
            }

            impl MulAssign<$t> for Checked<$t> {
                fn mul_assign(&mut self, other: $t) {
                    *self = *self * other;
                }
            }

            impl Div for Checked<$t> {
                type Output = Checked<$t>;

                fn div(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(x.checked_div(y)),
                        _ => Checked(None),
                    }
                }
            }

            impl Div<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn div(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(x.checked_div(other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl Div, div for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl Div, div for Checked<$t>, $t }

            impl DivAssign for Checked<$t> {
                fn div_assign(&mut self, other: Checked<$t>) {
                    *self = *self / other;
                }
            }

            impl DivAssign<$t> for Checked<$t> {
                fn div_assign(&mut self, other: $t) {
                    *self = *self / other;
                }
            }

            impl Rem for Checked<$t> {
                type Output = Checked<$t>;

                fn rem(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(x.checked_rem(y)),
                        _ => Checked(None),
                    }
                }
            }

            impl Rem<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn rem(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(x.checked_rem(other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl Rem, rem for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl Rem, rem for Checked<$t>, $t }

            impl RemAssign for Checked<$t> {
                fn rem_assign(&mut self, other: Checked<$t>) {
                    *self = *self % other;
                }
            }

            impl RemAssign<$t> for Checked<$t> {
                fn rem_assign(&mut self, other: $t) {
                    *self = *self % other;
                }
            }

            impl Not for Checked<$t> {
                type Output = Checked<$t>;

                fn not(self) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(Some(!x)),
                        None => Checked(None)
                    }
                }
            }

            forward_ref_unop! { impl Not, not for Checked<$t> }

            impl BitXor for Checked<$t> {
                type Output = Checked<$t>;

                fn bitxor(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(Some(x ^ y)),
                        _ => Checked(None),
                    }
                }
            }

            impl BitXor<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn bitxor(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(Some(x ^ other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl BitXor, bitxor for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl BitXor, bitxor for Checked<$t>, $t }

            impl BitXorAssign for Checked<$t> {
                fn bitxor_assign(&mut self, other: Checked<$t>) {
                    *self = *self ^ other;
                }
            }

            impl BitXorAssign<$t> for Checked<$t> {
                fn bitxor_assign(&mut self, other: $t) {
                    *self = *self ^ other;
                }
            }

            impl BitOr for Checked<$t> {
                type Output = Checked<$t>;

                fn bitor(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(Some(x | y)),
                        _ => Checked(None),
                    }
                }
            }

            impl BitOr<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn bitor(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(Some(x | other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl BitOr, bitor for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl BitOr, bitor for Checked<$t>, $t }

            impl BitOrAssign for Checked<$t> {
                fn bitor_assign(&mut self, other: Checked<$t>) {
                    *self = *self | other;
                }
            }

            impl BitOrAssign<$t> for Checked<$t> {
                fn bitor_assign(&mut self, other: $t) {
                    *self = *self | other;
                }
            }

            impl BitAnd for Checked<$t> {
                type Output = Checked<$t>;

                fn bitand(self, other: Checked<$t>) -> Checked<$t> {
                    match (self.0, other.0) {
                        (Some(x), Some(y)) => Checked(Some(x & y)),
                        _ => Checked(None),
                    }
                }
            }

            impl BitAnd<$t> for Checked<$t> {
                type Output = Checked<$t>;

                fn bitand(self, other: $t) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(Some(x & other)),
                        _ => Checked(None),
                    }
                }
            }

            forward_ref_binop! { impl BitAnd, bitand for Checked<$t>, Checked<$t> }
            forward_ref_binop! { impl BitAnd, bitand for Checked<$t>, $t }

            impl BitAndAssign for Checked<$t> {
                fn bitand_assign(&mut self, other: Checked<$t>) {
                    *self = *self & other;
                }
            }

            impl BitAndAssign<$t> for Checked<$t> {
                fn bitand_assign(&mut self, other: $t) {
                    *self = *self & other;
                }
            }

            impl Neg for Checked<$t> {
                type Output = Checked<$t>;

                fn neg(self) -> Checked<$t> {
                    match self.0 {
                        Some(x) => Checked(x.checked_neg()),
                        None => Checked(None)
                    }
                }
            }

            forward_ref_unop! { impl Neg, neg for Checked<$t> }
        )*
    };
}

checked_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
<commit_msg>Add in trait implementations for the actual primitives, refactor with more macros<commit_after>use std::fmt;
use std::ops::*;

#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
pub struct Checked<T>(pub Option<T>);

impl<T> Checked<T> {
    pub fn new(x: T) -> Checked<T> {
        Checked(Some(x))
    }
}

impl<T: fmt::Debug> fmt::Debug for Checked<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            Some(ref x) => x.fmt(f),
            None => "overflow".fmt(f),
        }
    }
}

impl<T: fmt::Display> fmt::Display for Checked<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            Some(ref x) => x.fmt(f),
            None => "overflow".fmt(f),
        }
    }
}

impl<T> From<T> for Checked<T> {
    fn from(x: T) -> Checked<T> {
        Checked(Some(x))
    }
}

impl<T> From<Option<T>> for Checked<T> {
    fn from(x: Option<T>) -> Checked<T> {
        Checked(x)
    }
}

// I'd like to
// impl<T, U> From<U> where T: From<U> for Checked<T>
// in the obvious way, but that "conflicts" with the default impl From<T> for T.
// This would subsume both the above Froms.

// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
    (impl $imp:ident, $method:ident for $t:ty {}) => {
        impl<'a> $imp for &'a $t {
            type Output = <$t as $imp>::Output;

            fn $method(self) -> <$t as $imp>::Output {
                $imp::$method(*self)
            }
        }
    }
}

// implements binary operators "&T op U", "T op &U", "&T op &U"
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
    (impl $imp:ident, $method:ident for $t:ty, $u:ty {}) => {
        impl<'a> $imp<$u> for &'a $t {
            type Output = <$t as $imp<$u>>::Output;

            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
                $imp::$method(*self, other)
            }
        }

        impl<'a> $imp<&'a $u> for $t {
            type Output = <$t as $imp<$u>>::Output;

            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
                $imp::$method(self, *other)
            }
        }

        impl<'a, 'b> $imp<&'a $u> for &'b $t {
            type Output = <$t as $imp<$u>>::Output;

            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
                $imp::$method(*self, *other)
            }
        }
    }
}

macro_rules! sh_impl {
    ($t:ident, $f:ident) => {
        impl Shl<Checked<$f>> for Checked<$t> {
            type Output = Checked<$t>;

            fn shl(self, other: Checked<$f>) -> Checked<$t> {
                match (self.0, other.0) {
                    (Some(x), Some(y)) => Checked(x.checked_shl(y)),
                    _ => Checked(None),
                }
            }
        }

        impl Shl<$f> for Checked<$t> {
            type Output = Checked<$t>;

            fn shl(self, other: $f) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(x.checked_shl(other)),
                    None => Checked(None),
                }
            }
        }

        forward_ref_binop! { impl Shl, shl for Checked<$t>, Checked<$f> {} }
        forward_ref_binop! { impl Shl, shl for Checked<$t>, $f {} }

        impl ShlAssign<$f> for Checked<$t> {
            fn shl_assign(&mut self, other: $f) {
                *self = *self << other;
            }
        }

        impl Shr<Checked<$f>> for Checked<$t> {
            type Output = Checked<$t>;

            fn shr(self, other: Checked<$f>) -> Checked<$t> {
                match (self.0, other.0) {
                    (Some(x), Some(y)) => Checked(x.checked_shr(y)),
                    _ => Checked(None),
                }
            }
        }

        impl Shr<$f> for Checked<$t> {
            type Output = Checked<$t>;

            fn shr(self, other: $f) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(x.checked_shr(other)),
                    None => Checked(None),
                }
            }
        }

        forward_ref_binop! { impl Shr, shr for Checked<$t>, Checked<$f> {} }
        forward_ref_binop! { impl Shr, shr for Checked<$t>, $f {} }

        impl ShrAssign<$f> for Checked<$t> {
            fn shr_assign(&mut self, other: $f) {
                *self = *self >> other;
            }
        }
    };
}

macro_rules! sh_impl_reverse {
    ($t:ident, $f:ident) => {
        impl Shl<Checked<$t>> for $f {
            type Output = Checked<$f>;

            fn shl(self, other: Checked<$t>) -> Checked<$f> {
                match other.0 {
                    Some(x) => Checked(self.checked_shl(x)),
                    None => Checked(None),
                }
            }
        }

        forward_ref_binop! { impl Shl, shl for $f, Checked<$t> {} }

        impl Shr<Checked<$t>> for $f {
            type Output = Checked<$f>;

            fn shr(self, other: Checked<$t>) -> Checked<$f> {
                match other.0 {
                    Some(x) => Checked(self.checked_shr(x)),
                    None => Checked(None),
                }
            }
        }

        forward_ref_binop! { impl Shr, shr for $f, Checked<$t> {} }
    };
}

macro_rules! sh_impl_all {
    ($($t:ident)*) => ($(
        // When checked_shX is added for other shift sizes, uncomment some of these.
        // sh_impl! { $t, u8 }
        // sh_impl! { $t, u16 }
        sh_impl! { $t, u32 }
        //sh_impl! { $t, u64 }
        //sh_impl! { $t, usize }

        //sh_impl! { $t, i8 }
        //sh_impl! { $t, i16 }
        //sh_impl! { $t, i32 }
        //sh_impl! { $t, i64 }
        //sh_impl! { $t, isize }

        // sh_impl_reverse! { u8, $t }
        // sh_impl_reverse! { u16, $t }
        sh_impl_reverse! { u32, $t }
        //sh_impl_reverse! { u64, $t }
        //sh_impl_reverse! { usize, $t }

        //sh_impl_reverse! { i8, $t }
        //sh_impl_reverse! { i16, $t }
        //sh_impl_reverse! { i32, $t }
        //sh_impl_reverse! { i64, $t }
        //sh_impl_reverse! { isize, $t }
    )*)
}

sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

// implements unary operators for checked types
macro_rules! impl_unop {
    (impl $imp:ident, $method:ident, $checked_method:ident for $t:ty {}) => {
        impl $imp for Checked<$t> {
            type Output = Checked<$t>;

            fn $method(self) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(x.$checked_method()),
                    None => Checked(None)
                }
            }
        }

        forward_ref_unop! { impl $imp, $method for Checked<$t> {} }
    }
}

// implements unary operators for checked types (with no checked operation)
macro_rules! impl_unop_unchecked {
    (impl $imp:ident, $method:ident for $t:ty {$op:tt}) => {
        impl $imp for Checked<$t> {
            type Output = Checked<$t>;

            fn $method(self) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(Some($op x)),
                    None => Checked(None)
                }
            }
        }

        forward_ref_unop! { impl $imp, $method for Checked<$t> {} }
    }
}

// implements binary operators for checked types
macro_rules! impl_binop {
    (impl $imp:ident, $method:ident, $checked_method:ident for $t:ty {}) => {
        impl $imp for Checked<$t> {
            type Output = Checked<$t>;

            fn $method(self, other: Checked<$t>) -> Checked<$t> {
                match (self.0, other.0) {
                    (Some(x), Some(y)) => Checked(x.$checked_method(y)),
                    _ => Checked(None),
                }
            }
        }

        impl $imp<$t> for Checked<$t> {
            type Output = Checked<$t>;

            fn $method(self, other: $t) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(x.$checked_method(other)),
                    _ => Checked(None),
                }
            }
        }

        impl $imp<Checked<$t>> for $t {
            type Output = Checked<$t>;

            fn $method(self, other: Checked<$t>) -> Checked<$t> {
                match other.0 {
                    Some(x) => Checked(self.$checked_method(x)),
                    None => Checked(None),
                }
            }
        }

        forward_ref_binop! { impl $imp, $method for Checked<$t>, Checked<$t> {} }
        forward_ref_binop! { impl $imp, $method for Checked<$t>, $t {} }
        forward_ref_binop! { impl $imp, $method for $t, Checked<$t> {} }
    }
}

// implements binary operators for checked types (no checked operation)
macro_rules! impl_binop_unchecked {
    (impl $imp:ident, $method:ident for $t:ty {$op:tt}) => {
        impl $imp for Checked<$t> {
            type Output = Checked<$t>;

            fn $method(self, other: Checked<$t>) -> Checked<$t> {
                match (self.0, other.0) {
                    (Some(x), Some(y)) => Checked(Some(x $op y)),
                    _ => Checked(None),
                }
            }
        }

        impl $imp<$t> for Checked<$t> {
            type Output = Checked<$t>;

            fn $method(self, other: $t) -> Checked<$t> {
                match self.0 {
                    Some(x) => Checked(Some(x $op other)),
                    _ => Checked(None),
                }
            }
        }

        impl $imp<Checked<$t>> for $t {
            type Output = Checked<$t>;

            fn $method(self, other: Checked<$t>) -> Checked<$t> {
                match other.0 {
                    Some(x) => Checked(Some(self $op x)),
                    None => Checked(None),
                }
            }
        }

        forward_ref_binop! { impl $imp, $method for Checked<$t>, Checked<$t> {} }
        forward_ref_binop! { impl $imp, $method for Checked<$t>, $t {} }
        forward_ref_binop! { impl $imp, $method for $t, Checked<$t> {} }
    }
}

// implements assignment operators for checked types
macro_rules! impl_binop_assign {
    (impl $imp:ident, $method:ident for $t:ty {$op:tt}) => {
        impl $imp for Checked<$t> {
            fn $method(&mut self, other: Checked<$t>) {
                *self = *self $op other;
            }
        }

        impl $imp<$t> for Checked<$t> {
            fn $method(&mut self, other: $t) {
                *self = *self $op other;
            }
        }
    };
}

macro_rules! checked_impl {
    ($($t:ty)*) => {
        $(
            impl_binop! { impl Add, add, checked_add for $t {} }
            impl_binop_assign! { impl AddAssign, add_assign for $t {+} }
            impl_binop! { impl Sub, sub, checked_sub for $t {} }
            impl_binop_assign! { impl SubAssign, sub_assign for $t {-} }
            impl_binop! { impl Mul, mul, checked_mul for $t {} }
            impl_binop_assign! { impl MulAssign, mul_assign for $t {*} }
            impl_binop! { impl Div, div, checked_div for $t {} }
            impl_binop_assign! { impl DivAssign, div_assign for $t {/} }
            impl_binop! { impl Rem, rem, checked_rem for $t {} }
            impl_binop_assign! { impl RemAssign, rem_assign for $t {%} }
            impl_unop_unchecked! { impl Not, not for $t {!} }
            impl_binop_unchecked! { impl BitXor, bitxor for $t {^} }
            impl_binop_assign! { impl BitXorAssign, bitxor_assign for $t {^} }
            impl_binop_unchecked! { impl BitOr, bitor for $t {|} }
            impl_binop_assign! { impl BitOrAssign, bitor_assign for $t {|} }
            impl_binop_unchecked! { impl BitAnd, bitand for $t {&} }
            impl_binop_assign! { impl BitAndAssign, bitand_assign for $t {&} }
            impl_unop! { impl Neg, neg, checked_neg for $t {} }
        )*
    };
}

checked_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
<|endoftext|>


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

use futures::{future, stream, Async, Future, Poll, Stream};
use tokio::io::AsyncRead;

/// Stream of bytes.
pub struct ByteStream {
    size_hint: Option<usize>,
    inner: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>,
}

impl ByteStream {
    /// Create a new `ByteStreamy` by wrapping a `futures` stream.
    pub fn new<S>(stream: S) -> ByteStream
    where
        S: Stream<Item = Vec<u8>, Error = io::Error> + Send + 'static,
    {
        ByteStream {
            size_hint: None,
            inner: Box::new(stream),
        }
    }

    pub(crate) fn size_hint(&self) -> Option<usize> {
        self.size_hint
    }

    /// Return an implementation of `AsyncRead` that uses async i/o to consume the stream.
    pub fn into_async_read(self) -> impl AsyncRead + Send {
        ImplAsyncRead::new(self.inner)
    }

    /// Return an implementation of `Read` that uses blocking i/o to consume the stream.
    pub fn into_blocking_read(self) -> impl io::Read + Send {
        ImplBlockingRead::new(self.inner)
    }
}

impl From<Vec<u8>> for ByteStream {
    fn from(buf: Vec<u8>) -> ByteStream {
        ByteStream {
            size_hint: Some(buf.len()),
            inner: Box::new(stream::once(Ok(buf))),
        }
    }
}

impl fmt::Debug for ByteStream {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<ByteStream size_hint={:?}>", self.size_hint)
    }
}

impl Stream for ByteStream {
    type Item = Vec<u8>;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        self.inner.poll()
    }
}

struct ImplAsyncRead {
    buffer: io::Cursor<Vec<u8>>,
    stream: stream::Fuse<Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>>,
}

impl ImplAsyncRead {
    fn new(stream: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>) -> Self {
        ImplAsyncRead {
            buffer: io::Cursor::new(Vec::new()),
            stream: stream.fuse(),
        }
    }
}

impl io::Read for ImplAsyncRead {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.len() == 0 {
            return Ok(0);
        }
        loop {
            let n = self.buffer.read(buf)?;
            if n > 0 {
                return Ok(n);
            }
            match self.stream.poll()? {
                Async::NotReady => {
                    return Err(io::ErrorKind::WouldBlock.into());
                }
                Async::Ready(Some(buffer)) => {
                    self.buffer = io::Cursor::new(buffer);
                    continue;
                }
                Async::Ready(None) => {
                    return Ok(0);
                }
            }
        }
    }
}

impl AsyncRead for ImplAsyncRead {}

struct ImplBlockingRead {
    inner: ImplAsyncRead,
}

impl ImplBlockingRead {
    fn new(stream: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>) -> Self {
        ImplBlockingRead {
            inner: ImplAsyncRead::new(stream),
        }
    }
}

impl io::Read for ImplBlockingRead {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        future::poll_fn(|| self.inner.poll_read(buf)).wait()
    }
}

#[test]
fn test_async_read() {
    use std::io::Read;

    let chunks = vec![b"1234".to_vec(), b"5678".to_vec()];
    let stream = ByteStream::new(stream::iter_ok(chunks));
    let mut async_read = stream.into_async_read();

    let mut buf = [0u8; 3];
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"123");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"4");
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"567");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"8");
    assert_eq!(async_read.read(&mut buf).unwrap(), 0);
}

#[test]
fn test_blocking_read() {
    use std::io::Read;

    let chunks = vec![b"1234".to_vec(), b"5678".to_vec()];
    let stream = ByteStream::new(stream::iter_ok(chunks));
    let mut async_read = stream.into_blocking_read();

    let mut buf = [0u8; 3];
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"123");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"4");
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"567");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"8");
    assert_eq!(async_read.read(&mut buf).unwrap(), 0);
}
<commit_msg>Remove y<commit_after>use std::fmt;
use std::io;

use futures::{future, stream, Async, Future, Poll, Stream};
use tokio::io::AsyncRead;

/// Stream of bytes.
pub struct ByteStream {
    size_hint: Option<usize>,
    inner: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>,
}

impl ByteStream {
    /// Create a new `ByteStream` by wrapping a `futures` stream.
    pub fn new<S>(stream: S) -> ByteStream
    where
        S: Stream<Item = Vec<u8>, Error = io::Error> + Send + 'static,
    {
        ByteStream {
            size_hint: None,
            inner: Box::new(stream),
        }
    }

    pub(crate) fn size_hint(&self) -> Option<usize> {
        self.size_hint
    }

    /// Return an implementation of `AsyncRead` that uses async i/o to consume the stream.
    pub fn into_async_read(self) -> impl AsyncRead + Send {
        ImplAsyncRead::new(self.inner)
    }

    /// Return an implementation of `Read` that uses blocking i/o to consume the stream.
    pub fn into_blocking_read(self) -> impl io::Read + Send {
        ImplBlockingRead::new(self.inner)
    }
}

impl From<Vec<u8>> for ByteStream {
    fn from(buf: Vec<u8>) -> ByteStream {
        ByteStream {
            size_hint: Some(buf.len()),
            inner: Box::new(stream::once(Ok(buf))),
        }
    }
}

impl fmt::Debug for ByteStream {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<ByteStream size_hint={:?}>", self.size_hint)
    }
}

impl Stream for ByteStream {
    type Item = Vec<u8>;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        self.inner.poll()
    }
}

struct ImplAsyncRead {
    buffer: io::Cursor<Vec<u8>>,
    stream: stream::Fuse<Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>>,
}

impl ImplAsyncRead {
    fn new(stream: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>) -> Self {
        ImplAsyncRead {
            buffer: io::Cursor::new(Vec::new()),
            stream: stream.fuse(),
        }
    }
}

impl io::Read for ImplAsyncRead {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.len() == 0 {
            return Ok(0);
        }
        loop {
            let n = self.buffer.read(buf)?;
            if n > 0 {
                return Ok(n);
            }
            match self.stream.poll()? {
                Async::NotReady => {
                    return Err(io::ErrorKind::WouldBlock.into());
                }
                Async::Ready(Some(buffer)) => {
                    self.buffer = io::Cursor::new(buffer);
                    continue;
                }
                Async::Ready(None) => {
                    return Ok(0);
                }
            }
        }
    }
}

impl AsyncRead for ImplAsyncRead {}

struct ImplBlockingRead {
    inner: ImplAsyncRead,
}

impl ImplBlockingRead {
    fn new(stream: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>) -> Self {
        ImplBlockingRead {
            inner: ImplAsyncRead::new(stream),
        }
    }
}

impl io::Read for ImplBlockingRead {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        future::poll_fn(|| self.inner.poll_read(buf)).wait()
    }
}

#[test]
fn test_async_read() {
    use std::io::Read;

    let chunks = vec![b"1234".to_vec(), b"5678".to_vec()];
    let stream = ByteStream::new(stream::iter_ok(chunks));
    let mut async_read = stream.into_async_read();

    let mut buf = [0u8; 3];
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"123");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"4");
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"567");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"8");
    assert_eq!(async_read.read(&mut buf).unwrap(), 0);
}

#[test]
fn test_blocking_read() {
    use std::io::Read;

    let chunks = vec![b"1234".to_vec(), b"5678".to_vec()];
    let stream = ByteStream::new(stream::iter_ok(chunks));
    let mut async_read = stream.into_blocking_read();

    let mut buf = [0u8; 3];
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"123");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"4");
    assert_eq!(async_read.read(&mut buf).unwrap(), 3);
    assert_eq!(&buf[..3], b"567");
    assert_eq!(async_read.read(&mut buf).unwrap(), 1);
    assert_eq!(&buf[..1], b"8");
    assert_eq!(async_read.read(&mut buf).unwrap(), 0);
}
<|endoftext|>


<commit_before>//! LR(1) interpeter. Just builds up parse trees. Intended for testing.

use lr1::core::*;
use lr1::lookahead::Token;
use generate::ParseTree;
use grammar::repr::*;
use std::iter::IntoIterator;
use std::fmt::{Debug, Display, Formatter, Error};
use util::Sep;

pub type InterpretError<'grammar> = (&'grammar LR1State<'grammar>, Token);

/// Feed in the given tokens and then EOF, returning the final parse tree that is reduced.
pub fn interpret<'grammar,TOKENS>(states: &'grammar [LR1State<'grammar>], tokens: TOKENS)
                         -> Result<ParseTree, InterpretError<'grammar>>
    where TOKENS: IntoIterator<Item=TerminalString>
{
    let mut m = Machine::new(states);
    m.execute(tokens.into_iter())
}

/// Feed in the given tokens and returns the states on the stack.
pub fn interpret_partial<'grammar,TOKENS>(states: &'grammar [LR1State<'grammar>],
                                          tokens: TOKENS)
                                          -> Result<Vec<StateIndex>,
                                                    InterpretError<'grammar>>
    where TOKENS: IntoIterator<Item=TerminalString>
{
    let mut m = Machine::new(states);
    try!(m.execute_partial(tokens.into_iter()));
    Ok(m.state_stack)
}

struct Machine<'grammar> {
    states: &'grammar [LR1State<'grammar>],
    state_stack: Vec<StateIndex>,
    data_stack: Vec<ParseTree>,
}

impl<'grammar> Machine<'grammar> {
    fn new(states: &'grammar [LR1State<'grammar>]) -> Machine<'grammar> {
        Machine { states: states,
                  state_stack: vec![],
                  data_stack: vec![] }
    }

    fn top_state(&self) -> &'grammar LR1State<'grammar> {
        let index = self.state_stack.last().unwrap();
        &self.states[index.0]
    }

    fn execute_partial<TOKENS>(&mut self, mut tokens: TOKENS)
                               -> Result<(), InterpretError<'grammar>>
        where TOKENS: Iterator<Item=TerminalString>
    {
        assert!(self.state_stack.is_empty());
        assert!(self.data_stack.is_empty());

        self.state_stack.push(StateIndex(0));

        let mut token = tokens.next();
        while let Some(terminal) = token {
            let state = self.top_state();

            // check whether we can shift this token
            if let Some(&next_index) = state.shifts.get(&terminal) {
                self.data_stack.push(ParseTree::Terminal(terminal));
                self.state_stack.push(next_index);
                token = tokens.next();
            } else if let Some(&production) = state.reductions.get(&Token::Terminal(terminal)) {
                let more = self.reduce(production);
                assert!(more);
            } else {
                return Err((state, Token::Terminal(terminal)));
            }
        }

        Ok(())
    }

    fn execute<TOKENS>(&mut self, tokens: TOKENS)
                           -> Result<ParseTree, InterpretError<'grammar>>
        where TOKENS: Iterator<Item=TerminalString>
    {
        try!(self.execute_partial(tokens));

        // drain now for EOF
        loop {
            let state = self.top_state();
            match state.reductions.get(&Token::EOF) {
                None => { return Err((state, Token::EOF)); }
                Some(&production) => {
                    if !self.reduce(production) {
                        assert_eq!(self.data_stack.len(), 1);
                        return Ok(self.data_stack.pop().unwrap());
                    }
                }
            }
        }
    }

    fn reduce(&mut self, production: &Production) -> bool {
        let args = production.symbols.len();

        // remove the top N items from the data stack
        let mut popped = vec![];
        for _ in 0 .. args {
            popped.push(self.data_stack.pop().unwrap());
        }
        popped.reverse();

        // remove the top N states
        for _ in 0 .. args {
            self.state_stack.pop().unwrap();
        }

        // construct the new, reduced tree and push it on the stack
        let tree = ParseTree::Nonterminal(production.nonterminal, popped);
        self.data_stack.push(tree);

        // recover the state and extract the "Goto" action
        let receiving_state = self.top_state();
        match receiving_state.gotos.get(&production.nonterminal) {
            Some(&goto_state) => {
                self.state_stack.push(goto_state);
                true // keep going
            }
            None => {
                false // all done
            }
        }
    }
}

impl Debug for ParseTree {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        Display::fmt(self, fmt)
    }
}

impl Display for ParseTree {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        match *self {
            ParseTree::Nonterminal(id, ref trees) => write!(fmt, "[{}: {}]", id, Sep(", ", trees)),
            ParseTree::Terminal(id) => write!(fmt, "{}", id),
        }
    }
}
<commit_msg>generalize interpreter to work for LR(0)<commit_after>//! LR(1) interpeter. Just builds up parse trees. Intended for testing.

use lr1::core::*;
use lr1::lookahead::*;
use generate::ParseTree;
use grammar::repr::*;
use std::iter::IntoIterator;
use std::fmt::{Debug, Display, Formatter, Error};
use util::Sep;

pub type InterpretError<'grammar, L> = (&'grammar State<'grammar, L>, Token);

/// Feed in the given tokens and then EOF, returning the final parse tree that is reduced.
pub fn interpret<'grammar, TOKENS, L>(states: &'grammar [State<'grammar, L>],
                                      tokens: TOKENS)
                                      -> Result<ParseTree, InterpretError<'grammar, L>>
    where TOKENS: IntoIterator<Item = TerminalString>,
          L: LookaheadInterpret
{
    let mut m = Machine::new(states);
    m.execute(tokens.into_iter())
}

/// Feed in the given tokens and returns the states on the stack.
pub fn interpret_partial<'grammar, TOKENS, L>
    (states: &'grammar [State<'grammar, L>],
     tokens: TOKENS)
     -> Result<Vec<StateIndex>, InterpretError<'grammar, L>>
    where TOKENS: IntoIterator<Item = TerminalString>,
          L: LookaheadInterpret
{
    let mut m = Machine::new(states);
    try!(m.execute_partial(tokens.into_iter()));
    Ok(m.state_stack)
}

struct Machine<'grammar, L: LookaheadInterpret + 'grammar> {
    states: &'grammar [State<'grammar, L>],
    state_stack: Vec<StateIndex>,
    data_stack: Vec<ParseTree>,
}

impl<'grammar, L> Machine<'grammar, L>
    where L: LookaheadInterpret
{
    fn new(states: &'grammar [State<'grammar, L>]) -> Machine<'grammar, L> {
        Machine {
            states: states,
            state_stack: vec![],
            data_stack: vec![],
        }
    }

    fn top_state(&self) -> &'grammar State<'grammar, L> {
        let index = self.state_stack.last().unwrap();
        &self.states[index.0]
    }

    fn execute_partial<TOKENS>(&mut self,
                               mut tokens: TOKENS)
                               -> Result<(), InterpretError<'grammar, L>>
        where TOKENS: Iterator<Item = TerminalString>
    {
        assert!(self.state_stack.is_empty());
        assert!(self.data_stack.is_empty());

        self.state_stack.push(StateIndex(0));

        let mut token = tokens.next();
        while let Some(terminal) = token {
            let state = self.top_state();

            // check whether we can shift this token
            if let Some(&next_index) = state.shifts.get(&terminal) {
                self.data_stack.push(ParseTree::Terminal(terminal));
                self.state_stack.push(next_index);
                token = tokens.next();
            } else if let Some(production) = L::reduction(state, Token::Terminal(terminal)) {
                let more = self.reduce(production);
                assert!(more);
            } else {
                return Err((state, Token::Terminal(terminal)));
            }
        }

        Ok(())
    }

    fn execute<TOKENS>(&mut self, tokens: TOKENS) -> Result<ParseTree, InterpretError<'grammar, L>>
        where TOKENS: Iterator<Item = TerminalString>
    {
        try!(self.execute_partial(tokens));

        // drain now for EOF
        loop {
            let state = self.top_state();
            match L::reduction(state, Token::EOF) {
                None => {
                    return Err((state, Token::EOF));
                }
                Some(production) => {
                    if !self.reduce(production) {
                        assert_eq!(self.data_stack.len(), 1);
                        return Ok(self.data_stack.pop().unwrap());
                    }
                }
            }
        }
    }

    fn reduce(&mut self, production: &Production) -> bool {
        let args = production.symbols.len();

        // remove the top N items from the data stack
        let mut popped = vec![];
        for _ in 0..args {
            popped.push(self.data_stack.pop().unwrap());
        }
        popped.reverse();

        // remove the top N states
        for _ in 0..args {
            self.state_stack.pop().unwrap();
        }

        // construct the new, reduced tree and push it on the stack
        let tree = ParseTree::Nonterminal(production.nonterminal, popped);
        self.data_stack.push(tree);

        // recover the state and extract the "Goto" action
        let receiving_state = self.top_state();
        match receiving_state.gotos.get(&production.nonterminal) {
            Some(&goto_state) => {
                self.state_stack.push(goto_state);
                true // keep going
            }
            None => {
                false // all done
            }
        }
    }
}

impl Debug for ParseTree {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        Display::fmt(self, fmt)
    }
}

impl Display for ParseTree {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        match *self {
            ParseTree::Nonterminal(id, ref trees) => write!(fmt, "[{}: {}]", id, Sep(", ", trees)),
            ParseTree::Terminal(id) => write!(fmt, "{}", id),
        }
    }
}

pub trait LookaheadInterpret: Lookahead {
    fn reduction<'grammar>(state: &State<'grammar, Self>,
                           token: Token)
                           -> Option<&'grammar Production>;
}

impl LookaheadInterpret for Nil {
    fn reduction<'grammar>(state: &State<'grammar, Self>,
                           token: Token)
                           -> Option<&'grammar Production> {
        state.reductions.values().next().cloned()
    }
}

impl LookaheadInterpret for Token {
    fn reduction<'grammar>(state: &State<'grammar, Self>,
                           token: Token)
                           -> Option<&'grammar Production> {
        state.reductions.get(&token).cloned()
    }
}
<|endoftext|>