<commit_before>#![crate_id = "base58"]
#![crate_type = "rlib"]
#![license = "Apache License, Version 2.0"]
#![deny(missing_doc)]

//! Rust-Base58 provides functions to encode and decode base58 values.

static BASE_256:u16 = 256;
static BASE_58:u16 = 58;

/// Encode a String into base58 String.
///
/// ```rust{.example}
/// extern crate base58;
/// use base58::encode_base58;
///
/// fn main() {
///   let encoded = encode_base58(String::from_str("azerty"));
///   println!("encoded: {}",encoded); // will print "encoded: qYPmmAqv"
/// }
/// ```
pub fn encode_base58 (input: String) -> String {
  let mut copied = input.into_bytes();
  let mut output:Vec<u8> = Vec::with_capacity(copied.len() * 138 / 100 + 1);
  let len = copied.len();

  if len == 0 {
    return String::new();
  }

  let mut count = 0;
  while count < len {
    let modulo = divide_mode58(&mut copied, count);
    let letter = from_alphabet(modulo);
    output.push(letter);

    if *copied.get(count) == 0 {
      count += 1;
    }
  }

  output.reverse();

  match String::from_utf8(output) {
    Ok(result) => result,
    Err(e) => fail!(e)
  }
}

/// Give the letter from the base58 alphabet
fn from_alphabet(position: u16) -> u8 {
  "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".char_at(position as uint) as u8
}

/// This function make the division of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_mode58(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base256: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_256 + num_base256;
    *x = (temp / BASE_58) as u8;
    remainder = temp % BASE_58;
  }

  remainder
}

#[cfg(test)]
mod tests {

  use super::divide_mode58;

  #[test]
  fn should_divide_zero_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_mode58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_without_modulo() {
    // Given
    let mut input = vec!(100u8, 43);

    // When
    let modulo = divide_mode58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 1);
    assert_eq!(*input.get(1), 186);
    assert_eq!(modulo, 7);
  }

}
<commit_msg>Add division by 256 + Rename division functions<commit_after>#![crate_id = "base58"]
#![crate_type = "rlib"]
#![license = "Apache License, Version 2.0"]
#![deny(missing_doc)]

//! Rust-Base58 provides functions to encode and decode base58 values.

static BASE_256:u16 = 256;
static BASE_58:u16 = 58;

/// Encode a String into base58 String.
///
/// ```rust{.example}
/// extern crate base58;
/// use base58::encode_base58;
///
/// fn main() {
///   let encoded = encode_base58(String::from_str("azerty"));
///   println!("encoded: {}",encoded); // will print "encoded: qYPmmAqv"
/// }
/// ```
pub fn encode_base58 (input: String) -> String {
  let mut copied = input.into_bytes();
  let mut output:Vec<u8> = Vec::with_capacity(copied.len() * 138 / 100 + 1);
  let len = copied.len();

  if len == 0 {
    return String::new();
  }

  let mut count = 0;
  while count < len {
    let modulo = divide_by_58(&mut copied, count);
    let letter = from_alphabet(modulo);
    output.push(letter);

    if *copied.get(count) == 0 {
      count += 1;
    }
  }

  output.reverse();

  match String::from_utf8(output) {
    Ok(result) => result,
    Err(e) => fail!(e)
  }
}

/// Give the letter from the base58 alphabet
fn from_alphabet(position: u16) -> u8 {
  "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".char_at(position as uint) as u8
}

/// This function make the division by 256 of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_by_58(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base256: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_256 + num_base256;
    *x = (temp / BASE_58) as u8;
    remainder = temp % BASE_58;
  }

  remainder
}

/// This function make the division by 58 of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_by_256(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base58: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_58 + num_base58;
    *x = (temp / BASE_256) as u8;
    remainder = temp % BASE_256;
  }

  remainder
}

#[cfg(test)]
mod tests {

  use super::divide_by_256;
  use super::divide_by_58;

	/* Divisions by 256 */

  #[test]
  fn should_divide_zero_by_58_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_by_58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_by_58_with_modulo_7() {
    // Given
    let mut input = vec!(100u8, 43);

    // When
    let modulo = divide_by_58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 1);
    assert_eq!(*input.get(1), 186);
    assert_eq!(modulo, 7);
  }

	/* Divisions by 58 */

  #[test]
  fn should_divide_zero_by_256_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_by_256(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_by_256_with_modulo_228() {
    // Given
    let mut input = vec!(13u8, 12, 88);

    // When
    let modulo = divide_by_256(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 2);
    assert_eq!(*input.get(2), 57);
    assert_eq!(modulo, 228);
  }

}
<|endoftext|>


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

//! Capture the screen with xlib

#![allow(dead_code, non_upper_case_globals, non_camel_case_types)]
#![feature(step_by)]

extern crate x11;
extern crate libc;

use libc::c_ulong;

pub mod ffi;

#[derive(Debug, Eq, PartialEq)]
struct RGB8 {
	r: u8,
	g: u8,
	b: u8,
}

/// From a bitmask for a color in a pixel, calculate the color size in bits and the bitshift
fn mask_size_and_shift(mut mask: c_ulong) -> (c_ulong, u16) {
	let (mut bits, mut shift) = (0, 0);
	let mut prev = 0;
	for _ in 0..(c_ulong::max_value() as f64).log2() as u16 {
		if mask & 1 == 1 {
			bits += 1;
			prev = 1;
		} else if prev == 1 {
			break;
		} else {
			shift += 1;
		}
		mask >>= 1;
	}
	(bits, shift)
}

#[test]
fn test_capture() {
	use x11::xlib;
	use std::ptr;
	use ffi::*;

	unsafe {

	// use the information from the environment variable DISPLAY to create the X connection:
	let display = xlib::XOpenDisplay(ptr::null_mut());
	if display.is_null() {
		panic!("Unable to connect X server");
	}

	let screen_num = xlib::XDefaultScreen(display);
	println!("Screen: {}", screen_num);

	let mut root_window = 0;
	let (mut root_x, mut root_y) = (0, 0);
	let (mut root_width, mut root_height, mut root_border_width) = (0, 0, 0);
	let mut root_pixel_depth = 0;
	if xlib::XGetGeometry(display, xlib::XRootWindow(display, screen_num),
		&mut root_window,
		&mut root_x, &mut root_y,
		&mut root_width, &mut root_height, &mut root_border_width,
		&mut root_pixel_depth) == 0
	{
		panic!("XGetGeometry failed");
	}
	println!("root window: {}; x, y: {:?}; w, h, bw: {:?}; d: {:?}",
		root_window, (root_x, root_y), (root_width, root_height, root_border_width),
		root_pixel_depth);

	println!("AllPlanes: {}, ZPixmap: {}\n", AllPlanes, ZPixmap);

	let image_ptr = xlib::XGetImage(display, root_window,
		0, 0,
		root_width, root_height,
		AllPlanes, ZPixmap);
	if image_ptr.is_null() {
		panic!("XGetImage failed");
	}
	let image = &mut *image_ptr;

	println!("width {}, height {}, depth {}, bytes_per_line {}, bits_per_pixel {}",
		image.width, image.height, image.depth, image.bytes_per_line, image.bits_per_pixel);

	let mut pixel_buf = Vec::with_capacity((image.height as usize * image.width as usize) / 9);
	for y in (0..image.height).step_by(3) {
		for x in (0..image.width).step_by(3) {
			let mut color = xlib::XColor{ pixel: xlib::XGetPixel(image_ptr, x, y),
				red: 0, green: 0, blue: 0,
				flags: 0, pad: 0,
			};
			xlib::XQueryColor(display, xlib::XDefaultColormap(display, screen_num), &mut color);
			pixel_buf.push(RGB8{
				r: (color.red / 256) as u8,
				g: (color.green / 256) as u8,
				b: (color.blue / 256) as u8
			});
		}
	}

	let n_pixels = (image.height as u64 * image.width as u64) / 9;
	let (r_tot, g_tot, b_tot) = pixel_buf.iter()
		.fold((0, 0, 0), |(r, g, b), p| (r + p.r as u64, g + p.g as u64, b + p.b as u64));
	println!("Avg color: {:?}", (r_tot/n_pixels, g_tot/n_pixels, b_tot/n_pixels));

	xlib::XFree(image_ptr as *mut _);
	xlib::XCloseDisplay(display);

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

//! Capture the screen with xlib

#![feature(unique)]
#![allow(dead_code, non_upper_case_globals, non_camel_case_types)]

extern crate x11;
extern crate libc;

use ffi::*;
use x11::xlib::{ self, Display, Window };
use libc::{ c_ulong, c_int };
use std::ptr::{ self, Unique };
use std::slice;

pub mod ffi;

#[derive(Debug, Eq, PartialEq, Clone, Copy)]
#[repr(C, packed)]
pub struct RGB8 {
	r: u8,
	g: u8,
	b: u8,
}

/// From a bitmask for a color in a pixel, calculate the color size in bits and the bitshift
fn mask_size_and_shift(mut mask: c_ulong) -> (c_ulong, u16) {
	let (mut bits, mut shift) = (0, 0);
	let mut prev = 0;
	for _ in 0..(c_ulong::max_value() as f64).log2() as u16 {
		if mask & 1 == 1 {
			bits += 1;
			prev = 1;
		} else if prev == 1 {
			break;
		} else {
			shift += 1;
		}
		mask >>= 1;
	}
	(bits, shift)
}

struct Desktop {
	display: Unique<Display>,
	window: Window,
	width: u32, height: u32,
}
impl Desktop {
	fn new(display: Unique<Display>, screen: c_int) -> Desktop {
		let mut root_window = 0;
		let (mut root_x, mut root_y) = (0, 0);
		let (mut root_width, mut root_height, mut root_border_width) = (0, 0, 0);
		let mut root_pixel_depth = 0;
		if unsafe { xlib::XGetGeometry(*display, xlib::XRootWindow(*display, screen),
			&mut root_window,
			&mut root_x, &mut root_y,
			&mut root_width, &mut root_height, &mut root_border_width,
			&mut root_pixel_depth) == 0 }
		{
			panic!("XGetGeometry failed");
		}

		Desktop{
			display: display,
			window: root_window,
			width: root_width, height: root_height,
		}
	}
}
impl Drop for Desktop {
	fn drop(&mut self) {
		unsafe {
			xlib::XCloseDisplay(*self.display);
		}
	}
}

pub struct Capturer {
	desktop: Desktop,
}
impl Capturer {
	pub fn new() -> Capturer {
		// use the information from the environment variable DISPLAY to create the X connection:
		let display = unsafe { Unique::new(xlib::XOpenDisplay(ptr::null_mut())) };
		if display.is_null() {
			panic!("Unable to connect X server");
		}

		let screen = unsafe { xlib::XDefaultScreen(*display) };
		Capturer{ desktop: Desktop::new(display, screen) }
	}

	pub fn capture_frame(&mut self) -> (Vec<RGB8>, (u32, u32)) {
		let image_ptr = unsafe { xlib::XGetImage(*self.desktop.display, self.desktop.window,
			0, 0,
			self.desktop.width, self.desktop.height,
			AllPlanes, ZPixmap) };
		if image_ptr.is_null() {
			panic!("XGetImage failed");
		}
		let image = unsafe { &mut *image_ptr };

		println!("w, h: {:?}; pad: {}; bpl: {}", (image.width, image.height), image.bitmap_pad, image.bytes_per_line);

		unsafe { if image.depth == 24 && image.bits_per_pixel == 32 &&
			image.red_mask == 0xFF0000 && image.green_mask == 0xFF00 && image.blue_mask == 0xFF
		{
			// It's plain (RGB8 + padding)s in memory
			let raw_img_data = slice::from_raw_parts(image.data as *mut (RGB8, u8),
				image.width as usize * image.height as usize
			).iter()
				.map(|&(pixel, _)| pixel)
				.collect();

			xlib::XFree(image_ptr as *mut _);

			(raw_img_data, (image.width as u32, image.height as u32))
		} else {
			xlib::XFree(image_ptr as *mut _);
			panic!("WRONG LAYOUT")
		} }
	}
}

#[test]
fn test() {
	let mut capturer = Capturer::new();
	println!("Any non-black: {}", capturer.capture_frame().0.iter()
		.any(|p| p.r != 0 || p.g != 0 || p.b != 0));
}<|endoftext|>


<commit_before>#![feature(io)]
#![feature(collections)]
#![doc(html_root_url = "http://cpjreynolds.github.io/rustty/rustty/index.html")]

//! Terminal UI library.

extern crate nix;

mod core;
mod util;

pub use core::terminal::Terminal;
pub use core::cellbuffer::{
    Cell,
    Style,
    Color,
    Attr,
};
pub use core::input::Event;
pub use util::error::Error;

<commit_msg>add lib.rs docs<commit_after>#![feature(io)]
#![feature(collections)]
#![doc(html_root_url = "http://cpjreynolds.github.io/rustty/rustty/index.html")]

//! # Rustty
//!
//! Rustty is a terminal UI library that provides a simple and concise abstraction over an
//! underlying terminal device.
//!
//! Rustty is based on the concepts of cells and events. The terminal display is an array of cells,
//! each holding a character and a set of foreground and background styles. Events are how a
//! terminal communicates changes in its state; each event represents some form of action taken by
//! the user, such as a keypress. Each terminal has an event stream that receives input events and
//! buffers them until they are read.
//!
//! More on the concepts of Rustty can be found in the
//! [README](https://github.com/cpjreynolds/rustty/blob/master/README.md)

extern crate nix;

mod core;
mod util;

pub use core::terminal::Terminal;
pub use core::cellbuffer::{
    Cell,
    Style,
    Color,
    Attr,
};
pub use core::input::Event;
pub use util::error::Error;

<|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:
//!
//! ```
//! #![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;
<commit_msg>silence an unused_feature warning<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, rand)]
#![cfg_attr(test, feature(test))]
#![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>#[allow(dead_code)]
mod about_variables {
    pub fn guess_this () -> i32 {
        let one = 5;
        let two = 7;
        let three = 3;
        let result = (one + two) / three;
        result
    }
}

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

    #[test]
    fn test_complicated () {
        assert_eq!(___, guess_this());
    }
}
<commit_msg>make return explicit<commit_after>#[allow(dead_code)]
mod about_variables {
    pub fn guess_this () -> i32 {
        let one = 5;
        let two = 7;
        let three = 3;
        let result = (one + two) / three;
        return result;
    }
}

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

    #[test]
    fn test_complicated () {
        assert_eq!(___, guess_this());
    }
}
<|endoftext|>


