<commit_before>//! Convenient utility methods, mostly for printing `syntect` data structures
//! prettily to the terminal.
use highlighting::{Style, StyleModifier};
use std::fmt::Write;
use std::ops::Range;
#[cfg(feature = "parsing")]
use parsing::ScopeStackOp;

/// Formats the styled fragments using 24-bit colour
/// terminal escape codes. Meant for debugging and testing.
/// It's currently fairly inefficient in its use of escape codes.
///
/// Note that this does not currently ever un-set the colour so that
/// the end of a line will also get highlighted with the background.
/// This means if you might want to use `println!("\x1b[0m");` after
/// to clear the colouring.
///
/// If `bg` is true then the background is also set
pub fn as_24_bit_terminal_escaped(v: &[(Style, &str)], bg: bool) -> String {
    let mut s: String = String::new();
    for &(ref style, text) in v.iter() {
        if bg {
            write!(s,
                   "\x1b[48;2;{};{};{}m",
                   style.background.r,
                   style.background.g,
                   style.background.b)
                .unwrap();
        }
        write!(s,
               "\x1b[38;2;{};{};{}m{}",
               style.foreground.r,
               style.foreground.g,
               style.foreground.b,
               text)
            .unwrap();
    }
    // s.push_str("\x1b[0m");
    s
}

/// Print out the various push and pop operations in a vector
/// with visual alignment to the line. Obviously for debugging.
#[cfg(feature = "parsing")]
pub fn debug_print_ops(line: &str, ops: &[(usize, ScopeStackOp)]) {
    for &(i, ref op) in ops.iter() {
        println!("{}", line.trim_right());
        print!("{: <1$}", "", i);
        match *op {
            ScopeStackOp::Push(s) => {
                println!("^ +{}", s);
            }
            ScopeStackOp::Pop(count) => {
                println!("^ pop {}", count);
            }
            ScopeStackOp::Clear(amount) => {
                println!("^ clear {:?}", amount);
            }
            ScopeStackOp::Restore => println!("^ restore"),
            ScopeStackOp::Noop => println!("noop"),
        }
    }
}

/// An iterator over the lines of a string, including the line endings.
///
/// This is similar to the standard library's `lines` method on `str`, except
/// that the yielded lines include the trailing newline character(s).
///
/// You can use it if you're parsing/highlighting some text that you have as a
/// string. With this, you can use the "newlines" variant of syntax definitions,
/// which is recommended.
///
/// # Examples
///
/// ```
/// use syntect::util::LinesWithEndings;
///
/// let mut lines = LinesWithEndings::from("foo\nbar\nbaz");
///
/// assert_eq!(Some("foo\n"), lines.next());
/// assert_eq!(Some("bar\n"), lines.next());
/// assert_eq!(Some("baz"), lines.next());
///
/// assert_eq!(None, lines.next());
/// ```
pub struct LinesWithEndings<'a> {
    input: &'a str,
}

impl<'a> LinesWithEndings<'a> {
    pub fn from(input: &'a str) -> LinesWithEndings<'a> {
        LinesWithEndings { input }
    }
}

impl<'a> Iterator for LinesWithEndings<'a> {
    type Item = &'a str;

    #[inline]
    fn next(&mut self) -> Option<&'a str> {
        if self.input.is_empty() {
            return None;
        }
        let split = self.input
            .find('\n')
            .map(|i| i + 1)
            .unwrap_or_else(|| self.input.len());
        let (line, rest) = self.input.split_at(split);
        self.input = rest;
        Some(line)
    }
}

/// Split a highlighted line at a byte index in the line into a before and
/// after component. It's just a helper that does the somewhat tricky logic
/// including splitting a span if the index lies on a boundary.
///
/// This can be used to extract a chunk of the line out for special treatment
/// like wrapping it in an HTML tag for extra styling.
///
/// Generic for testing purposes and fancier use cases, but intended for use with
/// the `Vec<(Style, &str)>` returned by `highlight` methods. Look at the source
/// code for `modify_range` for an example usage.
pub fn split_at<'a, A: Clone>(v: &[(A, &'a str)], split_i: usize) -> (Vec<(A, &'a str)>, Vec<(A, &'a str)>) {
    // This function works by gradually reducing the problem into smaller sub-problems from the front
    let mut rest = v;
    let mut rest_split_i = split_i;

    // Consume all tokens before the split
    let mut before = Vec::new();
    for tok in rest { // Use for instead of a while to avoid bounds checks
        if tok.1.len() > rest_split_i {
            break;
        }
        before.push(tok.clone());
        rest_split_i -= tok.1.len();
    }
    rest = &rest[before.len()..];

    let mut after = Vec::new();
    // If necessary, split the token the split falls inside
    if rest.len() > 0 && rest_split_i > 0 {
        let (sa, sb) = rest[0].1.split_at(rest_split_i);
        before.push((rest[0].0.clone(), sa));
        after.push((rest[0].0.clone(), sb));
        rest = &rest[1..];
    }

    after.extend_from_slice(rest);

    return (before, after);
}

/// Modify part of a highlighted line using a style modifier, useful for highlighting sections of a line.
///
/// # Examples
///
/// ```
/// use syntect::util::modify_range;
/// use syntect::highlighting::{Style, StyleModifier, FontStyle};
///
/// let plain = Style::default();
/// let boldmod = StyleModifier { foreground: None, background: None, font_style: Some(FontStyle::BOLD) };
/// let bold = plain.apply(boldmod);
///
/// let l = &[(plain, "abc"), (plain, "def"), (plain, "ghi")];
/// let l2 = modify_range(l, 1..6, boldmod);
/// assert_eq!(l2, &[(plain, "a"), (bold, "bc"), (bold, "def"), (plain, "ghi")]);
/// ```
pub fn modify_range<'a>(v: &[(Style, &'a str)], r: Range<usize>, modifier: StyleModifier) -> Vec<(Style, &'a str)> {
    let (mut result, in_and_after) = split_at(v, r.start);
    let (inside, mut after) = split_at(&in_and_after, r.end - r.start);

    result.extend(inside.iter().map(|(style, s)| { (style.apply(modifier), *s)}));
    result.append(&mut after);
    result
}

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

    #[test]
    fn test_lines_with_endings() {
        fn lines(s: &str) -> Vec<&str> {
            LinesWithEndings::from(s).collect()
        }

        assert!(lines("").is_empty());
        assert_eq!(lines("f"), vec!["f"]);
        assert_eq!(lines("foo"), vec!["foo"]);
        assert_eq!(lines("foo\n"), vec!["foo\n"]);
        assert_eq!(lines("foo\nbar"), vec!["foo\n", "bar"]);
        assert_eq!(lines("foo\nbar\n"), vec!["foo\n", "bar\n"]);
        assert_eq!(lines("foo\r\nbar"), vec!["foo\r\n", "bar"]);
        assert_eq!(lines("foo\r\nbar\r\n"), vec!["foo\r\n", "bar\r\n"]);
        assert_eq!(lines("\nfoo"), vec!["\n", "foo"]);
        assert_eq!(lines("\n\n\n"), vec!["\n", "\n", "\n"]);
    }

    #[test]
    fn test_split_at() {
        let l: &[(u8, &str)] = &[];
        let (before, after) = split_at(l, 0); // empty
        assert_eq!((&before[..], &after[..]), (&[][..],&[][..]));

        let l = &[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")];

        let (before, after) = split_at(l, 0); // at start
        assert_eq!((&before[..], &after[..]), (&[][..],&[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")][..]));

        let (before, after) = split_at(l, 4); // inside token
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc"), (1u8, "d")][..],&[(1u8, "ef"), (2u8, "ghi")][..]));

        let (before, after) = split_at(l, 3); // between tokens
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc")][..],&[(1u8, "def"), (2u8, "ghi")][..]));

        let (before, after) = split_at(l, 9); // just after last token
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")][..], &[][..]));

        let (before, after) = split_at(l, 10); // out of bounds
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")][..], &[][..]));
    }
}
<commit_msg>Update doc comment for the util module<commit_after>//! Convenient helper functions for common use cases:
//! printing to terminal, iterating lines with `\n`s, modifying ranges of highlighted output
use highlighting::{Style, StyleModifier};
use std::fmt::Write;
use std::ops::Range;
#[cfg(feature = "parsing")]
use parsing::ScopeStackOp;

/// Formats the styled fragments using 24-bit colour
/// terminal escape codes. Meant for debugging and testing.
/// It's currently fairly inefficient in its use of escape codes.
///
/// Note that this does not currently ever un-set the colour so that
/// the end of a line will also get highlighted with the background.
/// This means if you might want to use `println!("\x1b[0m");` after
/// to clear the colouring.
///
/// If `bg` is true then the background is also set
pub fn as_24_bit_terminal_escaped(v: &[(Style, &str)], bg: bool) -> String {
    let mut s: String = String::new();
    for &(ref style, text) in v.iter() {
        if bg {
            write!(s,
                   "\x1b[48;2;{};{};{}m",
                   style.background.r,
                   style.background.g,
                   style.background.b)
                .unwrap();
        }
        write!(s,
               "\x1b[38;2;{};{};{}m{}",
               style.foreground.r,
               style.foreground.g,
               style.foreground.b,
               text)
            .unwrap();
    }
    // s.push_str("\x1b[0m");
    s
}

/// Print out the various push and pop operations in a vector
/// with visual alignment to the line. Obviously for debugging.
#[cfg(feature = "parsing")]
pub fn debug_print_ops(line: &str, ops: &[(usize, ScopeStackOp)]) {
    for &(i, ref op) in ops.iter() {
        println!("{}", line.trim_right());
        print!("{: <1$}", "", i);
        match *op {
            ScopeStackOp::Push(s) => {
                println!("^ +{}", s);
            }
            ScopeStackOp::Pop(count) => {
                println!("^ pop {}", count);
            }
            ScopeStackOp::Clear(amount) => {
                println!("^ clear {:?}", amount);
            }
            ScopeStackOp::Restore => println!("^ restore"),
            ScopeStackOp::Noop => println!("noop"),
        }
    }
}

/// An iterator over the lines of a string, including the line endings.
///
/// This is similar to the standard library's `lines` method on `str`, except
/// that the yielded lines include the trailing newline character(s).
///
/// You can use it if you're parsing/highlighting some text that you have as a
/// string. With this, you can use the "newlines" variant of syntax definitions,
/// which is recommended.
///
/// # Examples
///
/// ```
/// use syntect::util::LinesWithEndings;
///
/// let mut lines = LinesWithEndings::from("foo\nbar\nbaz");
///
/// assert_eq!(Some("foo\n"), lines.next());
/// assert_eq!(Some("bar\n"), lines.next());
/// assert_eq!(Some("baz"), lines.next());
///
/// assert_eq!(None, lines.next());
/// ```
pub struct LinesWithEndings<'a> {
    input: &'a str,
}

impl<'a> LinesWithEndings<'a> {
    pub fn from(input: &'a str) -> LinesWithEndings<'a> {
        LinesWithEndings { input }
    }
}

impl<'a> Iterator for LinesWithEndings<'a> {
    type Item = &'a str;

    #[inline]
    fn next(&mut self) -> Option<&'a str> {
        if self.input.is_empty() {
            return None;
        }
        let split = self.input
            .find('\n')
            .map(|i| i + 1)
            .unwrap_or_else(|| self.input.len());
        let (line, rest) = self.input.split_at(split);
        self.input = rest;
        Some(line)
    }
}

/// Split a highlighted line at a byte index in the line into a before and
/// after component. It's just a helper that does the somewhat tricky logic
/// including splitting a span if the index lies on a boundary.
///
/// This can be used to extract a chunk of the line out for special treatment
/// like wrapping it in an HTML tag for extra styling.
///
/// Generic for testing purposes and fancier use cases, but intended for use with
/// the `Vec<(Style, &str)>` returned by `highlight` methods. Look at the source
/// code for `modify_range` for an example usage.
pub fn split_at<'a, A: Clone>(v: &[(A, &'a str)], split_i: usize) -> (Vec<(A, &'a str)>, Vec<(A, &'a str)>) {
    // This function works by gradually reducing the problem into smaller sub-problems from the front
    let mut rest = v;
    let mut rest_split_i = split_i;

    // Consume all tokens before the split
    let mut before = Vec::new();
    for tok in rest { // Use for instead of a while to avoid bounds checks
        if tok.1.len() > rest_split_i {
            break;
        }
        before.push(tok.clone());
        rest_split_i -= tok.1.len();
    }
    rest = &rest[before.len()..];

    let mut after = Vec::new();
    // If necessary, split the token the split falls inside
    if rest.len() > 0 && rest_split_i > 0 {
        let (sa, sb) = rest[0].1.split_at(rest_split_i);
        before.push((rest[0].0.clone(), sa));
        after.push((rest[0].0.clone(), sb));
        rest = &rest[1..];
    }

    after.extend_from_slice(rest);

    return (before, after);
}

