<commit_before>/*
* A basic EBML parser for Rust. Gives methods for both approaches; full parsing
* of an EBML file in-memory or incremental sequential parsing of nodes for
* environments that are more memory-constrained.
*
* The full parser allows you to get all sub-elements of a node in one call,
* because each node has a reference to the data it contains. All of the data is
* loaded into memory when the root node is parsed.
*
* The PartialElement only reads the data it needs to get the header of any
* single element. So if the data source is a file the full parser will load the
* whole file to memory, while the partial parser will only load at most one leaf
* node's value plus its id and size.
*
* The partial parser stores the offset of each node in the input stream, which
* is then used to jump to the node's data in the stream. This may cause the
* partial parser to do more random seeking.
*/

//extern crate time;
//use std::io::Memreader;
//use time::Timespec;
use std::io;

mod rebml {
    mod incremental {
        pub struct Parser {
            input: &Reader,
            id: u32,
            size: u64
        }

        impl Parser {
            // Create new EBML Parser and read in the first tag, if any. Consumes the input stream.
            fn new(&self) -> IoResult<Parser> {

            }

            /*
            Get next the next node after this one in the given input stream.
            */
            fn next(&self) -> Option<IoError> {
            }

            /*
            Get the subnode below this one, if any exists (returns IoError on failure)
            */
            fn down(&self) -> Option<IoError> {
            }

            /*
            Get the current depth in the Element tree
            */
            fn level(&self) -> u32 {}

            /*
            Get the value of this node
            */
            fn value(input: &Reader) -> IoResult<Value> {
            }
        }
    }
}
<commit_msg>Started on the implementation for the partial parser.<commit_after>/*
* A basic EBML parser for Rust. Gives methods for both approaches; full parsing
* of an EBML file in-memory or incremental sequential parsing of nodes for
* environments that are more memory-constrained.
*
* The full parser allows you to get all sub-elements of a node in one call,
* because each node has a reference to the data it contains. All of the data is
* loaded into memory when the root node is parsed.
*
* The PartialElement only reads the data it needs to get the header of any
* single element. So if the data source is a file the full parser will load the
* whole file to memory, while the partial parser will only load at most one leaf
* node's value plus its id and size.
*
* The partial parser stores the offset of each node in the input stream, which
* is then used to jump to the node's data in the stream. This may cause the
* partial parser to do more random seeking.
*/

//extern crate time;
//use std::io::Memreader;
//use time::Timespec;