<commit_before>#![feature(step_by)]

extern crate bit_vec ;

use bit_vec::BitVec;

const SIGNBIT : i32 = 1<<31;

pub fn modneg( x : i64, y : usize) -> usize {
	(( x % y as i64) + y as i64) as usize % y
	}

 pub fn signum(n : isize) -> i8 {
 	if n < 0 { -1 }
 	else if n > 0 { 1 }
 	else { 0 }
 	}

 pub fn nabs(n : isize) -> isize {
 	if n < 0 { -n } else { n }
 	//(n & !(1<<31)) as u32
 }

 pub fn maxm(m : isize , n :isize) -> isize {
 	if m>= n {m} else {n}
 }

pub fn int_sqrt(n :usize) -> usize {
	((n as f64).sqrt()).floor() as usize
}

#[inline]
pub fn cnt_query(mut pos : usize, counter : &[i32]) -> u32 {
	let mut acc = counter[pos] & !SIGNBIT  ;
	pos += 1 ;
	pos &= pos - 1 ;
	while pos  != 0 {
		acc+=counter[pos - 1] & !SIGNBIT;
		pos &= pos - 1;
	}
acc as u32
}

#[inline]
pub fn cnt_update(mut pos : usize, counter : &mut[i32], interval_length : usize ) {
    counter[pos] |= SIGNBIT;
    loop {
      counter[pos] -= 1;
      pos |= pos + 1;
      if pos >=interval_length {break;}
    }
    }

#[inline]
pub fn cnt_init(counter : &mut [i32] , interval_length : usize) {
	for i in 0..interval_length as i32 {
		counter[i as usize] = (i+1) & !i ;
	}
}

#[inline]
pub fn interval_clear(index : usize , offsets : &mut[usize],  counter : &mut[i32], interval_length : usize, prime : usize) {
   let mut j  = offsets[index] ;
   while j < interval_length {
   	if counter[j] > 0 { cnt_update( j, counter, interval_length ) ; }
   	j += prime ;
   	}
   offsets[index] = modneg( offsets[index] as i64 - interval_length as i64 , prime );
   }

 pub fn initialize_arrays(ll : usize, mu : &mut[isize], pi : &mut [usize],  primes : &mut [usize]) -> usize {
 	for j in  2..mu.len() {
 		if mu[j] == 1 {
 			let mut i = j ; while i <= ll + 1 {
// 			for i in (j..ll+2).step_by(2 * j - 1) {
 			 mu[i] = match mu[i] {
 				1 => 1 - 2 * j as isize,
 				_ => -mu[i] ,
 			} ;
 		i += 2 * j - 1 ;	}
 		}
 	}
 	for j in 2..int_sqrt(ll<<1) {
 		if mu[j] == 1- 2*j as isize {
 			let mut i = 2 * j * j - 2 * j + 1 ; while i <= ll + 1 {
// 			for i in ((2*j*j -2*j +1)..ll+2).step_by( 4*j*j -4*j +1 ) {
 			mu[i] = 0 ;
 			i += 4 * j * j - 4 * j + 1 ;
 			}
 		}
 	}
 	pi[1] = 0 ; pi[2] = 2 ;
primes[0] = 1 ; primes[1] = 2 ;
let mut pix = 1 ;
for (i , elem) in mu.iter().enumerate().skip(2) {
if *elem == 1 - 2 * i as isize {
 	pix += 1;
 	primes[pix] = 2 * i as usize -1 ;
}
pi[i as usize]=pix;
 }
 pix
 }

 pub fn ordinary_leaves(n : usize, count : &mut i64, mu : &[isize], m : u64) {
 	let mut i = 1 ; while i <= n {
//  for i in (1..(n + 1)).step_by(2) {
  	let term1 = signum(mu[(i+1) >> 1]) as i64;
  	if term1 !=0 {
  	*count +=  term1 * (m as i64/ i as i64) ;
  	}
 i += 2 ; }
  let mut i = 2 ; while i <= n {
//for i in (2..(n + 1)).step_by(4) {
	let term2 = signum(mu[((i >> 1)  + 1) >> 1]) as i64 ;
	if term2 !=0 {
		*count -= term2 * (m as i64 / i as i64) ;
		}
	i += 4 ;}
}

 pub fn rphi(term: i64,  mut a : usize, bit : i8 , primes: &[usize],  total : &mut i64 )  {
	loop {
		if a == 1 {
			*total +=  bit as i64 * term ;
			break;
			}
		else if term < primes[a] as i64 {
			*total += bit as i64 ;
			break;
				}
		else {
			a -= 1;
			rphi(term / (primes[a] as i64), a, -bit, primes, total) ;
					}
				}
		}

pub fn special_leaves_type_1_substitute(b : usize, primes : &[usize], n : usize, mu : &[isize], m : u64) -> i64 {
let pp = primes[b + 1]    ; let mut acc = 0 ;
let mut j = maxm((n / pp) as isize, pp as isize) as usize +1 ;
if j % 2 == 0 { j += 1;}
for i in (j..(n+1)).step_by(2) {
let muval1 = signum(mu[ ( i+1) >> 1 ] ) ;
if nabs(mu[(i + 1) >> 1]) > pp as isize && muval1 != 0 {
let term = (m / (i * pp) as u64) as i64;
let mut total : i64 = 0;
rphi(term, b + 1, 1, primes, &mut total)  ;
acc += muval1 as i64 * total ;
}
}
acc
}