/// Modify part of a highlighted line using a style modifier, useful for highlighting sections of a line.
///
/// # Examples
///
/// ```
/// use syntect::util::modify_range;
/// use syntect::highlighting::{Style, StyleModifier, FontStyle};
///
/// let plain = Style::default();
/// let boldmod = StyleModifier { foreground: None, background: None, font_style: Some(FontStyle::BOLD) };
/// let bold = plain.apply(boldmod);
///
/// let l = &[(plain, "abc"), (plain, "def"), (plain, "ghi")];
/// let l2 = modify_range(l, 1..6, boldmod);
/// assert_eq!(l2, &[(plain, "a"), (bold, "bc"), (bold, "def"), (plain, "ghi")]);
/// ```
pub fn modify_range<'a>(v: &[(Style, &'a str)], r: Range<usize>, modifier: StyleModifier) -> Vec<(Style, &'a str)> {
    let (mut result, in_and_after) = split_at(v, r.start);
    let (inside, mut after) = split_at(&in_and_after, r.end - r.start);

    result.extend(inside.iter().map(|(style, s)| { (style.apply(modifier), *s)}));
    result.append(&mut after);
    result
}

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

    #[test]
    fn test_lines_with_endings() {
        fn lines(s: &str) -> Vec<&str> {
            LinesWithEndings::from(s).collect()
        }

        assert!(lines("").is_empty());
        assert_eq!(lines("f"), vec!["f"]);
        assert_eq!(lines("foo"), vec!["foo"]);
        assert_eq!(lines("foo\n"), vec!["foo\n"]);
        assert_eq!(lines("foo\nbar"), vec!["foo\n", "bar"]);
        assert_eq!(lines("foo\nbar\n"), vec!["foo\n", "bar\n"]);
        assert_eq!(lines("foo\r\nbar"), vec!["foo\r\n", "bar"]);
        assert_eq!(lines("foo\r\nbar\r\n"), vec!["foo\r\n", "bar\r\n"]);
        assert_eq!(lines("\nfoo"), vec!["\n", "foo"]);
        assert_eq!(lines("\n\n\n"), vec!["\n", "\n", "\n"]);
    }

    #[test]
    fn test_split_at() {
        let l: &[(u8, &str)] = &[];
        let (before, after) = split_at(l, 0); // empty
        assert_eq!((&before[..], &after[..]), (&[][..],&[][..]));

        let l = &[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")];

        let (before, after) = split_at(l, 0); // at start
        assert_eq!((&before[..], &after[..]), (&[][..],&[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")][..]));

        let (before, after) = split_at(l, 4); // inside token
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc"), (1u8, "d")][..],&[(1u8, "ef"), (2u8, "ghi")][..]));

        let (before, after) = split_at(l, 3); // between tokens
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc")][..],&[(1u8, "def"), (2u8, "ghi")][..]));

        let (before, after) = split_at(l, 9); // just after last token
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")][..], &[][..]));

        let (before, after) = split_at(l, 10); // out of bounds
        assert_eq!((&before[..], &after[..]), (&[(0u8, "abc"), (1u8, "def"), (2u8, "ghi")][..], &[][..]));
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

extern crate num;
extern crate test;

use std::collections::hash_map::{HashMap,Hasher};
use std::num::{ToPrimitive,FromPrimitive}; // and regret it
use std::hash::Hash;
use std::ops::Shr;

use num::bigint::{ToBigUint,BigUint};
use num::{Zero,One,Integer};
use std::num::Float;

use test::Bencher;

/// Computes the greatest common divisor of two numbers using Euclid's method.
/// Behavior unspecified for negative numbers.
pub fn gcd<T>(a: T,  b: T) -> T
 where T: Clone + Zero + Integer,
{
	if (a == Zero::zero()) {
		b
	} else {
		gcd(b % a.clone(), a)
	}
}

/// Performs an integer square root, returning the largest integer whose square is not
///  greater than the argument.
pub fn isqrt<T>(n: T) -> T
 where T: Clone + FromPrimitive + ToPrimitive + Zero + Integer + Shr<usize, Output=T>,
{
	isqrt_fast(n.clone()).or_else(
		|| Some(isqrt_safe(n.clone()))
	).unwrap()
}

/// Used to convert an integral literal into an arbitrary type.
/// For zero and one, `num::Zero::zero()` and `num::One::one()` is preferred when they
///  are used as the additive/multiplicative identity, and `literal` is used otherwise.
#[inline]
pub fn literal<T>(n: isize) -> T
 where T: FromPrimitive,
{
	FromPrimitive::from_int(n).unwrap()
}

/// Computes `pow(x, power) % modulus` using exponentation by squaring.
pub fn mod_pow<T,P>(x: T, power: P, modulus: T) -> T
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
       P: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=P>,
{
	let mut prod:T = One::one();
	let mut remaining = power;
	let mut cur = x;
	while remaining > Zero::zero() {
		if remaining.is_odd() {
			prod = prod * cur.clone();
			prod = prod % modulus.clone();
		}
		remaining = remaining >> 1;
		cur = cur.clone() * cur;
		cur = cur % modulus.clone();
	}
	prod
}

#[test]
fn test_mod_pow()
{
	assert_eq!(mod_pow(234u64, 0, 1259), 1);
	assert_eq!(mod_pow(234u64, 1, 1259), 234);
	assert_eq!(mod_pow(234u64, 2412, 1259), 1091);
}

//-------------------------------
// isqrt helper methods

fn isqrt_fast<T>(x: T) -> Option<T>
 where T: FromPrimitive + ToPrimitive,
{
	x.to_f64().and_then(|f| {
		// Mantissa is 52 bits, and the square root takes half as many bits, so this
		//  may be a bit conservative.  The main concern is to avoid handling very
		//  large BigInts which may lose more than half of their precision.
		if f > 20f64.exp2() {
			None                 // Number too large, bail out!
		} else {
			FromPrimitive::from_f64(f.sqrt().floor())
		}
	})
}

fn isqrt_safe<T>(n: T) -> T
 where T: Clone + FromPrimitive + ToPrimitive + Zero + Integer + Shr<usize, Output=T>,
{
	// NOTE: while I'd like to remove the Shr bound, replacing '>> 1' with '/ 2' makes this
	//       algorithm take twice as long for BigInts :/
	if n.is_zero() { return Zero::zero(); }
	let mut x = n.clone();
	let mut y = (x.clone() + n.clone() / x.clone()) >> literal(1);
	while y < x {
		x = y.clone();
		y = (x.clone() + n.clone() / x.clone()) >> literal(1);
	}
	return x;
}

#[bench]
fn bench_fast(b: &mut Bencher) {
	b.iter(|| {
		(0us..1000us).map(|a| {isqrt_fast::<usize>(a).unwrap()}).collect::<Vec<usize>>()
	})
}

#[bench]
fn bench_safe(b: &mut Bencher) {
	b.iter(|| {
		(0us..1000us).map(isqrt_safe::<usize>).collect::<Vec<usize>>()
	})
}

#[bench]
fn bench_safe_bigint(b: &mut Bencher) {
	b.iter(|| {
		(0us..1000us).map(|a| isqrt_safe::<BigUint>(FromPrimitive::from_uint(a).unwrap())).collect::<Vec<BigUint>>()
	})
}

#[bench]
fn bench_safe_massive_bigint(b: &mut Bencher) {
	use std::rand::XorShiftRng;
	use num::bigint::RandBigInt;
	let mut r = XorShiftRng::new_unseeded();
	b.iter(|| {
		(0us..100us).map(|_| {
			isqrt_safe::<BigUint>(r.gen_biguint(100us))
		}).collect::<Vec<BigUint>>()
	})
}

#[test]
fn test_isqrt_consistency()
{
	(0us..1000).map(|x| {
		let bigX = x.to_biguint().unwrap();
		assert_eq!(isqrt_fast(x),            Some(isqrt_safe(x)));
		assert_eq!(isqrt_fast(bigX.clone()), Some(isqrt_safe(bigX.clone())));
	}).collect::<Vec<_>>();
}

#[cfg(test)]
mod tests {
	extern crate test;
	use super::*;
	use std::num::FromPrimitive;
	use std::num::ToPrimitive;
	use num::bigint::{ToBigUint,BigUint};

	// need to test isqrt with BigInt more rigorously

}
<commit_msg>Change gcd from recursive to iterative<commit_after>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

extern crate num;
extern crate test;

use std::collections::hash_map::{HashMap,Hasher};
use std::num::{ToPrimitive,FromPrimitive}; // and regret it
use std::hash::Hash;
use std::ops::Shr;
use std::fmt::Debug;

use num::bigint::{ToBigUint,BigUint};
use num::{Zero,One,Integer};
use std::num::Float;

use test::Bencher;

/// Computes the greatest common divisor of two numbers using Euclid's method.
/// Behavior unspecified for negative numbers.
pub fn gcd<T>(a: T,  b: T) -> T
 where T: Clone + Zero + Integer,
{
	let mut cur_a = a;
	let mut cur_b = b;
	while (!cur_a.is_zero()) {
		let old_b = cur_b;
		cur_b = cur_a.clone();
		cur_a = old_b % cur_a;
	}
	cur_b
}

#[bench]
fn bench_gcd(b: &mut Bencher) {
	use std::rand::weak_rng;
	use std::rand::Rng;
	let mut rng = weak_rng();
	b.iter(|| {
		let a = rng.gen_range(100000u32,1000000u32);
		let b = rng.gen_range(100000u32,1000000u32);
		gcd(a,b)
	})
}

/// Performs an integer square root, returning the largest integer whose square is not
///  greater than the argument.
pub fn isqrt<T>(n: T) -> T
 where T: Clone + FromPrimitive + ToPrimitive + Zero + Integer + Shr<usize, Output=T>,
{
	isqrt_fast(n.clone()).or_else(
		|| Some(isqrt_safe(n.clone()))
	).unwrap()
}

/// Used to convert an integral literal into an arbitrary type.
/// For zero and one, `num::Zero::zero()` and `num::One::one()` is preferred when they
///  are used as the additive/multiplicative identity, and `literal` is used otherwise.
#[inline]
pub fn literal<T>(n: isize) -> T
 where T: FromPrimitive,
{
	FromPrimitive::from_int(n).unwrap()
}

/// Computes `pow(x, power) % modulus` using exponentation by squaring.
pub fn mod_pow<T,P>(x: T, power: P, modulus: T) -> T
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
       P: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=P>,
{
	let mut prod:T = One::one();
	let mut remaining = power;
	let mut cur = x;
	while remaining > Zero::zero() {
		if remaining.is_odd() {
			prod = prod * cur.clone();
			prod = prod % modulus.clone();
		}
		remaining = remaining >> 1;
		cur = cur.clone() * cur;
		cur = cur % modulus.clone();
	}
	prod
}

#[test]
fn test_mod_pow()
{
	assert_eq!(mod_pow(234u64, 0, 1259), 1);
	assert_eq!(mod_pow(234u64, 1, 1259), 234);
	assert_eq!(mod_pow(234u64, 2412, 1259), 1091);
}

//-------------------------------
// isqrt helper methods

fn isqrt_fast<T>(x: T) -> Option<T>
 where T: FromPrimitive + ToPrimitive,
{
	x.to_f64().and_then(|f| {
		// Mantissa is 52 bits, and the square root takes half as many bits, so this
		//  may be a bit conservative.  The main concern is to avoid handling very
		//  large BigInts which may lose more than half of their precision.
		if f > 20f64.exp2() {
			None                 // Number too large, bail out!
		} else {
			FromPrimitive::from_f64(f.sqrt().floor())
		}
	})
}

fn isqrt_safe<T>(n: T) -> T
 where T: Clone + FromPrimitive + ToPrimitive + Zero + Integer + Shr<usize, Output=T>,
{
	// NOTE: while I'd like to remove the Shr bound, replacing '>> 1' with '/ 2' makes this
	//       algorithm take twice as long for BigInts :/
	if n.is_zero() { return Zero::zero(); }
	let mut x = n.clone();
	let mut y = (x.clone() + n.clone() / x.clone()) >> literal(1);
	while y < x {
		x = y.clone();
		y = (x.clone() + n.clone() / x.clone()) >> literal(1);
	}
	return x;
}

#[bench]
fn bench_fast(b: &mut Bencher) {
	b.iter(|| {
		(0us..1000us).map(|a| {isqrt_fast::<usize>(a).unwrap()}).collect::<Vec<usize>>()
	})
}

#[bench]
fn bench_safe(b: &mut Bencher) {
	b.iter(|| {
		(0us..1000us).map(isqrt_safe::<usize>).collect::<Vec<usize>>()
	})
}

#[bench]
fn bench_safe_bigint(b: &mut Bencher) {
	b.iter(|| {
		(0us..1000us).map(|a| isqrt_safe::<BigUint>(FromPrimitive::from_uint(a).unwrap())).collect::<Vec<BigUint>>()
	})
}

#[bench]
fn bench_safe_massive_bigint(b: &mut Bencher) {
	use std::rand::XorShiftRng;
	use num::bigint::RandBigInt;
	let mut r = XorShiftRng::new_unseeded();
	b.iter(|| {
		(0us..100us).map(|_| {
			isqrt_safe::<BigUint>(r.gen_biguint(100us))
		}).collect::<Vec<BigUint>>()
	})
}

#[test]
fn test_isqrt_consistency()
{
	(0us..1000).map(|x| {
		let bigX = x.to_biguint().unwrap();
		assert_eq!(isqrt_fast(x),            Some(isqrt_safe(x)));
		assert_eq!(isqrt_fast(bigX.clone()), Some(isqrt_safe(bigX.clone())));
	}).collect::<Vec<_>>();
}

#[cfg(test)]
mod tests {
	extern crate test;
	use super::*;
	use std::num::FromPrimitive;
	use std::num::ToPrimitive;
	use num::bigint::{ToBigUint,BigUint};

	// need to test isqrt with BigInt more rigorously

}
<|endoftext|>


<commit_before>//! Resource caching smart pointer

extern crate rustc_serialize;

use std::sync::Arc;
use std::ops::Deref;
use std::hash;
use std::collections::HashMap;
use std::fmt;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};

/// A type that implements a singleton resource store.
pub trait ResourceStore<K = String> {
    fn get_resource(key: &K) -> Option<Arc<Self>> where Self: Sized;

    fn insert_resource(key: K, resource: Self);
}

/// Smart pointer for an immutable cached resource.
///
/// The semantics are similar to Arc pointers.
///
/// Resource values will serialize as their key values, so they can be attached to structures that
/// require compact serialization.
#[derive(Clone)]
pub struct Resource<T, K = String> {
    handle: Arc<T>,
    key: K,
}

impl<T: Sized, K> AsRef<T> for Resource<T, K> {
    fn as_ref(&self) -> &T { self.handle.as_ref() }
}

impl<T: Sized, K> Deref for Resource<T, K> {
    type Target = T;

    #[inline(always)]
    fn deref(&self) -> &T { self.handle.deref() }
}

impl<T> Encodable for Resource<T> {
    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> { self.key.encode(e) }
}

impl<T: ResourceStore> Decodable for Resource<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        let key: String = Decodable::decode(d)?;;;
        Ok(Self::new(key).unwrap())
    }
}

impl<T, K: hash::Hash> hash::Hash for Resource<T, K> {
    fn hash<H: hash::Hasher>(&self, state: &mut H) { self.key.hash(state); }
}

impl<T, K: PartialEq> PartialEq for Resource<T, K> {
    fn eq(&self, other: &Self) -> bool { self.key.eq(&other.key) }
}

impl<T, K: Eq> Eq for Resource<T, K> {}

impl<T, K: fmt::Display> fmt::Display for Resource<T, K> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.key.fmt(formatter) }
}