mod rebml {
    use time::Timespec;
    enum Value {
		Uint(u64),
		Int(i64),
		Str(String),
		DateTimespec),
		Bin(&[u8]),
        SubElement,
		Nil, // Empty element
	}

    mod incremental {
        use std::io::{IoResult,IoError};
        pub struct Parser {
            input: &Reader,
            id: u32,
            size: u64
        }

        impl Parser {
            /*
            Create new EBML Parser and read in the first tag, if any. Expects the stream to start with the top-level
            EBML tag [1A][45][DF][A3]. Consumes the input stream.
            */
            pub fn new(input: Reader) -> IoResult<Parser> {
                let mut parser: Parser;
                parser.input = input;
                match parser.read_id() {
                    Ok(val) => parser.id = val,
                    Err(err) => return err,
                }
                match parser.read_size() {
                    Ok(val) => parser.size = val,
                    Err(err) => return err
                }
            }

            /*
            Get next the next node after this one in the given input stream.
            */
            pub fn next(&self) -> Option<IoError> {
            }

            /*
            Get the subnode below this one, if any exists (returns IoError on failure)
            */
            pub fn down(&self) -> Option<IoError> {
            }

            /*
            Get the current depth in the Element tree
            */
            pub fn level(&self) -> u32 {}

            /*
            Get the value of this node
            */
            pub fn value(input: &Reader) -> IoResult<Value> {
            }

            /*
            Helper function to read an id from the stream
            */
            fn read_id(&self) -> IoResult<u32> {
                // read first byte
                let u8 = match self.input.read_byte() {
                    Ok(val) => val,
                    Err(err) => return err, // TODO: will this actually return from fn? is there a better way to format this block?
                }
                // TODO: Count zeroes to get number of trailing bytes
                // TODO: Read trailing bytes
            }

            /*
            Helper function to read size from the stream
            */
            fn read_size(&self) -> IoResult<u64> {
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

#[macro_use] extern crate bitflags;
extern crate libc;

use std::io::{self, Error};
use std::os::unix::io::RawFd;

bitflags! {
    pub flags ControlOptions: i32 {
        /// Indicates an addition to the interest list.
        const EPOLL_CTL_ADD = libc::EPOLL_CTL_ADD,
        /// Indicates a modification of flags for an interest already in list.
        const EPOLL_CTL_MOD = libc::EPOLL_CTL_MOD,
        /// Indicates a removal of an interest from the list.
        const EPOLL_CTL_DEL = libc::EPOLL_CTL_DEL
    }
}

bitflags! {
    pub flags Events: u32 {
        /// Sets the Edge Triggered behavior for the associated file descriptor.
        ///
        /// The default behavior for epoll is Level Triggered.
        const EPOLLET      = libc::EPOLLET as u32,
        /// The associated file is available for read operations.
        const EPOLLIN      = libc::EPOLLIN as u32,
        /// Error condition happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; is not necessary to set it in events.
        const EPOLLERR     = libc::EPOLLERR as u32,
        /// Hang up happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; it is not necessary to set it in events.
        /// Note that when reading from a channel such as a pipe or a stream socket, this event
        /// merely indicates that the peer closed its end of the channel. Subsequent reads from
        /// the channel will return 0 (end of file) only after all outstanding data in the
        /// channel has been consumed.
        const EPOLLHUP     = libc::EPOLLHUP as u32,
        /// The associated file is available for write operations.
        const EPOLLOUT     = libc::EPOLLOUT as u32,
        /// There is urgent data available for read operations.
        const EPOLLPRI     = libc::EPOLLPRI as u32,
        /// Stream socket peer closed connection, or shut down writing half of connection.
        ///
        /// This flag is especially useful for writing simple code to detect peer shutdown when
        /// using Edge Triggered monitoring.
        const EPOLLRDHUP   = libc::EPOLLRDHUP as u32,
        /// If `EPOLLONESHOT` and `EPOLLET` are clear and the process has the `CAP_BLOCK_SUSPEND`
        /// capability, ensure that the system does not enter "suspend" or "hibernate" while this
        /// event is pending or being processed.
        ///
        /// The event is considered as being "processed" from the time when it is returned by
        /// a call to `wait` until the next call to `wait` on the same `EpollInstance`
        /// descriptor, the closure of that file descriptor, the removal of the event file
        /// descriptor with `EPOLL_CTL_DEL`, or the clearing of `EPOLLWAKEUP` for the event file
        /// descriptor with `EPOLL_CTL_MOD`.
        const EPOLLWAKEUP  = libc::EPOLLWAKEUP as u32,
        /// Sets the one-shot behavior for the associated file descriptor.
        ///
        /// This means that after an event is pulled out with `wait` the associated file
        /// descriptor is internally disabled and no other events will be reported by the epoll
        /// interface.  The user must call `ctl` with `EPOLL_CTL_MOD` to rearm the file
        /// descriptor with a new event mask.
        const EPOLLONESHOT = libc::EPOLLONESHOT as u32
    }
}

/// 'libc::epoll_event' equivalent.
#[repr(C)]
#[repr(packed)]
#[derive(Clone, Copy)]
pub struct Event {
    events: u32,
    data: u64
}

impl Event {
    pub fn new(events: Events, data: u64) -> Event {
        Event { events: events.bits(), data: data }
    }
}

/// Creates a new epoll file descriptor.
///
/// If `cloexec` is true, `FD_CLOEXEC` will be set on the returned file descriptor.
///
/// ## Notes
///
/// * `epoll_create(1)` is the underlying syscall.
pub fn create(cloexec: bool) -> io::Result<RawFd> {
    let epfd = unsafe {
        let fd = try!(cvt(libc::epoll_create(1)));
        if cloexec {
            let mut flags = try!(cvt(libc::fcntl(fd, libc::F_GETFD)));
            flags |= libc::FD_CLOEXEC;
            try!(cvt(libc::fcntl(fd, libc::F_SETFD, flags)));
        }
        fd
    };
    Ok(epfd)
}

/// Safe wrapper for `libc::epoll_ctl`
pub fn ctl(epfd: RawFd,
           op: ControlOptions,
           fd: RawFd,
           mut event: Event)
           -> io::Result<()>
{
    let e = &mut event as *mut _ as *mut libc::epoll_event;
    unsafe { try!(cvt(libc::epoll_ctl(epfd, op.bits, fd, e))) };
    Ok(())
}

/// Safe wrapper for `libc::epoll_wait`
///
/// ## Notes
///
/// * If `timeout` is negative, it will block until an event is received.
pub fn wait(epfd: RawFd,
            timeout: i32,
            buf: &mut [Event])
            -> io::Result<usize>
{
    let timeout = if timeout < -1 { -1 } else { timeout };
    let num_events = unsafe {
        try!(cvt(libc::epoll_wait(epfd,
                                  buf.as_mut_ptr() as *mut libc::epoll_event,
                                  buf.len() as i32,
                                  timeout))) as usize
    };
    Ok(num_events)
}

fn cvt(result: libc::c_int) -> io::Result<libc::c_int> {
    if result < 0 { Err(Error::last_os_error()) } else { Ok(result) }
}
<commit_msg>Make Event::events and Event::data public<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

#[macro_use] extern crate bitflags;
extern crate libc;

use std::io::{self, Error};
use std::os::unix::io::RawFd;

bitflags! {
    pub flags ControlOptions: i32 {
        /// Indicates an addition to the interest list.
        const EPOLL_CTL_ADD = libc::EPOLL_CTL_ADD,
        /// Indicates a modification of flags for an interest already in list.
        const EPOLL_CTL_MOD = libc::EPOLL_CTL_MOD,
        /// Indicates a removal of an interest from the list.
        const EPOLL_CTL_DEL = libc::EPOLL_CTL_DEL
    }
}

bitflags! {
    pub flags Events: u32 {
        /// Sets the Edge Triggered behavior for the associated file descriptor.
        ///
        /// The default behavior for epoll is Level Triggered.
        const EPOLLET      = libc::EPOLLET as u32,
        /// The associated file is available for read operations.
        const EPOLLIN      = libc::EPOLLIN as u32,
        /// Error condition happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; is not necessary to set it in events.
        const EPOLLERR     = libc::EPOLLERR as u32,
        /// Hang up happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; it is not necessary to set it in events.
        /// Note that when reading from a channel such as a pipe or a stream socket, this event
        /// merely indicates that the peer closed its end of the channel. Subsequent reads from
        /// the channel will return 0 (end of file) only after all outstanding data in the
        /// channel has been consumed.
        const EPOLLHUP     = libc::EPOLLHUP as u32,
        /// The associated file is available for write operations.
        const EPOLLOUT     = libc::EPOLLOUT as u32,
        /// There is urgent data available for read operations.
        const EPOLLPRI     = libc::EPOLLPRI as u32,
        /// Stream socket peer closed connection, or shut down writing half of connection.
        ///
        /// This flag is especially useful for writing simple code to detect peer shutdown when
        /// using Edge Triggered monitoring.
        const EPOLLRDHUP   = libc::EPOLLRDHUP as u32,
        /// If `EPOLLONESHOT` and `EPOLLET` are clear and the process has the `CAP_BLOCK_SUSPEND`
        /// capability, ensure that the system does not enter "suspend" or "hibernate" while this
        /// event is pending or being processed.
        ///
        /// The event is considered as being "processed" from the time when it is returned by
        /// a call to `wait` until the next call to `wait` on the same `EpollInstance`
        /// descriptor, the closure of that file descriptor, the removal of the event file
        /// descriptor with `EPOLL_CTL_DEL`, or the clearing of `EPOLLWAKEUP` for the event file
        /// descriptor with `EPOLL_CTL_MOD`.
        const EPOLLWAKEUP  = libc::EPOLLWAKEUP as u32,
        /// Sets the one-shot behavior for the associated file descriptor.
        ///
        /// This means that after an event is pulled out with `wait` the associated file
        /// descriptor is internally disabled and no other events will be reported by the epoll
        /// interface.  The user must call `ctl` with `EPOLL_CTL_MOD` to rearm the file
        /// descriptor with a new event mask.
        const EPOLLONESHOT = libc::EPOLLONESHOT as u32
    }
}

/// 'libc::epoll_event' equivalent.
#[repr(C)]
#[repr(packed)]
#[derive(Clone, Copy)]
pub struct Event {
    pub events: u32,
    pub data: u64
}

impl Event {
    pub fn new(events: Events, data: u64) -> Event {
        Event { events: events.bits(), data: data }
    }
}

/// Creates a new epoll file descriptor.
///
/// If `cloexec` is true, `FD_CLOEXEC` will be set on the returned file descriptor.
///
/// ## Notes
///
/// * `epoll_create(1)` is the underlying syscall.
pub fn create(cloexec: bool) -> io::Result<RawFd> {
    let epfd = unsafe {
        let fd = try!(cvt(libc::epoll_create(1)));
        if cloexec {
            let mut flags = try!(cvt(libc::fcntl(fd, libc::F_GETFD)));
            flags |= libc::FD_CLOEXEC;
            try!(cvt(libc::fcntl(fd, libc::F_SETFD, flags)));
        }
        fd
    };
    Ok(epfd)
}

/// Safe wrapper for `libc::epoll_ctl`
pub fn ctl(epfd: RawFd,
           op: ControlOptions,
           fd: RawFd,
           mut event: Event)
           -> io::Result<()>
{
    let e = &mut event as *mut _ as *mut libc::epoll_event;
    unsafe { try!(cvt(libc::epoll_ctl(epfd, op.bits, fd, e))) };
    Ok(())
}

/// Safe wrapper for `libc::epoll_wait`
///
/// ## Notes
///
/// * If `timeout` is negative, it will block until an event is received.
pub fn wait(epfd: RawFd,
            timeout: i32,
            buf: &mut [Event])
            -> io::Result<usize>
{
    let timeout = if timeout < -1 { -1 } else { timeout };
    let num_events = unsafe {
        try!(cvt(libc::epoll_wait(epfd,
                                  buf.as_mut_ptr() as *mut libc::epoll_event,
                                  buf.len() as i32,
                                  timeout))) as usize
    };
    Ok(num_events)
}

fn cvt(result: libc::c_int) -> io::Result<libc::c_int> {
    if result < 0 { Err(Error::last_os_error()) } else { Ok(result) }
}
<|endoftext|>


<commit_before>//! Provides some common lints for syntax extensions.
#![feature(plugin_registrar)]
#![feature(rustc_private)]

extern crate syntax;
#[macro_use]
extern crate rustc;

use syntax::ast;
use syntax::parse::token;
use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
use rustc::plugin;
use std::ops::Deref;

declare_lint!(DUMMY_SPAN,
              Warn,
              "detects uses of DUMMY_SP");

struct Pass;

impl Pass {
    fn new() -> Pass {
        Pass
    }
}

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

    fn check_expr(&mut self, cx: &Context, expr: &ast::Expr) {
        match expr.node {
            ast::ExprPath(None, ref path) => {
                let name = token::get_ident(path.segments.last().unwrap().identifier);
                if name.deref() == "DUMMY_SP" {
                    cx.span_lint(DUMMY_SPAN, expr.span,
                                 "usage of 'DUMMY_SP' is discouraged");
                }
            },
            _ => {},
        }
    }
}

#[plugin_registrar]
pub fn register_plugins(reg: &mut plugin::Registry) {
    reg.register_lint_pass(Box::new(Pass::new()) as LintPassObject);
}
<commit_msg>refactor: get_ident -> name.as_str<commit_after>//! Provides some common lints for syntax extensions.
#![feature(plugin_registrar)]
#![feature(rustc_private)]

extern crate syntax;
#[macro_use]
extern crate rustc;

use syntax::ast;
use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
use rustc::plugin;
use std::ops::Deref;

declare_lint!(DUMMY_SPAN,
              Warn,
              "detects uses of DUMMY_SP");

struct Pass;

impl Pass {
    fn new() -> Pass {
        Pass
    }
}

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

    fn check_expr(&mut self, cx: &Context, expr: &ast::Expr) {
        match expr.node {
            ast::ExprPath(None, ref path) => {
                let name = path.segments.last().unwrap().identifier.name.as_str();
                if name.deref() == "DUMMY_SP" {
                    cx.span_lint(DUMMY_SPAN, expr.span,
                                 "usage of 'DUMMY_SP' is discouraged");
                }
            },
            _ => {},
        }
    }
}

#[plugin_registrar]
pub fn register_plugins(reg: &mut plugin::Registry) {
    reg.register_lint_pass(Box::new(Pass::new()) as LintPassObject);
}
<|endoftext|>


<commit_before>// src/lib.rs
//
// Copyright 2015 David Creswick
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! # Mersenne Twister
//!
//! A pure rust port of the Mersenne Twister pseudorandom number
//! generator.
//!
//! **THESE ALGORITHMS ARE NOT APPROPRIATE FOR CRYPTOGRAPHIC USE.**
//!
//!
//! ## Usage
//!
//! If your application does not require a specific Mersenne Twister
//! flavor, you can use the default one for your target platform this
//! way:
//!
//! ```
//! extern crate mersenne_twister;
//! use mersenne_twister::MersenneTwister;
//! use std::rand::{Rng, SeedableRng};
//!
//! fn main() {
//!     // Get a seed somehow.
//!     let seed: u64 = 0x123456789abcdef;
//!     // Create the default RNG.
//!     let mut rng: MersenneTwister = SeedableRng::from_seed(seed);
//!
//!     // start grabbing randomness from rng...
//! }
//! ```
//!
//! Or if you want to use the default (fixed) seeds:
//!
//! ```
//! # use mersenne_twister::MersenneTwister;
//! # use std::rand::{Rng, SeedableRng};
//! use std::default::Default;
//! let mut rng: MersenneTwister = Default::default();
//! ```
//!
//! ## Portability
//!
//! Note that `MT19937` and `MT19937_64` are **not** identical
//! algorithms, despite their similar names. They produce different
//! output streams when given the same seed. You will need to pick a
//! specific flavor of the algorithm if portable reproducibility is
//! important to you.

#![unstable]
#![feature(core, test, rand)]
#![deny(missing_docs)]

#[cfg(test)]
extern crate test;

pub use mt19937::MT19937;
pub use mt19937_64::MT19937_64;

mod mt19937;
mod mt19937_64;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "32")]
pub type MersenneTwister = MT19937;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "64")]
pub type MersenneTwister = MT19937_64;
<commit_msg>fix doctest<commit_after>// src/lib.rs
//
// Copyright 2015 David Creswick
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! # Mersenne Twister
//!
//! A pure rust port of the Mersenne Twister pseudorandom number
//! generator.
//!
//! **THESE ALGORITHMS ARE NOT APPROPRIATE FOR CRYPTOGRAPHIC USE.**
//!
//!
//! ## Usage
//!
//! If your application does not require a specific Mersenne Twister
//! flavor, you can use the default one for your target platform this
//! way:
//!
//! ```
//! #![feature(rand)]
//! extern crate mersenne_twister;
//! use mersenne_twister::MersenneTwister;
//! use std::rand::{Rng, SeedableRng};
//!
//! fn main() {
//!     // Get a seed somehow.
//!     let seed: u64 = 0x123456789abcdef;
//!     // Create the default RNG.
//!     let mut rng: MersenneTwister = SeedableRng::from_seed(seed);
//!
//!     // start grabbing randomness from rng...
//! }
//! ```
//!
//! Or if you want to use the default (fixed) seeds:
//!
//! ```
//! # use mersenne_twister::MersenneTwister;
//! # use std::rand::{Rng, SeedableRng};
//! use std::default::Default;
//! let mut rng: MersenneTwister = Default::default();
//! ```
//!
//! ## Portability
//!
//! Note that `MT19937` and `MT19937_64` are **not** identical
//! algorithms, despite their similar names. They produce different
//! output streams when given the same seed. You will need to pick a
//! specific flavor of the algorithm if portable reproducibility is
//! important to you.

#![unstable]
#![feature(core, test, rand)]
#![deny(missing_docs)]

#[cfg(test)]
extern crate test;

pub use mt19937::MT19937;
pub use mt19937_64::MT19937_64;

mod mt19937;
mod mt19937_64;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "32")]
pub type MersenneTwister = MT19937;

/// The most platform-appropriate Mersenne Twister flavor.
#[cfg(target_pointer_width = "64")]
pub type MersenneTwister = MT19937_64;
<|endoftext|>


<commit_before>extern crate rand;
extern crate rayon;
// extern crate crossbeam;

use self::rand::{thread_rng, Rng};
use std::sync::{Arc, Mutex, RwLock};
use rayon::prelude::*;

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum State {
	Dead,
	Alive,
}

#[derive(Clone, PartialEq, Eq)]
pub struct GameCell {
	x: usize,
	y: usize,
	pub state: State,
}