pub fn special_leaves_type_1( b : usize , interval : usize ,  m1 : &mut [usize] , n : usize, pp : usize , m : u64 ,
 	 interval_boundaries : &[usize], mu : &[isize], count : &mut i64, phi : &[u64], counter : &[i32]) {
if m1[b] % 2 == 0 { m1[b] -= 1;}
let criterion = n / pp ;
while m1[b] > criterion {
   let y  = (m / (m1[b] as u64 * pp as u64 )) as usize  ; //print!("y = {} ",y) ;
   if y > interval_boundaries[interval + 1] - 2 { return ;}
   let   muvalue = mu[((m1[b]+1) >> 1) as usize];
   if nabs(muvalue) > pp as isize  {
        *count -=
        signum(muvalue) as i64 * (phi[b] as i64 + cnt_query((y + 1 - interval_boundaries[interval]), counter) as i64);
   }
   m1[b] -= 2 ;
      }
  }

pub fn special_leaves_type_2_initialize( b : usize, pb : usize, m : u64, t : &mut[usize], n : usize, pi : &[usize], a : usize, d2 : &mut[usize], count : &mut i64 )  {
let    term = (m / (pb as u64 * pb as u64)) as usize;
t[b] = match  term {
   term if term <= pb =>  b + 2,
   term if term < n =>  pi[(term + 1) >> 1] + 1,
   _ => a + 1,
       };
d2[b] = t[b] - 1 ;
*count += (a - d2[b]) as i64 ;
}

pub fn hard(b :  usize , interval : usize, y : usize, interval_boundaries : &[usize], count : &mut i64, counter : &[i32], s2bprimes : &mut usize, d2 : &mut [usize]) -> bool {
    if y + 1 >= interval_boundaries[interval+1] {return true; }
    *count+= cnt_query((y + 1 - interval_boundaries[interval]),counter) as i64;
    *s2bprimes += 1 ;
    d2[b] -= 1;
    false
    }

pub fn easy_sparse(b :  usize , interval : usize, y : usize, n : usize, tt : &mut[u8], switch : &mut [bool],interval_boundaries : &[usize],
	 count : &mut i64, counter : &[i32], s2bprimes : &mut usize, d2 : &mut [usize], pi : &[usize] ) -> bool  {
      if y >= n {
         if !switch[b] { switch[b]=true; return true; } else { tt[b] = 2 ; hard(b,interval,y,interval_boundaries,count,counter,s2bprimes,d2); }
      }
      else {
         let l = pi[((y + 1) >> 1)] - b + 1;
         *count += l as i64;
         d2[b] -= 1;
      }
    false
    }

pub fn easy_clustered(b :  usize , interval : usize, y : usize, n : usize, tt: &mut[u8], switch : &mut [bool], interval_boundaries : &[usize],
	 count : &mut i64, counter : &[i32], s2bprimes : &mut usize, d2 : &mut [usize], m : u64, pi : &[usize], p : &[usize] ) -> bool  {
     if y >= n {
        if !switch[b] { switch[b]=true; return true; } else { tt[b] = 2 ; hard(b,interval,y,interval_boundaries,count,counter,s2bprimes,d2); }
      }
     else
      {
     let   l = pi[((y + 1) >> 1)] - b + 1;
     let  term = m / (p[b + 1] as u64 * p[b + l] as u64);
     let  dprime = pi[((term + 1) >> 1) as usize];
     if p[dprime + 1] <= int_sqrt((m / p[b + 1] as u64) as usize) || dprime <= b  {
         tt[b] = 1;
         *count += l as i64;
         d2[b] -= 1 ;
        }
      else
    {
      *count +=  (l as u32 * (d2[b] - dprime) as u32) as i64 ;
      d2[b] = dprime;
      }
    }
    false
      }

    pub fn special_leaves_type_2(b: usize, interval : usize, s2bprimes : &mut usize, d2 : &mut[usize], m : u64, p : &[usize], tt : &mut[u8],
    	 n : usize, switch : &mut[bool], interval_boundaries : &[usize], count : &mut i64, counter : &[i32], pi : &[usize] )   {
    *s2bprimes= 0;
     loop {
      if d2[b] == b + 1 {return ; }
      else
      {
       let y = (m / (p[b + 1] as u64 * p[d2[b]] as u64)) as usize;
       match tt[b] {
          0 => { if easy_clustered(b, interval,y,n,tt,switch,interval_boundaries,count,counter,s2bprimes,d2,m,pi,p) { return;} continue ; } ,
          1 => { if easy_sparse(b,interval,y,n,tt,switch,interval_boundaries,count,counter,s2bprimes,d2,pi) { return ; }  continue ; } ,
          _ => { if (interval > 0 || counter[1] > 0) && hard(b,interval,y,interval_boundaries,count,counter,s2bprimes,d2) {return;} continue ; } ,
          }
      }
      }
     }

 pub fn sieve2( x : usize, y : usize,   p : &[usize],  block : &mut BitVec )
  {
block.clear();
   let mut i : usize = 1;
    while p[i] * p[i] <= y {
    let mut offset = modneg(1-x as i64,p[i]);
       while offset <= 1+(y-x)  {
    	 block.set(offset,true);
         offset += p[i];
        }
       i+=1 ;
    }
}

 pub fn p2(interval : usize, p2primes :  &mut usize, u : &mut usize, v :  &mut usize, n : usize, w : &mut usize,
   block : &mut BitVec , p : &[usize], m : u64 , interval_boundaries : &[usize], phi2 : &mut i64, counter : &[i32], a : usize  )
      {
  *p2primes = 0;
loop {
    if *u <= n { *phi2 -= (*v as i64 * (*v - 1) as i64) >> 1 ; return;}
   	if *u  < *w  {
   		*w = maxm(2,(*u -n) as isize) as usize;
   		sieve2(*w,*u+1,p,block) ;
   		    }
	let index = *u-*w+1;
    if !block[index] {
    let y  = (m / (*u as u64)) as usize;
    if y +1 >= interval_boundaries[interval + 1] { return ; }
    *phi2 += (cnt_query((y + 1 - interval_boundaries[interval]), counter) as usize + a) as i64 - 1;
    *p2primes += 1;
    *v += 1;
    }
    *u -= 2;
}
}

<commit_msg>OK for stable Rust. Error corrected<commit_after>//#![feature(step_by)]

extern crate bit_vec ;

use bit_vec::BitVec;

const SIGNBIT : i32 = 1<<31;

pub fn modneg( x : i64, y : usize) -> usize {
	(( x % y as i64) + y as i64) as usize % y
	}

 pub fn signum(n : isize) -> i8 {
 	if n < 0 { -1 }
 	else if n > 0 { 1 }
 	else { 0 }
 	}

 pub fn nabs(n : isize) -> isize {
 	if n < 0 { -n } else { n }
 	//(n & !(1<<31)) as u32
 }

 pub fn maxm(m : isize , n :isize) -> isize {
 	if m>= n {m} else {n}
 }

pub fn int_sqrt(n :usize) -> usize {
	((n as f64).sqrt()).floor() as usize
}

#[inline]
pub fn cnt_query(mut pos : usize, counter : &[i32]) -> u32 {
	let mut acc = counter[pos] & !SIGNBIT  ;
	pos += 1 ;
	pos &= pos - 1 ;
	while pos  != 0 {
		acc+=counter[pos - 1] & !SIGNBIT;
		pos &= pos - 1;
	}
acc as u32
}

#[inline]
pub fn cnt_update(mut pos : usize, counter : &mut[i32], interval_length : usize ) {
    counter[pos] |= SIGNBIT;
    loop {
      counter[pos] -= 1;
      pos |= pos + 1;
      if pos >=interval_length {break;}
    }
    }

#[inline]
pub fn cnt_init(counter : &mut [i32] , interval_length : usize) {
	for i in 0..interval_length as i32 {
		counter[i as usize] = (i+1) & !i ;
	}
}

#[inline]
pub fn interval_clear(index : usize , offsets : &mut[usize],  counter : &mut[i32], interval_length : usize, prime : usize) {
   let mut j  = offsets[index] ;
   while j < interval_length {
   	if counter[j] > 0 { cnt_update( j, counter, interval_length ) ; }
   	j += prime ;
   	}
   offsets[index] = modneg( offsets[index] as i64 - interval_length as i64 , prime );
   }

 pub fn initialize_arrays(ll : usize, mu : &mut[isize], pi : &mut [usize],  primes : &mut [usize]) -> usize {
 	for j in  2..mu.len() {
 		if mu[j] == 1 {
 			let mut i = j ; while i <= ll + 1 {
// 			for i in (j..ll+2).step_by(2 * j - 1) {
 			 mu[i] = match mu[i] {
 				1 => 1 - 2 * j as isize,
 				_ => -mu[i] ,
 			} ;
 		i += 2 * j - 1 ;	}
 		}
 	}
 	for j in 2..int_sqrt(ll<<1) {
 		if mu[j] == 1- 2*j as isize {
 			let mut i = 2 * j * j - 2 * j + 1 ; while i <= ll + 1 {
// 			for i in ((2*j*j -2*j +1)..ll+2).step_by( 4*j*j -4*j +1 ) {
 			mu[i] = 0 ;
 			i += 4 * j * j - 4 * j + 1 ;
 			}
 		}
 	}
 	pi[1] = 0 ; pi[2] = 2 ;
primes[0] = 1 ; primes[1] = 2 ;
let mut pix = 1 ;
for (i , elem) in mu.iter().enumerate().skip(2) {
if *elem == 1 - 2 * i as isize {
 	pix += 1;
 	primes[pix] = 2 * i as usize -1 ;
}
pi[i as usize]=pix;
 }
 pix
 }

 pub fn ordinary_leaves(n : usize, count : &mut i64, mu : &[isize], m : u64) {
 	let mut i = 1 ; while i <= n {
//  for i in (1..(n + 1)).step_by(2) {
  	let term1 = signum(mu[(i+1) >> 1]) as i64;
  	if term1 !=0 {
  	*count +=  term1 * (m as i64/ i as i64) ;
  	}
 i += 2 ; }
  let mut i = 2 ; while i <= n {
//for i in (2..(n + 1)).step_by(4) {
	let term2 = signum(mu[((i >> 1)  + 1) >> 1]) as i64 ;
	if term2 !=0 {
		*count -= term2 * (m as i64 / i as i64) ;
		}
	i += 4 ;}
}

 pub fn rphi(term: i64,  mut a : usize, bit : i8 , primes: &[usize],  total : &mut i64 )  {
	loop {
		if a == 1 {
			*total +=  bit as i64 * term ;
			break;
			}
		else if term < primes[a] as i64 {
			*total += bit as i64 ;
			break;
				}
		else {
			a -= 1;
			rphi(term / (primes[a] as i64), a, -bit, primes, total) ;
					}
				}
		}