impl<T, K: fmt::Debug> fmt::Debug for Resource<T, K> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.key.fmt(formatter) }
}

impl<K, T: ResourceStore<K>> Resource<T, K> {
    pub fn new(key: K) -> Option<Self> {
        if let Some(handle) = ResourceStore::get_resource(&key) {
            Some(Resource {
                handle: handle,
                key: key,
            })
        } else {
            None
        }
    }
}

/// A value that can be implicitly constructed given a key.
pub trait Loadable<K = String> {
    fn load(_key: &K) -> Option<Self>
        where Self: Sized
    {
        // Default implementation so that types with no load semantics can be used with
        // ResourceCache so that all inserts must be explicit.
        None
    }
}

/// A cache that associates resource values with paths.
///
/// Resources and paths are assumed to be immutable.
pub struct ResourceCache<T, K = String> {
    cache: HashMap<K, Arc<T>>,
}

impl<K: Eq + hash::Hash + Clone, T: Loadable<K>> ResourceCache<T, K> {
    pub fn new() -> ResourceCache<T, K> { ResourceCache { cache: HashMap::new() } }

    pub fn get(&mut self, key: &K) -> Option<Arc<T>> {
        if let Some(v) = self.cache.get(key) {
            return Some(v.clone());
        }

        if let Some(v) = T::load(key) {
            let v = Arc::new(v);
            self.cache.insert(key.clone(), v.clone());
            Some(v)
        } else {
            None
        }
    }

    pub fn insert(&mut self, key: K, value: T) { self.cache.insert(key, Arc::new(value)); }
}