impl GameCell {
	fn count_neighbors(&self, board: &Vec<GameCell>, size: usize) -> usize {
		let mut count: usize = 0;

		// UL
		match board.get((self.y - 1) * size + self.x - 1) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// UU
		match board.get((self.y - 1) * size + self.x + 0) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// UR
		match board.get((self.y - 1) * size + self.x + 1) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// L
		match board.get(self.y * size + self.x - 1) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// R
		match board.get(self.y * size + self.x + 1) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// DL
		match board.get((self.y + 1) * size + self.x - 1) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// DD
		match board.get((self.y + 1) * size + self.x + 0) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		// DR
		match board.get((self.y + 1) * size + self.x + 1) {
			Some(&GameCell {state: State::Alive, ..}) => count += 1,
			_ => {},
		}

		count
	}
}

// struct Board( Vec<GameCell> );

// impl Index<usize> for Board {
// 	type Output = State;

// 	fn index(&self, index: usize) -> &State {
// 		self.0[index].state;
// 	}
// }

#[derive(Clone)]
pub struct Game {
	pub size: usize,
	current: Arc<RwLock< Vec<GameCell> >>,
	next: Arc<Mutex< Vec<GameCell> >>,
}

// impl From<Vec<State>> for Game {
// 	fn from(preset_game: Vec<State>) -> Self {
// 		let size: usize = (preset_game.len() as f64).sqrt() as usize;
// 		assert!(size >= 3);

// 		Game {
// 			size: size,
// 			current: Arc::new(RwLock::new(preset_game.clone())),
// 			next: Arc::new(Mutex::new(preset_game.clone()))
// 		}
// 	}
// }

impl Game {
	pub fn new(size: usize, percent_chance_for_cell_to_be_alive: f64) -> Game {
		assert!(size >= 3);
		assert!(percent_chance_for_cell_to_be_alive < 1.0);
		assert!(percent_chance_for_cell_to_be_alive >= 0.0);

		let mut board = vec![GameCell {x: 0, y: 0, state: State::Dead}; size*size];

		for y in 0..size {
			for x in 0..size {
				let index = y * size + x;
				board[index].x = x;
				board[index].y = y;
				board[index].state = match thread_rng().next_f64() {
					i if i < percent_chance_for_cell_to_be_alive => State::Alive,
					_ => State::Dead,
				};
			}
		}

		Game {
			size: size,
			current: Arc::new(RwLock::new(board)),
			next: Arc::new(Mutex::new(Vec::with_capacity(size))),
		}
	}

	pub fn get_current_read_lock(&self) -> std::sync::RwLockReadGuard< Vec<GameCell> > {
		self.current.read().unwrap()
	}

	fn get_next_cell_from_current_cell_and_neighbors(game_cell: &GameCell, number_of_neighbors: usize) -> GameCell {
		match game_cell.state {
			State::Dead => {
				if number_of_neighbors != 3 {
					GameCell {x: game_cell.x, y: game_cell.y, state: State::Dead}
				} else {
					GameCell {x: game_cell.x, y: game_cell.y, state: State::Alive}
				}
			},
			State::Alive => {
				if number_of_neighbors < 2 || number_of_neighbors > 3 {
					GameCell {x: game_cell.x, y: game_cell.y, state: State::Dead}
				} else {
					GameCell {x: game_cell.x, y: game_cell.y, state: State::Alive}
				}
			}
		}
	}

	pub fn advance(&self) {
		let mut next_guard = self.next.lock().unwrap();
		let current_guard = self.current.read().unwrap();

		current_guard.par_iter()
			.map(|game_cell| {
				let neighbor_count = game_cell.count_neighbors(&*current_guard, self.size);
				Game::get_next_cell_from_current_cell_and_neighbors(game_cell, neighbor_count)
			})
			.collect_into(&mut *next_guard);

		// Exchange read lock for write lock
		drop(current_guard);
		let mut current_guard = self.current.write().unwrap();

		*current_guard = next_guard.clone();
	}

	// pub fn advance_toroidally(&self) {
	// 	// Get read lock for 'current' and mutex lock for 'next'
	// 	// N.B. By locking 'next' first, this ensures that if another thread tries
	// 	// 		to call 'advance', that thread will block until this is done.
	// 	let mut next = self.next.lock().unwrap();
	// 	let current = self.current.read().unwrap();

	// 	for y in 0..self.size {
	// 		for x in 0..self.size {
	// 			let ul = if y >= 1 {
	// 				if x != 0 { current[(y - 1) * self.size + x - 1] } // normal case
	// 				else { current[y * self.size - 1] } // left edge
	// 			} else {
	// 				if x != 0 { current[(self.size - 1) * self.size + x - 1] } // top edge
	// 				else { current[self.size * self.size - 1] } // top-left corner
	// 			};

	// 			let uu = if y >= 1 {
	// 				current[(y - 1) * self.size + x + 0] // normal case
	// 			} else {
	// 				current[(self.size - 1) * self.size + x + 0] // top edge
	// 			};

	// 			let ur = if y >= 1 {
	// 				if x != self.size - 1 { current[(y - 1) * self.size + x + 1] } // normal case
	// 				else { current[(y - 1) * self.size + 0] } // right edge
	// 			} else {
	// 				if x != self.size - 1 { current[(self.size - 1) * self.size + x + 1] } // top edge
	// 				else { current[(self.size - 1) * self.size + 0] } // top-right corner
	// 			};

	// 			let l = if x != 0 {
	// 				current[y * self.size + x - 1] // normal case
	// 			} else {
	// 				current[(y + 1) * self.size - 1] // left edge
	// 			};

	// 			let r = if x != self.size - 1 {
	// 				current[y * self.size + x + 1] // normal case
	// 			} else {
	// 				current[y * self.size + 0] // right edge
	// 			};

	// 			let dl = if y != self.size - 1 {
	// 				if x != 0 { current[(y + 1) * self.size + x - 1] } // normal case
	// 				else { current[(y + 2) * self.size - 1] } // left edge
	// 			} else {
	// 				if x != 0 { current[x - 1] } // bottom edge
	// 				else { current[self.size - 1] } // bottom-left corner
	// 			};

	// 			let dd = if y != self.size - 1 {
	// 				current[(y + 1) * self.size + x + 0] // normal case
	// 			} else {
	// 				current[x + 0] // bottom edge
	// 			};

	// 			let dr = if y != self.size - 1 {
	// 				if x != self.size - 1 { current[(y + 1) * self.size + x + 1] } // normal case
	// 				else { current[(y + 1) * self.size] } // right edge
	// 			} else {
	// 				if x != self.size - 1 { current[x + 1] } // bottom edge
	// 				else { current[0] } // bottom-right corner
	// 			};

	// 			let mut neighbors: usize = 0;
	// 			if ul == State::Alive { neighbors += 1; }
	// 			if uu == State::Alive { neighbors += 1; }
	// 			if ur == State::Alive { neighbors += 1; }
	// 			if l == State::Alive { neighbors += 1; }
	// 			if r == State::Alive { neighbors += 1; }
	// 			if dl == State::Alive { neighbors += 1; }
	// 			if dd == State::Alive { neighbors += 1; }
	// 			if dr == State::Alive { neighbors += 1; }

	// 			next[y * self.size + x] = Game::get_next_cell_from_current_cell_and_neighbors(current[y * self.size + x], neighbors);
	// 		}
	// 	}

	// 	// Exchange read lock for write lock
	// 	drop(current);
	// 	let mut current = self.current.write().unwrap();

	// 	*current = next.clone();
	// }
}
<commit_msg>Eliminate State enum<commit_after>extern crate rand;
extern crate rayon;
// extern crate crossbeam;

use self::rand::{thread_rng, Rng};
use std::sync::{Arc, Mutex, RwLock};
use rayon::prelude::*;

#[derive(Clone, PartialEq, Eq)]
pub struct GameCell {
	x: usize,
	y: usize,
	pub alive: bool,
}

impl GameCell {
	fn count_neighbors(&self, board: &Vec<GameCell>, size: usize) -> u8 {
		let mut count: u8 = 0;

		// UL
		if let Some(&GameCell {alive: true, ..}) = board.get((self.y - 1) * size + self.x - 1) { count += 1; }

		// UU
		if let Some(&GameCell {alive: true, ..}) = board.get((self.y - 1) * size + self.x + 0) { count += 1; }

		// UR
		if let Some(&GameCell {alive: true, ..}) = board.get((self.y - 1) * size + self.x + 1) { count += 1; }

		// L
		if let Some(&GameCell {alive: true, ..}) = board.get(self.y * size + self.x - 1)       { count += 1; }

		// R
		if let Some(&GameCell {alive: true, ..}) = board.get(self.y * size + self.x + 1)       { count += 1; }

		// DL
		if let Some(&GameCell {alive: true, ..}) = board.get((self.y + 1) * size + self.x - 1) { count += 1; }

		// DD
		if let Some(&GameCell {alive: true, ..}) = board.get((self.y + 1) * size + self.x + 0) { count += 1; }

		// DR
		if let Some(&GameCell {alive: true, ..}) = board.get((self.y + 1) * size + self.x + 1) { count += 1; }

		count
	}
}

// struct Board( Vec<GameCell> );

// impl Index<usize> for Board {
// 	type Output = State;

// 	fn index(&self, index: usize) -> &State {
// 		self.0[index].state;
// 	}
// }

#[derive(Clone)]
pub struct Game {
	pub size: usize,
	current: Arc<RwLock< Vec<GameCell> >>,
	next: Arc<Mutex< Vec<GameCell> >>,
}

// impl From<Vec<State>> for Game {
// 	fn from(preset_game: Vec<State>) -> Self {
// 		let size: usize = (preset_game.len() as f64).sqrt() as usize;
// 		assert!(size >= 3);

// 		Game {
// 			size: size,
// 			current: Arc::new(RwLock::new(preset_game.clone())),
// 			next: Arc::new(Mutex::new(preset_game.clone()))
// 		}
// 	}
// }

impl Game {
	pub fn new(size: usize, percent_chance_for_cell_to_be_alive: f64) -> Game {
		assert!(size >= 3);
		assert!(percent_chance_for_cell_to_be_alive < 1.0);
		assert!(percent_chance_for_cell_to_be_alive >= 0.0);

		let mut board = vec![GameCell {x: 0, y: 0, alive: false}; size*size];

		for y in 0..size {
			for x in 0..size {
				let index = y * size + x;
				board[index].x = x;
				board[index].y = y;
				board[index].alive = match thread_rng().next_f64() {
					i if i < percent_chance_for_cell_to_be_alive => true,
					_ => false,
				};
			}
		}

		Game {
			size: size,
			current: Arc::new(RwLock::new(board)),
			next: Arc::new(Mutex::new(Vec::with_capacity(size))),
		}
	}

	pub fn get_current_read_lock(&self) -> std::sync::RwLockReadGuard< Vec<GameCell> > {
		self.current.read().unwrap()
	}