pub fn special_leaves_type_1_substitute(b : usize, primes : &[usize], n : usize, mu : &[isize], m : u64) -> i64 {
let pp = primes[b + 1]    ; let mut acc = 0 ;
let mut j = maxm((n / pp) as isize, pp as isize) as usize +1 ;
if j % 2 == 0 { j += 1;}
let mut i = j ; while i <= n {
//for i in (j..(n+1)).step_by(2) {
let muval1 = signum(mu[ ( i+1) >> 1 ] ) ;
if nabs(mu[(i + 1) >> 1]) > pp as isize && muval1 != 0 {
let term = (m / (i * pp) as u64) as i64;
let mut total : i64 = 0;
rphi(term, b + 1, 1, primes, &mut total)  ;
acc += muval1 as i64 * total ;
}
i+=2 ; }
acc
}

pub fn special_leaves_type_1( b : usize , interval : usize ,  m1 : &mut [usize] , n : usize, pp : usize , m : u64 ,
 	 interval_boundaries : &[usize], mu : &[isize], count : &mut i64, phi : &[u64], counter : &[i32]) {
if m1[b] % 2 == 0 { m1[b] -= 1;}
let criterion = n / pp ;
while m1[b] > criterion {
   let y  = (m / (m1[b] as u64 * pp as u64 )) as usize  ; //print!("y = {} ",y) ;
   if y > interval_boundaries[interval + 1] - 2 { return ;}
   let   muvalue = mu[((m1[b]+1) >> 1) as usize];
   if nabs(muvalue) > pp as isize  {
        *count -=
        signum(muvalue) as i64 * (phi[b] as i64 + cnt_query((y + 1 - interval_boundaries[interval]), counter) as i64);
   }
   m1[b] -= 2 ;
      }
  }

pub fn special_leaves_type_2_initialize( b : usize, pb : usize, m : u64, t : &mut[usize], n : usize, pi : &[usize], a : usize, d2 : &mut[usize], count : &mut i64 )  {
let    term = (m / (pb as u64 * pb as u64)) as usize;
t[b] = match  term {
   term if term <= pb =>  b + 2,
   term if term < n =>  pi[(term + 1) >> 1] + 1,
   _ => a + 1,
       };
d2[b] = t[b] - 1 ;
*count += (a - d2[b]) as i64 ;
}

pub fn hard(b :  usize , interval : usize, y : usize, interval_boundaries : &[usize], count : &mut i64, counter : &[i32], s2bprimes : &mut usize, d2 : &mut [usize]) -> bool {
    if y + 1 >= interval_boundaries[interval+1] {return true; }
    *count+= cnt_query((y + 1 - interval_boundaries[interval]),counter) as i64;
    *s2bprimes += 1 ;
    d2[b] -= 1;
    false
    }

pub fn easy_sparse(b :  usize , interval : usize, y : usize, n : usize, tt : &mut[u8], switch : &mut [bool],interval_boundaries : &[usize],
	 count : &mut i64, counter : &[i32], s2bprimes : &mut usize, d2 : &mut [usize], pi : &[usize] ) -> bool  {
      if y >= n {
         if !switch[b] { switch[b]=true; return true; } else { tt[b] = 2 ; hard(b,interval,y,interval_boundaries,count,counter,s2bprimes,d2); }
      }
      else {
         let l = pi[((y + 1) >> 1)] - b + 1;
         *count += l as i64;
         d2[b] -= 1;
      }
    false
    }

pub fn easy_clustered(b :  usize , interval : usize, y : usize, n : usize, tt: &mut[u8], switch : &mut [bool], interval_boundaries : &[usize],
	 count : &mut i64, counter : &[i32], s2bprimes : &mut usize, d2 : &mut [usize], m : u64, pi : &[usize], p : &[usize] ) -> bool  {
     if y >= n {
        if !switch[b] { switch[b]=true; return true; } else { tt[b] = 2 ; hard(b,interval,y,interval_boundaries,count,counter,s2bprimes,d2); }
      }
     else
      {
     let   l = pi[((y + 1) >> 1)] - b + 1;
     let  term = m / (p[b + 1] as u64 * p[b + l] as u64);
     let  dprime = pi[((term + 1) >> 1) as usize];
     if p[dprime + 1] <= int_sqrt((m / p[b + 1] as u64) as usize) || dprime <= b  {
         tt[b] = 1;
         *count += l as i64;
         d2[b] -= 1 ;
        }
      else
    {
      *count +=  (l as u32 * (d2[b] - dprime) as u32) as i64 ;
      d2[b] = dprime;
      }
    }
    false
      }

    pub fn special_leaves_type_2(b: usize, interval : usize, s2bprimes : &mut usize, d2 : &mut[usize], m : u64, p : &[usize], tt : &mut[u8],
    	 n : usize, switch : &mut[bool], interval_boundaries : &[usize], count : &mut i64, counter : &[i32], pi : &[usize] )   {
    *s2bprimes= 0;
     loop {
      if d2[b] == b + 1 {return ; }
      else
      {
       let y = (m / (p[b + 1] as u64 * p[d2[b]] as u64)) as usize;
       match tt[b] {
          0 => { if easy_clustered(b, interval,y,n,tt,switch,interval_boundaries,count,counter,s2bprimes,d2,m,pi,p) { return;} continue ; } ,
          1 => { if easy_sparse(b,interval,y,n,tt,switch,interval_boundaries,count,counter,s2bprimes,d2,pi) { return ; }  continue ; } ,
          _ => { if (interval > 0 || counter[1] > 0) && hard(b,interval,y,interval_boundaries,count,counter,s2bprimes,d2) {return;} continue ; } ,
          }
      }
      }
     }

 pub fn sieve2( x : usize, y : usize,   p : &[usize],  block : &mut BitVec )
  {
block.clear();
   let mut i : usize = 1;
    while p[i] * p[i] <= y {
    let mut offset = modneg(1-x as i64,p[i]);
       while offset <= 1+(y-x)  {
    	 block.set(offset,true);
         offset += p[i];
        }
       i+=1 ;
    }
}

 pub fn p2(interval : usize, p2primes :  &mut usize, u : &mut usize, v :  &mut usize, n : usize, w : &mut usize,
   block : &mut BitVec , p : &[usize], m : u64 , interval_boundaries : &[usize], phi2 : &mut i64, counter : &[i32], a : usize  )
      {
  *p2primes = 0;
loop {
    if *u <= n { *phi2 -= (*v as i64 * (*v - 1) as i64) >> 1 ; return;}
   	if *u  < *w  {
   		*w = maxm(2,(*u -n) as isize) as usize;
   		sieve2(*w,*u+1,p,block) ;
   		    }
	let index = *u-*w+1;
    if !block[index] {
    let y  = (m / (*u as u64)) as usize;
    if y +1 >= interval_boundaries[interval + 1] { return ; }
    *phi2 += (cnt_query((y + 1 - interval_boundaries[interval]), counter) as usize + a) as i64 - 1;
    *p2primes += 1;
    *v += 1;
    }
    *u -= 2;
}
}

<|endoftext|>


<commit_before>#![warn(bad_style)]
// #![warn(missing_docs)]
#![warn(unused)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![warn(unused_results)]

extern crate crypto;
extern crate curl;
#[macro_use] extern crate log;
extern crate rand;
extern crate rustc_serialize;
extern crate time;
extern crate url;

use std::borrow::Cow;
use std::collections::HashMap;
use std::str;
use rand::Rng;
use rustc_serialize::base64::{self, ToBase64};
use crypto::hmac::Hmac;
use crypto::mac::{Mac, MacResult};
use crypto::sha1::Sha1;
use curl::http;
use curl::http::handle::Method;
use url::percent_encoding;

#[derive(Clone, Debug)]
pub struct Token<'a> { pub key: Cow<'a, str>, pub secret: Cow<'a, str> }

impl<'a> Token<'a> {
    pub fn new<K, S>(key: K, secret: S) -> Token<'a>
        where K : Into<Cow<'a, str>>, S: Into<Cow<'a, str>>
    {
        Token { key: key.into(), secret: secret.into() }
    }
}

pub type ParamList<'a> = HashMap<Cow<'a, str>, Cow<'a, str>>;

fn insert_param<'a, K, V>(param: &mut ParamList<'a>, key: K, value: V)
                          -> Option<Cow<'a, str>>
    where K : Into<Cow<'a, str>>, V: Into<Cow<'a, str>>
{
    param.insert(key.into(), value.into())
}

fn join_query<'a>(param: &ParamList<'a>) -> String {
    let mut pairs = param
        .iter()
        .map(|(k, v)| format!("{}={}", encode(&k), encode(&v)))
        .collect::<Vec<_>>();
    pairs.sort();
    pairs.connect("&")
}

fn encode(s: &str) -> String {
    percent_encoding::utf8_percent_encode(s, percent_encoding::FORM_URLENCODED_ENCODE_SET)
}

fn hmac_sha1(key: &[u8], data: &[u8]) -> MacResult {
    let mut hmac = Hmac::new(Sha1::new(), key);
    hmac.input(data);
    hmac.result()
}

fn signature(method: &str, uri: &str, query: &str, consumer_secret: &str, token_secret: Option<&str>) -> String {
    let base = format!("{}&{}&{}", encode(method), encode(uri), encode(query));
    let key  = format!("{}&{}", encode(consumer_secret), encode(token_secret.unwrap_or("")));
    let conf = base64::Config {
        char_set: base64::CharacterSet::Standard,
        newline: base64::Newline::LF,
        pad: true,
        line_length: None
    };
    debug!("Signature base string: {}", base);
    debug!("Authorization header: Authorization: {}", base);
    hmac_sha1(key.as_bytes(), base.as_bytes()).code().to_base64(conf)
}

fn header(param: &ParamList) -> String{
    let mut pairs = param
        .iter()
        .filter(|&(k, _)| k.starts_with("oauth_"))
        .map(|(k, v)| format!("{}=\"{}\"", k, encode(&v)))
        .collect::<Vec<_>>();
    pairs.sort();
    format!("OAuth {}", pairs.connect(", "))
}

