<commit_before>use api::join;
use std;
use super::ParallelIterator;
use super::len::{ParallelLen, THRESHOLD};
use super::state::ParallelIteratorState;

/// Specifies a "reduce operator". This is the combination of a start
/// value and a reduce function. The reduce function takes two items
/// and computes a reduced version. The start value `S` is a kind of
/// "zero" or "identity" value that may be intermingled as needed;
/// idealy, `reduce(S, X)` for any item `X` yields `X`.
///
/// Example: to sum up the values, use a `start_value` of `0` and a
/// reduce function of `reduce(a, b) = a + b`.
///
/// The order in which the reduce function will be applied is not
/// specified. For example, the input `[ 0 1 2 ]` might be reduced in a
/// sequential fashion:
///
/// ```ignore
/// reduce(reduce(reduce(S, 0), 1), 2)
/// ```
///
/// or it might be reduced in a tree-like way:
///
/// ```ignore
/// reduce(reduce(0, 1), reduce(S, 2))
/// ```
///
/// etc.
pub trait ReduceOp<T>: Sync {
    fn start_value(&self) -> T;
    fn reduce(&self, value1: T, value2: T) -> T;
}

pub fn reduce<PAR_ITER,REDUCE_OP,T>(pi: PAR_ITER, reduce_op: &REDUCE_OP) -> T
    where PAR_ITER: ParallelIterator<Item=T>,
          PAR_ITER::State: Send,
          REDUCE_OP: ReduceOp<T>,
          T: Send,
{
    let (shared, mut state) = pi.state();
    let len = state.len(&shared);
    reduce_helper(state, &shared, len, reduce_op)
}

fn reduce_helper<STATE,REDUCE_OP,T>(mut state: STATE,
                                    shared: &STATE::Shared,
                                    len: ParallelLen,
                                    reduce_op: &REDUCE_OP)
                                    -> T
    where STATE: ParallelIteratorState<Item=T> + Send,
          REDUCE_OP: ReduceOp<T>,
          T: Send,
{
    if len.cost > THRESHOLD && len.maximal_len > 1 {
        let mid = len.maximal_len / 2;
        let (left, right) = state.split_at(mid);
        let (left_val, right_val) =
            join(|| reduce_helper(left, shared, len.left_cost(mid), reduce_op),
                 || reduce_helper(right, shared, len.right_cost(mid), reduce_op));
        reduce_op.reduce(left_val, right_val)
    } else {
        let mut value = Some(reduce_op.start_value());
        while let Some(item) = state.next(shared) {
            value = Some(reduce_op.reduce(value.take().unwrap(), item));
        }
        value.unwrap()
    }
}

pub struct SumOp;

pub const SUM: &'static SumOp = &SumOp;

macro_rules! sum_rule {
    ($i:ty, $z:expr) => {
        impl ReduceOp<$i> for SumOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                value1 + value2
            }
        }
    }
}

sum_rule!(i8, 0);
sum_rule!(i16, 0);
sum_rule!(i32, 0);
sum_rule!(i64, 0);
sum_rule!(isize, 0);
sum_rule!(u8, 0);
sum_rule!(u16, 0);
sum_rule!(u32, 0);
sum_rule!(u64, 0);
sum_rule!(usize, 0);
sum_rule!(f32, 0.0);
sum_rule!(f64, 0.0);

pub struct MulOp;

pub const MUL: &'static MulOp = &MulOp;

macro_rules! mul_rule {
    ($i:ty, $z:expr) => {
        impl ReduceOp<$i> for MulOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                value1 * value2
            }
        }
    }
}

mul_rule!(i8, 1);
mul_rule!(i16, 1);
mul_rule!(i32, 1);
mul_rule!(i64, 1);
mul_rule!(isize, 1);
mul_rule!(u8, 1);
mul_rule!(u16, 1);
mul_rule!(u32, 1);
mul_rule!(u64, 1);
mul_rule!(usize, 1);
mul_rule!(f32, 1.0);
mul_rule!(f64, 1.0);

pub struct MinOp;

pub const MIN: &'static MinOp = &MinOp;

macro_rules! min_rule {
    ($i:ty, $z:expr, $f:expr) => {
        impl ReduceOp<$i> for MinOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                $f(value1, value2)
            }
        }
    }
}

min_rule!(i8, std::i8::MAX, std::cmp::min);
min_rule!(i16, std::i16::MAX, std::cmp::min);
min_rule!(i32, std::i32::MAX, std::cmp::min);
min_rule!(i64, std::i64::MAX, std::cmp::min);
min_rule!(isize, std::isize::MAX, std::cmp::min);
min_rule!(u8, std::u8::MAX, std::cmp::min);
min_rule!(u16, std::u16::MAX, std::cmp::min);
min_rule!(u32, std::u32::MAX, std::cmp::min);
min_rule!(u64, std::u64::MAX, std::cmp::min);
min_rule!(usize, std::usize::MAX, std::cmp::min);
min_rule!(f32, std::f32::INFINITY, f32::min);
min_rule!(f64, std::f64::INFINITY, f64::min);

pub struct MaxOp;

pub const MAX: &'static MaxOp = &MaxOp;

macro_rules! max_rule {
    ($i:ty, $z:expr, $f:expr) => {
        impl ReduceOp<$i> for MaxOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                $f(value1, value2)
            }
        }
    }
}

max_rule!(i8, std::i8::MIN, std::cmp::max);
max_rule!(i16, std::i16::MIN, std::cmp::max);
max_rule!(i32, std::i32::MIN, std::cmp::max);
max_rule!(i64, std::i64::MIN, std::cmp::max);
max_rule!(isize, std::isize::MIN, std::cmp::max);
max_rule!(u8, std::u8::MIN, std::cmp::max);
max_rule!(u16, std::u16::MIN, std::cmp::max);
max_rule!(u32, std::u32::MIN, std::cmp::max);
max_rule!(u64, std::u64::MIN, std::cmp::max);
max_rule!(usize, std::usize::MIN, std::cmp::max);
max_rule!(f32, std::f32::NEG_INFINITY, f32::max);
max_rule!(f64, std::f64::NEG_INFINITY, f64::max);

pub struct ReduceWithOp<OP> {
    op: OP
}

impl<OP> ReduceWithOp<OP> {
    pub fn new(op: OP) -> ReduceWithOp<OP> {
        ReduceWithOp {
            op: op
        }
    }
}

impl<ITEM,OP> ReduceOp<Option<ITEM>> for ReduceWithOp<OP>
    where OP: Fn(ITEM, ITEM) -> ITEM + Sync
{
    fn start_value(&self) -> Option<ITEM> {
        None
    }

    fn reduce(&self, value1: Option<ITEM>, value2: Option<ITEM>) -> Option<ITEM> {
        if let Some(value1) = value1 {
            if let Some(value2) = value2 {
                Some((self.op)(value1, value2))
            } else {
                Some(value1)
            }
        } else {
            value2
        }
    }
}
<commit_msg>Add reduce consumer implementation<commit_after>use api::join;
use std;
use std::marker::PhantomData;
use super::ParallelIterator;
use super::len::{ParallelLen, THRESHOLD};
use super::state::*;

/// Specifies a "reduce operator". This is the combination of a start
/// value and a reduce function. The reduce function takes two items
/// and computes a reduced version. The start value `S` is a kind of
/// "zero" or "identity" value that may be intermingled as needed;
/// idealy, `reduce(S, X)` for any item `X` yields `X`.
///
/// Example: to sum up the values, use a `start_value` of `0` and a
/// reduce function of `reduce(a, b) = a + b`.
///
/// The order in which the reduce function will be applied is not
/// specified. For example, the input `[ 0 1 2 ]` might be reduced in a
/// sequential fashion:
///
/// ```ignore
/// reduce(reduce(reduce(S, 0), 1), 2)
/// ```
///
/// or it might be reduced in a tree-like way:
///
/// ```ignore
/// reduce(reduce(0, 1), reduce(S, 2))
/// ```
///
/// etc.
pub trait ReduceOp<T>: Sync {
    fn start_value(&self) -> T;
    fn reduce(&self, value1: T, value2: T) -> T;
}

pub fn reduce<PAR_ITER,REDUCE_OP,T>(pi: PAR_ITER, reduce_op: &REDUCE_OP) -> T
    where PAR_ITER: ParallelIterator<Item=T>,
          PAR_ITER::State: Send,
          REDUCE_OP: ReduceOp<T>,
          T: Send,
{
    let (shared, mut state) = pi.state();
    let len = state.len(&shared);
    reduce_helper(state, &shared, len, reduce_op)
}

fn reduce_helper<STATE,REDUCE_OP,T>(mut state: STATE,
                                    shared: &STATE::Shared,
                                    len: ParallelLen,
                                    reduce_op: &REDUCE_OP)
                                    -> T
    where STATE: ParallelIteratorState<Item=T> + Send,
          REDUCE_OP: ReduceOp<T>,
          T: Send,
{
    if len.cost > THRESHOLD && len.maximal_len > 1 {
        let mid = len.maximal_len / 2;
        let (left, right) = state.split_at(mid);
        let (left_val, right_val) =
            join(|| reduce_helper(left, shared, len.left_cost(mid), reduce_op),
                 || reduce_helper(right, shared, len.right_cost(mid), reduce_op));
        reduce_op.reduce(left_val, right_val)
    } else {
        let mut value = Some(reduce_op.start_value());
        while let Some(item) = state.next(shared) {
            value = Some(reduce_op.reduce(value.take().unwrap(), item));
        }
        value.unwrap()
    }
}

#[doc(hidden)]
pub struct ReduceConsumer<PAR_ITER, REDUCE_OP>
    where PAR_ITER: ParallelIterator,
          REDUCE_OP: ReduceOp<PAR_ITER::Item>,
{
    data: PhantomData<(PAR_ITER, REDUCE_OP)>
}