	fn get_next_cell_from_current_cell_and_neighbors(game_cell: &GameCell, number_of_neighbors: u8) -> GameCell {
		match game_cell.alive {
			false => {
				if number_of_neighbors != 3 {
					GameCell {x: game_cell.x, y: game_cell.y, alive: false}
				} else {
					GameCell {x: game_cell.x, y: game_cell.y, alive: true}
				}
			},
			true => {
				if number_of_neighbors < 2 || number_of_neighbors > 3 {
					GameCell {x: game_cell.x, y: game_cell.y, alive: false}
				} else {
					GameCell {x: game_cell.x, y: game_cell.y, alive: true}
				}
			},
		}
	}

	pub fn advance(&self) {
		let mut next_guard = self.next.lock().unwrap();
		let current_guard = self.current.read().unwrap();

		current_guard.par_iter()
			.map(|game_cell| {
				let neighbor_count = game_cell.count_neighbors(&*current_guard, self.size);
				Game::get_next_cell_from_current_cell_and_neighbors(game_cell, neighbor_count)
			})
			.collect_into(&mut *next_guard);

		// Exchange read lock for write lock
		drop(current_guard);
		let mut current_guard = self.current.write().unwrap();

		*current_guard = next_guard.clone();
	}

	// pub fn advance_toroidally(&self) {
	// 	// Get read lock for 'current' and mutex lock for 'next'
	// 	// N.B. By locking 'next' first, this ensures that if another thread tries
	// 	// 		to call 'advance', that thread will block until this is done.
	// 	let mut next = self.next.lock().unwrap();
	// 	let current = self.current.read().unwrap();

	// 	for y in 0..self.size {
	// 		for x in 0..self.size {
	// 			let ul = if y >= 1 {
	// 				if x != 0 { current[(y - 1) * self.size + x - 1] } // normal case
	// 				else { current[y * self.size - 1] } // left edge
	// 			} else {
	// 				if x != 0 { current[(self.size - 1) * self.size + x - 1] } // top edge
	// 				else { current[self.size * self.size - 1] } // top-left corner
	// 			};

	// 			let uu = if y >= 1 {
	// 				current[(y - 1) * self.size + x + 0] // normal case
	// 			} else {
	// 				current[(self.size - 1) * self.size + x + 0] // top edge
	// 			};

	// 			let ur = if y >= 1 {
	// 				if x != self.size - 1 { current[(y - 1) * self.size + x + 1] } // normal case
	// 				else { current[(y - 1) * self.size + 0] } // right edge
	// 			} else {
	// 				if x != self.size - 1 { current[(self.size - 1) * self.size + x + 1] } // top edge
	// 				else { current[(self.size - 1) * self.size + 0] } // top-right corner
	// 			};

	// 			let l = if x != 0 {
	// 				current[y * self.size + x - 1] // normal case
	// 			} else {
	// 				current[(y + 1) * self.size - 1] // left edge
	// 			};

	// 			let r = if x != self.size - 1 {
	// 				current[y * self.size + x + 1] // normal case
	// 			} else {
	// 				current[y * self.size + 0] // right edge
	// 			};

	// 			let dl = if y != self.size - 1 {
	// 				if x != 0 { current[(y + 1) * self.size + x - 1] } // normal case
	// 				else { current[(y + 2) * self.size - 1] } // left edge
	// 			} else {
	// 				if x != 0 { current[x - 1] } // bottom edge
	// 				else { current[self.size - 1] } // bottom-left corner
	// 			};

	// 			let dd = if y != self.size - 1 {
	// 				current[(y + 1) * self.size + x + 0] // normal case
	// 			} else {
	// 				current[x + 0] // bottom edge
	// 			};

	// 			let dr = if y != self.size - 1 {
	// 				if x != self.size - 1 { current[(y + 1) * self.size + x + 1] } // normal case
	// 				else { current[(y + 1) * self.size] } // right edge
	// 			} else {
	// 				if x != self.size - 1 { current[x + 1] } // bottom edge
	// 				else { current[0] } // bottom-right corner
	// 			};

	// 			let mut neighbors: usize = 0;
	// 			if ul == State::Alive { neighbors += 1; }
	// 			if uu == State::Alive { neighbors += 1; }
	// 			if ur == State::Alive { neighbors += 1; }
	// 			if l == State::Alive { neighbors += 1; }
	// 			if r == State::Alive { neighbors += 1; }
	// 			if dl == State::Alive { neighbors += 1; }
	// 			if dd == State::Alive { neighbors += 1; }
	// 			if dr == State::Alive { neighbors += 1; }

	// 			next[y * self.size + x] = Game::get_next_cell_from_current_cell_and_neighbors(current[y * self.size + x], neighbors);
	// 		}
	// 	}

	// 	// Exchange read lock for write lock
	// 	drop(current);
	// 	let mut current = self.current.write().unwrap();

	// 	*current = next.clone();
	// }
}
<|endoftext|>


<commit_before>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ascii::AsciiExt;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

/// A single version of a crate published to the index
#[derive(RustcDecodable, Clone)]
pub struct Version {
    name: String,
    vers: String,
    deps: Vec<Dependency>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

impl Version {
    /// Name of the crate
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Name of this version
    pub fn version(&self) -> &str {
        &self.vers
    }

    /// Dependencies for this version
    pub fn dependencies(&self) -> &[Dependency] {
        &self.deps
    }

    /// Checksum of the package for this version
    pub fn checksum(&self) -> &str {
        &self.cksum
    }

    pub fn features(&self) -> &HashMap<String, Vec<String>> {
        &self.features
    }

    /// Whether this version was [yanked](http://doc.crates.io/crates-io.html#cargo-yank) from the
    /// index
    pub fn is_yanked(&self) -> bool {
        self.yanked
    }
}

/// A single dependency of a specific crate version
#[derive(RustcDecodable, Clone)]
pub struct Dependency {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>
}

impl Dependency {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn requirement(&self) -> &str {
        &self.req
    }

    pub fn features(&self) -> &[String] {
        &self.features
    }

    pub fn is_optional(&self) -> bool {
        self.optional
    }

    pub fn has_default_features(&self) -> bool {
        self.default_features
    }

    pub fn target(&self) -> Option<&str> {
        match self.target {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    pub fn kind(&self) -> Option<&str> {
        match self.kind {
            Some(ref s) => Some(s),
            None => None,
        }
    }
}

/// Constructed from `Index::crates`
pub struct Crates(CrateIndexPaths);

impl Iterator for Crates {
    type Item = Crate;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|p| Crate::new(&p))
    }
}

/// Constructed from `Index::crate_index_paths`
pub struct CrateIndexPaths(std::iter::Chain<glob::Paths, glob::Paths>);

impl CrateIndexPaths {
    fn new<P: AsRef<Path>>(path: P) -> CrateIndexPaths {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;
        let path = path.as_ref();

        let glob_pattern = format!("{}/*/*/*", path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        CrateIndexPaths(index_paths1.chain(index_paths2))
    }
}

impl Iterator for CrateIndexPaths {
    type Item = PathBuf;
    fn next(&mut self)  -> Option<Self::Item> {
        self.0.next().map(|glob_result| glob_result.unwrap())
    }
}

/// Wrapper around managing the crates.io-index git repository
pub struct Index {
    path: PathBuf,
}

impl Index {
    /// Construct a new Index supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> Index {
        Index{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Downloads the index to the path specified from the constructor
    pub fn fetch(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    /// Retrieve a single crate by name (case insensitive) from the index
    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.crate_index_paths()
            .find(|path| path.file_name()
                             .and_then(OsStr::to_str)
                             .map(|file_name| file_name.eq_ignore_ascii_case(crate_name))
                             .unwrap_or(false))
            .map(|p| Crate::new(&p))
    }

    /// Retrieve an iterator over all the crates in the index
    pub fn crates(&self) -> Crates {
        Crates(self.crate_index_paths())
    }

    /// Returns all the crate index file paths in the index
    pub fn crate_index_paths(&self) -> CrateIndexPaths {
        CrateIndexPaths::new(self.path.clone())  // TODO: remove this clone
    }
}

/// A single crate that contains many published versions
pub struct Crate {
    versions: Vec<Version>,
}

impl Crate {
    pub fn new<P: AsRef<Path>>(index_path: P) -> Crate {
        let index_path = index_path.as_ref();
        let mut versions = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let version: Version = rustc_serialize::json::decode(&line.unwrap()).unwrap();
            versions.push(version);
        }
        Crate {versions: versions}
    }

    /// Published versions of this crate sorted chronologically by date published
    pub fn versions(&self) -> &[Version] {
        &self.versions
    }

    pub fn earliest_version(&self) -> &Version {
        &self.versions[0]
    }

    pub fn latest_version(&self) -> &Version {
        &self.versions[self.versions.len() - 1]
    }
}

#[test]
fn test_dependencies() {
    let index = Index::new("_test".into());
    if !index.exists() {
        index.fetch().unwrap();
    }
    let crate_ = index.crates().nth(0).unwrap();
    let version = crate_.latest_version();
    let _ = version.deps;
}
<commit_msg>cargo fmt.<commit_after>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ascii::AsciiExt;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

/// A single version of a crate published to the index
#[derive(RustcDecodable, Clone)]
pub struct Version {
    name: String,
    vers: String,
    deps: Vec<Dependency>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

impl Version {
    /// Name of the crate
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Name of this version
    pub fn version(&self) -> &str {
        &self.vers
    }

    /// Dependencies for this version
    pub fn dependencies(&self) -> &[Dependency] {
        &self.deps
    }

    /// Checksum of the package for this version
    pub fn checksum(&self) -> &str {
        &self.cksum
    }

    pub fn features(&self) -> &HashMap<String, Vec<String>> {
        &self.features
    }

    /// Whether this version was [yanked](http://doc.crates.io/crates-io.html#cargo-yank) from the
    /// index
    pub fn is_yanked(&self) -> bool {
        self.yanked
    }
}

/// A single dependency of a specific crate version
#[derive(RustcDecodable, Clone)]
pub struct Dependency {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>,
}

impl Dependency {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn requirement(&self) -> &str {
        &self.req
    }

    pub fn features(&self) -> &[String] {
        &self.features
    }

    pub fn is_optional(&self) -> bool {
        self.optional
    }

    pub fn has_default_features(&self) -> bool {
        self.default_features
    }