fn body(param: &ParamList) -> String{
    let mut pairs = param
        .iter()
        .filter(|&(k, _)| !k.starts_with("oauth_"))
        .map(|(k, v)| format!("{}={}", k, encode(&v)))
        .collect::<Vec<_>>();
    pairs.sort();
    format!("{}", pairs.connect("&"))
}

fn get_header(method: Method, uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> (String, String) {
    let mut param = HashMap::new();
    let timestamp = format!("{}", time::now_utc().to_timespec().sec);
    let nonce = rand::thread_rng().gen_ascii_chars().take(32).collect::<String>();

    let _ = insert_param(&mut param, "oauth_consumer_key",     consumer.key.to_string());
    let _ = insert_param(&mut param, "oauth_nonce",            nonce);
    let _ = insert_param(&mut param, "oauth_signature_method", "HMAC-SHA1");
    let _ = insert_param(&mut param, "oauth_timestamp",        timestamp);
    let _ = insert_param(&mut param, "oauth_version",          "1.0");
    if let Some(tk) = token {
        let _ = insert_param(&mut param, "oauth_token", tk.key.as_ref());
    }

    if let Some(ps) = other_param {
        for (k, v) in ps.iter() {
            let _ = insert_param(&mut param, k.as_ref(), v.as_ref());
        }
    }

    let method_str = match method {
        Method::Options => "OPTIONS",
        Method::Get => "GET",
        Method::Head => "HEAD",
        Method::Post => "POST",
        Method::Put => "PUT",
        Method::Patch => "PATCH",
        Method::Delete => "DELETE",
        Method::Trace => "TRACE",
        Method::Connect => "CONNECT"
    };

    let sign = signature(method_str, uri,
                         join_query(&param).as_ref(),
                         consumer.secret.as_ref(),
                         token.map(|t| t.secret.as_ref()));
    let _ = insert_param(&mut param, "oauth_signature", sign);

    (header(&param), body(&param))
}

pub fn authorization_header(method: Method, uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> String {
    get_header(method, uri, consumer, token, other_param).0
}

pub fn get(uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> String {
    let (header, body) = get_header(Method::Get, uri, consumer, token, other_param);
    let resp = http::handle()
        .get(if body.len() > 0 { format!("{}?{}", uri, body) } else { format!("{}", uri) })
        .header("Authorization", header.as_ref())
        .exec().unwrap();
    debug!("{}", resp);
    assert_eq!(200, resp.get_code());
    str::from_utf8(resp.get_body()).unwrap().to_string()
}

pub fn post(uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> String {
    let (header, body) = get_header(Method::Post, uri, consumer, token, other_param);
    let resp = http::handle()
        .post(uri, &body)
        .header("Authorization", header.as_ref())
        .content_type("application/x-www-form-urlencoded")
        .exec().unwrap();
    debug!("{}", resp);
    assert_eq!(200, resp.get_code());
    str::from_utf8(resp.get_body()).unwrap().to_string()
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    #[test]
    fn query() {
        let mut map = HashMap::new();
        let _ = map.insert("aaa".into(), "AAA".into());
        let _ = map.insert("bbbb".into(), "BBBB".into());
        let query = super::join_query(&map);
        assert_eq!("aaa=AAA&bbbb=BBBB", query);
    }
}
<commit_msg>Remove deperecated methods usage<commit_after>#![warn(bad_style)]
// #![warn(missing_docs)]
#![warn(unused)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![warn(unused_results)]

extern crate crypto;
extern crate curl;
#[macro_use] extern crate log;
extern crate rand;
extern crate rustc_serialize;
extern crate time;
extern crate url;

use std::borrow::Cow;
use std::collections::HashMap;
use std::str;
use rand::Rng;
use rustc_serialize::base64::{self, ToBase64};
use crypto::hmac::Hmac;
use crypto::mac::{Mac, MacResult};
use crypto::sha1::Sha1;
use curl::http;
use curl::http::handle::Method;
use url::percent_encoding;

#[derive(Clone, Debug)]
pub struct Token<'a> { pub key: Cow<'a, str>, pub secret: Cow<'a, str> }

impl<'a> Token<'a> {
    pub fn new<K, S>(key: K, secret: S) -> Token<'a>
        where K : Into<Cow<'a, str>>, S: Into<Cow<'a, str>>
    {
        Token { key: key.into(), secret: secret.into() }
    }
}

pub type ParamList<'a> = HashMap<Cow<'a, str>, Cow<'a, str>>;

fn insert_param<'a, K, V>(param: &mut ParamList<'a>, key: K, value: V)
                          -> Option<Cow<'a, str>>
    where K : Into<Cow<'a, str>>, V: Into<Cow<'a, str>>
{
    param.insert(key.into(), value.into())
}

fn join_query<'a>(param: &ParamList<'a>) -> String {
    let mut pairs = param
        .iter()
        .map(|(k, v)| format!("{}={}", encode(&k), encode(&v)))
        .collect::<Vec<_>>();
    pairs.sort();
    pairs.join("&")
}

fn encode(s: &str) -> String {
    percent_encoding::utf8_percent_encode(s, percent_encoding::FORM_URLENCODED_ENCODE_SET)
}

fn hmac_sha1(key: &[u8], data: &[u8]) -> MacResult {
    let mut hmac = Hmac::new(Sha1::new(), key);
    hmac.input(data);
    hmac.result()
}

fn signature(method: &str, uri: &str, query: &str, consumer_secret: &str, token_secret: Option<&str>) -> String {
    let base = format!("{}&{}&{}", encode(method), encode(uri), encode(query));
    let key  = format!("{}&{}", encode(consumer_secret), encode(token_secret.unwrap_or("")));
    let conf = base64::Config {
        char_set: base64::CharacterSet::Standard,
        newline: base64::Newline::LF,
        pad: true,
        line_length: None
    };
    debug!("Signature base string: {}", base);
    debug!("Authorization header: Authorization: {}", base);
    hmac_sha1(key.as_bytes(), base.as_bytes()).code().to_base64(conf)
}

fn header(param: &ParamList) -> String{
    let mut pairs = param
        .iter()
        .filter(|&(k, _)| k.starts_with("oauth_"))
        .map(|(k, v)| format!("{}=\"{}\"", k, encode(&v)))
        .collect::<Vec<_>>();
    pairs.sort();
    format!("OAuth {}", pairs.join(", "))
}

fn body(param: &ParamList) -> String{
    let mut pairs = param
        .iter()
        .filter(|&(k, _)| !k.starts_with("oauth_"))
        .map(|(k, v)| format!("{}={}", k, encode(&v)))
        .collect::<Vec<_>>();
    pairs.sort();
    format!("{}", pairs.join("&"))
}

fn get_header(method: Method, uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> (String, String) {
    let mut param = HashMap::new();
    let timestamp = format!("{}", time::now_utc().to_timespec().sec);
    let nonce = rand::thread_rng().gen_ascii_chars().take(32).collect::<String>();

    let _ = insert_param(&mut param, "oauth_consumer_key",     consumer.key.to_string());
    let _ = insert_param(&mut param, "oauth_nonce",            nonce);
    let _ = insert_param(&mut param, "oauth_signature_method", "HMAC-SHA1");
    let _ = insert_param(&mut param, "oauth_timestamp",        timestamp);
    let _ = insert_param(&mut param, "oauth_version",          "1.0");
    if let Some(tk) = token {
        let _ = insert_param(&mut param, "oauth_token", tk.key.as_ref());
    }

    if let Some(ps) = other_param {
        for (k, v) in ps.iter() {
            let _ = insert_param(&mut param, k.as_ref(), v.as_ref());
        }
    }

    let method_str = match method {
        Method::Options => "OPTIONS",
        Method::Get => "GET",
        Method::Head => "HEAD",
        Method::Post => "POST",
        Method::Put => "PUT",
        Method::Patch => "PATCH",
        Method::Delete => "DELETE",
        Method::Trace => "TRACE",
        Method::Connect => "CONNECT"
    };

    let sign = signature(method_str, uri,
                         join_query(&param).as_ref(),
                         consumer.secret.as_ref(),
                         token.map(|t| t.secret.as_ref()));
    let _ = insert_param(&mut param, "oauth_signature", sign);

    (header(&param), body(&param))
}

pub fn authorization_header(method: Method, uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> String {
    get_header(method, uri, consumer, token, other_param).0
}

pub fn get(uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> String {
    let (header, body) = get_header(Method::Get, uri, consumer, token, other_param);
    let resp = http::handle()
        .get(if body.len() > 0 { format!("{}?{}", uri, body) } else { format!("{}", uri) })
        .header("Authorization", header.as_ref())
        .exec().unwrap();
    debug!("{}", resp);
    assert_eq!(200, resp.get_code());
    str::from_utf8(resp.get_body()).unwrap().to_string()
}

pub fn post(uri: &str, consumer: &Token, token: Option<&Token>, other_param: Option<&ParamList>) -> String {
    let (header, body) = get_header(Method::Post, uri, consumer, token, other_param);
    let resp = http::handle()
        .post(uri, &body)
        .header("Authorization", header.as_ref())
        .content_type("application/x-www-form-urlencoded")
        .exec().unwrap();
    debug!("{}", resp);
    assert_eq!(200, resp.get_code());
    str::from_utf8(resp.get_body()).unwrap().to_string()
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    #[test]
    fn query() {
        let mut map = HashMap::new();
        let _ = map.insert("aaa".into(), "AAA".into());
        let _ = map.insert("bbbb".into(), "BBBB".into());
        let query = super::join_query(&map);
        assert_eq!("aaa=AAA&bbbb=BBBB", query);
    }
}
<|endoftext|>


<commit_before>use std::fmt;

pub trait FromAscii: Sized {
    type Err;

    fn from_ascii(s: &[u8]) -> Result<Self, Self::Err>;
}

/// An error returned when parsing a `bool` from a ascii string fails.
#[derive(Debug, Clone, PartialEq)]
pub enum ParseBoolError {
    ParseBoolError
}

impl fmt::Display for ParseBoolError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "provided string was not `true` or `false`".fmt(f)
    }
}

impl FromAscii for bool {
    type Err = ParseBoolError;

    #[inline]
    fn from_ascii(s: &[u8]) -> Result<bool, ParseBoolError> {
        match s {
            b"true"  => Ok(true),
            b"false" => Ok(false),
            _       => Err(ParseBoolError::ParseBoolError),
        }
    }
}
<commit_msg>Add a test for boolean type parsing<commit_after>use std::fmt;

pub trait FromAscii: Sized {
    type Err;

    fn from_ascii(s: &[u8]) -> Result<Self, Self::Err>;
}

/// An error returned when parsing a `bool` from a ascii string fails.
#[derive(Debug, Clone, PartialEq)]
pub enum ParseBoolError {
    ParseBoolError
}

impl fmt::Display for ParseBoolError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "provided string was not `true` or `false`".fmt(f)
    }
}

impl FromAscii for bool {
    type Err = ParseBoolError;

    #[inline]
    fn from_ascii(s: &[u8]) -> Result<bool, ParseBoolError> {
        match s {
            b"true"  => Ok(true),
            b"false" => Ok(false),
            _       => Err(ParseBoolError::ParseBoolError),
        }
    }
}

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

    #[test]
    fn test_parse_bool() {
        assert_eq!(bool::from_ascii(b"true"), Ok(true));
        assert_eq!(bool::from_ascii(b"false"), Ok(false));
        assert_eq!(bool::from_ascii(b""), Err(ParseBoolError::ParseBoolError));
        assert_eq!(bool::from_ascii(b"true "), Err(ParseBoolError::ParseBoolError));
        assert_eq!(bool::from_ascii(b"false "), Err(ParseBoolError::ParseBoolError));
    }
}
<|endoftext|>