impl<PAR_ITER, REDUCE_OP> ReduceConsumer<PAR_ITER, REDUCE_OP>
    where PAR_ITER: ParallelIterator,
          REDUCE_OP: ReduceOp<PAR_ITER::Item>,
{
    fn new() -> ReduceConsumer<PAR_ITER, REDUCE_OP> {
        ReduceConsumer { data: PhantomData }
    }
}

unsafe impl<PAR_ITER, REDUCE_OP> Send for ReduceConsumer<PAR_ITER, REDUCE_OP>
    where PAR_ITER: ParallelIterator,
          REDUCE_OP: ReduceOp<PAR_ITER::Item>,
{ }

impl<PAR_ITER, REDUCE_OP> Consumer for ReduceConsumer<PAR_ITER, REDUCE_OP>
    where PAR_ITER: ParallelIterator,
          REDUCE_OP: ReduceOp<PAR_ITER::Item>,
{
    type Item = PAR_ITER::Item;
    type Shared = REDUCE_OP;
    type SeqState = PAR_ITER::Item;
    type Result = PAR_ITER::Item;
    type Left = Self;
    type Right = Self;

    unsafe fn split_at(self, _index: u64) -> (Self, Self) {
        (ReduceConsumer::new(), ReduceConsumer::new())
    }

    unsafe fn start(&mut self, reduce_op: &REDUCE_OP) -> PAR_ITER::Item {
        reduce_op.start_value()
    }

    unsafe fn consume(&mut self,
                      reduce_op: &REDUCE_OP,
                      prev_value: PAR_ITER::Item,
                      item: PAR_ITER::Item)
                      -> PAR_ITER::Item {
        reduce_op.reduce(prev_value, item)
    }

    unsafe fn complete(self,
                       _reduce_op: &REDUCE_OP,
                       state: PAR_ITER::Item)
                       -> PAR_ITER::Item {
        state
    }

    unsafe fn reduce(reduce_op: &REDUCE_OP,
                     a: PAR_ITER::Item,
                     b: PAR_ITER::Item)
                     -> PAR_ITER::Item {
        reduce_op.reduce(a, b)
    }
}

///////////////////////////////////////////////////////////////////////////
// Specific operations

pub struct SumOp;

pub const SUM: &'static SumOp = &SumOp;

macro_rules! sum_rule {
    ($i:ty, $z:expr) => {
        impl ReduceOp<$i> for SumOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                value1 + value2
            }
        }
    }
}

sum_rule!(i8, 0);
sum_rule!(i16, 0);
sum_rule!(i32, 0);
sum_rule!(i64, 0);
sum_rule!(isize, 0);
sum_rule!(u8, 0);
sum_rule!(u16, 0);
sum_rule!(u32, 0);
sum_rule!(u64, 0);
sum_rule!(usize, 0);
sum_rule!(f32, 0.0);
sum_rule!(f64, 0.0);

pub struct MulOp;

pub const MUL: &'static MulOp = &MulOp;

macro_rules! mul_rule {
    ($i:ty, $z:expr) => {
        impl ReduceOp<$i> for MulOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                value1 * value2
            }
        }
    }
}

mul_rule!(i8, 1);
mul_rule!(i16, 1);
mul_rule!(i32, 1);
mul_rule!(i64, 1);
mul_rule!(isize, 1);
mul_rule!(u8, 1);
mul_rule!(u16, 1);
mul_rule!(u32, 1);
mul_rule!(u64, 1);
mul_rule!(usize, 1);
mul_rule!(f32, 1.0);
mul_rule!(f64, 1.0);

pub struct MinOp;

pub const MIN: &'static MinOp = &MinOp;

macro_rules! min_rule {
    ($i:ty, $z:expr, $f:expr) => {
        impl ReduceOp<$i> for MinOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                $f(value1, value2)
            }
        }
    }
}

min_rule!(i8, std::i8::MAX, std::cmp::min);
min_rule!(i16, std::i16::MAX, std::cmp::min);
min_rule!(i32, std::i32::MAX, std::cmp::min);
min_rule!(i64, std::i64::MAX, std::cmp::min);
min_rule!(isize, std::isize::MAX, std::cmp::min);
min_rule!(u8, std::u8::MAX, std::cmp::min);
min_rule!(u16, std::u16::MAX, std::cmp::min);
min_rule!(u32, std::u32::MAX, std::cmp::min);
min_rule!(u64, std::u64::MAX, std::cmp::min);
min_rule!(usize, std::usize::MAX, std::cmp::min);
min_rule!(f32, std::f32::INFINITY, f32::min);
min_rule!(f64, std::f64::INFINITY, f64::min);

pub struct MaxOp;

pub const MAX: &'static MaxOp = &MaxOp;

macro_rules! max_rule {
    ($i:ty, $z:expr, $f:expr) => {
        impl ReduceOp<$i> for MaxOp {
            fn start_value(&self) -> $i {
                $z
            }
            fn reduce(&self, value1: $i, value2: $i) -> $i {
                $f(value1, value2)
            }
        }
    }
}

max_rule!(i8, std::i8::MIN, std::cmp::max);
max_rule!(i16, std::i16::MIN, std::cmp::max);
max_rule!(i32, std::i32::MIN, std::cmp::max);
max_rule!(i64, std::i64::MIN, std::cmp::max);
max_rule!(isize, std::isize::MIN, std::cmp::max);
max_rule!(u8, std::u8::MIN, std::cmp::max);
max_rule!(u16, std::u16::MIN, std::cmp::max);
max_rule!(u32, std::u32::MIN, std::cmp::max);
max_rule!(u64, std::u64::MIN, std::cmp::max);
max_rule!(usize, std::usize::MIN, std::cmp::max);
max_rule!(f32, std::f32::NEG_INFINITY, f32::max);
max_rule!(f64, std::f64::NEG_INFINITY, f64::max);

pub struct ReduceWithOp<OP> {
    op: OP
}

impl<OP> ReduceWithOp<OP> {
    pub fn new(op: OP) -> ReduceWithOp<OP> {
        ReduceWithOp {
            op: op
        }
    }
}

impl<ITEM,OP> ReduceOp<Option<ITEM>> for ReduceWithOp<OP>
    where OP: Fn(ITEM, ITEM) -> ITEM + Sync
{
    fn start_value(&self) -> Option<ITEM> {
        None
    }

    fn reduce(&self, value1: Option<ITEM>, value2: Option<ITEM>) -> Option<ITEM> {
        if let Some(value1) = value1 {
            if let Some(value2) = value2 {
                Some((self.op)(value1, value2))
            } else {
                Some(value1)
            }
        } else {
            value2
        }
    }
}
<|endoftext|>


<commit_before>class cat<U> {
  priv {
    let mut info : [U];
    let mut meows : uint;
  }

  let how_hungry : int;

  new(in_x : uint, in_y : int, -in_info: [U])
    { self.meows = in_x; self.how_hungry = in_y;
      self.info <- in_info; }

  fn speak<T>(stuff: [T]) {
    self.meows += stuff.len();
  }
  fn meow_count() -> uint { self.meows }
}

fn main() {
  let nyan : cat<int> = cat::<int>(52u, 99, [9]);
  let kitty = cat(1000u, 2, ["tabby"]);
  assert(nyan.how_hungry == 99);
  assert(kitty.how_hungry == 2);
  nyan.speak([1,2,3]);
  assert(nyan.meow_count() == 55u);
  kitty.speak(["meow", "mew", "purr", "chirp"]);
  assert(kitty.meow_count() == 1004u);
}
<commit_msg>xfail - metadata encoding doesn't work, which breaks Windows<commit_after>// xfail-test
// needs metadata encoding on Windows
class cat<U> {
  priv {
    let mut info : [U];
    let mut meows : uint;
  }

  let how_hungry : int;

  new(in_x : uint, in_y : int, -in_info: [U])
    { self.meows = in_x; self.how_hungry = in_y;
      self.info <- in_info; }

  fn speak<T>(stuff: [T]) {
    self.meows += stuff.len();
  }
  fn meow_count() -> uint { self.meows }
}

fn main() {
  let nyan : cat<int> = cat::<int>(52u, 99, [9]);
  let kitty = cat(1000u, 2, ["tabby"]);
  assert(nyan.how_hungry == 99);
  assert(kitty.how_hungry == 2);
  nyan.speak([1,2,3]);
  assert(nyan.meow_count() == 55u);
  kitty.speak(["meow", "mew", "purr", "chirp"]);
  assert(kitty.meow_count() == 1004u);
}
<|endoftext|>


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

// run-pass
// compile-flags:--test -g

#[cfg(target_os = "macos")]
#[test]
fn simple_test() {
    use std::{env, panic, fs};

    // Find our dSYM and replace the DWARF binary with an empty file
    let mut dsym_path = env::current_exe().unwrap();
    let executable_name = dsym_path.file_name().unwrap().to_str().unwrap().to_string();
    assert!(dsym_path.pop()); // Pop executable
    dsym_path.push(format!("{}.dSYM/Contents/Resources/DWARF/{0}", executable_name));
    {
        let file = fs::OpenOptions::new().read(false).write(true).truncate(true).create(false)
            .open(&dsym_path).unwrap();
    }

    env::set_var("RUST_BACKTRACE", "1");

    // We don't need to die of panic, just trigger a backtrace
    let _ = panic::catch_unwind(|| {
        assert!(false);
    });
}
<commit_msg>Allow `unused_variables` lint to placate test failure exposed by macos builders.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// run-pass
#![allow(unused_variables)]
// compile-flags:--test -g