/// Implement a thread-local store for a given resource type.
///
/// Name is the identifier for the store, key and value are the types of the resource cache keys
/// and the resources.
///
///     # #[macro_use] extern crate calx_resource;
///     use calx_resource::{Resource, ResourceStore, Loadable};
///
///     // A custom resource type.
///     struct MyResource { pub text: String }
///
///     // Must be present even if there's no specific implementation.
///     impl Loadable for MyResource {}
///
///     // Generate a resource store.
///     impl_store!(MY_RESOURCE_STORE, String, MyResource);
///
///     fn main() {
///         // Save a resource in the store using a key.
///         MyResource::insert_resource(
///             "test_resource".to_string(),
///             MyResource { text: "Hello, world!".to_string() });
///
///         // Fetch a resource handle from the store using our key.
///         let handle: Resource<MyResource> =
///             Resource::new("test_resource".to_string()).unwrap();
///         assert!(&handle.text == "Hello, world!");
///     }
#[macro_export]
macro_rules! impl_store {
    ($name:ident, $key:ty, $value:ty) => {
    thread_local!(static $name: ::std::cell::RefCell<$crate::ResourceCache<$value, $key>> =
                  ::std::cell::RefCell::new($crate::ResourceCache::new()));

    impl $crate::ResourceStore<$key> for $value {
        fn get_resource(key: &$key) -> Option<::std::sync::Arc<Self>> {
            $name.with(|t| t.borrow_mut().get(key))
        }

        fn insert_resource(key: $key, value: $value) {
            $name.with(|t| t.borrow_mut().insert(key, value));
        }
    }}
}
<commit_msg>Fix rustfmt bug<commit_after>//! Resource caching smart pointer

extern crate rustc_serialize;

use std::sync::Arc;
use std::ops::Deref;
use std::hash;
use std::collections::HashMap;
use std::fmt;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};

/// A type that implements a singleton resource store.
pub trait ResourceStore<K = String> {
    fn get_resource(key: &K) -> Option<Arc<Self>> where Self: Sized;

    fn insert_resource(key: K, resource: Self);
}

/// Smart pointer for an immutable cached resource.
///
/// The semantics are similar to Arc pointers.
///
/// Resource values will serialize as their key values, so they can be attached to structures that
/// require compact serialization.
#[derive(Clone)]
pub struct Resource<T, K = String> {
    handle: Arc<T>,
    key: K,
}

impl<T: Sized, K> AsRef<T> for Resource<T, K> {
    fn as_ref(&self) -> &T { self.handle.as_ref() }
}

impl<T: Sized, K> Deref for Resource<T, K> {
    type Target = T;

    #[inline(always)]
    fn deref(&self) -> &T { self.handle.deref() }
}

impl<T> Encodable for Resource<T> {
    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> { self.key.encode(e) }
}

impl<T: ResourceStore> Decodable for Resource<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        let key: String = Decodable::decode(d)?;
        Ok(Self::new(key).unwrap())
    }
}

impl<T, K: hash::Hash> hash::Hash for Resource<T, K> {
    fn hash<H: hash::Hasher>(&self, state: &mut H) { self.key.hash(state); }
}

impl<T, K: PartialEq> PartialEq for Resource<T, K> {
    fn eq(&self, other: &Self) -> bool { self.key.eq(&other.key) }
}

impl<T, K: Eq> Eq for Resource<T, K> {}

impl<T, K: fmt::Display> fmt::Display for Resource<T, K> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.key.fmt(formatter) }
}

impl<T, K: fmt::Debug> fmt::Debug for Resource<T, K> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.key.fmt(formatter) }
}

impl<K, T: ResourceStore<K>> Resource<T, K> {
    pub fn new(key: K) -> Option<Self> {
        if let Some(handle) = ResourceStore::get_resource(&key) {
            Some(Resource {
                handle: handle,
                key: key,
            })
        } else {
            None
        }
    }
}

/// A value that can be implicitly constructed given a key.
pub trait Loadable<K = String> {
    fn load(_key: &K) -> Option<Self>
        where Self: Sized
    {
        // Default implementation so that types with no load semantics can be used with
        // ResourceCache so that all inserts must be explicit.
        None
    }
}

/// A cache that associates resource values with paths.
///
/// Resources and paths are assumed to be immutable.
pub struct ResourceCache<T, K = String> {
    cache: HashMap<K, Arc<T>>,
}

impl<K: Eq + hash::Hash + Clone, T: Loadable<K>> ResourceCache<T, K> {
    pub fn new() -> ResourceCache<T, K> { ResourceCache { cache: HashMap::new() } }

    pub fn get(&mut self, key: &K) -> Option<Arc<T>> {
        if let Some(v) = self.cache.get(key) {
            return Some(v.clone());
        }

        if let Some(v) = T::load(key) {
            let v = Arc::new(v);
            self.cache.insert(key.clone(), v.clone());
            Some(v)
        } else {
            None
        }
    }

    pub fn insert(&mut self, key: K, value: T) { self.cache.insert(key, Arc::new(value)); }
}

/// Implement a thread-local store for a given resource type.
///
/// Name is the identifier for the store, key and value are the types of the resource cache keys
/// and the resources.
///
///     # #[macro_use] extern crate calx_resource;
///     use calx_resource::{Resource, ResourceStore, Loadable};
///
///     // A custom resource type.
///     struct MyResource { pub text: String }
///
///     // Must be present even if there's no specific implementation.
///     impl Loadable for MyResource {}
///
///     // Generate a resource store.
///     impl_store!(MY_RESOURCE_STORE, String, MyResource);
///
///     fn main() {
///         // Save a resource in the store using a key.
///         MyResource::insert_resource(
///             "test_resource".to_string(),
///             MyResource { text: "Hello, world!".to_string() });
///
///         // Fetch a resource handle from the store using our key.
///         let handle: Resource<MyResource> =
///             Resource::new("test_resource".to_string()).unwrap();
///         assert!(&handle.text == "Hello, world!");
///     }
#[macro_export]
macro_rules! impl_store {
    ($name:ident, $key:ty, $value:ty) => {
    thread_local!(static $name: ::std::cell::RefCell<$crate::ResourceCache<$value, $key>> =
                  ::std::cell::RefCell::new($crate::ResourceCache::new()));

    impl $crate::ResourceStore<$key> for $value {
        fn get_resource(key: &$key) -> Option<::std::sync::Arc<Self>> {
            $name.with(|t| t.borrow_mut().get(key))
        }

        fn insert_resource(key: $key, value: $value) {
            $name.with(|t| t.borrow_mut().insert(key, value));
        }
    }}
}
<|endoftext|>


<commit_before>//! Asynchronous streams
//!
//! See [Asynchronous Programming in Rust](https://aturon.github.io/apr/) for an
//! overview.

use Poll;
use task;

/// A stream of values produced asynchronously.
///
/// If `Future` is an asynchronous version of `Result`, then `Stream` is an
/// asynchronous version of `Iterator`. A stream represents a sequence of
/// value-producing events that occur asynchronously to the caller.
///
/// The trait is modeled after `Future`, but allows `poll_next` to be called
/// even after a value has been produced, yielding `None` once the stream has
/// been fully exhausted.
///
/// # Errors
///
/// Streams, like futures, also bake in errors through an associated `Error`
/// type. An error on a stream **does not terminate the stream**. That is,
/// after one error is received, another value may be received from the same
/// stream (it's valid to keep polling). Thus a stream is somewhat like an
/// `Iterator<Item = Result<T, E>>`, and is always terminated by returning
/// `None`.
pub trait Stream {
    /// Values yielded by the stream.
    type Item;

    /// Errors yielded by the stream.
    type Error;

    /// Attempt to pull out the next value of this stream, returning `None` if
    /// the stream is finished.
    ///
    /// This method, like [`Future::poll`](::future::Future::poll), makes
    /// progress on producing the next value in the stream, but does not block
    /// if one is not available yet; it instead queues the current task to be
    /// woken up when more progress is possible.
    ///
    /// # Return value
    ///
    /// There are several possible return values, each indicating a distinct
    /// stream state:
    ///
    /// - [`Ok(Pending)`](::Async) means that this stream's next value is not
    /// ready yet. Implementations will ensure that the current task will be
    /// notified when the next value may be ready.
    ///
    /// - [`Ok(Ready(Some(val)))`](::Async) means that the stream has
    /// successfully produced a value, `val`, and may produce further values
    /// on subsequent `poll_next` calls.
    ///
    /// - [`Ok(Ready(None))`](::Async) means that the stream has terminated, and
    /// `poll_next` should not be invoked again.
    ///
    /// - `Err(err)` means that the stream encountered an error while trying to
    /// `poll_next`. Subsequent calls to `poll_next` *are* allowed, and may
    /// return further values or errors.
    ///
    /// # Panics
    ///
    /// Once a stream is finished, i.e. `Ready(None)` has been returned, further
    /// calls to `poll_next` may result in a panic or other "bad behavior".  If this
    /// is difficult to guard against then the `fuse` adapter can be used to
    /// ensure that `poll_next` always returns `Ready(None)` in subsequent calls.
    fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error>;
}

impl<'a, S: ?Sized + Stream> Stream for &'a mut S {
    type Item = S::Item;
    type Error = S::Error;

    fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
        (**self).poll_next(cx)
    }
}

if_std! {
    impl<S: ?Sized + Stream> Stream for ::std::boxed::Box<S> {
        type Item = S::Item;
        type Error = S::Error;

        fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
            (**self).poll_next(cx)
        }
    }

    impl<S: Stream> Stream for ::std::panic::AssertUnwindSafe<S> {
        type Item = S::Item;
        type Error = S::Error;

        fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<S::Item>, S::Error> {
            self.0.poll_next(cx)
        }
    }
}
<commit_msg>Final fixes<commit_after>//! Asynchronous streams
//!
//! See [Asynchronous Programming in Rust](https://aturon.github.io/apr/) for an
//! overview.

use Poll;
use task;

/// A stream of values produced asynchronously.
///
/// If `Future` is an asynchronous version of `Result`, then `Stream` is an
/// asynchronous version of `Iterator`. A stream represents a sequence of
/// value-producing events that occur asynchronously to the caller.
///
/// The trait is modeled after `Future`, but allows `poll_next` to be called
/// even after a value has been produced, yielding `None` once the stream has
/// been fully exhausted.
///
/// # Errors
///
/// Streams, like futures, also bake in errors through an associated `Error`
/// type. An error on a stream **does not terminate the stream**. That is,
/// after one error is received, another value may be received from the same
/// stream (it's valid to keep polling). Thus a stream is somewhat like an
/// `Iterator<Item = Result<T, E>>`, and is always terminated by returning
/// `None`.
pub trait Stream {
    /// Values yielded by the stream.
    type Item;

    /// Errors yielded by the stream.
    type Error;