<commit_before>#[test]
fn it_works() {
}
<commit_msg>Base functionality ok<commit_after>use std::iter::Zip;

/*
 * zip2
 */
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Zip2<A, B> {
    subzip: Zip<A, B>
}
impl<A, B> Iterator for Zip2<A, B> where
A: Iterator,
B: Iterator
{
    type Item = (A::Item, B::Item);

    #[inline]
    fn next(&mut self) -> Option<(A::Item, B::Item)> {
        self.subzip.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.subzip.size_hint()
    }
}
fn zip2<U, V>(u: U, v: V) -> Zip2<U::IntoIter, V::IntoIter> where
    U: IntoIterator,
    V: IntoIterator,
{
    Zip2 {
        subzip: u.into_iter().zip(v.into_iter())
    }
}

/*
 * zip3
 */
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Zip3<A, B, C> {
    subzip: Zip<Zip2<A, B>, C>
}
impl<A, B, C> Iterator for Zip3<A, B, C> where A: Iterator, B: Iterator, C: Iterator
{
    type Item = (A::Item, B::Item, C::Item);

    #[inline]
    fn next(&mut self) -> Option<(A::Item, B::Item, C::Item)> {
        self.subzip.next().map(|((a, b), c)| (a, b, c))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.subzip.size_hint()
    }
}

fn zip3<U, V, W>(u: U, v: V, w: W) -> Zip3<U::IntoIter, V::IntoIter, W::IntoIter> where
    U: IntoIterator,
    V: IntoIterator,
    W: IntoIterator,
{
    Zip3 {
        subzip: zip2(u, v).zip(w.into_iter())
    }
}

/*
 * zip4
 */
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Zip4<A, B, C, D> {
    subzip: Zip<Zip3<A, B, C>, D>
}
impl<A, B, C, D> Iterator for Zip4<A, B, C, D> where
    A: Iterator,
    B: Iterator,
    C: Iterator,
    D: Iterator,
{
    type Item = (A::Item, B::Item, C::Item, D::Item);

    #[inline]
    fn next(&mut self) -> Option<(A::Item, B::Item, C::Item, D::Item)> {
        self.subzip.next().map(|((a, b, c), d)| (a, b, c, d))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.subzip.size_hint()
    }
}

fn zip4<IA, IB, IC, ID>(ia: IA, ib: IB, ic: IC, id: ID)
    -> Zip4<IA::IntoIter, IB::IntoIter, IC::IntoIter, ID::IntoIter> where
    IA: IntoIterator,
    IB: IntoIterator,
    IC: IntoIterator,
    ID: IntoIterator,
{
    Zip4 {
        subzip: zip3(ia, ib, ic).zip(id.into_iter())
    }
}

/*
 * zip4
 */
macro_rules! impl_zipn {
    ($ZipN:ident $zipn:ident $ZipNPrev:ident $zipnprev:ident ( $($A:ident $a:ident $IA:ident $ia:ident)+ ) $ALast:ident $alast:ident $IALast:ident $ialast:ident) => (
        #[derive(Clone)]
        #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
        pub struct $ZipN<$($A),*, $ALast> {
            subzip: Zip<$ZipNPrev<$($A),*>, $ALast>
        }
        impl<$($A),*, $ALast> Iterator for $ZipN<$($A),*, $ALast> where
            $($A: Iterator),*,
            $ALast: Iterator
        {
            type Item = ($($A::Item),*, $ALast::Item);

            #[inline]
            fn next(&mut self) -> Option<($($A::Item),*, $ALast::Item)> {
                self.subzip.next().map(|(( $($a),* ), $alast)| ($($a),*, $alast))
            }

            #[inline]
            fn size_hint(&self) -> (usize, Option<usize>) {
                self.subzip.size_hint()
            }
        }
        fn $zipn<$($IA),*, $IALast>($($ia: $IA),*, $ialast: $IALast)
           -> $ZipN<$($IA::IntoIter),*, $IALast::IntoIter>
        where
            $($IA: IntoIterator),*,
            $IALast: IntoIterator
        {
            $ZipN {
                subzip: $zipnprev($($ia),*).zip($ialast.into_iter())
            }
        }
        /*
        pub struct Zip4<A, B, C, D> {
            subzip: Zip<Zip3<A, B, C>, D>
        }
        impl<A, B, C, D> Iterator for Zip4<A, B, C, D> where
            A: Iterator,
            B: Iterator,
            C: Iterator,
            D: Iterator,
        {
            type Item = (A::Item, B::Item, C::Item, D::Item);

            #[inline]
            fn next(&mut self) -> Option<(A::Item, B::Item, C::Item, D::Item)> {
                self.subzip.next().map(|((a, b, c), d)| (a, b, c, d))
            }

            #[inline]
            fn size_hint(&self) -> (usize, Option<usize>) {
                self.subzip.size_hint()
            }
        }

        fn zip4<IA, IB, IC, ID>(ia: IA, ib: IB, ic: IC, id: ID)
            -> Zip4<IA::IntoIter, IB::IntoIter, IC::IntoIter, ID::IntoIter> where
            IA: IntoIterator,
            IB: IntoIterator,
            IC: IntoIterator,
            ID: IntoIterator,
        {
            Zip4 {
                subzip: zip3(ia, ib, ic).zip(id.into_iter())
            }
        }
        */
    );
}

impl_zipn!(Zip5 zip5 Zip4 zip4
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id)
           E e IE ie);
impl_zipn!(Zip6 zip6 Zip5 zip5
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie)
           F f IF iff);
impl_zipn!(Zip7 zip7 Zip6 zip6
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie
            F f IF iff)
           G g IG ig);
impl_zipn!(Zip8 zip8 Zip7 zip7
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie
            F f IF iff
            G g IG ig)
           H h IH ih);
impl_zipn!(Zip9 zip9 Zip8 zip8
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie
            F f IF iff
            G g IG ig
            H h IH ih)
           I i II ii);
impl_zipn!(Zip10 zip10 Zip9 zip9
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie
            F f IF iff
            G g IG ig
            H h IH ih
            I i II ii)
           J j IJ ij);
impl_zipn!(Zip11 zip11 Zip10 zip10
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie
            F f IF iff
            G g IG ig
            H h IH ih
            I i II ii
            J j IJ ij)
           K k IK ik);
impl_zipn!(Zip12 zip12 Zip11 zip11
           (A a IA ia
            B b IB ib
            C c IC ic
            D d ID id
            E e IE ie
            F f IF iff
            G g IG ig
            H h IH ih
            I i II ii
            J j IJ ij
            K k IK ik)
           L l IL il);

#[cfg(test)]
mod tests {
    #![allow(non_upper_case_globals)]
    use super::{zip2, zip3, zip4, zip5, zip6, zip7, zip8, zip9, zip10, zip11,
                zip12};
    const a: [i8; 3] = [0, 1, 2];
    const b: [i8; 3] = [3, 4, 5];
    const c: [i8; 3] = [6, 7, 8];
    const d: [i8; 3] = [9, 10, 11];
    const e: [i8; 3] = [12, 13, 14];
    const f: [i8; 3] = [15, 16, 17];
    const g: [i8; 3] = [18, 19, 20];
    const h: [i8; 3] = [21, 22, 23];
    const i: [i8; 3] = [24, 25, 26];
    const j: [i8; 3] = [27, 28, 29];
    const k: [i8; 3] = [30, 31, 32];
    const l: [i8; 3] = [33, 34, 35];

    #[test]
    fn test_zip2() {
        let ab = zip2(a.iter(),
                      b.iter())
                 .map(|(&aa, &bb)| (aa, bb))
                 .collect::<Vec<_>>();
        assert_eq!(ab, vec![(0, 3),
                            (1, 4),
                            (2, 5)]);
    }

    #[test]
    fn test_zip3() {
        let abc = zip3(a.iter(),
                       b.iter(),
                       c.iter())
                 .map(|(&aa, &bb, &cc)| (aa, bb, cc))
                 .collect::<Vec<_>>();
        assert_eq!(abc, vec![(0, 3, 6),
                             (1, 4, 7),
                             (2, 5, 8)]);
    }

    #[test]
    fn test_zip4() {
        let abcd = zip4(a.iter(),
                        b.iter(),
                        c.iter(),
                        d.iter())
                 .map(|(&aa, &bb, &cc, &dd)| (aa, bb, cc, dd))
                 .collect::<Vec<_>>();
        assert_eq!(abcd, vec![(0, 3, 6, 9),
                              (1, 4, 7, 10),
                              (2, 5, 8, 11)]);
    }