    pub fn target(&self) -> Option<&str> {
        match self.target {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    pub fn kind(&self) -> Option<&str> {
        match self.kind {
            Some(ref s) => Some(s),
            None => None,
        }
    }
}

/// Constructed from `Index::crates`
pub struct Crates(CrateIndexPaths);

impl Iterator for Crates {
    type Item = Crate;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|p| Crate::new(&p))
    }
}

/// Constructed from `Index::crate_index_paths`
pub struct CrateIndexPaths(std::iter::Chain<glob::Paths, glob::Paths>);

impl CrateIndexPaths {
    fn new<P: AsRef<Path>>(path: P) -> CrateIndexPaths {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;
        let path = path.as_ref();

        let glob_pattern = format!("{}/*/*/*", path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        CrateIndexPaths(index_paths1.chain(index_paths2))
    }
}

impl Iterator for CrateIndexPaths {
    type Item = PathBuf;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|glob_result| glob_result.unwrap())
    }
}

/// Wrapper around managing the crates.io-index git repository
pub struct Index {
    path: PathBuf,
}

impl Index {
    /// Construct a new Index supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> Index {
        Index { path: path }
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Downloads the index to the path specified from the constructor
    pub fn fetch(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    /// Retrieve a single crate by name (case insensitive) from the index
    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.crate_index_paths()
            .find(|path| {
                path.file_name()
                    .and_then(OsStr::to_str)
                    .map(|file_name| file_name.eq_ignore_ascii_case(crate_name))
                    .unwrap_or(false)
            })
            .map(|p| Crate::new(&p))
    }

    /// Retrieve an iterator over all the crates in the index
    pub fn crates(&self) -> Crates {
        Crates(self.crate_index_paths())
    }

    /// Returns all the crate index file paths in the index
    pub fn crate_index_paths(&self) -> CrateIndexPaths {
        CrateIndexPaths::new(self.path.clone()) // TODO: remove this clone
    }
}

/// A single crate that contains many published versions
pub struct Crate {
    versions: Vec<Version>,
}

impl Crate {
    pub fn new<P: AsRef<Path>>(index_path: P) -> Crate {
        let index_path = index_path.as_ref();
        let mut versions = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let version: Version = rustc_serialize::json::decode(&line.unwrap()).unwrap();
            versions.push(version);
        }
        Crate { versions: versions }
    }

    /// Published versions of this crate sorted chronologically by date published
    pub fn versions(&self) -> &[Version] {
        &self.versions
    }

    pub fn earliest_version(&self) -> &Version {
        &self.versions[0]
    }

    pub fn latest_version(&self) -> &Version {
        &self.versions[self.versions.len() - 1]
    }
}

#[test]
fn test_dependencies() {
    let index = Index::new("_test".into());
    if !index.exists() {
        index.fetch().unwrap();
    }
    let crate_ = index.crates().nth(0).unwrap();
    let version = crate_.latest_version();
    let _ = version.deps;
}
<|endoftext|>


<commit_before>#![no_std]

#[cfg(not(test))]
extern crate core as std;

#[cfg(test)]
extern crate std;

/** This macro can be used to ensure that a function is called only once. It panics if the function
is called a second time.

# Example

Using the macro:

```rust
#[macro_use]
extern crate once;

fn init() {
    assert_has_not_been_called!();

    // code that should only run once
}

fn main() {
    init();
    // init(); // "assertion failed: called == false"
}
```

Custom error message:

```rust
#[macro_use]
extern crate once;

fn init() {
    assert_has_not_been_called!("the init function must only be called {}", "once");
}

fn main() {
    init();
    // init(); // "the init function must only be called once"
}
```
**/
#[macro_export]
macro_rules! assert_has_not_been_called {
    () => {
        assert_has_not_been_called!("assertion failed: has_run == false");
    };
    ($($arg:tt)+) => {{
        fn assert_has_not_been_called() {
            use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
            static CALLED: AtomicBool = ATOMIC_BOOL_INIT;
            let called = CALLED.swap(true, Ordering::Relaxed);
            assert!(called == false, $($arg)+);
        }
        assert_has_not_been_called();
    }};
}

#[test]
fn test_run_once() {
    fn init() {
        assert_has_not_been_called!();
    }
    init();
}

#[test]
fn test_run_once_different_fns() {
    fn init1() {
        assert_has_not_been_called!();
    }
    fn init2() {
        assert_has_not_been_called!();
    }
    init1();
    init2();
}

#[test]
#[should_panic]
fn test_run_twice() {
    fn init() {
        assert_has_not_been_called!();
    }
    init();
    init();
}

#[test]
fn test_hygiene1() {
    fn init() {
        assert_has_not_been_called!();

        #[allow(dead_code)]
        fn assert_has_not_been_called() {}
    }
    init();
}

#[test]
fn test_hygiene2() {
    fn init() {
        assert_has_not_been_called!();

        #[allow(dead_code)]
        static HAS_RUN: bool = false;
    }
    init();
}
<commit_msg>Fix no_std build<commit_after>#![no_std]

#[cfg(test)]
extern crate std;

// Re-export libcore using an alias so that the macros can work in no_std
// crates while remaining compatible with normal crates.
#[allow(private_in_public)]
#[doc(hidden)]
pub use core as __core;

/** This macro can be used to ensure that a function is called only once. It panics if the function
is called a second time.

# Example

Using the macro:

```rust
#[macro_use]
extern crate once;

fn init() {
    assert_has_not_been_called!();

    // code that should only run once
}

fn main() {
    init();
    // init(); // "assertion failed: called == false"
}
```

Custom error message:

```rust
#[macro_use]
extern crate once;

fn init() {
    assert_has_not_been_called!("the init function must only be called {}", "once");
}

fn main() {
    init();
    // init(); // "the init function must only be called once"
}
```
**/
#[macro_export]
macro_rules! assert_has_not_been_called {
    () => {
        assert_has_not_been_called!("assertion failed: has_run == false");
    };
    ($($arg:tt)+) => {{
        fn assert_has_not_been_called() {
            use $crate::__core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
            static CALLED: AtomicBool = ATOMIC_BOOL_INIT;
            let called = CALLED.swap(true, Ordering::Relaxed);
            assert!(called == false, $($arg)+);
        }
        assert_has_not_been_called();
    }};
}

#[test]
fn test_run_once() {
    fn init() {
        assert_has_not_been_called!();
    }
    init();
}

#[test]
fn test_run_once_different_fns() {
    fn init1() {
        assert_has_not_been_called!();
    }
    fn init2() {
        assert_has_not_been_called!();
    }
    init1();
    init2();
}

#[test]
#[should_panic]
fn test_run_twice() {
    fn init() {
        assert_has_not_been_called!();
    }
    init();
    init();
}

#[test]
fn test_hygiene1() {
    fn init() {
        assert_has_not_been_called!();

        #[allow(dead_code)]
        fn assert_has_not_been_called() {}
    }
    init();
}

#[test]
fn test_hygiene2() {
    fn init() {
        assert_has_not_been_called!();

        #[allow(dead_code)]
        static HAS_RUN: bool = false;
    }
    init();
}
<|endoftext|>


<commit_before>//! Lorem ipsum generator.
//!
//! This crate contains functions for generating pseudo-Latin lorem
//! ipsum placeholder text. The traditional lorem ipsum text start
//! like this:
//!
//! > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
//! > eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
//! > enim ad minim veniam, quis nostrud exercitation ullamco laboris
//! > nisi ut aliquip ex ea commodo consequat. [...]
//!
//! This text is in the [`LOREM_IPSUM`] constant. Random text looking
//! like the above can be generated using the [`lipsum`] function.
//! This function allows you to generate as much text as desired and
//! each invocation will generate different text. This is done using a
//! [Markov chain] based on both the [`LOREM_IPSUM`] and
//! [`LIBER_PRIMUS`] texts. The latter constant holds the full text of
//! the first book of a work by Cicero, of which the lorem ipsum text
//! is a scrambled subset.
//!
//! The random looking text is generatd using a Markov chain of order
//! two, which simply means that the next word is based on the
//! previous two words in the input texts. The Markov chain can be
//! used with other input texts by creating an instance of
//! [`MarkovChain`] and calling its [`learn`] method.
//!
//! [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
//! [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
//! [`lipsum`]: fn.lipsum.html
//! [`MarkovChain`]: struct.MarkovChain.html
//! [`learn`]: struct.MarkovChain.html#method.learn
//! [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain

extern crate rand;

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;
use rand::Rng;

/// A bigram is simply two consecutive words.
type Bigram<'a> = (&'a str, &'a str);

/// Simple order two Markov chain implementation.
///
/// The [Markov chain] is a chain of order two, which means that it
/// will use the previous two words (a bigram) when predicting the
/// next word. This is normally enough to generate random text that
/// looks somewhat plausible. The implementation is based on
/// [Generating arbitrary text with Markov chains in Rust][blog post].
///
/// [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain
/// [blog post]: https://blakewilliams.me/posts/generating-arbitrary-text-with-markov-chains-in-rust
#[derive(Default)]
pub struct MarkovChain<'a> {
    map: HashMap<Bigram<'a>, Vec<&'a str>>,
}

impl<'a> MarkovChain<'a> {
    /// Create a new Markov chain. It will use a default thread-local
    /// random number generator.
    pub fn new() -> MarkovChain<'a> {
        MarkovChain { map: HashMap::new() }
    }

    /// Add new text to the Markov chain. This can be called several
    /// times to build up the chain.
    pub fn learn(&mut self, sentence: &'a str) {
        let words = sentence.split_whitespace().collect::<Vec<&str>>();
        for window in words.windows(3) {
            let (a, b, c) = (window[0], window[1], window[2]);
            self.map.entry((a, b)).or_insert(vec![]).push(c);
        }
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from a random point in the Markov chain.
    pub fn generate(&self, n: usize) -> String {
        if self.map.is_empty() {
            // The learn method has not been called.
            return String::new();
        }

        let mut rng = rand::thread_rng();
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        self.generate_from(n, **rng.choose(&keys).unwrap())
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from the given bigram.
    pub fn generate_from(&self, n: usize, from: Bigram<'a>) -> String {
        let mut rng = rand::thread_rng(); // make part of struct
        let keys = self.map.keys().collect::<Vec<&Bigram>>();
        let (mut a, mut b) = from;
        let mut sentence = String::from(a) + " " + b;

        for _ in 0..n {
            while !self.map.contains_key(&(a, b)) {
                let new_key = **rng.choose(&keys).unwrap();
                a = new_key.0;
                b = new_key.1;
            }

            let next_words = &self.map[&(a, b)];
            let c = rng.choose(next_words).unwrap();
            sentence.push(' ');
            sentence.push_str(c);
            a = b;
            b = c;
        }

        return sentence;
    }
}

/// The traditional lorem ipsum text as given in [Wikipedia]. Using
/// this text alone for a Markov chain of order two doesn't work very
/// well since each bigram (two consequtive words) is followed by just
/// one other word. In other words, the Markov chain will always
/// produce the same output and recreate the lorem ipsum text
/// precisely. However, combining it with the full text in
/// [`LIBER_PRIMUS`] works well.
///
/// [Wikipedia]: https://en.wikipedia.org/wiki/Lorem_ipsum
/// [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
const LOREM_IPSUM: &str = include_str!("lorem-ipsum.txt");

/// The first book in Cicero's work De finibus bonorum et malorum ("On
/// the ends of good and evil"). The lorem ipsum text in
/// [`LOREM_IPSUM`] is derived from part of this text.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
const LIBER_PRIMUS: &str = include_str!("liber-primus.txt");

lazy_static! {
    /// Markov chain generating lorem ipsum text.
    static ref LOREM_IPSUM_CHAIN: MarkovChain<'static> = {
        let mut chain = MarkovChain::new();
        chain.learn(LOREM_IPSUM);
        chain.learn(LIBER_PRIMUS);
        chain
    };
}