    /// Attempt to pull out the next value of this stream, registering the
    /// current task for wakeup if the value is not yet available, and returning
    /// `None` if the stream is exhausted.
    ///
    /// # Return value
    ///
    /// There are several possible return values, each indicating a distinct
    /// stream state:
    ///
    /// - [`Ok(Pending)`](::Async) means that this stream's next value is not
    /// ready yet. Implementations will ensure that the current task will be
    /// notified when the next value may be ready.
    ///
    /// - [`Ok(Ready(Some(val)))`](::Async) means that the stream has
    /// successfully produced a value, `val`, and may produce further values
    /// on subsequent `poll_next` calls.
    ///
    /// - [`Ok(Ready(None))`](::Async) means that the stream has terminated, and
    /// `poll_next` should not be invoked again.
    ///
    /// - `Err(err)` means that the stream encountered an error while trying to
    /// `poll_next`. Subsequent calls to `poll_next` *are* allowed, and may
    /// return further values or errors.
    ///
    /// # Panics
    ///
    /// Once a stream is finished, i.e. `Ready(None)` has been returned, further
    /// calls to `poll_next` may result in a panic or other "bad behavior".  If this
    /// is difficult to guard against then the `fuse` adapter can be used to
    /// ensure that `poll_next` always returns `Ready(None)` in subsequent calls.
    fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error>;
}

impl<'a, S: ?Sized + Stream> Stream for &'a mut S {
    type Item = S::Item;
    type Error = S::Error;

    fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
        (**self).poll_next(cx)
    }
}

if_std! {
    impl<S: ?Sized + Stream> Stream for ::std::boxed::Box<S> {
        type Item = S::Item;
        type Error = S::Error;

        fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
            (**self).poll_next(cx)
        }
    }

    impl<S: Stream> Stream for ::std::panic::AssertUnwindSafe<S> {
        type Item = S::Item;
        type Error = S::Error;

        fn poll_next(&mut self, cx: &mut task::Context) -> Poll<Option<S::Item>, S::Error> {
            self.0.poll_next(cx)
        }
    }
}
<|endoftext|>


<commit_before>pub enum StoreAction {
    Create,
    Retrieve,
    Update,
    Delete,

    // "Read" doesn't matter, as we do not use git on read actions, only when altering content.
}
<commit_msg>Impl Debug, Clone, Display for StoreAction<commit_after>use std::fmt::{Display, Formatter, Error};

#[derive(Clone, Debug)]
pub enum StoreAction {
    Create,
    Retrieve,
    Update,
    Delete,
}

impl Display for StoreAction {

    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        write!(fmt, "StoreAction: {}",
                match *self {
                    StoreAction::Create   => "create",
                    StoreAction::Retrieve => "retrieve",
                    StoreAction::Update   => "update",
                    StoreAction::Delete   => "delete",
                })
    }

}

<|endoftext|>


<commit_before>// Copyright ⓒ 2015-2018 Kevin B. Knapp
//
// `clap_generate` is distributed under the terms of both the MIT license and the Apache License
// (Version 2.0).
// See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files in this repository
// for more information.

//! Generates stuff for [`clap`](https://github.com/clap-rs/clap) based CLIs

#![doc(html_logo_url = "https://clap.rs/images/media/clap.png")]
#![doc(html_root_url = "https://docs.rs/clap_generate/3.0.0-beta.2")]
#![deny(
    missing_docs,
    trivial_casts,
    unused_import_braces,
    unused_allocation,
    trivial_numeric_casts
)]
#![forbid(unsafe_code)]
#![allow(clippy::needless_doctest_main)]

const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
                                  report at https://github.com/clap-rs/clap/issues";

#[macro_use]
#[allow(missing_docs)]
mod macros;

/// Contains some popular generators
pub mod generators;
/// Contains supported shells for auto-completion scripts
mod shell;

use std::ffi::OsString;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

#[doc(inline)]
pub use generators::Generator;
#[doc(inline)]
pub use shell::Shell;

/// Generate a file for a specified generator at compile time.
///
/// **NOTE:** to generate the file at compile time you must use a `build.rs` "Build Script"
///
/// # Examples
///
/// The following example generates a bash completion script via a `build.rs` script. In this
/// simple example, we'll demo a very small application with only a single subcommand and two
/// args. Real applications could be many multiple levels deep in subcommands, and have tens or
/// potentially hundreds of arguments.
///
/// First, it helps if we separate out our `App` definition into a separate file. Whether you
/// do this as a function, or bare App definition is a matter of personal preference.
///
/// ```
/// // src/cli.rs
///
/// use clap::{App, Arg};
///
/// pub fn build_cli() -> App<'static> {
///     App::new("compl")
///         .about("Tests completions")
///         .arg(Arg::new("file")
///             .about("some input file"))
///         .subcommand(App::new("test")
///             .about("tests things")
///             .arg(Arg::new("case")
///                 .long("case")
///                 .takes_value(true)
///                 .about("the case to test")))
/// }
/// ```
///
/// In our regular code, we can simply call this `build_cli()` function, then call
/// `get_matches()`, or any of the other normal methods directly after. For example:
///
/// ```ignore
/// // src/main.rs
///
/// mod cli;
///
/// fn main() {
///     let m = cli::build_cli().get_matches();
///
///     // normal logic continues...
/// }
/// ```
///
/// Next, we set up our `Cargo.toml` to use a `build.rs` build script.
///
/// ```toml
/// # Cargo.toml
/// build = "build.rs"
///
/// [build-dependencies]
/// clap = "*"
/// ```
///
/// Next, we place a `build.rs` in our project root.
///
/// ```ignore
/// use clap_generate::{generate_to, generators::Bash};
///
/// include!("src/cli.rs");
///
/// fn main() {
///     let outdir = match env::var_os("OUT_DIR") {
///         None => return,
///         Some(outdir) => outdir,
///     };
///
///     let mut app = build_cli();
///     generate_to::<Bash, _, _>(
///         &mut app,     // We need to specify what generator to use
///         "myapp",      // We need to specify the bin name manually
///         outdir,       // We need to specify where to write to
///     );
/// }
/// ```
///
/// Now, once we compile there will be a `{bin_name}.bash` file in the directory.
/// Assuming we compiled with debug mode, it would be somewhere similar to
/// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash`.
///
/// **NOTE:** Please look at the individual [generators]
/// to see the name of the files generated.
pub fn generate_to<G, S, T>(app: &mut clap::App, bin_name: S, out_dir: T)
where
    G: Generator,
    S: Into<String>,
    T: Into<OsString>,
{
    let out_dir = PathBuf::from(out_dir.into());
    let file_name = G::file_name(app.get_bin_name().unwrap());

    let mut file = match File::create(out_dir.join(file_name)) {
        Err(why) => panic!("couldn't create completion file: {}", why),
        Ok(file) => file,
    };

    generate::<G, S>(app, bin_name, &mut file)
}

/// Generate a completions file for a specified shell at runtime.
///
/// Until `cargo install` can install extra files like a completion script, this may be
/// used e.g. in a command that outputs the contents of the completion script, to be
/// redirected into a file by the user.
///
/// # Examples
///
/// Assuming a separate `cli.rs` like the [example above](generate_to()),
/// we can let users generate a completion script using a command:
///
/// ```ignore
/// // src/main.rs
///
/// mod cli;
/// use std::io;
/// use clap_generate::{generate, generators::Bash};
///
/// fn main() {
///     let matches = cli::build_cli().get_matches();
///
///     if matches.is_present("generate-bash-completions") {
///         generate::<Bash, _>(&mut cli::build_cli(), "myapp", &mut io::stdout());
///     }
///
///     // normal logic continues...
/// }
///
/// ```
///
/// Usage:
///
/// ```shell
/// $ myapp generate-bash-completions > /usr/share/bash-completion/completions/myapp.bash
/// ```
pub fn generate<G, S>(app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
where
    G: Generator,
    S: Into<String>,
{
    app.set_bin_name(bin_name);

    // TODO: All the subcommands need to be built instead of just the top one
    app._build();
    app._build_bin_names();

    G::generate(app, buf)
}
<commit_msg>Add PathBuf to clap_generate::generate_to<commit_after>// Copyright ⓒ 2015-2018 Kevin B. Knapp
//
// `clap_generate` is distributed under the terms of both the MIT license and the Apache License
// (Version 2.0).
// See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files in this repository
// for more information.

//! Generates stuff for [`clap`](https://github.com/clap-rs/clap) based CLIs

#![doc(html_logo_url = "https://clap.rs/images/media/clap.png")]
#![doc(html_root_url = "https://docs.rs/clap_generate/3.0.0-beta.2")]
#![deny(
    missing_docs,
    trivial_casts,
    unused_import_braces,
    unused_allocation,
    trivial_numeric_casts
)]
#![forbid(unsafe_code)]
#![allow(clippy::needless_doctest_main)]

const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
                                  report at https://github.com/clap-rs/clap/issues";

#[macro_use]
#[allow(missing_docs)]
mod macros;

/// Contains some popular generators
pub mod generators;
/// Contains supported shells for auto-completion scripts
mod shell;

use std::ffi::OsString;
use std::fs::File;
use std::io::Error;
use std::io::Write;
use std::path::PathBuf;

#[doc(inline)]
pub use generators::Generator;
#[doc(inline)]
pub use shell::Shell;