    #[test]
    fn test_zip5() {
        let abcde = zip5(a.iter(),
                        b.iter(),
                        c.iter(),
                        d.iter(),
                        e.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee)| (aa, bb, cc, dd, ee))
                 .collect::<Vec<_>>();
        assert_eq!(abcde, vec![(0, 3, 6, 9,  12),
                               (1, 4, 7, 10, 13),
                               (2, 5, 8, 11, 14)]);
    }

    #[test]
    fn test_zip6() {
        let abcdef = zip6(a.iter(),
                          b.iter(),
                          c.iter(),
                          d.iter(),
                          e.iter(),
                          f.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff)| (aa, bb, cc, dd, ee, ff))
                 .collect::<Vec<_>>();
        assert_eq!(abcdef, vec![(0, 3, 6, 9,  12, 15),
                                (1, 4, 7, 10, 13, 16),
                                (2, 5, 8, 11, 14, 17)]);
    }

    #[test]
    fn test_zip7() {
        let abcdefg = zip7(a.iter(),
                           b.iter(),
                           c.iter(),
                           d.iter(),
                           e.iter(),
                           f.iter(),
                           g.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff, &gg)|
                       ( aa,  bb,  cc,  dd,  ee,  ff,  gg))
                 .collect::<Vec<_>>();
        assert_eq!(abcdefg, vec![(0, 3, 6, 9,  12, 15, 18),
                                 (1, 4, 7, 10, 13, 16, 19),
                                 (2, 5, 8, 11, 14, 17, 20)]);
    }

    #[test]
    fn test_zip8() {
        let abcdefgh = zip8(a.iter(),
                            b.iter(),
                            c.iter(),
                            d.iter(),
                            e.iter(),
                            f.iter(),
                            g.iter(),
                            h.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff, &gg, &hh)|
                       ( aa,  bb,  cc,  dd,  ee,  ff,  gg,  hh))
                 .collect::<Vec<_>>();
        assert_eq!(abcdefgh, vec![(0, 3, 6, 9,  12, 15, 18, 21),
                                   (1, 4, 7, 10, 13, 16, 19, 22),
                                   (2, 5, 8, 11, 14, 17, 20, 23)]);
    }

    #[test]
    fn test_zip9() {
        let abcdefghi = zip9(a.iter(),
                             b.iter(),
                             c.iter(),
                             d.iter(),
                             e.iter(),
                             f.iter(),
                             g.iter(),
                             h.iter(),
                             i.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff, &gg, &hh, &ii)|
                       ( aa,  bb,  cc,  dd,  ee,  ff,  gg,  hh,  ii))
                 .collect::<Vec<_>>();
        assert_eq!(abcdefghi, vec![(0, 3, 6, 9,  12, 15, 18, 21, 24),
                                    (1, 4, 7, 10, 13, 16, 19, 22, 25),
                                    (2, 5, 8, 11, 14, 17, 20, 23, 26)]);
    }

    #[test]
    fn test_zip10() {
        let abcdefghij = zip10(a.iter(),
                              b.iter(),
                              c.iter(),
                              d.iter(),
                              e.iter(),
                              f.iter(),
                              g.iter(),
                              h.iter(),
                              i.iter(),
                              j.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff, &gg, &hh, &ii, &jj)|
                       ( aa,  bb,  cc,  dd,  ee,  ff,  gg,  hh,  ii,  jj))
                 .collect::<Vec<_>>();
        assert_eq!(abcdefghij, vec![(0, 3, 6, 9,  12, 15, 18, 21, 24, 27),
                                     (1, 4, 7, 10, 13, 16, 19, 22, 25, 28),
                                     (2, 5, 8, 11, 14, 17, 20, 23, 26, 29)]);
    }

    #[test]
    fn test_zip11() {
        let abcdefghijk = zip11(a.iter(),
                                b.iter(),
                                c.iter(),
                                d.iter(),
                                e.iter(),
                                f.iter(),
                                g.iter(),
                                h.iter(),
                                i.iter(),
                                j.iter(),
                                k.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff, &gg, &hh, &ii, &jj, &kk)|
                       ( aa,  bb,  cc,  dd,  ee,  ff,  gg,  hh,  ii,  jj,  kk))
                 .collect::<Vec<_>>();
        assert_eq!(abcdefghijk, vec![(0, 3, 6, 9,  12, 15, 18, 21, 24, 27, 30),
                                      (1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31),
                                      (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32)]);
    }

    #[test]
    fn test_zip12() {
        let abcdefghijkl = zip12(a.iter(),
                                 b.iter(),
                                 c.iter(),
                                 d.iter(),
                                 e.iter(),
                                 f.iter(),
                                 g.iter(),
                                 h.iter(),
                                 i.iter(),
                                 j.iter(),
                                 k.iter(),
                                 l.iter())
                 .map(|(&aa, &bb, &cc, &dd, &ee, &ff, &gg, &hh, &ii, &jj, &kk, &ll)|
                       ( aa,  bb,  cc,  dd,  ee,  ff,  gg,  hh,  ii,  jj,  kk,  ll))
                 .collect::<Vec<_>>();
        assert_eq!(abcdefghijkl, vec![(0, 3, 6, 9,  12, 15, 18, 21, 24, 27, 30, 33),
                                      (1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34),
                                      (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35)]);
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![feature(core)]

//! A SDL2 window back-end for the Piston game engine.

extern crate sdl2;
extern crate window;
extern crate shader_version;
extern crate input;
extern crate gl;
#[macro_use]
extern crate quack;

// External crates.
use std::mem::transmute;
use window::{
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    CaptureCursor, DrawSize, Title, ExitOnEsc
};
use input::{ keyboard, Button, MouseButton, Input, Motion };
use shader_version::opengl::OpenGL;
use quack::{ Associative, Set };

/// A widow implemented by SDL2 back-end.
pub struct Sdl2Window {
    /// SDL window handle
    pub window: sdl2::video::Window,
    /// Allow dead code because this keeps track of the OpenGL context.
    /// Will be released on drop.
    #[allow(dead_code)]
    pub context: sdl2::video::GLContext,
    /// SDL context
    pub sdl_context: sdl2::Sdl,
    should_close: bool,
    mouse_relative: Option<(f64, f64)>,
    exit_on_esc: bool,
}

impl Sdl2Window {
    /// Creates a new game window for SDL2.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> Sdl2Window {
        let sdl_context = sdl2::init(sdl2::INIT_EVERYTHING).unwrap();
        let (major, minor) = opengl.get_major_minor();
        sdl2::video::gl_set_attribute(
            sdl2::video::GLAttr::GLContextMajorVersion,
            major as i32
        );
        sdl2::video::gl_set_attribute(
            sdl2::video::GLAttr::GLContextMinorVersion,
            minor as i32
        );
        sdl2::video::gl_set_attribute(
            sdl2::video::GLAttr::GLContextProfileMask,
            sdl2::video::GLProfile::GLCoreProfile as i32
        );
        if settings.samples != 0 {
            sdl2::video::gl_set_attribute(
                sdl2::video::GLAttr::GLMultiSampleBuffers,
                1
            );
            sdl2::video::gl_set_attribute(
                sdl2::video::GLAttr::GLMultiSampleSamples,
                settings.samples as i32
            );
        }

        let window = sdl2::video::Window::new(
            settings.title.as_slice(),
            sdl2::video::WindowPos::PosCentered,
            sdl2::video::WindowPos::PosCentered,
            settings.size[0] as i32,
            settings.size[1] as i32,
            sdl2::video::OPENGL| sdl2::video::RESIZABLE
        ).unwrap();
        if settings.fullscreen {
            window.set_fullscreen(sdl2::video::FullscreenType::FTTrue);
        }

        // Send text input events.
        sdl2::keyboard::start_text_input();

        let context = window.gl_create_context().unwrap();

        // Load the OpenGL function pointers
        gl::load_with(|s| unsafe {
            transmute(sdl2::video::gl_get_proc_address(s))
        });

        Sdl2Window {
            exit_on_esc: settings.exit_on_esc,
            should_close: false,
            window: window,
            context: context,
            sdl_context: sdl_context,
            mouse_relative: None,
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        // First check for a pending relative mouse move event.
        match self.mouse_relative {
            Some((x, y)) => {
                self.mouse_relative = None;
                return Some(Input::Move(Motion::MouseRelative(x, y)));
            }
            None => {}
        }

        // Even though we create a new EventPump each time we poll an event
        // this should not be a problem since it only contains phantom data
        // and therefore should actually not have any overhead.
        let event = match self.sdl_context.event_pump().poll_event() {
            Some( ev ) => ev,
            None => return None
        };
        match event {
            sdl2::event::Event::Quit{..} => {
                self.should_close = true;
            }
            sdl2::event::Event::TextInput { text, .. } => {
                return Some(Input::Text(text));
            }
            sdl2::event::Event::KeyDown { keycode: key, repeat, ..} => {
                // SDL2 repeats the key down event.
                // If the event is the same as last one, ignore it.
                if repeat {
                    return self.poll_event()
                }

                if self.exit_on_esc
                && key == sdl2::keycode::KeyCode::Escape {
                    self.should_close = true;
                } else {
                    return Some(Input::Press(Button::Keyboard(sdl2_map_key(key))));
                }
            }
            sdl2::event::Event::KeyUp { keycode: key, repeat, .. } => {
                if repeat {
                    return self.poll_event()
                }
                return Some(Input::Release(Button::Keyboard(sdl2_map_key(key))));
            }
            sdl2::event::Event::MouseButtonDown { mouse_btn: button, .. } => {
                return Some(Input::Press(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseButtonUp { mouse_btn: button, .. } => {
                return Some(Input::Release(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseMotion { x, y, xrel: dx, yrel: dy, .. } => {
                // Send relative move movement next time.
                self.mouse_relative = Some((dx as f64, dy as f64));
                return Some(Input::Move(Motion::MouseCursor(x as f64, y as f64)));
            },
            sdl2::event::Event::MouseWheel { x, y, .. } => {
                return Some(Input::Move(Motion::MouseScroll(x as f64, y as f64)));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::Resized, data1: w, data2: h, .. } => {
                return Some(Input::Resize(w as u32, h as u32));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusGained, .. } => {
                return Some(Input::Focus(true));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusLost, .. } => {
                return Some(Input::Focus(false));
            }
            _ => {}
        }
        None
    }
}

impl Drop for Sdl2Window {
    fn drop(&mut self) {
        self.set_mut(CaptureCursor(false));
    }
}

quack! {
    _obj: Sdl2Window[]
    get:
        fn () -> ShouldClose [] { ShouldClose(_obj.should_close) }
        fn () -> Size [] {
            let (w, h) = _obj.window.get_size();
            Size([w as u32, h as u32])
        }
        fn () -> DrawSize [] {
            let (w, h) = _obj.window.get_drawable_size();
            DrawSize([w as u32, h as u32])
        }
        fn () -> Title [] { Title(_obj.window.get_title()) }
        fn () -> ExitOnEsc [] { ExitOnEsc(_obj.exit_on_esc) }
    set:
        fn (val: CaptureCursor) [] {
            sdl2::mouse::set_relative_mouse_mode(val.0)
        }
        fn (val: ShouldClose) [] { _obj.should_close = val.0 }
        fn (val: Title) [] { _obj.window.set_title(val.0.as_slice()).unwrap() }
        fn (val: ExitOnEsc) [] { _obj.exit_on_esc = val.0 }
    action:
        fn (__: SwapBuffers) -> () [] { _obj.window.gl_swap_window() }
        fn (__: PollEvent) -> Option<Input> [] { _obj.poll_event() }
}

impl Associative for (PollEvent, Sdl2Window) {
    type Type = Input;
}

/// Maps a SDL2 key to piston-input key.
pub fn sdl2_map_key(keycode: sdl2::keycode::KeyCode) -> keyboard::Key {
    use std::num::FromPrimitive;
    FromPrimitive::from_u64(keycode as u64).unwrap()
}

/// Maps a SDL2 mouse button to piston-input button.
pub fn sdl2_map_mouse(button: sdl2::mouse::Mouse) -> MouseButton {
    match button {
        sdl2::mouse::Mouse::Left => MouseButton::Left,
        sdl2::mouse::Mouse::Right => MouseButton::Right,
        sdl2::mouse::Mouse::Middle => MouseButton::Middle,
        sdl2::mouse::Mouse::X1 => MouseButton::X1,
        sdl2::mouse::Mouse::X2 => MouseButton::X2,
        sdl2::mouse::Mouse::Unknown(_) => MouseButton::Unknown,
    }
}
<commit_msg>Explicitly use 32bit color<commit_after>#![deny(missing_docs)]
#![feature(core)]

//! A SDL2 window back-end for the Piston game engine.

extern crate sdl2;
extern crate window;
extern crate shader_version;
extern crate input;
extern crate gl;
#[macro_use]
extern crate quack;

// External crates.
use std::mem::transmute;
use window::{
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    CaptureCursor, DrawSize, Title, ExitOnEsc
};
use input::{ keyboard, Button, MouseButton, Input, Motion };
use shader_version::opengl::OpenGL;
use quack::{ Associative, Set };

/// A widow implemented by SDL2 back-end.
pub struct Sdl2Window {
    /// SDL window handle
    pub window: sdl2::video::Window,
    /// Allow dead code because this keeps track of the OpenGL context.
    /// Will be released on drop.
    #[allow(dead_code)]
    pub context: sdl2::video::GLContext,
    /// SDL context
    pub sdl_context: sdl2::Sdl,
    should_close: bool,
    mouse_relative: Option<(f64, f64)>,
    exit_on_esc: bool,
}

impl Sdl2Window {
    /// Creates a new game window for SDL2.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> Sdl2Window {
        let sdl_context = sdl2::init(sdl2::INIT_EVERYTHING).unwrap();

        // Not all drivers default to 32bit color, so explicitly set it to 32bit color
        sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLRedSize, 8);
        sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLGreenSize, 8);
        sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLBlueSize, 8);
        sdl2::video::gl_set_attribute(sdl2::video::GLAttr::GLAlphaSize, 8);

        let (major, minor) = opengl.get_major_minor();
        sdl2::video::gl_set_attribute(
            sdl2::video::GLAttr::GLContextMajorVersion,
            major as i32
        );
        sdl2::video::gl_set_attribute(
            sdl2::video::GLAttr::GLContextMinorVersion,
            minor as i32
        );
        sdl2::video::gl_set_attribute(
            sdl2::video::GLAttr::GLContextProfileMask,
            sdl2::video::GLProfile::GLCoreProfile as i32
        );
        if settings.samples != 0 {
            sdl2::video::gl_set_attribute(
                sdl2::video::GLAttr::GLMultiSampleBuffers,
                1
            );
            sdl2::video::gl_set_attribute(
                sdl2::video::GLAttr::GLMultiSampleSamples,
                settings.samples as i32
            );
        }

        let window = sdl2::video::Window::new(
            settings.title.as_slice(),
            sdl2::video::WindowPos::PosCentered,
            sdl2::video::WindowPos::PosCentered,
            settings.size[0] as i32,
            settings.size[1] as i32,
            sdl2::video::OPENGL| sdl2::video::RESIZABLE
        ).unwrap();
        if settings.fullscreen {
            window.set_fullscreen(sdl2::video::FullscreenType::FTTrue);
        }

        // Send text input events.
        sdl2::keyboard::start_text_input();

        let context = window.gl_create_context().unwrap();

        // Load the OpenGL function pointers
        gl::load_with(|s| unsafe {
            transmute(sdl2::video::gl_get_proc_address(s))
        });

        Sdl2Window {
            exit_on_esc: settings.exit_on_esc,
            should_close: false,
            window: window,
            context: context,
            sdl_context: sdl_context,
            mouse_relative: None,
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        // First check for a pending relative mouse move event.
        match self.mouse_relative {
            Some((x, y)) => {
                self.mouse_relative = None;
                return Some(Input::Move(Motion::MouseRelative(x, y)));
            }
            None => {}
        }

        // Even though we create a new EventPump each time we poll an event
        // this should not be a problem since it only contains phantom data
        // and therefore should actually not have any overhead.
        let event = match self.sdl_context.event_pump().poll_event() {
            Some( ev ) => ev,
            None => return None
        };
        match event {
            sdl2::event::Event::Quit{..} => {
                self.should_close = true;
            }
            sdl2::event::Event::TextInput { text, .. } => {
                return Some(Input::Text(text));
            }
            sdl2::event::Event::KeyDown { keycode: key, repeat, ..} => {
                // SDL2 repeats the key down event.
                // If the event is the same as last one, ignore it.
                if repeat {
                    return self.poll_event()
                }

                if self.exit_on_esc
                && key == sdl2::keycode::KeyCode::Escape {
                    self.should_close = true;
                } else {
                    return Some(Input::Press(Button::Keyboard(sdl2_map_key(key))));
                }
            }
            sdl2::event::Event::KeyUp { keycode: key, repeat, .. } => {
                if repeat {
                    return self.poll_event()
                }
                return Some(Input::Release(Button::Keyboard(sdl2_map_key(key))));
            }
            sdl2::event::Event::MouseButtonDown { mouse_btn: button, .. } => {
                return Some(Input::Press(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseButtonUp { mouse_btn: button, .. } => {
                return Some(Input::Release(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseMotion { x, y, xrel: dx, yrel: dy, .. } => {
                // Send relative move movement next time.
                self.mouse_relative = Some((dx as f64, dy as f64));
                return Some(Input::Move(Motion::MouseCursor(x as f64, y as f64)));
            },
            sdl2::event::Event::MouseWheel { x, y, .. } => {
                return Some(Input::Move(Motion::MouseScroll(x as f64, y as f64)));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::Resized, data1: w, data2: h, .. } => {
                return Some(Input::Resize(w as u32, h as u32));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusGained, .. } => {
                return Some(Input::Focus(true));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusLost, .. } => {
                return Some(Input::Focus(false));
            }
            _ => {}
        }
        None
    }
}

impl Drop for Sdl2Window {
    fn drop(&mut self) {
        self.set_mut(CaptureCursor(false));
    }
}

quack! {
    _obj: Sdl2Window[]
    get:
        fn () -> ShouldClose [] { ShouldClose(_obj.should_close) }
        fn () -> Size [] {
            let (w, h) = _obj.window.get_size();
            Size([w as u32, h as u32])
        }
        fn () -> DrawSize [] {
            let (w, h) = _obj.window.get_drawable_size();
            DrawSize([w as u32, h as u32])
        }
        fn () -> Title [] { Title(_obj.window.get_title()) }
        fn () -> ExitOnEsc [] { ExitOnEsc(_obj.exit_on_esc) }
    set:
        fn (val: CaptureCursor) [] {
            sdl2::mouse::set_relative_mouse_mode(val.0)
        }
        fn (val: ShouldClose) [] { _obj.should_close = val.0 }
        fn (val: Title) [] { _obj.window.set_title(val.0.as_slice()).unwrap() }
        fn (val: ExitOnEsc) [] { _obj.exit_on_esc = val.0 }
    action:
        fn (__: SwapBuffers) -> () [] { _obj.window.gl_swap_window() }
        fn (__: PollEvent) -> Option<Input> [] { _obj.poll_event() }
}

impl Associative for (PollEvent, Sdl2Window) {
    type Type = Input;
}

/// Maps a SDL2 key to piston-input key.
pub fn sdl2_map_key(keycode: sdl2::keycode::KeyCode) -> keyboard::Key {
    use std::num::FromPrimitive;
    FromPrimitive::from_u64(keycode as u64).unwrap()
}

/// Maps a SDL2 mouse button to piston-input button.
pub fn sdl2_map_mouse(button: sdl2::mouse::Mouse) -> MouseButton {
    match button {
        sdl2::mouse::Mouse::Left => MouseButton::Left,
        sdl2::mouse::Mouse::Right => MouseButton::Right,
        sdl2::mouse::Mouse::Middle => MouseButton::Middle,
        sdl2::mouse::Mouse::X1 => MouseButton::X1,
        sdl2::mouse::Mouse::X2 => MouseButton::X2,
        sdl2::mouse::Mouse::Unknown(_) => MouseButton::Unknown,
    }
}
<|endoftext|>