/// Generate `n` words of lorem ipsum text. The output starts with
/// "Lorem ipsum" and continues with the standard lorem ipsum text
/// from [`LOREM_IPSUM`]. The text will become random if sufficiently
/// long output is requested.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub fn lipsum(n: usize) -> String {
    LOREM_IPSUM_CHAIN.generate_from(n, ("Lorem", "ipsum"))
}

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

    #[test]
    fn starts_with_lorem_ipsum() {
        assert_eq!(&lipsum(10)[..11], "Lorem ipsum");
    }

    #[test]
    fn empty_chain() {
        let chain = MarkovChain::new();
        assert_eq!(chain.generate(10), "");
    }

    #[test]
    fn generate_from() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        assert_eq!(chain.generate_from(1, ("foo", "bar")), "foo bar baz");
        assert_eq!(chain.generate_from(1, ("bar", "baz")), "bar baz quuz");
    }

    #[test]
    fn generate_from_no_panic() {
        // No panic when asked to generate a chain from a starting
        // point that doesn't exist in the chain.
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz");
        assert_eq!(chain.generate_from(1, ("xxx", "yyy")), "xxx yyy baz");
    }

    #[test]
    fn chain_map() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        let map = &chain.map;

        assert_eq!(map.len(), 2);
        assert_eq!(map[&("foo", "bar")], vec!["baz"]);
        assert_eq!(map[&("bar", "baz")], vec!["quuz"]);
    }
}
<commit_msg>lib: make constants public<commit_after>//! Lorem ipsum generator.
//!
//! This crate contains functions for generating pseudo-Latin lorem
//! ipsum placeholder text. The traditional lorem ipsum text start
//! like this:
//!
//! > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
//! > eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
//! > enim ad minim veniam, quis nostrud exercitation ullamco laboris
//! > nisi ut aliquip ex ea commodo consequat. [...]
//!
//! This text is in the [`LOREM_IPSUM`] constant. Random text looking
//! like the above can be generated using the [`lipsum`] function.
//! This function allows you to generate as much text as desired and
//! each invocation will generate different text. This is done using a
//! [Markov chain] based on both the [`LOREM_IPSUM`] and
//! [`LIBER_PRIMUS`] texts. The latter constant holds the full text of
//! the first book of a work by Cicero, of which the lorem ipsum text
//! is a scrambled subset.
//!
//! The random looking text is generatd using a Markov chain of order
//! two, which simply means that the next word is based on the
//! previous two words in the input texts. The Markov chain can be
//! used with other input texts by creating an instance of
//! [`MarkovChain`] and calling its [`learn`] method.
//!
//! [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
//! [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
//! [`lipsum`]: fn.lipsum.html
//! [`MarkovChain`]: struct.MarkovChain.html
//! [`learn`]: struct.MarkovChain.html#method.learn
//! [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain

extern crate rand;

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;
use rand::Rng;

/// A bigram is simply two consecutive words.
type Bigram<'a> = (&'a str, &'a str);

/// Simple order two Markov chain implementation.
///
/// The [Markov chain] is a chain of order two, which means that it
/// will use the previous two words (a bigram) when predicting the
/// next word. This is normally enough to generate random text that
/// looks somewhat plausible. The implementation is based on
/// [Generating arbitrary text with Markov chains in Rust][blog post].
///
/// [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain
/// [blog post]: https://blakewilliams.me/posts/generating-arbitrary-text-with-markov-chains-in-rust
#[derive(Default)]
pub struct MarkovChain<'a> {
    map: HashMap<Bigram<'a>, Vec<&'a str>>,
}

impl<'a> MarkovChain<'a> {
    /// Create a new Markov chain. It will use a default thread-local
    /// random number generator.
    pub fn new() -> MarkovChain<'a> {
        MarkovChain { map: HashMap::new() }
    }

    /// Add new text to the Markov chain. This can be called several
    /// times to build up the chain.
    pub fn learn(&mut self, sentence: &'a str) {
        let words = sentence.split_whitespace().collect::<Vec<&str>>();
        for window in words.windows(3) {
            let (a, b, c) = (window[0], window[1], window[2]);
            self.map.entry((a, b)).or_insert(vec![]).push(c);
        }
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from a random point in the Markov chain.
    pub fn generate(&self, n: usize) -> String {
        if self.map.is_empty() {
            // The learn method has not been called.
            return String::new();
        }

        let mut rng = rand::thread_rng();
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        self.generate_from(n, **rng.choose(&keys).unwrap())
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from the given bigram.
    pub fn generate_from(&self, n: usize, from: Bigram<'a>) -> String {
        let mut rng = rand::thread_rng(); // make part of struct
        let keys = self.map.keys().collect::<Vec<&Bigram>>();
        let (mut a, mut b) = from;
        let mut sentence = String::from(a) + " " + b;

        for _ in 0..n {
            while !self.map.contains_key(&(a, b)) {
                let new_key = **rng.choose(&keys).unwrap();
                a = new_key.0;
                b = new_key.1;
            }

            let next_words = &self.map[&(a, b)];
            let c = rng.choose(next_words).unwrap();
            sentence.push(' ');
            sentence.push_str(c);
            a = b;
            b = c;
        }

        return sentence;
    }
}

/// The traditional lorem ipsum text as given in [Wikipedia]. Using
/// this text alone for a Markov chain of order two doesn't work very
/// well since each bigram (two consequtive words) is followed by just
/// one other word. In other words, the Markov chain will always
/// produce the same output and recreate the lorem ipsum text
/// precisely. However, combining it with the full text in
/// [`LIBER_PRIMUS`] works well.
///
/// [Wikipedia]: https://en.wikipedia.org/wiki/Lorem_ipsum
/// [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
pub const LOREM_IPSUM: &str = include_str!("lorem-ipsum.txt");

/// The first book in Cicero's work De finibus bonorum et malorum ("On
/// the ends of good and evil"). The lorem ipsum text in
/// [`LOREM_IPSUM`] is derived from part of this text.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub const LIBER_PRIMUS: &str = include_str!("liber-primus.txt");

lazy_static! {
    /// Markov chain generating lorem ipsum text.
    static ref LOREM_IPSUM_CHAIN: MarkovChain<'static> = {
        let mut chain = MarkovChain::new();
        chain.learn(LOREM_IPSUM);
        chain.learn(LIBER_PRIMUS);
        chain
    };
}

/// Generate `n` words of lorem ipsum text. The output starts with
/// "Lorem ipsum" and continues with the standard lorem ipsum text
/// from [`LOREM_IPSUM`]. The text will become random if sufficiently
/// long output is requested.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub fn lipsum(n: usize) -> String {
    LOREM_IPSUM_CHAIN.generate_from(n, ("Lorem", "ipsum"))
}

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

    #[test]
    fn starts_with_lorem_ipsum() {
        assert_eq!(&lipsum(10)[..11], "Lorem ipsum");
    }

    #[test]
    fn empty_chain() {
        let chain = MarkovChain::new();
        assert_eq!(chain.generate(10), "");
    }

    #[test]
    fn generate_from() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        assert_eq!(chain.generate_from(1, ("foo", "bar")), "foo bar baz");
        assert_eq!(chain.generate_from(1, ("bar", "baz")), "bar baz quuz");
    }

    #[test]
    fn generate_from_no_panic() {
        // No panic when asked to generate a chain from a starting
        // point that doesn't exist in the chain.
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz");
        assert_eq!(chain.generate_from(1, ("xxx", "yyy")), "xxx yyy baz");
    }

    #[test]
    fn chain_map() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        let map = &chain.map;

        assert_eq!(map.len(), 2);
        assert_eq!(map[&("foo", "bar")], vec!["baz"]);
        assert_eq!(map[&("bar", "baz")], vec!["quuz"]);
    }
}
<|endoftext|>


<commit_before>//! This crate is a port of
//! [Haskell's QuickCheck](http://hackage.haskell.org/package/QuickCheck).
//!
//! For detailed examples, please see the
//! [README](https://github.com/BurntSushi/quickcheck).

#![allow(deprecated)] // for connect -> join in 1.3

extern crate env_logger;
#[macro_use] extern crate log;
extern crate rand;

pub use arbitrary::{
    Arbitrary, Gen, StdGen,
    empty_shrinker, single_shrinker,
};
pub use rand::Rng;
pub use tester::{QuickCheck, Testable, TestResult, quickcheck};

/// A macro for writing quickcheck tests.
///
/// This macro takes as input one or more property functions to test, and
/// produces a proper `#[test]` function for each property. If the property
/// fails, the behavior is as if `quickcheck` were called on the property
/// (i.e., it panics and fails the test).
///
/// Note that this macro doesn't support `mut` or patterns in parameters.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate quickcheck; fn main() {
/// quickcheck! {
///     fn prop_reverse_reverse(xs: Vec<usize>) -> bool {
///         let rev: Vec<_> = xs.clone().into_iter().rev().collect();
///         let revrev: Vec<_> = rev.into_iter().rev().collect();
///         xs == revrev
///     }
/// }
/// # }
/// ```
#[macro_export]
macro_rules! quickcheck {
    (@as_items $($i:item)*) => ($($i)*);
    {
        $(
            fn $fn_name:ident($($arg_name:ident : $arg_ty:ty),*) -> $ret:ty {
                $($code:tt)*
            }
        )*
    } => (
        quickcheck! {
            @as_items
            $(
                #[test]
                fn $fn_name() {
                    fn prop($($arg_name: $arg_ty),*) -> $ret {
                        $($code)*
                    }
                    $crate::quickcheck(prop as fn($($arg_ty),*) -> $ret);
                }
            )*
        }
    )
}

mod arbitrary;
mod tester;

#[cfg(test)]
mod tests;
<commit_msg>Fix doc test. Weird bug...<commit_after>//! This crate is a port of
//! [Haskell's QuickCheck](http://hackage.haskell.org/package/QuickCheck).
//!
//! For detailed examples, please see the
//! [README](https://github.com/BurntSushi/quickcheck).

#![allow(deprecated)] // for connect -> join in 1.3

extern crate env_logger;
#[macro_use] extern crate log;
extern crate rand;

pub use arbitrary::{
    Arbitrary, Gen, StdGen,
    empty_shrinker, single_shrinker,
};
pub use rand::Rng;
pub use tester::{QuickCheck, Testable, TestResult, quickcheck};