#[cfg(target_os = "macos")]
#[test]
fn simple_test() {
    use std::{env, panic, fs};

    // Find our dSYM and replace the DWARF binary with an empty file
    let mut dsym_path = env::current_exe().unwrap();
    let executable_name = dsym_path.file_name().unwrap().to_str().unwrap().to_string();
    assert!(dsym_path.pop()); // Pop executable
    dsym_path.push(format!("{}.dSYM/Contents/Resources/DWARF/{0}", executable_name));
    {
        let file = fs::OpenOptions::new().read(false).write(true).truncate(true).create(false)
            .open(&dsym_path).unwrap();
    }

    env::set_var("RUST_BACKTRACE", "1");

    // We don't need to die of panic, just trigger a backtrace
    let _ = panic::catch_unwind(|| {
        assert!(false);
    });
}
<|endoftext|>


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

// xfail-win32
// error-pattern:ran out of stack

// Test that the task fails after hitting the recursion limit, but
// that it doesn't bring down the whole proc

pub fn main() {
    do task::spawn_unlinked {
        fn f() { f() };
        f();
    };
}
<commit_msg>test: Remove run-pass/too-much-recursion.rs<commit_after><|endoftext|>


<commit_before>#[derive(Debug, PartialEq)]
enum LexerErrorCode {
    InvalidSyntax,
    TrailingCharacters,
    EOFWhileReadingToken,
}

#[derive(Debug, PartialEq)]
enum LexerError {
    SyntaxError {
        code: LexerErrorCode,
        line: usize,
        col: usize,
    }
}

#[derive(Debug, PartialEq)]
enum Token {
    Number(f64),
    String(String),
    Symbol(String),
    ListStart,
    ListEnd,
    Error(LexerError),
}

#[derive(Debug, PartialEq)]
enum LexerState {
    Start,
    BeforeFinish,
    ReadList,
    Finish,
}

pub struct Lexer<T> {
    reader: T,
    cur_char: Option<char>,
    line: usize,
    col: usize,
    state: LexerState,
    lvl: isize,
}

impl<T: Iterator<Item=char>> Iterator for Lexer<T> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        match self.state {
            LexerState::Finish => {
                None
            },
            LexerState::BeforeFinish => {
                self.read_whitespaces();
                self.cur_char
                    .and(Some(self.error_token(LexerErrorCode::TrailingCharacters)))
                    .or_else(|| { self.state = LexerState::Finish; None })
            },
            _ => {
                Some(self.read())
            }
        }
    }
}

impl<T: Iterator<Item=char>> Lexer<T> {
    fn new(reader: T) -> Lexer<T> {
        let mut l = Lexer {
            reader: reader,
            cur_char: None,
            line: 1,
            col: 0,
            state: LexerState::Start,
            lvl: 0,
        };
        l.bump();
        l
    }

    fn read(&mut self) -> Token {
        loop {
            self.read_whitespaces();
            match self.state {
                LexerState::Start => {
                    return self.read_start()
                },
                LexerState::ReadList => {
                    return self.read_list()
                },
                _ => {
                    return self.error_token(LexerErrorCode::InvalidSyntax)
                }
            }
        }
    }

    fn read_start(&mut self) -> Token {
        let token = self.read_token();
        self.state = match token {
            Token::Error(_) => {
                LexerState::Finish
            },
            Token::ListStart => {
                LexerState::ReadList
            },
            _ => {
                LexerState::BeforeFinish
            },
        };
        token
    }

    fn read_token(&mut self) -> Token {
        if let Some(c) = self.cur_char {
            match c {
                'a' ... 'z' | 'A' ... 'Z' => {
                    self.read_symbol()
                },
                '0' ... '9' | '-' => {
                    self.read_number()
                },
                '"' => {
                    self.read_string()
                },
                '(' => {
                    self.bump();
                    Token::ListStart
                },
                ')' => {
                    self.bump();
                    Token::ListEnd
                },
                _ => {
                    self.error_token(LexerErrorCode::InvalidSyntax)
                }
            }
        } else {
            self.error_token(LexerErrorCode::EOFWhileReadingToken)
        }
    }

    fn read_symbol(&mut self) -> Token {
        let mut res = String::new();

        while let Some(c) = self.cur_char {
            match c {
                ' ' | '\t' | '\r' | '\n' => {
                    break
                },
                _ => {
                    res.push(c);
                }
            }
            self.bump();
        }

        Token::Symbol(res)
    }

    fn read_number(&mut self) -> Token {
        let mut neg = false;

        if let Some('-') = self.cur_char {
            neg = true;
            self.bump();
        }

        let mut accum = 0_f64;

        while let Some(c) = self.cur_char {
            match c {
                '0' ... '9' => {
                    let c_as_usize = (c as usize) - ('0' as usize);
                    accum *= 10_f64;
                    accum += c_as_usize as f64;
                    self.bump()
                },
                '.' => {
                    self.bump();

                    let mut dec = 1.0;
                    while let Some(c) = self.cur_char {
                        match c {
                            '0' ... '9' => {
                                let c_as_usize = (c as usize) - ('0' as usize);
                                dec /= 10.0;
                                accum += (c_as_usize as f64) * dec;
                                self.bump();
                            },
                            _ => {
                                break
                            }
                        }
                    }
                },
                ' ' | '\t' | '\r' | '\n' | ')' => {
                    break
                },
                _ => {
                    return self.error_token(LexerErrorCode::InvalidSyntax)
                }
            }
        }

        if neg {
            accum *= -1_f64;
        }

        Token::Number(accum)
    }

    fn read_string(&mut self) -> Token {
        let mut res = String::new();

        self.bump();

        while let Some(c) = self.cur_char {
            match c {
                '"' => {
                    break
                },
                _ => {
                    res.push(c);
                }
            }
            self.bump();
        }

        self.bump();

        Token::String(res)
    }

    fn read_list(&mut self) -> Token {
        let token = self.read_token();
        self.state = match token {
            Token::Error(_) => {
                LexerState::Finish
            },
            Token::ListStart => {
                self.lvl += 1;
                LexerState::ReadList
            },
            Token::ListEnd => {
                if self.lvl > 0 {
                    self.lvl -= 1;
                    LexerState::ReadList
                } else {
                    LexerState::BeforeFinish
                }
            },
            _ => {
                LexerState::ReadList
            }
        };
        token
    }

    fn read_whitespaces(&mut self) {
        while let Some(c) = self.cur_char {
            match c {
                ' ' | '\t' | '\r' | '\n' => {
                    self.bump();
                },
                _ => {
                    break;
                }
            }
        }
    }

    fn bump(&mut self) {
        self.cur_char = self.reader.next();
        if Some('\n') == self.cur_char {
            self.line += 1;
            self.col = 1;
        } else {
            self.col += 1;
        }
    }

    fn error_token(&mut self, ec: LexerErrorCode) -> Token {
        self.state = LexerState::Finish;
        Token::Error(LexerError::SyntaxError {
            code: ec,
            line: self.line,
            col: self.col
        })
    }
}

#[cfg(test)]
mod tests {
    use super::{Lexer, Token, LexerError, LexerErrorCode};