/// Generate a file for a specified generator at compile time.
///
/// **NOTE:** to generate the file at compile time you must use a `build.rs` "Build Script"
///
/// # Examples
///
/// The following example generates a bash completion script via a `build.rs` script. In this
/// simple example, we'll demo a very small application with only a single subcommand and two
/// args. Real applications could be many multiple levels deep in subcommands, and have tens or
/// potentially hundreds of arguments.
///
/// First, it helps if we separate out our `App` definition into a separate file. Whether you
/// do this as a function, or bare App definition is a matter of personal preference.
///
/// ```
/// // src/cli.rs
///
/// use clap::{App, Arg};
///
/// pub fn build_cli() -> App<'static> {
///     App::new("compl")
///         .about("Tests completions")
///         .arg(Arg::new("file")
///             .about("some input file"))
///         .subcommand(App::new("test")
///             .about("tests things")
///             .arg(Arg::new("case")
///                 .long("case")
///                 .takes_value(true)
///                 .about("the case to test")))
/// }
/// ```
///
/// In our regular code, we can simply call this `build_cli()` function, then call
/// `get_matches()`, or any of the other normal methods directly after. For example:
///
/// ```ignore
/// // src/main.rs
///
/// mod cli;
///
/// fn main() {
///     let _m = cli::build_cli().get_matches();
///
///     // normal logic continues...
/// }
/// ```
///
/// Next, we set up our `Cargo.toml` to use a `build.rs` build script.
///
/// ```toml
/// # Cargo.toml
/// build = "build.rs"
///
/// [dependencies]
/// clap = "*"
///
/// [build-dependencies]
/// clap = "*"
/// clap_generate = "*"
/// ```
///
/// Next, we place a `build.rs` in our project root.
///
/// ```ignore
/// use clap_generate::{generate_to, generators::Bash};
/// use std::env;
/// use std::io::Error;
///
/// include!("src/cli.rs");
///
/// fn main() -> Result<(), Error> {
///     let outdir = match env::var_os("OUT_DIR") {
///         None => return Ok(()),
///         Some(outdir) => outdir,
///     };
///
///     let mut app = build_cli();
///     let path = generate_to::<Bash, _, _>(
///         &mut app, // We need to specify what generator to use
///         "myapp",  // We need to specify the bin name manually
///         outdir,   // We need to specify where to write to
///     )?;
///
///     println!("cargo:warning=completion file is generated: {:?}", path);
///
///     Ok(())
/// }
/// ```
///
/// Now, once we compile there will be a `{bin_name}.bash` file in the directory.
/// Assuming we compiled with debug mode, it would be somewhere similar to
/// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash`.
///
/// **NOTE:** Please look at the individual [generators]
/// to see the name of the files generated.
pub fn generate_to<G, S, T>(app: &mut clap::App, bin_name: S, out_dir: T) -> Result<PathBuf, Error>
where
    G: Generator,
    S: Into<String>,
    T: Into<OsString>,
{
    app.set_bin_name(bin_name);

    let out_dir = PathBuf::from(out_dir.into());
    let file_name = G::file_name(app.get_bin_name().unwrap());

    let path = out_dir.join(file_name);
    let mut file = File::create(&path)?;

    _generate::<G, S>(app, &mut file);
    Ok(path)
}