/// A macro for writing quickcheck tests.
///
/// This macro takes as input one or more property functions to test, and
/// produces a proper `#[test]` function for each property. If the property
/// fails, the behavior is as if `quickcheck` were called on the property
/// (i.e., it panics and fails the test).
///
/// Note that this macro doesn't support `mut` or patterns in parameters.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate quickcheck; fn main() {
/// quickcheck! {
///     fn prop_reverse_reverse(xs: Vec<usize>) -> bool {
///         let rev: Vec<_> = xs.clone().into_iter().rev().collect();
///         let revrev: Vec<_> = rev.into_iter().rev().collect();
///         xs == revrev
///     }
/// };
/// # }
/// ```
#[macro_export]
macro_rules! quickcheck {
    (@as_items $($i:item)*) => ($($i)*);
    {
        $(
            fn $fn_name:ident($($arg_name:ident : $arg_ty:ty),*) -> $ret:ty {
                $($code:tt)*
            }
        )*
    } => (
        quickcheck! {
            @as_items
            $(
                #[test]
                fn $fn_name() {
                    fn prop($($arg_name: $arg_ty),*) -> $ret {
                        $($code)*
                    }
                    $crate::quickcheck(prop as fn($($arg_ty),*) -> $ret);
                }
            )*
        }
    )
}

mod arbitrary;
mod tester;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>
#[derive(PartialEq, Show)]
enum TomlFragment<'a> {
    Whitespace(&'a str),
}

#[derive(PartialEq, Show)]
struct ParseResult<'a> {
    fragment : TomlFragment<'a>,
    remainder : &'a str,
}

fn parse_whitespace(s : &str) -> Option<ParseResult> {
    if s.is_empty() {
        return None;
    }

    if !s.char_at(0).is_whitespace() {
        return None;
    }

    let mut index : uint = 0;

    for c in s.chars() {
        if !c.is_whitespace() {
            break;
        }

        index = index + 1;
    }

    let fragment = TomlFragment::Whitespace(s.slice(0, index));
    let remainder = s.slice_from(index);

    return Some(ParseResult { fragment: fragment, remainder: remainder });
}

#[test]
fn parse_whitespace_empty_string() {
    assert_eq!(None, parse_whitespace(""));
}

#[test]
fn parse_whitespace_no_whitespace_str() {
    assert_eq!(None, parse_whitespace("abc"));
}

#[test]
fn parse_whitespace_one_space() {
    let fragment = TomlFragment::Whitespace(" ");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace(" "));
}

#[test]
fn parse_whitespace_two_spaces() {
    let fragment = TomlFragment::Whitespace("  ");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace("  "));
}

#[test]
fn parse_whitespace_one_space_one_letter() {
    let fragment = TomlFragment::Whitespace(" ");
    let remainder = "w";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace(" w"));
}

#[test]
fn parse_whitespace_unix_newline() {
    let fragment = TomlFragment::Whitespace("\n");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace("\n"));
}

#[test]
fn parse_whitespace_windows_newline() {
    let fragment = TomlFragment::Whitespace("\r\n");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace("\r\n"));
}
<commit_msg>Parse full line comments<commit_after>
#[derive(PartialEq, Show)]
enum TomlFragment<'a> {
    Whitespace(&'a str),

    //doesn't include the leading '#'
    Comment(&'a str),
}

#[derive(PartialEq, Show)]
struct ParseResult<'a> {
    fragment : TomlFragment<'a>,
    remainder : &'a str,
}

fn parse_comment(s : &str) -> Option<ParseResult> {
    if s.is_empty() {
        return None;
    }

    if s.char_at(0) != '#' {
        return None;
    }

    match s.lines().nth(0) {
        Some(comment) => {
            let fragment = TomlFragment::Comment(comment.slice_from(1));
            let remainder = s.slice_from(comment.len());

            Some(ParseResult { fragment: fragment, remainder: remainder })
        }
        None => None
    }
}

#[test]
fn parse_comment_empty_str() {
    assert_eq!(None, parse_comment(""));
}

#[test]
fn parse_comment_non_comment_str() {
    assert_eq!(None, parse_comment("test"));
}

#[test]
fn parse_comment_only_comment_char() {
    let fragment = TomlFragment::Comment("");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_comment("#"));
}

#[test]
fn parse_comment_unix_newline() {
    let fragment = TomlFragment::Comment("");
    let remainder = "\n";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_comment("#\n"));
}

#[test]
fn parse_comment_windows_newline() {
    let fragment = TomlFragment::Comment("\r");
    let remainder = "\n";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_comment("#\r\n"));
}

#[test]
fn parse_comment_text() {
    let fragment = TomlFragment::Comment("some comment");
    let remainder= "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_comment("#some comment"));
}

#[test]
fn parse_comment_content_after() {
    let fragment = TomlFragment::Comment("test 123! :)");
    let remainder = "\ncontent";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_comment("#test 123! :)\ncontent"));
}

fn parse_whitespace(s : &str) -> Option<ParseResult> {
    if s.is_empty() {
        return None;
    }

    if !s.char_at(0).is_whitespace() {
        return None;
    }

    let mut index : uint = 0;

    for c in s.chars() {
        if !c.is_whitespace() {
            break;
        }

        index = index + 1;
    }

    let fragment = TomlFragment::Whitespace(s.slice(0, index));
    let remainder = s.slice_from(index);

    return Some(ParseResult { fragment: fragment, remainder: remainder });
}

#[test]
fn parse_whitespace_empty_string() {
    assert_eq!(None, parse_whitespace(""));
}

#[test]
fn parse_whitespace_no_whitespace_str() {
    assert_eq!(None, parse_whitespace("abc"));
}

#[test]
fn parse_whitespace_one_space() {
    let fragment = TomlFragment::Whitespace(" ");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace(" "));
}

#[test]
fn parse_whitespace_two_spaces() {
    let fragment = TomlFragment::Whitespace("  ");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace("  "));
}

#[test]
fn parse_whitespace_one_space_one_letter() {
    let fragment = TomlFragment::Whitespace(" ");
    let remainder = "w";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace(" w"));
}

#[test]
fn parse_whitespace_unix_newline() {
    let fragment = TomlFragment::Whitespace("\n");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace("\n"));
}

#[test]
fn parse_whitespace_windows_newline() {
    let fragment = TomlFragment::Whitespace("\r\n");
    let remainder = "";

    assert_eq!(Some(ParseResult { fragment: fragment, remainder: remainder }), parse_whitespace("\r\n"));
}
<|endoftext|>


<commit_before>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![allow(raw_pointer_deriving)]

extern crate libc;

use std::c_str::CString;
use std::fmt;
use std::string::String;
use std::vec::Vec;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

#[cfg(target_os="windows")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi;

pub enum Object {
    Buffer(ffi::C_Buffer),
    Window(ffi::C_Window),
    Tabpage(ffi::C_Tabpage),
    Boolean(ffi::C_Boolean),
    Integer(ffi::C_Integer),
    Float(ffi::C_Float),
    String(String),
    Array(ffi::C_Array),
    Dictionary(ffi::C_Dictionary),
}

impl fmt::Show for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Object::Buffer(_) => write!(f, "Buffer"),
            Object::Window(_) => write!(f, "Window"),
            Object::Tabpage(_) => write!(f, "Tabpage"),
            Object::Boolean(_) => write!(f, "Boolean"),
            Object::Integer(_) => write!(f, "Integer"),
            Object::Float(_) => write!(f, "Float"),
            Object::String(_) => write!(f, "String"),
            Object::Array(_) => write!(f, "Array"),
            Object::Dictionary(_) => write!(f, "Dictionary"),
        }
    }
}

unsafe fn c_object_to_object(obj: *mut ffi::C_Object) -> Option<Object> {
    match (*obj).object_type {
        ffi::ObjectType::BufferType =>
            Some(Object::Buffer((*(obj as *mut ffi::C_Object_Buffer)).data)),
        ffi::ObjectType::WindowType =>
            Some(Object::Window((*(obj as *mut ffi::C_Object_Window)).data)),
        ffi::ObjectType::TabpageType =>
            Some(Object::Tabpage((*(obj as *mut ffi::C_Object_Tabpage)).data)),
        ffi::ObjectType::NilType =>
            None,
        ffi::ObjectType::BooleanType =>
            Some(Object::Boolean((*(obj as *mut ffi::C_Object_Boolean)).data)),
        ffi::ObjectType::IntegerType =>
            Some(Object::Integer((*(obj as *mut ffi::C_Object_Integer)).data)),
        ffi::ObjectType::FloatType =>
            Some(Object::Float((*(obj as *mut ffi::C_Object_Float)).data)),
        ffi::ObjectType::StringType => {
            let vim_s: ffi::C_String = (*(obj as *mut ffi::C_Object_String)).data;
            let s = String::from_raw_buf_len(vim_s.data as *const u8, vim_s.size as uint);
            Some(Object::String(s))
        },
        ffi::ObjectType::ArrayType =>
            Some(Object::Array((*(obj as *mut ffi::C_Object_Array)).data)),
        ffi::ObjectType::DictionaryType =>
            Some(Object::Dictionary((*(obj as *mut ffi::C_Object_Dictionary)).data)),
    }
}

pub fn run_with_fds(args: Vec<String>, read_fd: i32, write_fd: i32) -> i32 {
    let v: Vec<CString> = args.iter().map(|s| s.as_slice().to_c_str()).collect();
    let vp: Vec<*const ffi::c_char> = v.iter().map(|s| s.as_ptr()).collect();
    let p_vp: *const *const ffi::c_char = vp.as_ptr();

    unsafe { ffi::nvim_main(vp.len() as i32, p_vp, read_fd, write_fd) }
}

pub fn run(args: Vec<String>) -> i32 {
    run_with_fds(args, -1, -1)
}

pub fn serialize_message(id: u64, method: &'static str, args: &Array) -> String {
    unsafe {
        let buf = ffi::vim_msgpack_new();
        let vim_str = ffi::C_String {data: method.as_ptr() as *const i8, size: method.len() as u64};
        ffi::vim_serialize_request(id, vim_str, args.unwrap_value(), buf);
        let s = String::from_raw_buf_len((*buf).data as *const u8, (*buf).size as uint);
        ffi::vim_msgpack_free(buf);
        s
    }
}

pub fn deserialize_message(message: &String) -> Array {
    unsafe {
        let mut arr_raw = Array::new().unwrap_value();
        let s = ffi::C_String {
            data: message.as_slice().as_ptr() as *const i8,
            size: message.len() as u64
        };
        ffi::vim_msgpack_parse(s, &mut arr_raw);
        Array::wrap_value(arr_raw)
    }
}