    #[test]
    fn test_read_nil() {
        let sym_name = "nil".to_string();
        let mut lexer = Lexer::new(sym_name.chars());
        assert_eq!(Some(Token::Symbol(sym_name.clone())), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_integer_as_float() {
        let mut lexer = Lexer::new("64".chars());
        assert_eq!(Some(Token::Number(64_f64)), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_float() {
        let mut lexer = Lexer::new("64.5".chars());
        assert_eq!(Some(Token::Number(64.5)), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_string() {
        let s = "rust is beautiful".to_string();
        let actual_input = format!(r#""{}""#, s);
        let mut lexer = Lexer::new(actual_input.chars());
        assert_eq!(Some(Token::String(s)), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_symbol() {
        let sym_name = "my-symbol".to_string();
        let mut lexer = Lexer::new(sym_name.chars());
        assert_eq!(Some(Token::Symbol(sym_name.clone())), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_incorrect_symbol_starting_with_digit() {
        let sym_name = "6-my-incorrect-symbol".to_string();
        let mut lexer = Lexer::new(sym_name.chars());
        let expected_result = Some(Token::Error(LexerError::SyntaxError {
            code: LexerErrorCode::InvalidSyntax,
            line: 1,
            col: 2
        }));
        assert_eq!(expected_result, lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_dense_expression() {
        let lexer = Lexer::new("(def a 1)".chars());
        let expected_result = vec![Token::ListStart,
                                   Token::Symbol("def".to_string()),
                                   Token::Symbol("a".to_string()),
                                   Token::Number(1_f64),
                                   Token::ListEnd];
        assert_eq!(expected_result, lexer.collect::<Vec<Token>>())
    }

    #[test]
    fn test_read_sparse_expression() {
        let lexer = Lexer::new(" ( \n def a\n1)   \n".chars());
        let expected_result = vec![Token::ListStart,
                                   Token::Symbol("def".to_string()),
                                   Token::Symbol("a".to_string()),
                                   Token::Number(1_f64),
                                   Token::ListEnd];
        assert_eq!(expected_result, lexer.collect::<Vec<Token>>())
    }
}
<commit_msg>Add test for nested list expressions<commit_after>#[derive(Debug, PartialEq)]
enum LexerErrorCode {
    InvalidSyntax,
    TrailingCharacters,
    EOFWhileReadingToken,
}

#[derive(Debug, PartialEq)]
enum LexerError {
    SyntaxError {
        code: LexerErrorCode,
        line: usize,
        col: usize,
    }
}

#[derive(Debug, PartialEq)]
enum Token {
    Number(f64),
    String(String),
    Symbol(String),
    ListStart,
    ListEnd,
    Error(LexerError),
}

#[derive(Debug, PartialEq)]
enum LexerState {
    Start,
    BeforeFinish,
    ReadList,
    Finish,
}

pub struct Lexer<T> {
    reader: T,
    cur_char: Option<char>,
    line: usize,
    col: usize,
    state: LexerState,
    lvl: isize,
}

impl<T: Iterator<Item=char>> Iterator for Lexer<T> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        match self.state {
            LexerState::Finish => {
                None
            },
            LexerState::BeforeFinish => {
                self.read_whitespaces();
                self.cur_char
                    .and(Some(self.error_token(LexerErrorCode::TrailingCharacters)))
                    .or_else(|| { self.state = LexerState::Finish; None })
            },
            _ => {
                Some(self.read())
            }
        }
    }
}

impl<T: Iterator<Item=char>> Lexer<T> {
    fn new(reader: T) -> Lexer<T> {
        let mut l = Lexer {
            reader: reader,
            cur_char: None,
            line: 1,
            col: 0,
            state: LexerState::Start,
            lvl: 0,
        };
        l.bump();
        l
    }

    fn bump(&mut self) {
        self.cur_char = self.reader.next();
        if Some('\n') == self.cur_char {
            self.line += 1;
            self.col = 1;
        } else {
            self.col += 1;
        }
    }

    fn read(&mut self) -> Token {
        loop {
            self.read_whitespaces();
            match self.state {
                LexerState::Start => {
                    return self.read_start()
                },
                LexerState::ReadList => {
                    return self.read_list()
                },
                _ => {
                    return self.error_token(LexerErrorCode::InvalidSyntax)
                }
            }
        }
    }

    fn read_start(&mut self) -> Token {
        let token = self.read_token();
        self.state = match token {
            Token::Error(_) => {
                LexerState::Finish
            },
            Token::ListStart => {
                LexerState::ReadList
            },
            _ => {
                LexerState::BeforeFinish
            },
        };
        token
    }

    fn read_token(&mut self) -> Token {
        if let Some(c) = self.cur_char {
            match c {
                'a' ... 'z' | 'A' ... 'Z' | '+' => {
                    self.read_symbol()
                },
                '0' ... '9' | '-' => {
                    self.read_number()
                },
                '"' => {
                    self.read_string()
                },
                '(' => {
                    self.bump();
                    Token::ListStart
                },
                ')' => {
                    self.bump();
                    Token::ListEnd
                },
                _ => {
                    self.error_token(LexerErrorCode::InvalidSyntax)
                }
            }
        } else {
            self.error_token(LexerErrorCode::EOFWhileReadingToken)
        }
    }

    fn read_symbol(&mut self) -> Token {
        let mut res = String::new();

        while let Some(c) = self.cur_char {
            match c {
                ' ' | '\t' | '\r' | '\n' => {
                    break
                },
                _ => {
                    res.push(c);
                }
            }
            self.bump();
        }

        Token::Symbol(res)
    }

    fn read_number(&mut self) -> Token {
        let mut neg = false;

        if let Some('-') = self.cur_char {
            neg = true;
            self.bump();
        }

        let mut accum = 0_f64;

        while let Some(c) = self.cur_char {
            match c {
                '0' ... '9' => {
                    let c_as_usize = (c as usize) - ('0' as usize);
                    accum *= 10_f64;
                    accum += c_as_usize as f64;
                    self.bump()
                },
                '.' => {
                    self.bump();

                    let mut dec = 1.0;
                    while let Some(c) = self.cur_char {
                        match c {
                            '0' ... '9' => {
                                let c_as_usize = (c as usize) - ('0' as usize);
                                dec /= 10.0;
                                accum += (c_as_usize as f64) * dec;
                                self.bump();
                            },
                            _ => {
                                break
                            }
                        }
                    }
                },
                ' ' | '\t' | '\r' | '\n' | ')' => {
                    break
                },
                _ => {
                    return self.error_token(LexerErrorCode::InvalidSyntax)
                }
            }
        }

        if neg {
            accum *= -1_f64;
        }

        Token::Number(accum)
    }

    fn read_string(&mut self) -> Token {
        let mut res = String::new();

        self.bump();

        while let Some(c) = self.cur_char {
            match c {
                '"' => {
                    break
                },
                _ => {
                    res.push(c);
                }
            }
            self.bump();
        }

        self.bump();

        Token::String(res)
    }

    fn read_list(&mut self) -> Token {
        let token = self.read_token();
        match token {
            Token::ListStart => {
                self.lvl += 1;
            },
            Token::ListEnd => {
                if self.lvl > 0 {
                    self.lvl -= 1;
                } else {
                    self.state = LexerState::BeforeFinish
                }
            },
            Token::Error(_) => {
                self.state = LexerState::Finish
            },
            _ => {}
        };
        token
    }

    fn read_whitespaces(&mut self) {
        while let Some(c) = self.cur_char {
            match c {
                ' ' | '\t' | '\r' | '\n' => {
                    self.bump();
                },
                _ => {
                    break;
                }
            }
        }
    }

    fn error_token(&mut self, ec: LexerErrorCode) -> Token {
        self.state = LexerState::Finish;
        Token::Error(LexerError::SyntaxError {
            code: ec,
            line: self.line,
            col: self.col
        })
    }
}

#[cfg(test)]
mod tests {
    use super::{Lexer, Token, LexerError, LexerErrorCode};

    #[test]
    fn test_read_nil() {
        let sym_name = "nil".to_string();
        let mut lexer = Lexer::new(sym_name.chars());
        assert_eq!(Some(Token::Symbol(sym_name.clone())), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_integer_as_float() {
        let mut lexer = Lexer::new("64".chars());
        assert_eq!(Some(Token::Number(64_f64)), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_float() {
        let mut lexer = Lexer::new("64.5".chars());
        assert_eq!(Some(Token::Number(64.5)), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_string() {
        let s = "rust is beautiful".to_string();
        let actual_input = format!(r#""{}""#, s);
        let mut lexer = Lexer::new(actual_input.chars());
        assert_eq!(Some(Token::String(s)), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_symbol() {
        let sym_name = "my-symbol".to_string();
        let mut lexer = Lexer::new(sym_name.chars());
        assert_eq!(Some(Token::Symbol(sym_name.clone())), lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_incorrect_symbol_starting_with_digit() {
        let sym_name = "6-my-incorrect-symbol".to_string();
        let mut lexer = Lexer::new(sym_name.chars());
        let expected_result = Some(Token::Error(LexerError::SyntaxError {
            code: LexerErrorCode::InvalidSyntax,
            line: 1,
            col: 2
        }));
        assert_eq!(expected_result, lexer.next());
        assert_eq!(None, lexer.next());
    }

    #[test]
    fn test_read_dense_expression() {
        let lexer = Lexer::new("(def a 1)".chars());
        let expected_result = vec![Token::ListStart,
                                   Token::Symbol("def".to_string()),
                                   Token::Symbol("a".to_string()),
                                   Token::Number(1_f64),
                                   Token::ListEnd];
        assert_eq!(expected_result, lexer.collect::<Vec<Token>>())
    }

    #[test]
    fn test_read_sparse_expression() {
        let lexer = Lexer::new(" ( \n def a\n1)   \n".chars());
        let expected_result = vec![Token::ListStart,
                                   Token::Symbol("def".to_string()),
                                   Token::Symbol("a".to_string()),
                                   Token::Number(1_f64),
                                   Token::ListEnd];
        assert_eq!(expected_result, lexer.collect::<Vec<Token>>())
    }

    #[test]
    fn test_read_nested_list_expressions() {
        let lexer = Lexer::new("(def a (+ 1 1))".chars());
        let expected_result = vec![Token::ListStart,
                                   Token::Symbol("def".to_string()),
                                   Token::Symbol("a".to_string()),
                                   Token::ListStart,
                                   Token::Symbol("+".to_string()),
                                   Token::Number(1_f64),
                                   Token::Number(1_f64),
                                   Token::ListEnd,
                                   Token::ListEnd];
        assert_eq!(expected_result, lexer.collect::<Vec<Token>>())
    }
}
<|endoftext|>


<commit_before>use Conn;
use conn::futures::Query;
use conn::futures::query_result::futures::CollectAll;
use conn::futures::query_result::TextQueryResult;
use conn::futures::query_result::UnconsumedQueryResult;
use conn::futures::read_max_allowed_packet::ReadMaxAllowedPacket;
use consts;
use errors::*;
use io::futures::ConnectingStream;
use io::futures::WritePacket;
use io::Stream;
use lib_futures::Async;
use lib_futures::Async::Ready;
use lib_futures::Future;
use lib_futures::Poll;
use lib_futures::stream::Stream as StreamTrait;
use lib_futures::stream::StreamFuture;
#[macro_use] use macros;
use Opts;
use proto::ErrPacket;
use proto::HandshakePacket;
use proto::HandshakeResponse;
use proto::Packet;
use proto::PacketType;

/// Future that resolves to a `Conn`.
pub struct NewConn {
    step: Step,
    opts: Opts,
    status: consts::StatusFlags,
    id: u32,
    version: (u16, u16, u16),
    init: Vec<String>,
}

steps! {
    NewConn {
        ConnectingStream(ConnectingStream),
        ReadHandshake(StreamFuture<Stream>),
        WriteHandshake(WritePacket),
        ReadResponse(StreamFuture<Stream>),
        ReadMaxAllowedPacket(ReadMaxAllowedPacket),
        Query(Query),
        CollectAll(CollectAll<TextQueryResult>),
    }
}

pub fn new(connecting_stream: ConnectingStream, opts: Opts) -> NewConn {
    NewConn {
        init: opts.get_init().to_owned(),
        opts: opts,
        step: Step::ConnectingStream(connecting_stream),
        status: consts::StatusFlags::empty(),
        id: 0,
        version: (0, 0, 0),
    }
}

impl Future for NewConn {
    type Item = Conn;
    type Error = Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match try_ready!(self.either_poll()) {
            Out::ConnectingStream(stream) => {
                self.step = Step::ReadHandshake(stream.into_future());
                self.poll()
            },
            Out::ReadHandshake((maybe_packet, stream)) => match maybe_packet {
                Some((packet, seq_id)) => {
                    if packet.is(PacketType::Err) {
                        let err_packet = ErrPacket::new(packet);
                        return Err(ErrorKind::Server(err_packet.unwrap()).into());
                    }
                    let handshake = HandshakePacket::new(packet);
                    self.version = try!(handshake.srv_ver_parsed());
                    self.id = handshake.conn_id();
                    self.status = handshake.status_flags()
                        .unwrap_or(consts::StatusFlags::empty());
                    let handshake_response = HandshakeResponse::new(&handshake,
                                                                    self.opts.get_user(),
                                                                    self.opts.get_pass(),
                                                                    self.opts.get_db_name());
                    let future = stream.write_packet(handshake_response.as_ref().to_vec(),
                                                     seq_id + 1);
                    self.step = Step::WriteHandshake(future);
                    self.poll()
                },
                None => panic!("No handshake!?"),
            },
            Out::WriteHandshake((stream, _)) => { // TODO: take seq_id to account
                self.step = Step::ReadResponse(stream.into_future());
                self.poll()
            },
            Out::ReadResponse((maybe_packet, stream)) => match maybe_packet {
                Some((packet, seq_id)) => {
                    if packet.is(PacketType::Err) {
                        let err_packet = ErrPacket::new(packet).unwrap();
                        return Err(ErrorKind::Server(err_packet).into());
                    } else {
                        let conn = Conn {
                            last_command: consts::Command::COM_PING,
                            capabilities: consts::CLIENT_PROTOCOL_41 |
                                consts::CLIENT_SECURE_CONNECTION |
                                consts::CLIENT_LONG_PASSWORD |
                                consts::CLIENT_TRANSACTIONS |
                                consts::CLIENT_LOCAL_FILES |
                                consts::CLIENT_MULTI_STATEMENTS |
                                consts::CLIENT_MULTI_RESULTS |
                                consts::CLIENT_PS_MULTI_RESULTS,
                            status: self.status,
                            last_insert_id: 0,
                            affected_rows: 0,
                            stream: Some(stream),
                            seq_id: seq_id,
                            max_allowed_packet: 65536,
                            warnings: 0,
                            version: self.version,
                            id: self.id,
                            has_result: None,
                            pool: None,
                        };
                        self.step = Step::ReadMaxAllowedPacket(conn.read_max_allowed_packet());
                        self.poll()
                    }
                },
                None => panic!("No handshake response!?"),
            },
            Out::ReadMaxAllowedPacket(conn) => {
                match self.init.pop() {
                    Some(query) => {
                        self.step = Step::Query(conn.query(query));
                        self.poll()
                    },
                    None => Ok(Ready(conn)),
                }
            },
            Out::Query(query_result) => {
                self.step = Step::CollectAll(query_result.collect_all());
                self.poll()
            },
            Out::CollectAll((_, conn)) => {
                match self.init.pop() {
                    Some(query) => {
                        self.step = Step::Query(conn.query(query));
                        self.poll()
                    },
                    Node => Ok(Ready(conn)),
                }
            }
        }
    }
}
<commit_msg>Improve NewConn implementation<commit_after>use Conn;
use conn::futures::Query;
use conn::futures::query_result::futures::CollectAll;
use conn::futures::query_result::TextQueryResult;
use conn::futures::query_result::UnconsumedQueryResult;
use conn::futures::read_max_allowed_packet::ReadMaxAllowedPacket;
use consts;
use errors::*;
use io::futures::ConnectingStream;
use io::futures::WritePacket;
use io::Stream;
use lib_futures::Async;
use lib_futures::Async::Ready;
use lib_futures::Future;
use lib_futures::Poll;
use lib_futures::stream::Stream as StreamTrait;
use lib_futures::stream::StreamFuture;
use Opts;
use proto::ErrPacket;
use proto::HandshakePacket;
use proto::HandshakeResponse;
use proto::PacketType;

/// Future that resolves to a `Conn`.
pub struct NewConn {
    step: Step,
    opts: Opts,
    status: consts::StatusFlags,
    id: u32,
    version: (u16, u16, u16),
    init_len: usize,
}

steps! {
    NewConn {
        ConnectingStream(ConnectingStream),
        ReadHandshake(StreamFuture<Stream>),
        WriteHandshake(WritePacket),
        ReadResponse(StreamFuture<Stream>),
        ReadMaxAllowedPacket(ReadMaxAllowedPacket),
        Query(Query),
        CollectAll(CollectAll<TextQueryResult>),
    }
}

pub fn new(connecting_stream: ConnectingStream, opts: Opts) -> NewConn {
    NewConn {
        init_len: opts.get_init().len(),
        opts: opts,
        step: Step::ConnectingStream(connecting_stream),
        status: consts::StatusFlags::empty(),
        id: 0,
        version: (0, 0, 0),
    }
}

impl Future for NewConn {
    type Item = Conn;
    type Error = Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match try_ready!(self.either_poll()) {
            Out::ConnectingStream(stream) => {
                self.step = Step::ReadHandshake(stream.into_future());
                self.poll()
            },
            Out::ReadHandshake((maybe_packet, stream)) => match maybe_packet {
                Some((packet, seq_id)) => {
                    if packet.is(PacketType::Err) {
                        let err_packet = ErrPacket::new(packet);
                        return Err(ErrorKind::Server(err_packet.unwrap()).into());
                    }
                    let handshake = HandshakePacket::new(packet);
                    self.version = try!(handshake.srv_ver_parsed());
                    self.id = handshake.conn_id();
                    self.status = handshake.status_flags()
                        .unwrap_or(consts::StatusFlags::empty());
                    let handshake_response = HandshakeResponse::new(&handshake,
                                                                    self.opts.get_user(),
                                                                    self.opts.get_pass(),
                                                                    self.opts.get_db_name());
                    let future = stream.write_packet(handshake_response.as_ref().to_vec(),
                                                     seq_id + 1);
                    self.step = Step::WriteHandshake(future);
                    self.poll()
                },
                None => panic!("No handshake!?"),
            },
            Out::WriteHandshake((stream, _)) => { // TODO: take seq_id to account
                self.step = Step::ReadResponse(stream.into_future());
                self.poll()
            },
            Out::ReadResponse((maybe_packet, stream)) => match maybe_packet {
                Some((packet, seq_id)) => {
                    if packet.is(PacketType::Err) {
                        let err_packet = ErrPacket::new(packet).unwrap();
                        return Err(ErrorKind::Server(err_packet).into());
                    } else {
                        let conn = Conn {
                            last_command: consts::Command::COM_PING,
                            capabilities: consts::CLIENT_PROTOCOL_41 |
                                consts::CLIENT_SECURE_CONNECTION |
                                consts::CLIENT_LONG_PASSWORD |
                                consts::CLIENT_TRANSACTIONS |
                                consts::CLIENT_LOCAL_FILES |
                                consts::CLIENT_MULTI_STATEMENTS |
                                consts::CLIENT_MULTI_RESULTS |
                                consts::CLIENT_PS_MULTI_RESULTS,
                            status: self.status,
                            last_insert_id: 0,
                            affected_rows: 0,
                            stream: Some(stream),
                            seq_id: seq_id,
                            max_allowed_packet: 65536,
                            warnings: 0,
                            version: self.version,
                            id: self.id,
                            has_result: None,
                            pool: None,
                        };
                        self.step = Step::ReadMaxAllowedPacket(conn.read_max_allowed_packet());
                        self.poll()
                    }
                },
                None => panic!("No handshake response!?"),
            },
            Out::ReadMaxAllowedPacket(conn) => {
                let step = match self.opts.get_init().get(self.opts.get_init().len() - self.init_len) {
                    Some(query) => Step::Query(conn.query(query)),
                    None => return Ok(Ready(conn)),
                };
                self.step = step;
                self.init_len -= 1;
                self.poll()
            },
            Out::Query(query_result) => {
                self.step = Step::CollectAll(query_result.collect_all());
                self.poll()
            },
            Out::CollectAll((_, conn)) => {
                let step = match self.opts.get_init().get(self.opts.get_init().len() - self.init_len) {
                    Some(query) => Step::Query(conn.query(query)),
                    None => return Ok(Ready(conn)),
                };
                self.step = step;
                self.init_len -= 1;
                self.poll()
            }
        }
    }
}
<|endoftext|>


<commit_before>///! Encoding-decoding tests
///!
///! These integration tests check that for each format the
///! `encode` and `decode` functions are consistent by doing a
///! round trip conversion of arbitrary instances of nodes.
///!
///! Uses `serde_json::to_value` for assertions because currently unable
///! to compare nodes directly. `serde_json::Value` provides most readable
///! way to compare.
use pretty_assertions::assert_eq;
use proptest::prelude::*;
use stencila::methods::{decode, encode};
use stencila_schema::{BlockContent, Node};

mod strategies;
use strategies::{article, code_chunk, node, Freedom};

proptest! {
    // Tests for generic data serialization formats

    // Given the high confidence for encoding/decoding for the
    // following formats the number of test cases is minimal
    #![proptest_config(ProptestConfig::with_cases(5))]

    #[cfg(all(feature="encode-json", feature="decode-json"))]
    #[test]
    fn json(input in node(Freedom::Max)) {
        let content = encode::json::encode(&input, None).unwrap();
        let output = decode::json::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[cfg(all(feature="encode-yaml", feature="decode-yaml"))]
    #[test]
    fn yaml(input in node(Freedom::Max)) {
        let content = encode::yaml::encode(&input).unwrap();
        let output = decode::yaml::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }
}

proptest! {
    // Tests for RPNGs
    //
    // RPNGs can be used for all node types but theses tests
    // focus on the types for which they are most predominately used.
    // Given the slowness of generating PNGs only use very few cases.
    #![proptest_config(ProptestConfig::with_cases(3))]

    #[cfg(all(target_os="linux", feature="encode-rpng", feature="decode-rpng"))]
    #[test]
    fn rpng(chunk in code_chunk(Freedom::Max)) {
        let input = if let BlockContent::CodeChunk(chunk) = chunk {
            Node::CodeChunk(chunk)
        } else {
            panic!("Whaaat?!@#!!")
        };
        let content = tokio::runtime::Runtime::new().unwrap().block_on(async {
            encode::rpng::encode(&input, "data://").await.unwrap()
        });
        let output = decode::rpng::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }
}

proptest! {
    // Tests for article formats

    // Given the relatively high randomness and complexity of each input
    // we reduce the number of test cases from the default of 256
    #![proptest_config(ProptestConfig::with_cases(100))]

    #[cfg(all(feature="encode-html", feature="decode-html"))]
    #[test]
    fn html(input in article(Freedom::Max)) {
        let content = encode::html::encode(&input, None).unwrap();
        let output = decode::html::decode(&content, false).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[cfg(all(feature="encode-md", feature="decode-md"))]
    #[test]
    fn md(input in article(Freedom::Min)) {
        let content = encode::md::encode(&input).unwrap();
        let output = decode::md::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[cfg(all(feature="encode-rmd", feature="decode-rmd"))]
    #[test]
    fn rmd(input in article(Freedom::Min)) {
        let content = encode::rmd::encode(&input).unwrap();
        let output = decode::rmd::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[cfg(all(feature="encode-pandoc", feature="decode-pandoc"))]
    #[test]
    fn pandoc(input in article(Freedom::Min)) {
        let pandoc = encode::pandoc::encode_node(&input).unwrap();
        let output = decode::pandoc::decode_pandoc(pandoc).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }
}

proptest! {
    // Tests for formats that spawn Pandoc

    // Given the relative slowness of spawning a new process for
    // pandoc, only a few tests cases.
    #![proptest_config(ProptestConfig::with_cases(10))]

    #[ignore = "End-to-end not yet completely working"]
    #[cfg(all(feature="encode-latex", feature="decode-latex"))]
    #[test]
    fn latex(input in article(Freedom::Min)) {
        tokio::runtime::Runtime::new().unwrap().block_on(async {
            let content = encode::latex::encode(&input).await.unwrap();
            let output = decode::latex::decode(&content).await.unwrap();
            assert_eq!(
                serde_json::to_value(&input).unwrap(),
                serde_json::to_value(&output).unwrap()
            )
        })
    }

    #[ignore = "End-to-end not yet completely working"]
    #[cfg(all(feature="encode-docx", feature="decode-docx"))]
    #[test]
    fn docx(input in article(Freedom::Min)) {
        tokio::runtime::Runtime::new().unwrap().block_on(async {
            let path = "file://temp.docx".to_string();
            encode::docx::encode(&input, &path).await.unwrap();
            let output = decode::docx::decode(&path).await.unwrap();
            assert_eq!(
                serde_json::to_value(&input).unwrap(),
                serde_json::to_value(&output).unwrap()
            )
        })
    }
}
<commit_msg>test(Endode-decode): Use local macro<commit_after>///! Encoding-decoding tests
///!
///! These integration tests check that for each format the
///! `encode` and `decode` functions are consistent by doing a
///! round trip conversion of arbitrary instances of nodes.
///!
///! Uses `serde_json::to_value` for assertions because currently unable
///! to compare nodes directly. `serde_json::Value` provides most readable
///! way to compare.
use proptest::prelude::*;
use stencila::methods::{decode, encode};
use stencila_schema::{BlockContent, Node};

mod strategies;
use strategies::{article, code_chunk, node, Freedom};

macro_rules! assert_json_eq {
    ($expr1:expr, $expr2:expr) => {
        pretty_assertions::assert_eq!(
            serde_json::to_value(&$expr1).unwrap(),
            serde_json::to_value(&$expr2).unwrap()
        );
    };
}

proptest! {
    // Tests for generic data serialization formats

    // Given the high confidence for encoding/decoding for the
    // following formats the number of test cases is minimal
    #![proptest_config(ProptestConfig::with_cases(5))]

    #[cfg(all(feature="encode-json", feature="decode-json"))]
    #[test]
    fn json(input in node(Freedom::Max)) {
        let content = encode::json::encode(&input, None).unwrap();
        let output = decode::json::decode(&content).unwrap();
        assert_json_eq!(input, output);
    }

    #[cfg(all(feature="encode-yaml", feature="decode-yaml"))]
    #[test]
    fn yaml(input in node(Freedom::Max)) {
        let content = encode::yaml::encode(&input).unwrap();
        let output = decode::yaml::decode(&content).unwrap();
        assert_json_eq!(input, output);
    }
}

proptest! {
    // Tests for RPNGs
    //
    // RPNGs can be used for all node types but theses tests
    // focus on the types for which they are most predominately used.
    // Given the slowness of generating PNGs only use very few cases.
    #![proptest_config(ProptestConfig::with_cases(3))]

    #[cfg(all(target_os="linux", feature="encode-rpng", feature="decode-rpng"))]
    #[test]
    fn rpng(chunk in code_chunk(Freedom::Max)) {
        let input = if let BlockContent::CodeChunk(chunk) = chunk {
            Node::CodeChunk(chunk)
        } else {
            panic!("Whaaat?!@#!!")
        };
        let content = tokio::runtime::Runtime::new().unwrap().block_on(async {
            encode::rpng::encode(&input, "data://").await.unwrap()
        });
        let output = decode::rpng::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }
}

proptest! {
    // Tests for article formats

    // Given the relatively high randomness and complexity of each input
    // we reduce the number of test cases from the default of 256
    #![proptest_config(ProptestConfig::with_cases(100))]

    #[cfg(all(feature="encode-html", feature="decode-html"))]
    #[test]
    fn html(input in article(Freedom::Max)) {
        let content = encode::html::encode(&input, None).unwrap();
        let output = decode::html::decode(&content, false).unwrap();
        assert_json_eq!(input, output);
    }

    #[cfg(all(feature="encode-md", feature="decode-md"))]
    #[test]
    fn md(input in article(Freedom::Min)) {
        let content = encode::md::encode(&input).unwrap();
        let output = decode::md::decode(&content).unwrap();
        assert_json_eq!(input, output);
    }

    #[cfg(all(feature="encode-rmd", feature="decode-rmd"))]
    #[test]
    fn rmd(input in article(Freedom::Min)) {
        let content = encode::rmd::encode(&input).unwrap();
        let output = decode::rmd::decode(&content).unwrap();
        assert_eq!(
            serde_json::to_value(&input).unwrap(),
            serde_json::to_value(&output).unwrap()
        )
    }

    #[cfg(all(feature="encode-pandoc", feature="decode-pandoc"))]
    #[test]
    fn pandoc(input in article(Freedom::Min)) {
        let pandoc = encode::pandoc::encode_node(&input).unwrap();
        let output = decode::pandoc::decode_pandoc(pandoc).unwrap();
        assert_json_eq!(input, output);
    }
}

proptest! {
    // Tests for formats that spawn Pandoc

    // Given the relative slowness of spawning a new process for
    // pandoc, only a few tests cases.
    #![proptest_config(ProptestConfig::with_cases(10))]

    #[ignore = "End-to-end not yet completely working"]
    #[cfg(all(feature="encode-latex", feature="decode-latex"))]
    #[test]
    fn latex(input in article(Freedom::Min)) {
        tokio::runtime::Runtime::new().unwrap().block_on(async {
            let content = encode::latex::encode(&input).await.unwrap();
            let output = decode::latex::decode(&content).await.unwrap();
            assert_eq!(
                serde_json::to_value(&input).unwrap(),
                serde_json::to_value(&output).unwrap()
            )
        })
    }

    #[ignore = "End-to-end not yet completely working"]
    #[cfg(all(feature="encode-docx", feature="decode-docx"))]
    #[test]
    fn docx(input in article(Freedom::Min)) {
        tokio::runtime::Runtime::new().unwrap().block_on(async {
            let path = "file://temp.docx".to_string();
            encode::docx::encode(&input, &path).await.unwrap();
            let output = decode::docx::decode(&path).await.unwrap();
            assert_eq!(
                serde_json::to_value(&input).unwrap(),
                serde_json::to_value(&output).unwrap()
            )
        })
    }
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate racer_testutils;
extern crate test;
use test::Bencher;

use racer_testutils::*;

#[bench]
fn completes_hashmap(b: &mut Bencher) {
    let src = r"
    use std::collections::HashM~
";
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}

#[bench]
fn completes_methods_for_vec(b: &mut Bencher) {
    let src = r"
    let vec = Vec::new();
    let a = vec.~
";
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}

#[bench]
fn completes_methods_for_file_open(b: &mut Bencher) {
    let src = r#"
    use std::io;
    use std::io::prelude::*;
    use std::fs::File;
    let mut f = File::open("no-file-here"):
    f.~
"#;
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}
<commit_msg>Add follows_std & follows_collections benchmark<commit_after>#![feature(test)]
extern crate racer_testutils;
extern crate test;
use test::Bencher;

use racer_testutils::*;

#[bench]
fn completes_hashmap(b: &mut Bencher) {
    let src = r"
    use std::collections::HashM~
";
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}

#[bench]
fn completes_methods_for_vec(b: &mut Bencher) {
    let src = r"
    let vec = Vec::new();
    let a = vec.~
";
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}

#[bench]
fn completes_methods_for_file_open(b: &mut Bencher) {
    let src = r#"
    use std::io;
    use std::io::prelude::*;
    use std::fs::File;
    let mut f = File::open("no-file-here"):
    f.~
"#;
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}

#[bench]
fn follows_std(b: &mut Bencher) {
    let src = r#"
    use std::~
"#;
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}

#[bench]
fn follows_collections(b: &mut Bencher) {
    let src = r#"
    use std::collections::~
"#;
    let mut var = vec![];
    b.iter(|| {
        var = get_all_completions(src, None);
    })
}
<|endoftext|>


<commit_before>//! Allows dynamic dispatch to object-unsafe traits, with some caveats.
//!
//! `list_of_types` works around Rust's lack of generic/associated statics by requiring the program to specify a single "list of types" at compile time, which must include everything that you want to call into dynamically. This must be globally unique within the program. That is, if a *library* wants to use these features, it must rely on being passed the global list as a generic parameter.
//!
//! Creating a list of types is simple: you wrap each type `T` into `ListedType<T>`, then put the `ListedType`s into tuples (possibly nested tuples). All the traits necessary to use a list for automatically implemented for all nested tuples of `ListedType`s. For instance, ((ListedType<i64>, ListedType<String>, ListedType<Vec<usize>>), ListedType<bool>) is a valid list with 4 types in it.

use std::marker::PhantomData;

#[macro_export]
macro_rules! time_steward_make_sublist {
  (mod $mod: ident visits $T: ident where $($where:tt)*) => {mod $mod {
    use std::marker::PhantomData;
    use std::any::Any;
    use $crate::dynamic::list_of_types::{List, SubListRepresentative, ListedType};
    pub trait Visitor {
      fn visit<$T>(&mut self) where $($where)*;
    }
    pub unsafe trait SubList: List {
      fn visit_all<V: Visitor>(visitor: &mut V);
      fn count()->usize;
      fn count_before<T>()->usize;
    }
    unsafe impl <T: Any> SubList for ListedType<T> {
      #[inline(always)]
      default fn visit_all<V: Visitor>(_: &mut V) {}
      #[inline(always)]
      default fn count()->usize {0}
      #[inline(always)]
      default fn count_before<U>()->usize {panic!("invoked count_before on a list that doesn't contain the type")}
    }
    unsafe impl <$T: Any> SubList for ListedType<$T> where $($where)* {
      #[inline(always)]
      fn visit_all<V: Visitor>(visitor: &mut V) {
        visitor.visit::<$T>();
      }
      #[inline(always)]
      fn count()->usize {1}
      #[inline(always)]
      fn count_before<U>()->usize {0}
    }
    __time_steward_internal_sublist_tuple_impls! (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31);

    pub struct Representative <GlobalList: SubList> (PhantomData <GlobalList>,!);
    unsafe impl <GlobalList: SubList> SubListRepresentative for Representative <GlobalList> {
      fn count()->usize {
        $crate::dynamic::list_of_types::assert_unique_global_list::<GlobalList>();
        GlobalList::count()
      }
      fn count_before<T>()->usize {
        $crate::dynamic::list_of_types::assert_unique_global_list::<GlobalList>();
        GlobalList::count_before::<T>()
      }
    }/*{
      fn visit_all<V: Visitor>(visitor: &mut V) {
        GlobalList::visit_all(visitor);
      }
    }*/
  }}
}
pub struct ListedType<T: Any>(PhantomData <T>, !);

#[macro_export]
#[doc(hidden)]
macro_rules! __time_steward_internal_sublist_tuple_impls {
  ($TL: ident $(, $T: ident)*) => {
    unsafe impl<$($T,)* $TL> SubList for ($($T,)* $TL,)
      where $($T: SubList,)* $TL: SubList
    {
      #[inline(always)]
      fn visit_all<V: Visitor>(visitor: &mut V) {
        $($T::visit_all(visitor);)*
        $TL::visit_all(visitor);
      }
      #[inline(always)]
      fn count()->usize {
        $($T::count() + )* $TL::count()
      }
      #[inline(always)]
      fn count_before<T>()->usize {
        let count = 0;
        $(if $T::includes::<T> () {return count + $T::count_before::<T>()}
        let count = count + $T::count();)*
        if $TL::includes::<T> () {return count + $TL::count_before::<T>()}
        panic!("invoked count_before on a list that doesn't contain the type")
      }
    }
    __time_steward_internal_sublist_tuple_impls! ($($T),*);
  };
  () => {};
}

pub unsafe trait List: Any {
  fn includes <T> ()->bool;
}
pub unsafe trait SubListRepresentative {
  fn count()->usize;
  fn count_before<T>()->usize;
}

pub unsafe trait AmI <T> {fn am_i()->bool;}
unsafe impl <T, U> AmI <T> for U {default fn am_i()->bool {false}}
unsafe impl <T> AmI <T> for T {fn am_i()->bool {true}}

unsafe impl <T: Any> List for ListedType<T> {
  #[inline(always)]
  fn includes<U>()->bool {<T as AmI<U>>::am_i()}
}

macro_rules! tuple_impls {
  ($TL: ident $(, $T: ident)*) => {
    unsafe impl<$($T,)* $TL> List for ($($T,)* $TL,)
      where $($T: List,)* $TL: List
    {
      #[inline(always)]
      fn includes<T>()->bool {
        $($T::includes::<T>() || )* $TL::includes::<T>()
      }
    }
    tuple_impls! ($($T),*);
  };
  () => {};
}

tuple_impls! (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31);

#[derive (Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct DeterministicallyRandomlyIdentifiedTypeId(u64);
pub trait DeterministicallyRandomlyIdentifiedType {
  const ID: DeterministicallyRandomlyIdentifiedTypeId;
}

fn assert_unique_global_list <GlobalList: List>() {
  use std::any::TypeId;
  use std::cell::Cell;
  thread_local! {
    static LIST_ID: Cell<Option <TypeId>> = Cell::new (None);
  }
  LIST_ID.with (| id_cell | {
    let id = TypeId::of::<GlobalList>();
    if let Some (existing) = id_cell.get() {
      assert!(id == existing, "invoked dynamic function with two different global lists (see the list_of_types documentation for why this is wrong");
      return
    }
    id_cell.set (Some(id));
  });
}

time_steward_make_sublist! (
mod whatever visits T where T: super::DeterministicallyRandomlyIdentifiedType);
/*
#[macro_export]
macro_rules! time_steward_sublist_fn {
  (static $visitor_data: ident: $VisitorData: ty: $VisitorTrait: ident = $initial_value: expr followed by visit<$T> (&mut $self_hack) $visitation_effect: expr; fn $function_name: ident <$GlobalList: $SubList: ident> ($($argument_name: ident: $argument_type:ty),*)->$return_type:ty $($body:tt)*) => {

    fn $function_name <GlobalList: $List> $($argument_name: $argument_type),*)->$return_type:ty {
      struct Visitor ($VisitorData);
      impl VisitorTrait for Visitor {
        fn visit<$T>(&mut $self_hack) where  {$visitation_effect}
      }
      thread_local! {
        static DATA: $VisitorData = {
          let mut visitor = Visitor ($initial_value);
          <GlobalList as DeterministicallyRandomlyIdentifiedTypesList>::visit_all (&mut visitor);
          visitor.0
        };
      }
      DATA.with (| $visitor_data | {$($body)*})
  }
}
  */

#[macro_export]
macro_rules! time_steward_visit_sublist {
  (&mut $object: ident: $Object: ty, <$GlobalList: ident as $mod: ident::SubList>, $($method: tt)*) => {
    impl $mod::Visitor for $Object {
      $($method)*
    }
    <$GlobalList as $mod::SubList>::visit_all (&mut $object);
  }
}
#[macro_export]
macro_rules! time_steward_with_sublist_table {
  (<$GlobalList: ident as $mod: ident::SubList>, Vec<$Entry: ty> [$T: ident => {$entry: expr} where $($where: tt)*], | $table: ident | $($closure: tt)*) => {{
    assert_unique_global_list::<$GlobalList>();
    use std::cell::RefCell;
    use std::mem;
    thread_local! {
      static TABLE: RefCell<Vec<DeterministicallyRandomlyIdentifiedTypeId>> = RefCell::new(Vec::new());
    }
    TABLE.with (| table | {
      let mut guard = table.borrow_mut();
      if guard.is_empty() {
        mem::replace (&mut*guard, {
          let mut result = Vec::with_capacity($mod::Representative::<$GlobalList>::count());
          time_steward_visit_sublist! (
            &mut result: Vec<$Entry>,
            <$GlobalList as $mod::SubList>,
            fn visit<$T>(&mut self) where $($where)* {self.push ($entry);}
          );
          result
        });
      }
      let $table = &*guard;
      $($closure)*
    })
  }}
}

use std::any::Any ;

fn index_to_id <GlobalList: whatever::SubList> (index: usize)->Option <DeterministicallyRandomlyIdentifiedTypeId> {
  time_steward_with_sublist_table! (
    <GlobalList as whatever::SubList>,
    Vec<DeterministicallyRandomlyIdentifiedTypeId> [T => {T::ID} where T: DeterministicallyRandomlyIdentifiedType],
    | table | table.get (index).cloned()
  )
}

<commit_msg>more list of types work<commit_after>//! Allows dynamic dispatch to object-unsafe traits, with some caveats.
//!
//! `list_of_types` works around Rust's lack of generic/associated statics by requiring the program to specify a single "list of types" at compile time, which must include everything that you want to call into dynamically. This must be globally unique within the program. That is, if a *library* wants to use these features, it must rely on being passed the global list as a generic parameter.
//!
//! Creating a list of types is simple: you wrap each type `T` into `ListedType<T>`, then put the `ListedType`s into tuples (possibly nested tuples). All the traits necessary to use a list for automatically implemented for all nested tuples of `ListedType`s. For instance, ((ListedType<i64>, ListedType<String>, ListedType<Vec<usize>>), ListedType<bool>) is a valid list with 4 types in it.

use std::marker::PhantomData;

#[macro_export]
macro_rules! time_steward_make_sublist {
  (mod $mod: ident visits $T: ident where $($where:tt)*) => {mod $mod {
    use std::marker::PhantomData;
    use std::any::Any;
    use $crate::dynamic::list_of_types::{List, ListedType, SubListRepresentative, GlobalListConscious};
    pub trait Visitor {
      fn visit<$T>(&mut self) where $($where)*;
    }
    pub unsafe trait SubList: List {
      fn visit_all<V: Visitor>(visitor: &mut V);
      fn count()->usize;
      fn count_before<T>()->usize;
    }
    unsafe impl <T: Any> SubList for ListedType<T> {
      #[inline(always)]
      default fn visit_all<V: Visitor>(_: &mut V) {}
      #[inline(always)]
      default fn count()->usize {0}
      #[inline(always)]
      default fn count_before<U>()->usize {panic!("invoked count_before on a list that doesn't contain the type")}
    }
    unsafe impl <$T: Any> SubList for ListedType<$T> where $($where)* {
      #[inline(always)]
      fn visit_all<V: Visitor>(visitor: &mut V) {
        visitor.visit::<$T>();
      }
      #[inline(always)]
      fn count()->usize {1}
      #[inline(always)]
      fn count_before<U>()->usize {0}
    }
    __time_steward_internal_sublist_tuple_impls! (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31);

    pub struct Representative <GlobalList: SubList> (PhantomData <GlobalList>,!);
    impl <GlobalList: SubList> GlobalListConscious for Representative <GlobalList> {
      type GlobalList = GlobalList;
    }
    unsafe impl <GlobalList: SubList> SubListRepresentative for Representative <GlobalList> {
      fn count()->usize {
        $crate::dynamic::list_of_types::assert_unique_global_list::<GlobalList>();
        GlobalList::count()
      }
      fn count_before<T>()->usize {
        $crate::dynamic::list_of_types::assert_unique_global_list::<GlobalList>();
        GlobalList::count_before::<T>()
      }
    }/*{
      fn visit_all<V: Visitor>(visitor: &mut V) {
        GlobalList::visit_all(visitor);
      }
    }*/
  }}
}
pub struct ListedType<T: Any>(PhantomData <T>, !);

#[macro_export]
#[doc(hidden)]
macro_rules! __time_steward_internal_sublist_tuple_impls {
  ($TL: ident $(, $T: ident)*) => {
    unsafe impl<$($T,)* $TL> SubList for ($($T,)* $TL,)
      where $($T: SubList,)* $TL: SubList
    {
      #[inline(always)]
      fn visit_all<V: Visitor>(visitor: &mut V) {
        $($T::visit_all(visitor);)*
        $TL::visit_all(visitor);
      }
      #[inline(always)]
      fn count()->usize {
        $($T::count() + )* $TL::count()
      }
      #[inline(always)]
      fn count_before<T>()->usize {
        let count = 0;
        $(if $T::includes::<T> () {return count + $T::count_before::<T>()}
        let count = count + $T::count();)*
        if $TL::includes::<T> () {return count + $TL::count_before::<T>()}
        panic!("invoked count_before on a list that doesn't contain the type")
      }
    }
    __time_steward_internal_sublist_tuple_impls! ($($T),*);
  };
  () => {};
}

pub unsafe trait List: Any {
  fn includes <T> ()->bool;
}
pub trait GlobalListConscious {
  type GlobalList: List;
}
pub unsafe trait SubListRepresentative {
  fn count()->usize;
  fn count_before<T>()->usize;
}

pub unsafe trait AmI <T> {fn am_i()->bool;}
unsafe impl <T, U> AmI <T> for U {default fn am_i()->bool {false}}
unsafe impl <T> AmI <T> for T {fn am_i()->bool {true}}

unsafe impl <T: Any> List for ListedType<T> {
  #[inline(always)]
  fn includes<U>()->bool {<T as AmI<U>>::am_i()}
}

macro_rules! tuple_impls {
  ($TL: ident $(, $T: ident)*) => {
    unsafe impl<$($T,)* $TL> List for ($($T,)* $TL,)
      where $($T: List,)* $TL: List
    {
      #[inline(always)]
      fn includes<T>()->bool {
        $($T::includes::<T>() || )* $TL::includes::<T>()
      }
    }
    tuple_impls! ($($T),*);
  };
  () => {};
}

tuple_impls! (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31);

#[derive (Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct DeterministicallyRandomlyIdentifiedTypeId(u64);
pub trait DeterministicallyRandomlyIdentifiedType {
  const ID: DeterministicallyRandomlyIdentifiedTypeId;
}

fn assert_unique_global_list <GlobalList: List>() {
  use std::any::TypeId;
  use std::cell::Cell;
  thread_local! {
    static LIST_ID: Cell<Option <TypeId>> = Cell::new (None);
  }
  LIST_ID.with (| id_cell | {
    let id = TypeId::of::<GlobalList>();
    if let Some (existing) = id_cell.get() {
      assert!(id == existing, "invoked dynamic function with two different global lists (see the list_of_types documentation for why this is wrong");
      return
    }
    id_cell.set (Some(id));
  });
}

time_steward_make_sublist! (
mod whatever visits T where T: super::DeterministicallyRandomlyIdentifiedType);
/*
#[macro_export]
macro_rules! time_steward_sublist_fn {
  (static $visitor_data: ident: $VisitorData: ty: $VisitorTrait: ident = $initial_value: expr followed by visit<$T> (&mut $self_hack) $visitation_effect: expr; fn $function_name: ident <$GlobalList: $SubList: ident> ($($argument_name: ident: $argument_type:ty),*)->$return_type:ty $($body:tt)*) => {

    fn $function_name <GlobalList: $List> $($argument_name: $argument_type),*)->$return_type:ty {
      struct Visitor ($VisitorData);
      impl VisitorTrait for Visitor {
        fn visit<$T>(&mut $self_hack) where  {$visitation_effect}
      }
      thread_local! {
        static DATA: $VisitorData = {
          let mut visitor = Visitor ($initial_value);
          <GlobalList as DeterministicallyRandomlyIdentifiedTypesList>::visit_all (&mut visitor);
          visitor.0
        };
      }
      DATA.with (| $visitor_data | {$($body)*})
  }
}
  */

#[macro_export]
macro_rules! time_steward_visit_sublist {
  (&mut $object: ident: $Object: ty, <$GlobalList: ident as $mod: ident::SubList>, $($method: tt)*) => {
    impl $mod::Visitor for $Object {
      $($method)*
    }
    <$GlobalList as $mod::SubList>::visit_all (&mut $object);
  }
}
#[macro_export]
macro_rules! time_steward_with_sublist_table {
  (<$GlobalList: ident as $mod: ident::SubList>, Vec<$Entry: ty> [$T: ident => {$entry: expr} where $($where: tt)*], | $table: ident | $($closure: tt)*) => {{
    assert_unique_global_list::<$GlobalList>();
    use std::cell::RefCell;
    use std::mem;
    thread_local! {
      static TABLE: RefCell<Vec<DeterministicallyRandomlyIdentifiedTypeId>> = RefCell::new(Vec::new());
    }
    TABLE.with (| table | {
      let mut guard = table.borrow_mut();
      if guard.is_empty() {
        mem::replace (&mut*guard, {
          let mut result = Vec::with_capacity($mod::Representative::<$GlobalList>::count());
          time_steward_visit_sublist! (
            &mut result: Vec<$Entry>,
            <$GlobalList as $mod::SubList>,
            fn visit<$T>(&mut self) where $($where)* {self.push ($entry);}
          );
          result
        });
      }
      let $table = &*guard;
      $($closure)*
    })
  }}
}

use std::any::Any ;

fn index_to_id <GlobalList: whatever::SubList> (index: usize)->Option <DeterministicallyRandomlyIdentifiedTypeId> {
  time_steward_with_sublist_table! (
    <GlobalList as whatever::SubList>,
    Vec<DeterministicallyRandomlyIdentifiedTypeId> [T => {T::ID} where T: DeterministicallyRandomlyIdentifiedType],
    | table | table.get (index).cloned()
  )
}

#[macro_export]
macro_rules! time_steward_dynamic_sublist_fn {
  (fn $function_name: ident <GlobalList as $mod: ident::SubList> (index: usize)->{$inner_function: ident::<Type(index)> ($($arguments: tt)*)->$Return:ty} where $($where: tt)*) => {
    fn $function_name <GlobalList: $mod::SubList> (index: usize)->fn ($($arguments)*)->$Return {
      time_steward_with_sublist_table! (
        <GlobalList as whatever::SubList>,
        Vec<DeterministicallyRandomlyIdentifiedTypeId> [T => {$inner_function::<T>} where $($where)*],
        | table | *table.get (index).expect("invoked dynamic sublist fn with an invalid index")
      )
    }
  }
}

<|endoftext|>


<commit_before>macro_rules! toml_template {
    ($name: expr) => {
        format_args!(
            r##"
[package]
name = "{0}-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.3"

[dependencies.{0}]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]
"##,
            $name
        )
    };
}

macro_rules! toml_bin_template {
    ($name: expr) => {
        format_args!(
            r#"
[[bin]]
name = "{0}"
path = "fuzz_targets/{0}.rs"
test = false
doc = false
"#,
            $name
        )
    };
}

macro_rules! gitignore_template {
    () => {
        format_args!(
            r##"
target
corpus
artifacts
"##
        )
    };
}

macro_rules! target_template {
    () => {
        format_args!(
            r##"#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {{
    // fuzzed code goes here
}});
"##
        )
    };
}
<commit_msg>Use `libfuzzer-sys` version 0.4.0 in the new project template<commit_after>macro_rules! toml_template {
    ($name: expr) => {
        format_args!(
            r##"
[package]
name = "{0}-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"

[dependencies.{0}]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]
"##,
            $name
        )
    };
}

macro_rules! toml_bin_template {
    ($name: expr) => {
        format_args!(
            r#"
[[bin]]
name = "{0}"
path = "fuzz_targets/{0}.rs"
test = false
doc = false
"#,
            $name
        )
    };
}

macro_rules! gitignore_template {
    () => {
        format_args!(
            r##"
target
corpus
artifacts
"##
        )
    };
}

macro_rules! target_template {
    () => {
        format_args!(
            r##"#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {{
    // fuzzed code goes here
}});
"##
        )
    };
}
<|endoftext|>