/// Generate a completions file for a specified shell at runtime.
///
/// Until `cargo install` can install extra files like a completion script, this may be
/// used e.g. in a command that outputs the contents of the completion script, to be
/// redirected into a file by the user.
///
/// # Examples
///
/// Assuming a separate `cli.rs` like the [example above](generate_to()),
/// we can let users generate a completion script using a command:
///
/// ```ignore
/// // src/main.rs
///
/// mod cli;
/// use std::io;
/// use clap_generate::{generate, generators::Bash};
///
/// fn main() {
///     let matches = cli::build_cli().get_matches();
///
///     if matches.is_present("generate-bash-completions") {
///         generate::<Bash, _>(&mut cli::build_cli(), "myapp", &mut io::stdout());
///     }
///
///     // normal logic continues...
/// }
///
/// ```
///
/// Usage:
///
/// ```shell
/// $ myapp generate-bash-completions > /usr/share/bash-completion/completions/myapp.bash
/// ```
pub fn generate<G, S>(app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
where
    G: Generator,
    S: Into<String>,
{
    app.set_bin_name(bin_name);
    _generate::<G, S>(app, buf)
}

fn _generate<G, S>(app: &mut clap::App, buf: &mut dyn Write)
where
    G: Generator,
    S: Into<String>,
{
    // TODO: All the subcommands need to be built instead of just the top one
    app._build();
    app._build_bin_names();

    G::generate(app, buf)
}
<|endoftext|>


<commit_before>extern crate rand;

use rand::Rng;

use std::net::SocketAddr;

use messages::{Any, RawMessage, Connect, Status, Message, RequestPeers};
use events::Channel;
use super::{NodeHandler, RequestData, ExternalMessage, NodeTimeout};

impl<S> NodeHandler<S>
    where S: Channel<ApplicationEvent = ExternalMessage, Timeout = NodeTimeout>
{
    pub fn handle_message(&mut self, raw: RawMessage) {
        // TODO: check message headers (network id, protocol version)
        // FIXME: call message.verify method
        //     if !raw.verify() {
        //         return;
        //     }

        //FIXME: add whitelist verify public_key

        let msg = Any::from_raw(raw).unwrap();
        match msg {
            Any::Connect(msg) => self.handle_connect(msg),
            Any::Status(msg) => self.handle_status(msg),
            Any::Consensus(msg) => self.handle_consensus(msg),
            Any::Request(msg) => self.handle_request(msg),
            Any::Block(msg) => self.handle_block(msg),
            Any::Transaction(msg) => self.handle_tx(msg),
        }
    }

    pub fn handle_connected(&mut self, addr: &SocketAddr) {
        info!("Connected to: {}", addr);
        let message = self.state.our_connect_message().clone();
        self.send_to_addr(addr, message.raw());
    }

    pub fn handle_disconnected(&mut self, addr: &SocketAddr) {
        info!("Disconnected from: {}", addr);
        let need_reconnect = self.state.remove_peer_with_addr(addr);
        if need_reconnect {
            self.connect(addr);
        }
    }

    pub fn handle_connect(&mut self, message: Connect) {
        // TODO add spam protection
        let address = message.addr();
        if address == self.state.our_connect_message().addr() {
            return;
        }
        // Check if we have another connect message from peer with the given public_key
        let public_key = *message.pub_key();
        let mut need_connect = true;
        if let Some(saved_message) = self.state.peers().get(&public_key) {
            if saved_message.time() > message.time() {
                error!("Received outdated Connect message from {}", address);
                return;
            } else if saved_message.time() < message.time() {
                need_connect = saved_message.addr() != message.addr();
            } else if saved_message.addr() != message.addr() {
                error!("Received weird Connect message from {}", address);
                return;
            }
        }
        info!("Received Connect message from {}, {}",
              address,
              need_connect);
        self.state.add_peer(public_key, message);
        if need_connect {
            // TODO: reduce double sending of connect message
            info!("Send Connect message to {}", address);
            self.connect(&address);
        }
    }

    pub fn handle_status(&mut self, msg: Status) {
        let self_height = self.state.height();
        trace!("HANDLE STATUS: current height = {}, msg height = {}", self_height, msg.height());

        // Handle message from future height
        if msg.height() > self_height {
            let peer = msg.from();

            //verify message
            if !msg.verify_signature(peer) {
                return;
            }

            // Check validator height info
            if msg.height() > self.state.node_height(peer) {
                // Update validator height
                self.state.set_node_height(*peer, msg.height());
            }

            // Request block
            self.request(RequestData::Block(self_height), *peer);
        }
    }

    pub fn handle_request_peers(&mut self, msg: RequestPeers) {
        let peers: Vec<Connect> = self.state.peers().iter().map(|(_, b)| b.clone()).collect();
        debug!("HANDLE REQUEST PEERS: Sending {:?} peers to {:?}", peers, msg.from());

        for peer in peers {
            self.send_to_peer(*msg.from(), peer.raw());
        }
    }

    pub fn handle_status_timeout(&mut self) {
        let hash = self.blockchain.last_hash().unwrap();
        // Send status
        let status = Status::new(self.state.public_key(),
                                 self.state.height(),
                                 &hash,
                                 self.state.secret_key());
        trace!("Broadcast status: {:?}", status);
        self.broadcast(status.raw());

        self.add_status_timeout();
    }

    pub fn handle_peer_exchange_timeout(&mut self) {
        if !self.state.peers().is_empty() {
            let to = self.state.peers().len();
            let gen_peer_id = || -> usize {
                let mut rng = rand::thread_rng();
                rng.gen_range(0, to)
            };

            let peer = self.state
                .peers()
                .iter()
                .map(|x| x.1.clone())
                .nth(gen_peer_id())
                .unwrap();
            let peer = peer.clone();
            let msg = RequestPeers::new(self.state.public_key(),
                                        peer.pub_key(),
                                        self.state.secret_key());
            trace!("Request peers from peer with addr {:?}", peer.addr());
            self.send_to_peer(*peer.pub_key(), msg.raw());
        }
        self.add_peer_exchange_timeout();
    }
}
<commit_msg>Revert 'height' variable renaming<commit_after>extern crate rand;

use rand::Rng;

use std::net::SocketAddr;

use messages::{Any, RawMessage, Connect, Status, Message, RequestPeers};
use events::Channel;
use super::{NodeHandler, RequestData, ExternalMessage, NodeTimeout};

impl<S> NodeHandler<S>
    where S: Channel<ApplicationEvent = ExternalMessage, Timeout = NodeTimeout>
{
    pub fn handle_message(&mut self, raw: RawMessage) {
        // TODO: check message headers (network id, protocol version)
        // FIXME: call message.verify method
        //     if !raw.verify() {
        //         return;
        //     }

        //FIXME: add whitelist verify public_key

        let msg = Any::from_raw(raw).unwrap();
        match msg {
            Any::Connect(msg) => self.handle_connect(msg),
            Any::Status(msg) => self.handle_status(msg),
            Any::Consensus(msg) => self.handle_consensus(msg),
            Any::Request(msg) => self.handle_request(msg),
            Any::Block(msg) => self.handle_block(msg),
            Any::Transaction(msg) => self.handle_tx(msg),
        }
    }

    pub fn handle_connected(&mut self, addr: &SocketAddr) {
        info!("Connected to: {}", addr);
        let message = self.state.our_connect_message().clone();
        self.send_to_addr(addr, message.raw());
    }

    pub fn handle_disconnected(&mut self, addr: &SocketAddr) {
        info!("Disconnected from: {}", addr);
        let need_reconnect = self.state.remove_peer_with_addr(addr);
        if need_reconnect {
            self.connect(addr);
        }
    }

    pub fn handle_connect(&mut self, message: Connect) {
        // TODO add spam protection
        let address = message.addr();
        if address == self.state.our_connect_message().addr() {
            return;
        }
        // Check if we have another connect message from peer with the given public_key
        let public_key = *message.pub_key();
        let mut need_connect = true;
        if let Some(saved_message) = self.state.peers().get(&public_key) {
            if saved_message.time() > message.time() {
                error!("Received outdated Connect message from {}", address);
                return;
            } else if saved_message.time() < message.time() {
                need_connect = saved_message.addr() != message.addr();
            } else if saved_message.addr() != message.addr() {
                error!("Received weird Connect message from {}", address);
                return;
            }
        }
        info!("Received Connect message from {}, {}",
              address,
              need_connect);
        self.state.add_peer(public_key, message);
        if need_connect {
            // TODO: reduce double sending of connect message
            info!("Send Connect message to {}", address);
            self.connect(&address);
        }
    }

    pub fn handle_status(&mut self, msg: Status) {
        let height = self.state.height();
        trace!("HANDLE STATUS: current height = {}, msg height = {}", height, msg.height());

        // Handle message from future height
        if msg.height() > height {
            let peer = msg.from();

            //verify message
            if !msg.verify_signature(peer) {
                return;
            }

            // Check validator height info
            if msg.height() > self.state.node_height(peer) {
                // Update validator height
                self.state.set_node_height(*peer, msg.height());
            }

            // Request block
            self.request(RequestData::Block(height), *peer);
        }
    }

    pub fn handle_request_peers(&mut self, msg: RequestPeers) {
        let peers: Vec<Connect> = self.state.peers().iter().map(|(_, b)| b.clone()).collect();
        debug!("HANDLE REQUEST PEERS: Sending {:?} peers to {:?}", peers, msg.from());

        for peer in peers {
            self.send_to_peer(*msg.from(), peer.raw());
        }
    }

    pub fn handle_status_timeout(&mut self) {
        let hash = self.blockchain.last_hash().unwrap();
        // Send status
        let status = Status::new(self.state.public_key(),
                                 self.state.height(),
                                 &hash,
                                 self.state.secret_key());
        trace!("Broadcast status: {:?}", status);
        self.broadcast(status.raw());

        self.add_status_timeout();
    }

    pub fn handle_peer_exchange_timeout(&mut self) {
        if !self.state.peers().is_empty() {
            let to = self.state.peers().len();
            let gen_peer_id = || -> usize {
                let mut rng = rand::thread_rng();
                rng.gen_range(0, to)
            };

            let peer = self.state
                .peers()
                .iter()
                .map(|x| x.1.clone())
                .nth(gen_peer_id())
                .unwrap();
            let peer = peer.clone();
            let msg = RequestPeers::new(self.state.public_key(),
                                        peer.pub_key(),
                                        self.state.secret_key());
            trace!("Request peers from peer with addr {:?}", peer.addr());
            self.send_to_peer(*peer.pub_key(), msg.raw());
        }
        self.add_peer_exchange_timeout();
    }
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// 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/.

use std::cell::{Cell, UnsafeCell};
use std::{mem, ptr};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering};

use futures::{Async, Poll};
use futures::stream::Stream;
use futures::task::{self, Task};

#[cfg(target_pointer_width = "32")]
const PAD: usize = 16;
#[cfg(target_pointer_width = "64")]
const PAD: usize = 8;

#[repr(C)]
struct RingBuffer<T, E> {
    read:          AtomicUsize,
    last_write:    Cell<usize>,
    _padding1:     [usize; PAD - 2],
    write:         AtomicUsize,
    last_read:     Cell<usize>,
    _padding2:     [usize; PAD - 2],
    buffer:        *mut T,
    capacity:      usize,
    size:          usize,
    pub error:     AtomicPtr<E>,
    pub is_closed: AtomicBool,
    task:          UnsafeCell<Option<Task>>,
    pub task_lock: AtomicBool
}

impl<T, E> RingBuffer<T, E> {
    #[inline]
    pub fn new(capacity: usize) -> RingBuffer<T, E> {
        let size = capacity.next_power_of_two();
        let mut vec = Vec::with_capacity(size);
        let ptr = vec.as_mut_ptr();

        mem::forget(vec);

        RingBuffer {
            read:       AtomicUsize::new(0),
            last_write: Cell::new(0),
            _padding1:  [0; PAD - 2],
            write:      AtomicUsize::new(0),
            last_read:  Cell::new(0),
            _padding2:  [0; PAD - 2],
            buffer:     ptr,
            capacity:   capacity,
            size:       size,
            error:      AtomicPtr::new(ptr::null_mut()),
            is_closed:  AtomicBool::new(false),
            task:       UnsafeCell::new(None),
            task_lock:  AtomicBool::new(false)
        }
    }

    #[inline]
    pub fn try_push(&self, value: T) -> Option<T> {
        let read = self.last_read.get();
        let write = self.write.load(Ordering::Relaxed);

        if read + self.capacity <= write {
            let read = self.read.load(Ordering::Relaxed);
            self.last_read.set(read);

            if read + self.capacity <= write {
                return Some(value);
            }
        }

        self.push(write, value);

        self.write.store(write.wrapping_add(1), Ordering::Relaxed);

        self.try_unpark();

        None
    }

    #[inline]
    pub fn try_pop(&self) -> Option<T> {
        let read = self.read.load(Ordering::Relaxed);
        let write = self.last_write.get();

        if read == write {
            let write = self.write.load(Ordering::Relaxed);
            self.last_write.set(write);

            if read == write {
                return None;
            }
        }

        let result = self.pop(read);

        self.read.store(read.wrapping_add(1), Ordering::Relaxed);

        Some(result)
    }

    #[inline]
    pub fn try_park(&self) -> bool {
        let locked = self.task_lock.swap(true, Ordering::Relaxed);

        if !locked {
            self.swap(Some(task::park()));

            self.task_lock.store(false, Ordering::Relaxed);
        }

        !locked
    }

    #[inline]
    pub fn try_unpark(&self) -> bool {
        let locked = self.task_lock.swap(true, Ordering::Relaxed);

        if !locked {
            let task = self.swap(None);

            if let Some(task) = task {
                task.unpark();
            }

            self.task_lock.store(false, Ordering::Relaxed);
        }

        !locked
    }

    #[inline]
    pub fn swap(&self, option: Option<Task>) -> Option<Task> {
        let mut task = unsafe { &mut *self.task.get()};
        mem::replace(task, option)
    }

    #[inline]
    fn push(&self, index: usize, value: T) {
        unsafe {
            ptr::write(&mut *self.buffer.offset(self.index(index)), value);
        }
    }

    #[inline]
    fn pop(&self, index: usize) -> T {
        unsafe {
            ptr::read(self.buffer.offset(self.index(index)))
        }
    }

    #[inline]
    fn index(&self, index: usize) -> isize {
        (index & (self.size - 1)) as isize
    }
}

impl<T, E> Drop for RingBuffer<T, E> {
    fn drop(&mut self) {
        unsafe  {
            Vec::from_raw_parts(self.buffer, 0, self.size);
        }
    }
}

unsafe impl<T: Send, E: Send> Send for RingBuffer<T, E> {}
unsafe impl<T: Sync, E: Sync> Sync for RingBuffer<T, E> {}

pub struct BufferedStream<T, E> {
    buffer: Arc<RingBuffer<T, E>>
}

impl<T, E> Stream for BufferedStream<T, E> {
    type Item  = T;
    type Error = E;

    fn poll(&mut self) -> Poll<Option<T>, E> {
        let error = self.buffer.error.load(Ordering::Acquire);

        if !error.is_null() {
            let error = unsafe { Err(*Box::from_raw(error)) };
            self.buffer.error.store(ptr::null_mut(), Ordering::Release);

            return error;
        }

        match self.buffer.try_pop() {
            Some(value) => Ok(Async::Ready(Some(value))),
            None => {
                if self.buffer.is_closed.load(Ordering::Relaxed) {
                    Ok(Async::Ready(None))
                } else {
                    loop {
                        if self.buffer.try_park() {
                            break;
                        }
                    }

                    Ok(Async::NotReady)
                }
            }
        }
    }
}

pub struct BufferedSender<T, E> {
    buffer: Arc<RingBuffer<T, E>>
}

impl<T, E> BufferedSender<T, E> {
    #[inline]
    pub fn send(&self, value: T) {
        let mut value = value;

        loop {
            value = match self.buffer.try_push(value) {
                Some(value) => value,
                None        => break
            };
        }
    }

    #[inline]
    pub fn fail(self, error: E) {
        let boxed = Box::new(error);
        self.buffer.error.store(Box::into_raw(boxed), Ordering::Release);
    }
}

impl<T, E> Drop for BufferedSender<T, E> {
    fn drop(&mut self) {
        self.buffer.is_closed.store(true, Ordering::Relaxed);

        loop {
            if self.buffer.try_unpark() {
                break;
            }
        }
    }
}

pub fn buffered<T, E>(capacity: usize) -> (BufferedSender<T, E>, BufferedStream<T, E>) {
    let buffer = Arc::new(RingBuffer::new(capacity));

    (BufferedSender { buffer: buffer.clone() }, BufferedStream { buffer: buffer })
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;
    use std::thread;
    use std::time::Duration;

    use futures::future::Future;
    use futures::stream::Stream;

    use super::*;

    #[test]
    fn ring_push_pop() {
        let ring: RingBuffer<i32, ()> = RingBuffer::new(3);

        assert_eq!(ring.try_push(1), None);
        assert_eq!(ring.try_push(2), None);
        assert_eq!(ring.try_push(3), None);
        assert_eq!(ring.try_push(4), Some(4));

        assert_eq!(ring.try_pop(), Some(1));
        assert_eq!(ring.try_pop(), Some(2));
        assert_eq!(ring.try_pop(), Some(3));
        assert_eq!(ring.try_pop(), None);

        assert_eq!(ring.try_push(1), None);
        assert_eq!(ring.try_push(2), None);
        assert_eq!(ring.try_push(3), None);
        assert_eq!(ring.try_push(4), Some(4));

        assert_eq!(ring.try_pop(), Some(1));
        assert_eq!(ring.try_pop(), Some(2));
        assert_eq!(ring.try_pop(), Some(3));
        assert_eq!(ring.try_pop(), None);
    }

    #[test]
    fn buffer_fail() {
        let (sender, stream) = buffered::<(), String>(1);

        sender.fail("error".to_owned());

        assert_eq!(stream.collect().wait(), Err("error".to_owned()))
    }

    #[test]
    fn ring_async() {
        let ring: Arc<RingBuffer<i32, ()>> = Arc::new(RingBuffer::new(10));
        let clone = ring.clone();

        thread::spawn(move || {
            for _ in 0..10 {
                thread::sleep(Duration::from_millis(1));

                assert_eq!(clone.try_push(1), None);
            }
        });

        let mut count = 0;

        loop {
            if ring.try_pop().is_some() {
                count += 1;
            }

            if count == 10 {
                break;
            }
        }
    }

    #[test]
    fn sender_stream() {
        let (sender, stream) = buffered::<i32, ()>(3);

        thread::spawn(move || {
            thread::sleep(Duration::from_millis(10));

            for _ in 0..100 {
                sender.send(1);
            }
        });

        let sum = stream.fold(0, |sum, value| {
            Ok(sum + value)
        }).wait().unwrap();

        assert_eq!(sum, 100);
    }
}
<commit_msg>Fixed concurrency issue.<commit_after>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// 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/.

use std::cell::{Cell, UnsafeCell};
use std::{mem, ptr};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering};