#[deriving(Copy)]
pub struct Array {
    value: ffi::C_Array
}

impl Array {
    pub fn new() -> Array {
        Array {
            value: ffi::C_Array {
                items: ::std::ptr::null_mut(),
                size: 0,
                capacity: 0,
            }
        }
    }

    pub fn add_buffer(&mut self, val: ffi::C_Buffer) {
        unsafe { ffi::vim_array_add_buffer(val, &mut self.value) }
    }

    pub fn add_window(&mut self, val: ffi::C_Window) {
        unsafe { ffi::vim_array_add_window(val, &mut self.value) }
    }

    pub fn add_tabpage(&mut self, val: ffi::C_Tabpage) {
        unsafe { ffi::vim_array_add_tabpage(val, &mut self.value) }
    }

    pub fn add_nil(&mut self) {
        unsafe { ffi::vim_array_add_nil(&mut self.value) }
    }

    pub fn add_boolean(&mut self, val: ffi::C_Boolean) {
        unsafe { ffi::vim_array_add_boolean(val, &mut self.value) }
    }

    pub fn add_integer(&mut self, val: ffi::C_Integer) {
        unsafe { ffi::vim_array_add_integer(val, &mut self.value) }
    }

    pub fn add_float(&mut self, val: ffi::C_Float) {
        unsafe { ffi::vim_array_add_float(val, &mut self.value) }
    }

    pub fn add_string(&mut self, val: &str) {
        unsafe {
            // we need to copy the string into memory not managed by Rust,
            // so api_free_array can clear it
            let ptr = ffi::malloc(val.len() as u64);
            ::std::ptr::copy_memory(ptr, val.as_ptr() as *const ffi::c_void, val.len());
            let vim_str = ffi::C_String {data: ptr as *const i8, size: val.len() as u64};
            ffi::vim_array_add_string(vim_str, &mut self.value)
        }
    }

    pub fn add_array(&mut self, val: &Array) {
        unsafe { ffi::vim_array_add_array(val.unwrap_value(), &mut self.value) }
    }

    pub fn add_dictionary(&mut self, val: ffi::C_Dictionary) {
        unsafe { ffi::vim_array_add_dictionary(val, &mut self.value) }
    }

    pub fn get(&self, index: u64) -> Option<Object> {
        if index >= self.len() {
            return None;
        }
        unsafe { c_object_to_object(self.value.items.offset(index as int)) }
    }

    pub fn len(&self) -> u64 {
        self.value.size
    }

    #[doc(hidden)]
    pub fn unwrap_value(&self) -> ffi::C_Array {
        self.value
    }

    #[doc(hidden)]
    pub fn wrap_value(c_array: ffi::C_Array) -> Array {
        Array {
            value: c_array
        }
    }
}

impl Drop for Array {
    fn drop(&mut self) {
        unsafe { ffi::api_free_array(self.value) };
    }
}

#[test]
fn test_request() {
    let mut args = Array::new();
    args.add_integer(80);
    args.add_integer(24);
    args.add_string("hello");
    let msg = serialize_message(1, "attach_ui", &args);
    let arr = deserialize_message(&msg);
    println!("LENGTH: {}", arr.len());
    for i in range(0, arr.len()) {
        println!("{}", arr.get(i));
    }
}
<commit_msg>Improve types<commit_after>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![allow(raw_pointer_deriving)]

extern crate libc;

use std::c_str::CString;
use std::fmt;
use std::string::String;
use std::vec::Vec;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

#[cfg(target_os="windows")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi;

pub enum Object {
    Buffer(ffi::C_Buffer),
    Window(ffi::C_Window),
    Tabpage(ffi::C_Tabpage),
    Boolean(ffi::C_Boolean),
    Integer(ffi::C_Integer),
    Float(ffi::C_Float),
    String(String),
    Array(Array),
    Dictionary(ffi::C_Dictionary),
}

impl fmt::Show for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Object::Buffer(ref obj) => write!(f, "Buffer({})", obj),
            Object::Window(ref obj) => write!(f, "Window({})", obj),
            Object::Tabpage(ref obj) => write!(f, "Tabpage({})", obj),
            Object::Boolean(ref obj) => write!(f, "Boolean({})", obj),
            Object::Integer(ref obj) => write!(f, "Integer({})", obj),
            Object::Float(ref obj) => write!(f, "Float({})", obj),
            Object::String(ref obj) => write!(f, "String({})", obj),
            Object::Array(ref obj) => write!(f, "Array(Length: {})", obj.len()),
            Object::Dictionary(ref obj) => write!(f, "Dictionary(Length: {})", obj.size),
        }
    }
}

unsafe fn c_object_to_object(obj: *mut ffi::C_Object) -> Option<Object> {
    match (*obj).object_type {
        ffi::ObjectType::BufferType =>
            Some(Object::Buffer((*(obj as *mut ffi::C_Object_Buffer)).data)),
        ffi::ObjectType::WindowType =>
            Some(Object::Window((*(obj as *mut ffi::C_Object_Window)).data)),
        ffi::ObjectType::TabpageType =>
            Some(Object::Tabpage((*(obj as *mut ffi::C_Object_Tabpage)).data)),
        ffi::ObjectType::NilType =>
            None,
        ffi::ObjectType::BooleanType =>
            Some(Object::Boolean((*(obj as *mut ffi::C_Object_Boolean)).data)),
        ffi::ObjectType::IntegerType =>
            Some(Object::Integer((*(obj as *mut ffi::C_Object_Integer)).data)),
        ffi::ObjectType::FloatType =>
            Some(Object::Float((*(obj as *mut ffi::C_Object_Float)).data)),
        ffi::ObjectType::StringType => {
            let vim_str: ffi::C_String = (*(obj as *mut ffi::C_Object_String)).data;
            let s = String::from_raw_buf_len(vim_str.data as *const u8, vim_str.size as uint);
            Some(Object::String(s))
        },
        ffi::ObjectType::ArrayType =>
            Some(Object::Array(Array::wrap_value((*(obj as *mut ffi::C_Object_Array)).data))),
        ffi::ObjectType::DictionaryType =>
            Some(Object::Dictionary((*(obj as *mut ffi::C_Object_Dictionary)).data)),
    }
}

pub fn run_with_fds(args: Vec<String>, read_fd: i32, write_fd: i32) -> i32 {
    let v: Vec<CString> = args.iter().map(|s| s.as_slice().to_c_str()).collect();
    let vp: Vec<*const ffi::c_char> = v.iter().map(|s| s.as_ptr()).collect();
    let p_vp: *const *const ffi::c_char = vp.as_ptr();

    unsafe { ffi::nvim_main(vp.len() as i32, p_vp, read_fd, write_fd) }
}

pub fn run(args: Vec<String>) -> i32 {
    run_with_fds(args, -1, -1)
}

pub fn serialize_message(id: u64, method: &'static str, args: &Array) -> String {
    unsafe {
        let buf = ffi::vim_msgpack_new();
        let vim_str = ffi::C_String {data: method.as_ptr() as *const i8, size: method.len() as u64};
        ffi::vim_serialize_request(id, vim_str, args.unwrap_value(), buf);
        let s = String::from_raw_buf_len((*buf).data as *const u8, (*buf).size as uint);
        ffi::vim_msgpack_free(buf);
        s
    }
}

pub fn deserialize_message(message: &String) -> Array {
    unsafe {
        let mut arr_raw = Array::new().unwrap_value();
        let s = ffi::C_String {
            data: message.as_slice().as_ptr() as *const i8,
            size: message.len() as u64
        };
        ffi::vim_msgpack_parse(s, &mut arr_raw);
        Array::wrap_value(arr_raw)
    }
}

#[deriving(Copy)]
pub struct Array {
    value: ffi::C_Array
}

impl Array {
    pub fn new() -> Array {
        Array {
            value: ffi::C_Array {
                items: ::std::ptr::null_mut(),
                size: 0,
                capacity: 0,
            }
        }
    }

    pub fn add_buffer(&mut self, val: ffi::C_Buffer) {
        unsafe { ffi::vim_array_add_buffer(val, &mut self.value) }
    }

    pub fn add_window(&mut self, val: ffi::C_Window) {
        unsafe { ffi::vim_array_add_window(val, &mut self.value) }
    }

    pub fn add_tabpage(&mut self, val: ffi::C_Tabpage) {
        unsafe { ffi::vim_array_add_tabpage(val, &mut self.value) }
    }

    pub fn add_nil(&mut self) {
        unsafe { ffi::vim_array_add_nil(&mut self.value) }
    }

    pub fn add_boolean(&mut self, val: ffi::C_Boolean) {
        unsafe { ffi::vim_array_add_boolean(val, &mut self.value) }
    }

    pub fn add_integer(&mut self, val: ffi::C_Integer) {
        unsafe { ffi::vim_array_add_integer(val, &mut self.value) }
    }

    pub fn add_float(&mut self, val: ffi::C_Float) {
        unsafe { ffi::vim_array_add_float(val, &mut self.value) }
    }

    pub fn add_string(&mut self, val: &str) {
        unsafe {
            // we need to copy the string into memory not managed by Rust,
            // so api_free_array can clear it
            let ptr = ffi::malloc(val.len() as u64);
            ::std::ptr::copy_memory(ptr, val.as_ptr() as *const ffi::c_void, val.len());
            let vim_str = ffi::C_String {data: ptr as *const i8, size: val.len() as u64};
            ffi::vim_array_add_string(vim_str, &mut self.value)
        }
    }

    pub fn add_array(&mut self, val: &Array) {
        unsafe { ffi::vim_array_add_array(val.unwrap_value(), &mut self.value) }
    }

    pub fn add_dictionary(&mut self, val: ffi::C_Dictionary) {
        unsafe { ffi::vim_array_add_dictionary(val, &mut self.value) }
    }

    pub fn get(&self, index: u64) -> Option<Object> {
        if index >= self.len() {
            return None;
        }
        unsafe { c_object_to_object(self.value.items.offset(index as int)) }
    }

    pub fn len(&self) -> u64 {
        self.value.size
    }

    #[doc(hidden)]
    pub fn unwrap_value(&self) -> ffi::C_Array {
        self.value
    }

    #[doc(hidden)]
    pub fn wrap_value(c_array: ffi::C_Array) -> Array {
        Array {
            value: c_array
        }
    }
}

impl Drop for Array {
    fn drop(&mut self) {
        unsafe { ffi::api_free_array(self.value) };
    }
}

#[test]
fn test_request() {
    let mut args = Array::new();
    args.add_integer(80);
    args.add_integer(24);
    args.add_string("hello");
    let msg = serialize_message(1, "attach_ui", &args);
    let arr = deserialize_message(&msg);
    println!("LENGTH: {}", arr.len());
    for i in range(0, arr.len()) {
        println!("{}", arr.get(i));
    }
}
<|endoftext|>