use futures::{Async, Poll};
use futures::stream::Stream;
use futures::task::{self, Task};

#[cfg(target_pointer_width = "32")]
const PAD: usize = 16;
#[cfg(target_pointer_width = "64")]
const PAD: usize = 8;

#[repr(C)]
struct RingBuffer<T, E> {
    read:          AtomicUsize,
    last_write:    Cell<usize>,
    _padding1:     [usize; PAD - 2],
    write:         AtomicUsize,
    last_read:     Cell<usize>,
    _padding2:     [usize; PAD - 2],
    buffer:        *mut T,
    capacity:      usize,
    size:          usize,
    pub error:     AtomicPtr<E>,
    pub is_closed: AtomicBool,
    task:          UnsafeCell<Option<Task>>,
    pub task_lock: AtomicBool
}

impl<T, E> RingBuffer<T, E> {
    #[inline]
    pub fn new(capacity: usize) -> RingBuffer<T, E> {
        let size = capacity.next_power_of_two();
        let mut vec = Vec::with_capacity(size);
        let ptr = vec.as_mut_ptr();

        mem::forget(vec);

        RingBuffer {
            read:       AtomicUsize::new(0),
            last_write: Cell::new(0),
            _padding1:  [0; PAD - 2],
            write:      AtomicUsize::new(0),
            last_read:  Cell::new(0),
            _padding2:  [0; PAD - 2],
            buffer:     ptr,
            capacity:   capacity,
            size:       size,
            error:      AtomicPtr::new(ptr::null_mut()),
            is_closed:  AtomicBool::new(false),
            task:       UnsafeCell::new(None),
            task_lock:  AtomicBool::new(false)
        }
    }

    #[inline]
    pub fn try_push(&self, value: T) -> Option<T> {
        let read = self.last_read.get();
        let write = self.write.load(Ordering::Relaxed);

        if read + self.capacity <= write {
            let read = self.read.load(Ordering::Relaxed);
            self.last_read.set(read);

            if read + self.capacity <= write {
                // Last park might have happened while we were pushing, so we need to try and unpark
                // in order to make sure that we don't dead lock at full capacity.
                self.try_unpark();

                return Some(value);
            }
        }

        self.push(write, value);

        self.write.store(write.wrapping_add(1), Ordering::Relaxed);

        self.try_unpark();

        None
    }

    #[inline]
    pub fn try_pop(&self) -> Option<T> {
        let read = self.read.load(Ordering::Relaxed);
        let write = self.last_write.get();

        if read == write {
            let write = self.write.load(Ordering::Relaxed);
            self.last_write.set(write);

            if read == write {
                return None;
            }
        }

        let result = self.pop(read);

        self.read.store(read.wrapping_add(1), Ordering::Relaxed);

        Some(result)
    }

    #[inline]
    pub fn try_unpark(&self) {
        let locked = self.task_lock.swap(true, Ordering::Relaxed);

        if !locked {
            let task = self.swap(None);

            if let Some(task) = task {
                task.unpark();
            }

            self.task_lock.store(false, Ordering::Relaxed);
        }
    }

    #[inline]
    pub fn swap(&self, option: Option<Task>) -> Option<Task> {
        let mut task = unsafe { &mut *self.task.get()};
        mem::replace(task, option)
    }

    #[inline]
    fn push(&self, index: usize, value: T) {
        unsafe {
            ptr::write(&mut *self.buffer.offset(self.index(index)), value);
        }
    }

    #[inline]
    fn pop(&self, index: usize) -> T {
        unsafe {
            ptr::read(self.buffer.offset(self.index(index)))
        }
    }

    #[inline]
    fn index(&self, index: usize) -> isize {
        (index & (self.size - 1)) as isize
    }
}

impl<T, E> Drop for RingBuffer<T, E> {
    fn drop(&mut self) {
        unsafe  {
            Vec::from_raw_parts(self.buffer, 0, self.size);
        }
    }
}

unsafe impl<T: Send, E: Send> Send for RingBuffer<T, E> {}
unsafe impl<T: Sync, E: Sync> Sync for RingBuffer<T, E> {}

pub struct BufferedStream<T, E> {
    buffer: Arc<RingBuffer<T, E>>
}

impl<T, E> Stream for BufferedStream<T, E> {
    type Item  = T;
    type Error = E;

    fn poll(&mut self) -> Poll<Option<T>, E> {
        let error = self.buffer.error.load(Ordering::Relaxed);

        if !error.is_null() {
            let error = unsafe { Err(*Box::from_raw(error)) };
            self.buffer.error.store(ptr::null_mut(), Ordering::Relaxed);

            error
        } else {
            match self.buffer.try_pop() {
                Some(value) => Ok(Async::Ready(Some(value))),
                None => {
                    loop {
                        let locked = self.buffer.task_lock.swap(true, Ordering::Relaxed);

                        if !locked {
                            match self.buffer.try_pop() {
                                Some(value) => {
                                    self.buffer.task_lock.store(false, Ordering::Relaxed);

                                    return Ok(Async::Ready(Some(value)));
                                }
                                None => {
                                    if self.buffer.is_closed.load(Ordering::Relaxed) {
                                        self.buffer.task_lock.store(false, Ordering::Relaxed);

                                        return Ok(Async::Ready(None));
                                    } else {
                                        self.buffer.swap(Some(task::park()));
                                        self.buffer.task_lock.store(false, Ordering::Relaxed);

                                        return Ok(Async::NotReady);
                                    }
                                }
                            };
                        }
                    }
                }
            }
        }
    }
}

pub struct BufferedSender<T, E> {
    buffer: Arc<RingBuffer<T, E>>
}

impl<T, E> BufferedSender<T, E> {
    #[inline]
    pub fn send(&self, value: T) {
        let mut value = value;

        loop {
            value = match self.buffer.try_push(value) {
                Some(value) => value,
                None        => break
            };
        }
    }

    #[inline]
    pub fn fail(self, error: E) {
        let boxed = Box::new(error);
        self.buffer.error.store(Box::into_raw(boxed), Ordering::Relaxed);
    }
}

impl<T, E> Drop for BufferedSender<T, E> {
    fn drop(&mut self) {
        loop {
            let locked = self.buffer.task_lock.swap(true, Ordering::Relaxed);

            if !locked {
                self.buffer.is_closed.store(true, Ordering::Relaxed);

                let task = self.buffer.swap(None);

                if let Some(task) = task {
                    task.unpark();
                }

                self.buffer.task_lock.store(false, Ordering::Relaxed);

                break;
            }
        }
    }
}

pub fn buffered<T, E>(capacity: usize) -> (BufferedSender<T, E>, BufferedStream<T, E>) {
    let buffer = Arc::new(RingBuffer::new(capacity));

    (BufferedSender { buffer: buffer.clone() }, BufferedStream { buffer: buffer })
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;
    use std::thread;
    use std::time::Duration;

    use futures::future::Future;
    use futures::stream::Stream;

    use super::*;

    #[test]
    fn ring_push_pop() {
        let ring: RingBuffer<i32, ()> = RingBuffer::new(3);

        assert_eq!(ring.try_push(1), None);
        assert_eq!(ring.try_push(2), None);
        assert_eq!(ring.try_push(3), None);
        assert_eq!(ring.try_push(4), Some(4));

        assert_eq!(ring.try_pop(), Some(1));
        assert_eq!(ring.try_pop(), Some(2));
        assert_eq!(ring.try_pop(), Some(3));
        assert_eq!(ring.try_pop(), None);

        assert_eq!(ring.try_push(1), None);
        assert_eq!(ring.try_push(2), None);
        assert_eq!(ring.try_push(3), None);
        assert_eq!(ring.try_push(4), Some(4));

        assert_eq!(ring.try_pop(), Some(1));
        assert_eq!(ring.try_pop(), Some(2));
        assert_eq!(ring.try_pop(), Some(3));
        assert_eq!(ring.try_pop(), None);
    }

    #[test]
    fn buffer_fail() {
        let (sender, stream) = buffered::<(), String>(1);

        sender.fail("error".to_owned());

        assert_eq!(stream.collect().wait(), Err("error".to_owned()))
    }

    #[test]
    fn ring_async() {
        let ring: Arc<RingBuffer<i32, ()>> = Arc::new(RingBuffer::new(10));
        let clone = ring.clone();

        thread::spawn(move || {
            for _ in 0..10 {
                thread::sleep(Duration::from_millis(1));

                assert_eq!(clone.try_push(1), None);
            }
        });

        let mut count = 0;

        loop {
            if ring.try_pop().is_some() {
                count += 1;
            }

            if count == 10 {
                break;
            }
        }
    }

    #[test]
    fn sender_stream() {
        let (sender, stream) = buffered::<i32, ()>(3);

        thread::spawn(move || {
            for _ in 0..1000 {
                sender.send(1);
            }
        });

        let sum = stream.fold(0, |sum, value| {
            Ok(sum + value)
        }).wait().unwrap();

        assert_eq!(sum, 1000);
    }
}

<|endoftext|>


<commit_before>fn main() {
    let captured_value = 7u32;

    let closure = |&:argument| {
        println!("I captured this: {}", captured_value);
        println!("Argument passed was: {}", argument);

        true
    };

    println!("Closure returned: {}", closure("a string"));
}
<commit_msg>closures: fix obsolete syntax `&:`.<commit_after>fn main() {
    let captured_value = 7u32;

    let closure = |argument| {
        println!("I captured this: {}", captured_value);
        println!("Argument passed was: {}", argument);

        true
    };

    println!("Closure returned: {}", closure("a string"));
}
<|endoftext|>