<commit_before>#![feature(track_caller)]
use std::fmt::Debug;

// Helper function to avoid promotion so that this tests "run-time" casts, not CTFE.
// Doesn't make a big difference when running this in Miri, but when running this in
// rustc (with -Zmir-opt-level=0) for comparison it means we use LLVM casts.
#[track_caller]
#[inline(never)]
fn assert_eq<T: PartialEq + Debug>(x: T, y: T) {
    assert_eq!(x, y);
}

fn main() {
    // basic arithmetic
    assert_eq(6.0_f32*6.0_f32, 36.0_f32);
    assert_eq(6.0_f64*6.0_f64, 36.0_f64);
    assert_eq(-{5.0_f32}, -5.0_f32);
    assert_eq(-{5.0_f64}, -5.0_f64);
    // infinities, NaN
    assert!((5.0_f32/0.0).is_infinite());
    assert!((5.0_f64/0.0).is_infinite());
    assert!((-5.0_f32).sqrt().is_nan());
    assert!((-5.0_f64).sqrt().is_nan());
    // byte-level transmute
    let x: u64 = unsafe { std::mem::transmute(42.0_f64) };
    let y: f64 = unsafe { std::mem::transmute(x) };
    assert_eq(y, 42.0_f64);
    let x: u32 = unsafe { std::mem::transmute(42.0_f32) };
    let y: f32 = unsafe { std::mem::transmute(x) };
    assert_eq(y, 42.0_f32);

    // f32-to-int casts
    assert_eq(5.0f32 as u32, 5);
    assert_eq(-5.0f32 as u32, 0);
    assert_eq(5.0f32 as i32, 5);
    assert_eq(-5.0f32 as i32, -5);
    assert_eq(std::f32::MAX as i32, i32::MAX);
    assert_eq(std::f32::INFINITY as i32, i32::MAX);
    assert_eq(std::f32::MAX as u32, u32::MAX);
    assert_eq(std::f32::INFINITY as u32, u32::MAX);
    assert_eq(std::f32::MIN as i32, i32::MIN);
    assert_eq(std::f32::NEG_INFINITY as i32, i32::MIN);
    assert_eq(std::f32::MIN as u32, 0);
    assert_eq(std::f32::NEG_INFINITY as u32, 0);
    assert_eq(std::f32::NAN as i32, 0);
    assert_eq(std::f32::NAN as u32, 0);
    assert_eq(u128::MAX as f32, std::f32::INFINITY);
    assert_eq((u32::MAX-127) as f32 as u32, u32::MAX); // rounding loss
    assert_eq((u32::MAX-128) as f32 as u32, u32::MAX-255); // rounding loss

    // f64-to-int casts
    assert_eq(5.0f64 as u64, 5);
    assert_eq(-5.0f64 as u64, 0);
    assert_eq(5.0f64 as i64, 5);
    assert_eq(-5.0f64 as i64, -5);
    assert_eq(std::f64::MAX as i64, i64::MAX);
    assert_eq(std::f64::INFINITY as i64, i64::MAX);
    assert_eq(std::f64::MAX as u64, u64::MAX);
    assert_eq(std::f64::INFINITY as u64, u64::MAX);
    assert_eq(std::f64::MIN as i64, i64::MIN);
    assert_eq(std::f64::NEG_INFINITY as i64, i64::MIN);
    assert_eq(std::f64::MIN as u64, 0);
    assert_eq(std::f64::NEG_INFINITY as u64, 0);
    assert_eq(std::f64::NAN as i64, 0);
    assert_eq(std::f64::NAN as u64, 0);
    assert_eq(u128::MAX as f64 as u128, u128::MAX);
    assert_eq((u64::MAX-1023) as f64 as u64, u64::MAX); // rounding loss
    assert_eq((u64::MAX-1024) as f64 as u64, u64::MAX-2047); // rounding loss

    // f32 <-> f64 casts
    assert_eq(5.0f64 as f32, 5.0f32);
    assert_eq(5.0f32 as f64, 5.0f64);
    assert_eq(std::f64::MAX as f32, std::f32::INFINITY);
    assert_eq(std::f64::MIN as f32, std::f32::NEG_INFINITY);
    assert_eq(std::f32::INFINITY as f64, std::f64::INFINITY);
    assert_eq(std::f32::NEG_INFINITY as f64, std::f64::NEG_INFINITY);

    // f32 min/max
    assert_eq((1.0 as f32).max(-1.0), 1.0);
    assert_eq((1.0 as f32).min(-1.0), -1.0);
    assert_eq(std::f32::NAN.min(9.0), 9.0);
    assert_eq(std::f32::NAN.max(-9.0), -9.0);
    assert_eq((9.0 as f32).min(std::f32::NAN), 9.0);
    assert_eq((-9.0 as f32).max(std::f32::NAN), -9.0);

    // f64 min/max
    assert_eq((1.0 as f64).max(-1.0), 1.0);
    assert_eq((1.0 as f64).min(-1.0), -1.0);
    assert_eq(std::f64::NAN.min(9.0), 9.0);
    assert_eq(std::f64::NAN.max(-9.0), -9.0);
    assert_eq((9.0 as f64).min(std::f64::NAN), 9.0);
    assert_eq((-9.0 as f64).max(std::f64::NAN), -9.0);

    // f32 copysign
    assert_eq(3.5_f32.copysign(0.42), 3.5_f32);
    assert_eq(3.5_f32.copysign(-0.42), -3.5_f32);
    assert_eq((-3.5_f32).copysign(0.42), 3.5_f32);
    assert_eq((-3.5_f32).copysign(-0.42), -3.5_f32);
    assert!(std::f32::NAN.copysign(1.0).is_nan());

    // f64 copysign
    assert_eq(3.5_f64.copysign(0.42), 3.5_f64);
    assert_eq(3.5_f64.copysign(-0.42), -3.5_f64);
    assert_eq((-3.5_f64).copysign(0.42), 3.5_f64);
    assert_eq((-3.5_f64).copysign(-0.42), -3.5_f64);
    assert!(std::f64::NAN.copysign(1.0).is_nan());
}
<commit_msg>fix float test comments and test a few more int->float casts<commit_after>#![feature(track_caller)]
use std::fmt::Debug;

// Helper function to avoid promotion so that this tests "run-time" casts, not CTFE.
// Doesn't make a big difference when running this in Miri, but it means we can compare this
// with the LLVM backend by running `rustc -Zmir-opt-level=0 -Zsaturating-float-casts`.
#[track_caller]
#[inline(never)]
fn assert_eq<T: PartialEq + Debug>(x: T, y: T) {
    assert_eq!(x, y);
}

fn main() {
    // basic arithmetic
    assert_eq(6.0_f32*6.0_f32, 36.0_f32);
    assert_eq(6.0_f64*6.0_f64, 36.0_f64);
    assert_eq(-{5.0_f32}, -5.0_f32);
    assert_eq(-{5.0_f64}, -5.0_f64);
    // infinities, NaN
    assert!((5.0_f32/0.0).is_infinite());
    assert!((5.0_f64/0.0).is_infinite());
    assert!((-5.0_f32).sqrt().is_nan());
    assert!((-5.0_f64).sqrt().is_nan());
    // byte-level transmute
    let x: u64 = unsafe { std::mem::transmute(42.0_f64) };
    let y: f64 = unsafe { std::mem::transmute(x) };
    assert_eq(y, 42.0_f64);
    let x: u32 = unsafe { std::mem::transmute(42.0_f32) };
    let y: f32 = unsafe { std::mem::transmute(x) };
    assert_eq(y, 42.0_f32);

    // f32 <-> int casts
    assert_eq(5.0f32 as u32, 5);
    assert_eq(-5.0f32 as u32, 0);
    assert_eq(5.0f32 as i32, 5);
    assert_eq(-5.0f32 as i32, -5);
    assert_eq(std::f32::MAX as i32, i32::MAX);
    assert_eq(std::f32::INFINITY as i32, i32::MAX);
    assert_eq(std::f32::MAX as u32, u32::MAX);
    assert_eq(std::f32::INFINITY as u32, u32::MAX);
    assert_eq(std::f32::MIN as i32, i32::MIN);
    assert_eq(std::f32::NEG_INFINITY as i32, i32::MIN);
    assert_eq(std::f32::MIN as u32, 0);
    assert_eq(std::f32::NEG_INFINITY as u32, 0);
    assert_eq(std::f32::NAN as i32, 0);
    assert_eq(std::f32::NAN as u32, 0);
    assert_eq((u32::MAX-127) as f32 as u32, u32::MAX); // rounding loss
    assert_eq((u32::MAX-128) as f32 as u32, u32::MAX-255); // rounding loss
    assert_eq(127i8 as f32, 127.0f32);
    assert_eq(i128::MIN as f32, -170141183460469231731687303715884105728.0f32);
    assert_eq(u128::MAX as f32, std::f32::INFINITY); // saturation

    // f64 <-> int casts
    assert_eq(5.0f64 as u64, 5);
    assert_eq(-5.0f64 as u64, 0);
    assert_eq(5.0f64 as i64, 5);
    assert_eq(-5.0f64 as i64, -5);
    assert_eq(std::f64::MAX as i64, i64::MAX);
    assert_eq(std::f64::INFINITY as i64, i64::MAX);
    assert_eq(std::f64::MAX as u64, u64::MAX);
    assert_eq(std::f64::INFINITY as u64, u64::MAX);
    assert_eq(std::f64::MIN as i64, i64::MIN);
    assert_eq(std::f64::NEG_INFINITY as i64, i64::MIN);
    assert_eq(std::f64::MIN as u64, 0);
    assert_eq(std::f64::NEG_INFINITY as u64, 0);
    assert_eq(std::f64::NAN as i64, 0);
    assert_eq(std::f64::NAN as u64, 0);
    assert_eq((u64::MAX-1023) as f64 as u64, u64::MAX); // rounding loss
    assert_eq((u64::MAX-1024) as f64 as u64, u64::MAX-2047); // rounding loss
    assert_eq(u128::MAX as f64 as u128, u128::MAX);
    assert_eq(i16::MIN as f64, -32768.0f64);
    assert_eq(u128::MAX as f64, 340282366920938463463374607431768211455.0f64); // even that fits...

    // f32 <-> f64 casts
    assert_eq(5.0f64 as f32, 5.0f32);
    assert_eq(5.0f32 as f64, 5.0f64);
    assert_eq(std::f64::MAX as f32, std::f32::INFINITY);
    assert_eq(std::f64::MIN as f32, std::f32::NEG_INFINITY);
    assert_eq(std::f32::INFINITY as f64, std::f64::INFINITY);
    assert_eq(std::f32::NEG_INFINITY as f64, std::f64::NEG_INFINITY);

    // f32 min/max
    assert_eq((1.0 as f32).max(-1.0), 1.0);
    assert_eq((1.0 as f32).min(-1.0), -1.0);
    assert_eq(std::f32::NAN.min(9.0), 9.0);
    assert_eq(std::f32::NAN.max(-9.0), -9.0);
    assert_eq((9.0 as f32).min(std::f32::NAN), 9.0);
    assert_eq((-9.0 as f32).max(std::f32::NAN), -9.0);

    // f64 min/max
    assert_eq((1.0 as f64).max(-1.0), 1.0);
    assert_eq((1.0 as f64).min(-1.0), -1.0);
    assert_eq(std::f64::NAN.min(9.0), 9.0);
    assert_eq(std::f64::NAN.max(-9.0), -9.0);
    assert_eq((9.0 as f64).min(std::f64::NAN), 9.0);
    assert_eq((-9.0 as f64).max(std::f64::NAN), -9.0);

    // f32 copysign
    assert_eq(3.5_f32.copysign(0.42), 3.5_f32);
    assert_eq(3.5_f32.copysign(-0.42), -3.5_f32);
    assert_eq((-3.5_f32).copysign(0.42), 3.5_f32);
    assert_eq((-3.5_f32).copysign(-0.42), -3.5_f32);
    assert!(std::f32::NAN.copysign(1.0).is_nan());

    // f64 copysign
    assert_eq(3.5_f64.copysign(0.42), 3.5_f64);
    assert_eq(3.5_f64.copysign(-0.42), -3.5_f64);
    assert_eq((-3.5_f64).copysign(0.42), 3.5_f64);
    assert_eq((-3.5_f64).copysign(-0.42), -3.5_f64);
    assert!(std::f64::NAN.copysign(1.0).is_nan());
}
<|endoftext|>


<commit_before>//! [GET /_matrix/identity/v2/pubkey/isvalid](https://matrix.org/docs/spec/identity_service/0.3.0#get-matrix-identity-v2-pubkey-isvalid)

use ruma_api::ruma_api;

ruma_api! {
    metadata: {
        description: "Check whether a long-term public key is valid. The response should always be the same, provided the key exists.",
        method: GET,
        name: "check_public_key_validity",
        path: "/_matrix/identity/v2/pubkey/isvalid",
        authentication: None,
        rate_limited: false,
    }

    request: {
        /// Base64-encoded (no padding) public key to check for validity.
        #[ruma_api(query)]
        pub public_key: &'a str,
    }

    response: {
        /// Whether the public key is recognised and is currently valid.
        pub valid: bool,
    }
}

impl<'a> Request<'a> {
    /// Create a `Request` with the given base64-encoded (unpadded) public key.
    pub fn new(public_key: &'a str) -> Self {
        Self { public_key }
    }
}

impl Response {
    /// Create a `Response` with the given bool indicating the validity of the public key.
    pub fn new(valid: bool) -> Self {
        Self { valid }
    }
}
<commit_msg>identity-service-api: Fix a typo<commit_after>//! [GET /_matrix/identity/v2/pubkey/isvalid](https://matrix.org/docs/spec/identity_service/r0.3.0#get-matrix-identity-v2-pubkey-isvalid)

use ruma_api::ruma_api;

ruma_api! {
    metadata: {
        description: "Check whether a long-term public key is valid. The response should always be the same, provided the key exists.",
        method: GET,
        name: "check_public_key_validity",
        path: "/_matrix/identity/v2/pubkey/isvalid",
        authentication: None,
        rate_limited: false,
    }

    request: {
        /// Base64-encoded (no padding) public key to check for validity.
        #[ruma_api(query)]
        pub public_key: &'a str,
    }

    response: {
        /// Whether the public key is recognised and is currently valid.
        pub valid: bool,
    }
}

impl<'a> Request<'a> {
    /// Create a `Request` with the given base64-encoded (unpadded) public key.
    pub fn new(public_key: &'a str) -> Self {
        Self { public_key }
    }
}

impl Response {
    /// Create a `Response` with the given bool indicating the validity of the public key.
    pub fn new(valid: bool) -> Self {
        Self { valid }
    }
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::fs::File;
use std::string::String;
use std::path::Path;
use std::vec::Vec;
use std::io::BufReader;
use json;
use game::constants::{CHARACTER_JSON_PATH, CHARACTER_BUF_LENGTH, ZOMBIE_JSON_PATH};
use tiled::Map;
use tiled;
use critter::CritterData;

pub fn load_map_file(filename: &str) -> Map {
  let file = match File::open(&Path::new(&filename)) {
    Ok(f) => f,
    Err(e) => panic!("File {} not found: {}", filename, e),
  };
  let reader = BufReader::new(file);
  match tiled::parse(reader) {
    Ok(m) => m,
    Err(e) => panic!("Map parse error {:?}", e)
  }
}

pub fn get_map_tile(map: &Map, layer_index: usize, x: usize, y: usize) -> u32 {
  let layer = match map.layers.get(layer_index) {
    None => panic!("Layer_index value out of index {:?}", map.layers),
    Some(l) => l
  };
  let y_index = match layer.tiles.iter().rev().nth(y) {
    None => panic!("X value out of index {:?}", map.layers[0]),
    Some(x) => x
  };
  match y_index.get(x) {
    None => panic!("Y value out of index {:?}", layer.tiles[y]),
    Some(val) => *val
  }
}

fn read_sprite_file(filename: &str) -> String {
  let path = Path::new(&filename);
  let mut file = match File::open(&path) {
    Ok(f) => f,
    Err(e) => panic!("File {} not found: {}", filename, e),
  };
  let mut buf = String::new();
  match file.read_to_string(&mut buf) {
    Ok(_) => buf,
    Err(e) => panic!("read file {} error {}", filename, e),
  }
}

pub fn load_character() -> Vec<CritterData> {
  let mut sprites = Vec::with_capacity(CHARACTER_BUF_LENGTH + 64);
  let character_json = read_sprite_file(CHARACTER_JSON_PATH);
  let character = match json::parse(&character_json) {
    Ok(res) => res,
    Err(e) => panic!("Character JSON parse error {:?}", e),
  };
  for x in 0..16 {
    for y in 0..14 {
      let key = &format!("run_{}_{}", x, y);
      sprites.push(CritterData::new([
        character["frames"][key]["frame"]["x"].as_f32().unwrap(),
        character["frames"][key]["frame"]["y"].as_f32().unwrap(),
        character["frames"][key]["frame"]["w"].as_f32().unwrap(),
        character["frames"][key]["frame"]["h"].as_f32().unwrap(),
      ]));
    }
  }

  for x in 0..15 {
    for y in 0..4 {
      let key = &format!("fire_{}_{}", x, y);
      sprites.push(CritterData::new([
        character["frames"][key]["frame"]["x"].as_f32().unwrap(),
        character["frames"][key]["frame"]["y"].as_f32().unwrap(),
        character["frames"][key]["frame"]["w"].as_f32().unwrap(),
        character["frames"][key]["frame"]["h"].as_f32().unwrap(),
      ]));
    }
  }

  sprites
}

pub fn load_zombie() -> Vec<CritterData> {
  let mut sprites = Vec::with_capacity(128);
  let character_json = read_sprite_file(ZOMBIE_JSON_PATH);
  let zombie = match json::parse(&character_json) {
    Ok(res) => res,
    Err(e) => panic!("Character JSON parse error {:?}", e),
  };
  for x in 0..7 {
    for y in 0..4 {
      let key = &format!("still_{}_{}", x, y);
      sprites.push(CritterData::new([
        zombie["frames"][key]["frame"]["x"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["y"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["w"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["h"].as_f32().unwrap()
      ]));
    }
  }

  for x in 0..7 {
    for y in 0..7 {
      let key = &format!("walk_{}_{}", x, y);
      sprites.push(CritterData::new([
        zombie["frames"][key]["frame"]["x"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["y"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["w"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["h"].as_f32().unwrap()
      ]));
    }
  }
  sprites
}
<commit_msg>Update sprite loading functions<commit_after>use std::io::prelude::*;
use std::fs::File;
use std::string::String;
use std::path::Path;
use std::vec::Vec;
use std::io::BufReader;
use json;
use game::constants::{CHARACTER_JSON_PATH, CHARACTER_BUF_LENGTH, ZOMBIE_JSON_PATH};
use tiled::Map;
use tiled;
use critter::CritterData;

pub fn load_map_file(filename: &str) -> Map {
  let file = match File::open(&Path::new(&filename)) {
    Ok(f) => f,
    Err(e) => panic!("File {} not found: {}", filename, e),
  };
  let reader = BufReader::new(file);
  match tiled::parse(reader) {
    Ok(m) => m,
    Err(e) => panic!("Map parse error {:?}", e)
  }
}

pub fn get_map_tile(map: &Map, layer_index: usize, x: usize, y: usize) -> u32 {
  let layer = match map.layers.get(layer_index) {
    None => panic!("Layer_index value out of index {:?}", map.layers),
    Some(l) => l
  };
  let y_index = match layer.tiles.iter().rev().nth(y) {
    None => panic!("X value out of index {:?}", map.layers[0]),
    Some(x) => x
  };
  match y_index.get(x) {
    None => panic!("Y value out of index {:?}", layer.tiles[y]),
    Some(val) => *val
  }
}

fn read_sprite_file(filename: &str) -> String {
  let path = Path::new(&filename);
  let mut file = match File::open(&path) {
    Ok(f) => f,
    Err(e) => panic!("File {} not found: {}", filename, e),
  };
  let mut buf = String::new();
  match file.read_to_string(&mut buf) {
    Ok(_) => buf,
    Err(e) => panic!("read file {} error {}", filename, e),
  }
}

pub fn load_character() -> Vec<CritterData> {
  let mut sprites = Vec::with_capacity(CHARACTER_BUF_LENGTH + 64);
  let character_json = read_sprite_file(CHARACTER_JSON_PATH);
  let character = match json::parse(&character_json) {
    Ok(res) => res,
    Err(e) => panic!("Character {} parse error {:?}", CHARACTER_JSON_PATH, e),
  };
  for x in 0..16 {
    for y in 0..14 {
      let key = &format!("run_{}_{}", x, y);
      sprites.push(CritterData::new([
        character["frames"][key]["frame"]["x"].as_f32().unwrap(),
        character["frames"][key]["frame"]["y"].as_f32().unwrap(),
        character["frames"][key]["frame"]["w"].as_f32().unwrap(),
        character["frames"][key]["frame"]["h"].as_f32().unwrap(),
      ]));
    }
  }

  for x in 0..15 {
    for y in 0..4 {
      let key = &format!("fire_{}_{}", x, y);
      sprites.push(CritterData::new([
        character["frames"][key]["frame"]["x"].as_f32().unwrap(),
        character["frames"][key]["frame"]["y"].as_f32().unwrap(),
        character["frames"][key]["frame"]["w"].as_f32().unwrap(),
        character["frames"][key]["frame"]["h"].as_f32().unwrap(),
      ]));
    }
  }

  sprites
}

pub fn load_zombie() -> Vec<CritterData> {
  let mut sprites = Vec::with_capacity(128);
  let zombie_json = read_sprite_file(ZOMBIE_JSON_PATH);
  let zombie = match json::parse(&zombie_json) {
    Ok(res) => res,
    Err(e) =>  panic!("Zombie {} parse error {:?}", ZOMBIE_JSON_PATH, e),
  };
  for x in 0..7 {
    for y in 0..4 {
      let key = &format!("still_{}_{}", x, y);
      sprites.push(CritterData::new([
        zombie["frames"][key]["frame"]["x"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["y"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["w"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["h"].as_f32().unwrap()
      ]));
    }
  }

  for x in 0..7 {
    for y in 0..7 {
      let key = &format!("walk_{}_{}", x, y);
      sprites.push(CritterData::new([
        zombie["frames"][key]["frame"]["x"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["y"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["w"].as_f32().unwrap(),
        zombie["frames"][key]["frame"]["h"].as_f32().unwrap()
      ]));
    }
  }
  sprites
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "qc", feature(plugin, custom_attribute))]
#![cfg_attr(feature="qc", plugin(quickcheck_macros))]
#![allow(dead_code)]

//! The purpose of these tests is to cover corner cases of iterators
//! and adaptors.
//!
//! In particular we test the tedious size_hint and exact size correctness.

#[macro_use]
extern crate itertools;

#[cfg(feature = "qc")]
extern crate quickcheck;

#[cfg(feature = "qc")]
mod quicktests {

use quickcheck as qc;
use std::ops::Range;
use itertools;
use itertools::Itertools;
use itertools::{
    Zip,
    Stride,
    EitherOrBoth,
};

/// Our base iterator that we can impl Arbitrary for
#[derive(Clone, Debug)]
pub struct Iter<T>(Range<T>);

impl<T> Iterator for Iter<T> where Range<T>: Iterator
{
    type Item = <Range<T> as Iterator>::Item;
    fn next(&mut self) -> Option<Self::Item> { self.0.next() }
    fn size_hint(&self) -> (usize, Option<usize>)
    {
        self.0.size_hint()
    }
}

impl<T> DoubleEndedIterator for Iter<T> where Range<T>: DoubleEndedIterator
{
    fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back() }
}

impl<T> ExactSizeIterator for Iter<T> where Range<T>: ExactSizeIterator
{ }

impl<T> qc::Arbitrary for Iter<T> where T: qc::Arbitrary
{
    fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
    {
        Iter(T::arbitrary(g)..T::arbitrary(g))
    }

    fn shrink(&self) -> Box<Iterator<Item=Iter<T>>>
    {
        let r = self.0.clone();
        Box::new(
            r.start.shrink().flat_map(move |x| {
                r.end.shrink().map(move |y| (x.clone(), y))
            })
            .map(|(a, b)| Iter(a..b))
        )
    }
}

fn correct_size_hint<I: Iterator>(it: I) -> bool {
    let (low, hi) = it.size_hint();
    let cnt = it.count();
    cnt >= low &&
        (hi.is_none() || hi.unwrap() >= cnt)
}

fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
    // check every iteration
    let (mut low, mut hi) = it.size_hint();
    if Some(low) != hi { return false; }
    while let Some(_) = it.next() {
        let (xlow, xhi) = it.size_hint();
        if low - 1 != xlow { return false; }
        low = xlow;
        hi = xhi;
        if Some(low) != hi { return false; }
    }
    let (low, hi) = it.size_hint();
    low == 0 && hi == Some(0)
}

/*
 * NOTE: Range<i8> is broken!
 * (all signed ranges are)
#[quickcheck]
fn size_range_i8(a: Iter<i8>) -> bool {
    exact_size(a)
}

#[quickcheck]
fn size_range_i16(a: Iter<i16>) -> bool {
    exact_size(a)
}

#[quickcheck]
fn size_range_u8(a: Iter<u8>) -> bool {
    exact_size(a)
}
 */

#[quickcheck]
fn size_stride(data: Vec<u8>, stride: isize) -> bool {
    if stride == 0 {
        return true
    }
    exact_size(Stride::from_slice(&data, stride))
}

#[quickcheck]
fn equal_stride(data: Vec<u8>, stride: i8) -> bool {
    if stride == 0 {
        return true
    }
    if stride > 0 {
        itertools::equal(Stride::from_slice(&data, stride as isize),
                         data.iter().step(stride as usize))
    } else {
        itertools::equal(Stride::from_slice(&data, stride as isize),
                         data.iter().rev().step(-stride as usize))
    }
}

#[quickcheck]
fn size_product(a: Iter<u16>, b: Iter<u16>) -> bool {
    correct_size_hint(a.cartesian_product(b))
}

#[quickcheck]
fn size_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>) -> bool {
    correct_size_hint(iproduct!(a, b, c))
}

#[quickcheck]
fn equal_merge(a: Vec<i16>, b: Vec<i16>) -> bool {
    let mut sa = a.clone();
    let mut sb = b.clone();
    sa.sort();
    sb.sort();
    let mut merged = sa.clone() + &sb;
    merged.sort();
    itertools::equal(&merged, sa.iter().merge(&sb))

}
#[quickcheck]
fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
    correct_size_hint(a.merge(b))
}

#[quickcheck]
fn size_zip(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
    exact_size(Zip::new((a, b, c)))
}

#[quickcheck]
fn size_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
    exact_size(a.zip_longest(b))
}

#[quickcheck]
fn size_2_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
    let it = a.clone().zip_longest(b.clone());
    let jt = a.clone().zip_longest(b.clone());
    itertools::equal(a.clone(),
                     it.filter_map(|elt| match elt {
                         EitherOrBoth::Both(x, _) => Some(x),
                         EitherOrBoth::Left(x) => Some(x),
                         _ => None,
                     }
                     ))
        &&
    itertools::equal(b.clone(),
                     jt.filter_map(|elt| match elt {
                         EitherOrBoth::Both(_, y) => Some(y),
                         EitherOrBoth::Right(y) => Some(y),
                         _ => None,
                     }
                     ))
}

fn equal_islice(a: Vec<i16>, x: usize, y: usize) -> bool {
    if x > y || y > a.len() { return true; }
    let slc = &a[x..y];
    itertools::equal(a.iter().slice(x..y), slc)
}

#[quickcheck]
fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
    correct_size_hint(a.interleave(b))
}

#[quickcheck]
fn size_intersperse(a: Iter<i16>, x: i16) -> bool {
    correct_size_hint(a.intersperse(x))
}

#[quickcheck]
fn equal_intersperse(a: Vec<i32>, x: i32) -> bool {
    let mut inter = false;
    let mut i = 0;
    for elt in a.iter().cloned().intersperse(x) {
        if inter {
            if elt != x { return false }
        } else {
            if elt != a[i] { return false }
            i += 1;
        }
        inter = !inter;
    }
    true
}

#[quickcheck]
fn equal_dedup(a: Vec<i32>) -> bool {
    let mut b = a.clone();
    b.dedup();
    itertools::equal(&b, a.iter().dedup())
}

#[quickcheck]
fn size_dedup(a: Vec<i32>) -> bool {
    correct_size_hint(a.iter().dedup())
}

#[quickcheck]
fn size_group_by(a: Vec<i8>) -> bool {
    correct_size_hint(a.iter().group_by(|x| x.abs()))
}

#[quickcheck]
fn size_linspace(a: f32, b: f32, n: usize) -> bool {
    let it = itertools::linspace(a, b, n);
    it.len() == n &&
        exact_size(it)
}

#[quickcheck]
fn equal_repeatn(n: usize, x: i32) -> bool {
    let it = itertools::RepeatN::new(x, n);
    exact_size(it)
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn size_ziptrusted(a: Vec<u8>, b: Vec<u8>) -> bool {
    exact_size(itertools::ZipTrusted::new((a.iter(), b.iter())))
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn size_ziptrusted3(a: Vec<u8>, b: Vec<u8>, c: Vec<u8>) -> bool {
    exact_size(itertools::ZipTrusted::new((a.iter(), b.iter(), c.iter())))
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn equal_ziptrusted_mix(a: Vec<u8>, b: Vec<()>, x: u8, y: u8) -> bool {
    let it = itertools::ZipTrusted::new((a.iter(), b.iter(), x..y));
    let jt = Zip::new((a.iter(), b.iter(), x..y));
    itertools::equal(it, jt)
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn size_ziptrusted_mix(a: Vec<u8>, b: Vec<()>, x: u8, y: u8) -> bool {
    exact_size(itertools::ZipTrusted::new((a.iter(), b.iter(), x..y)))
}

}
<commit_msg>More thorough size hint check<commit_after>#![cfg_attr(feature = "qc", feature(plugin, custom_attribute))]
#![cfg_attr(feature="qc", plugin(quickcheck_macros))]
#![allow(dead_code)]

//! The purpose of these tests is to cover corner cases of iterators
//! and adaptors.
//!
//! In particular we test the tedious size_hint and exact size correctness.

#[macro_use]
extern crate itertools;

#[cfg(feature = "qc")]
extern crate quickcheck;

#[cfg(feature = "qc")]
mod quicktests {

use quickcheck as qc;
use std::ops::Range;
use itertools;
use itertools::Itertools;
use itertools::{
    Zip,
    Stride,
    EitherOrBoth,
};

/// Our base iterator that we can impl Arbitrary for
#[derive(Clone, Debug)]
pub struct Iter<T>(Range<T>);

impl<T> Iterator for Iter<T> where Range<T>: Iterator
{
    type Item = <Range<T> as Iterator>::Item;
    fn next(&mut self) -> Option<Self::Item> { self.0.next() }
    fn size_hint(&self) -> (usize, Option<usize>)
    {
        self.0.size_hint()
    }
}

impl<T> DoubleEndedIterator for Iter<T> where Range<T>: DoubleEndedIterator
{
    fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back() }
}

impl<T> ExactSizeIterator for Iter<T> where Range<T>: ExactSizeIterator
{ }

impl<T> qc::Arbitrary for Iter<T> where T: qc::Arbitrary
{
    fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
    {
        Iter(T::arbitrary(g)..T::arbitrary(g))
    }

    fn shrink(&self) -> Box<Iterator<Item=Iter<T>>>
    {
        let r = self.0.clone();
        Box::new(
            r.start.shrink().flat_map(move |x| {
                r.end.shrink().map(move |y| (x.clone(), y))
            })
            .map(|(a, b)| Iter(a..b))
        )
    }
}

fn correct_size_hint_fast<I: Iterator>(it: I) -> bool {
    let (low, hi) = it.size_hint();
    let cnt = it.count();
    cnt >= low &&
        (hi.is_none() || hi.unwrap() >= cnt)
}

fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
    // record size hint at each iteration
    let initial_hint = it.size_hint();
    let mut hints = Vec::with_capacity(initial_hint.0 + 1);
    hints.push(initial_hint);
    while let Some(_) = it.next() {
        hints.push(it.size_hint())
    }

    let mut true_count = hints.len(); // start off +1 too much

    // check all the size hints
    for &(low, hi) in &hints {
        true_count -= 1;
        if low > true_count ||
            (hi.is_some() && hi.unwrap() < true_count)
        {
            println!("True size: {:?}, size hint: {:?}", true_count, (low, hi));
            println!("All hints: {:?}", hints);
            return false
        }
    }
    true
}

fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
    // check every iteration
    let (mut low, mut hi) = it.size_hint();
    if Some(low) != hi { return false; }
    while let Some(_) = it.next() {
        let (xlow, xhi) = it.size_hint();
        if low - 1 != xlow { return false; }
        low = xlow;
        hi = xhi;
        if Some(low) != hi { return false; }
    }
    let (low, hi) = it.size_hint();
    low == 0 && hi == Some(0)
}

/*
 * NOTE: Range<i8> is broken!
 * (all signed ranges are)
#[quickcheck]
fn size_range_i8(a: Iter<i8>) -> bool {
    exact_size(a)
}

#[quickcheck]
fn size_range_i16(a: Iter<i16>) -> bool {
    exact_size(a)
}

#[quickcheck]
fn size_range_u8(a: Iter<u8>) -> bool {
    exact_size(a)
}
 */

#[quickcheck]
fn size_stride(data: Vec<u8>, stride: isize) -> bool {
    if stride == 0 {
        return true
    }
    exact_size(Stride::from_slice(&data, stride))
}

#[quickcheck]
fn equal_stride(data: Vec<u8>, stride: i8) -> bool {
    if stride == 0 {
        return true
    }
    if stride > 0 {
        itertools::equal(Stride::from_slice(&data, stride as isize),
                         data.iter().step(stride as usize))
    } else {
        itertools::equal(Stride::from_slice(&data, stride as isize),
                         data.iter().rev().step(-stride as usize))
    }
}

#[quickcheck]
fn size_product(a: Iter<u16>, b: Iter<u16>) -> bool {
    correct_size_hint(a.cartesian_product(b))
}

#[quickcheck]
fn size_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>) -> bool {
    correct_size_hint(iproduct!(a, b, c))
}

#[quickcheck]
fn equal_merge(a: Vec<i16>, b: Vec<i16>) -> bool {
    let mut sa = a.clone();
    let mut sb = b.clone();
    sa.sort();
    sb.sort();
    let mut merged = sa.clone() + &sb;
    merged.sort();
    itertools::equal(&merged, sa.iter().merge(&sb))

}
#[quickcheck]
fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
    correct_size_hint(a.merge(b))
}

#[quickcheck]
fn size_zip(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
    exact_size(Zip::new((a, b, c)))
}

#[quickcheck]
fn size_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
    exact_size(a.zip_longest(b))
}

#[quickcheck]
fn size_2_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
    let it = a.clone().zip_longest(b.clone());
    let jt = a.clone().zip_longest(b.clone());
    itertools::equal(a.clone(),
                     it.filter_map(|elt| match elt {
                         EitherOrBoth::Both(x, _) => Some(x),
                         EitherOrBoth::Left(x) => Some(x),
                         _ => None,
                     }
                     ))
        &&
    itertools::equal(b.clone(),
                     jt.filter_map(|elt| match elt {
                         EitherOrBoth::Both(_, y) => Some(y),
                         EitherOrBoth::Right(y) => Some(y),
                         _ => None,
                     }
                     ))
}

fn equal_islice(a: Vec<i16>, x: usize, y: usize) -> bool {
    if x > y || y > a.len() { return true; }
    let slc = &a[x..y];
    itertools::equal(a.iter().slice(x..y), slc)
}

#[quickcheck]
fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
    correct_size_hint(a.interleave(b))
}

#[quickcheck]
fn size_intersperse(a: Iter<i16>, x: i16) -> bool {
    correct_size_hint(a.intersperse(x))
}

#[quickcheck]
fn equal_intersperse(a: Vec<i32>, x: i32) -> bool {
    let mut inter = false;
    let mut i = 0;
    for elt in a.iter().cloned().intersperse(x) {
        if inter {
            if elt != x { return false }
        } else {
            if elt != a[i] { return false }
            i += 1;
        }
        inter = !inter;
    }
    true
}

#[quickcheck]
fn equal_dedup(a: Vec<i32>) -> bool {
    let mut b = a.clone();
    b.dedup();
    itertools::equal(&b, a.iter().dedup())
}

#[quickcheck]
fn size_dedup(a: Vec<i32>) -> bool {
    correct_size_hint(a.iter().dedup())
}

#[quickcheck]
fn size_group_by(a: Vec<i8>) -> bool {
    correct_size_hint(a.iter().group_by(|x| x.abs()))
}

#[quickcheck]
fn size_linspace(a: f32, b: f32, n: usize) -> bool {
    let it = itertools::linspace(a, b, n);
    it.len() == n &&
        exact_size(it)
}

#[quickcheck]
fn equal_repeatn(n: usize, x: i32) -> bool {
    let it = itertools::RepeatN::new(x, n);
    exact_size(it)
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn size_ziptrusted(a: Vec<u8>, b: Vec<u8>) -> bool {
    exact_size(itertools::ZipTrusted::new((a.iter(), b.iter())))
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn size_ziptrusted3(a: Vec<u8>, b: Vec<u8>, c: Vec<u8>) -> bool {
    exact_size(itertools::ZipTrusted::new((a.iter(), b.iter(), c.iter())))
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn equal_ziptrusted_mix(a: Vec<u8>, b: Vec<()>, x: u8, y: u8) -> bool {
    let it = itertools::ZipTrusted::new((a.iter(), b.iter(), x..y));
    let jt = Zip::new((a.iter(), b.iter(), x..y));
    itertools::equal(it, jt)
}

#[cfg(feature = "unstable")]
#[quickcheck]
fn size_ziptrusted_mix(a: Vec<u8>, b: Vec<()>, x: u8, y: u8) -> bool {
    exact_size(itertools::ZipTrusted::new((a.iter(), b.iter(), x..y)))
}

}
<|endoftext|>


<commit_before>extern crate tokio_core;
extern crate env_logger;
extern crate futures;

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

use futures::Future;
use futures::future;
use futures::sync::oneshot;
use tokio_core::reactor::{Core, Timeout};

#[test]
fn simple() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx1, rx1) = oneshot::channel();
    let (tx2, rx2) = oneshot::channel();
    lp.handle().spawn(future::lazy(|| {
        tx1.send(1).unwrap();
        Ok(())
    }));
    lp.remote().spawn(|_| {
        future::lazy(|| {
            tx2.send(2).unwrap();
            Ok(())
        })
    });

    assert_eq!(lp.run(rx1.join(rx2)).unwrap(), (1, 2));
}

#[test]
fn simple_core_poll() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx, rx) = mpsc::channel();
    let (tx1, tx2) = (tx.clone(), tx.clone());

    lp.turn(Some(Duration::new(0, 0)));
    lp.handle().spawn(future::lazy(move || {
        tx1.send(1).unwrap();
        Ok(())
    }));
    lp.turn(Some(Duration::new(0, 0)));
    lp.handle().spawn(future::lazy(move || {
        tx2.send(2).unwrap();
        Ok(())
    }));
    assert_eq!(rx.try_recv().unwrap(), 1);
    assert!(rx.try_recv().is_err());
    lp.turn(Some(Duration::new(0, 0)));
    assert_eq!(rx.try_recv().unwrap(), 2);
}

#[test]
fn spawn_in_poll() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx1, rx1) = oneshot::channel();
    let (tx2, rx2) = oneshot::channel();
    let remote = lp.remote();
    lp.handle().spawn(future::lazy(move || {
        tx1.send(1).unwrap();
        remote.spawn(|_| {
            future::lazy(|| {
                tx2.send(2).unwrap();
                Ok(())
            })
        });
        Ok(())
    }));

    assert_eq!(lp.run(rx1.join(rx2)).unwrap(), (1, 2));
}

#[test]
fn drop_timeout_in_spawn() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx, rx) = oneshot::channel();
    let remote = lp.remote();
    thread::spawn(move || {
        remote.spawn(|handle| {
            drop(Timeout::new(Duration::new(1, 0), handle));
            tx.send(()).unwrap();
            Ok(())
        });
    });

    lp.run(rx).unwrap();
}
<commit_msg>Add a test for spawn-in-drop<commit_after>extern crate tokio_core;
extern crate env_logger;
extern crate futures;

use std::any::Any;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

use futures::{Future, Poll};
use futures::future;
use futures::sync::oneshot;
use tokio_core::reactor::{Core, Timeout};

#[test]
fn simple() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx1, rx1) = oneshot::channel();
    let (tx2, rx2) = oneshot::channel();
    lp.handle().spawn(future::lazy(|| {
        tx1.send(1).unwrap();
        Ok(())
    }));
    lp.remote().spawn(|_| {
        future::lazy(|| {
            tx2.send(2).unwrap();
            Ok(())
        })
    });

    assert_eq!(lp.run(rx1.join(rx2)).unwrap(), (1, 2));
}

#[test]
fn simple_core_poll() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx, rx) = mpsc::channel();
    let (tx1, tx2) = (tx.clone(), tx.clone());

    lp.turn(Some(Duration::new(0, 0)));
    lp.handle().spawn(future::lazy(move || {
        tx1.send(1).unwrap();
        Ok(())
    }));
    lp.turn(Some(Duration::new(0, 0)));
    lp.handle().spawn(future::lazy(move || {
        tx2.send(2).unwrap();
        Ok(())
    }));
    assert_eq!(rx.try_recv().unwrap(), 1);
    assert!(rx.try_recv().is_err());
    lp.turn(Some(Duration::new(0, 0)));
    assert_eq!(rx.try_recv().unwrap(), 2);
}

#[test]
fn spawn_in_poll() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx1, rx1) = oneshot::channel();
    let (tx2, rx2) = oneshot::channel();
    let remote = lp.remote();
    lp.handle().spawn(future::lazy(move || {
        tx1.send(1).unwrap();
        remote.spawn(|_| {
            future::lazy(|| {
                tx2.send(2).unwrap();
                Ok(())
            })
        });
        Ok(())
    }));

    assert_eq!(lp.run(rx1.join(rx2)).unwrap(), (1, 2));
}

#[test]
fn drop_timeout_in_spawn() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx, rx) = oneshot::channel();
    let remote = lp.remote();
    thread::spawn(move || {
        remote.spawn(|handle| {
            drop(Timeout::new(Duration::new(1, 0), handle));
            tx.send(()).unwrap();
            Ok(())
        });
    });

    lp.run(rx).unwrap();
}

#[test]
fn spawn_in_drop() {
    drop(env_logger::init());
    let mut lp = Core::new().unwrap();

    let (tx, rx) = oneshot::channel();
    let remote = lp.remote();

    struct OnDrop<F: FnMut()>(F);

    impl<F: FnMut()> Drop for OnDrop<F> {
        fn drop(&mut self) {
            (self.0)();
        }
    }

    struct MyFuture {
        _data: Box<Any>,
    }

    impl Future for MyFuture {
        type Item = ();
        type Error = ();

        fn poll(&mut self) -> Poll<(), ()> {
            Ok(().into())
        }
    }

    thread::spawn(move || {
        let mut tx = Some(tx);
        remote.spawn(|handle| {
            let handle = handle.clone();
            MyFuture {
                _data: Box::new(OnDrop(move || {
                    let mut tx = tx.take();
                    handle.spawn_fn(move || {
                        tx.take().unwrap().send(()).unwrap();
                        Ok(())
                    });
                })),

            }
        });
    });

    lp.run(rx).unwrap();
}
<|endoftext|>


<commit_before>use env::{Environment, Point};
use graph::{BasicBlockIndex, FuncGraph};
use graph_algorithms::Graph;
use graph_algorithms::bit_set::{BitBuf, BitSet, BitSlice};
use nll_repr::repr;
use regionck::RegionCheck;
use std::collections::HashMap;

pub struct LoansInScope<'rck> {
    regionck: &'rck RegionCheck<'rck>,
    loans: Vec<Loan<'rck>>,
    loans_in_scope_after_block: BitSet<FuncGraph>,
    loans_by_point: HashMap<Point, usize>,
}

pub struct Loan<'rck> {
    point: Point,
    path: &'rck repr::Path,
    kind: repr::BorrowKind,
    region: repr::RegionName,
}

impl<'rck> LoansInScope<'rck> {
    pub fn new(regionck: &'rck RegionCheck<'rck>) -> Self {
        let env = regionck.env();

        // Collect the full set of loans; these are just the set of
        // `&foo` expressions.
        let loans: Vec<_> =
            env.reverse_post_order
               .iter()
               .flat_map(|&block| {
                   env.graph.block_data(block)
                            .actions
                            .iter()
                            .enumerate()
                            .flat_map(move |(index, action)| match action.kind {
                                repr::ActionKind::Borrow(_, region, kind, ref path) => {
                                    let point = Point { block, action: index };
                                    Some(Loan { point, region, kind, path })
                                }

                                _ => None,
                            })
               })
               .collect();

        // Make a convenient hash map for getting the index of a loan
        // based on where it appears.
        let loans_by_point: HashMap<_, _> =
            loans.iter()
                 .enumerate()
                 .map(|(index, loan)| (loan.point, index))
                 .collect();

        // Get a bit set with the set of in-scope loans at each point
        // in the graph. These correspond to the set of loans in scope
        // at the end of the block.
        let loans_in_scope_after_block = BitSet::new(env.graph, loans.len());

        // iterate until fixed point
        let mut this = LoansInScope { regionck, loans, loans_by_point, loans_in_scope_after_block };
        this.compute();

        this
    }

    pub fn env(&self) -> &'rck Environment<'rck> {
        self.regionck.env()
    }

    /// Invokes `callback` with the loans in scope at each point.
    pub fn walk<CB>(&self, mut callback: CB)
        where CB: FnMut(Point, Option<&repr::Action>, &[&Loan])
    {
        let env = self.env();
        let mut loans = Vec::with_capacity(self.loans.len());
        let mut bits = self.loans_in_scope_after_block.empty_buf();
        for &block in &env.reverse_post_order {
            self.simulate_block(env, &mut bits, block, |point, action, bits| {
                // Convert from the bitset into a vector of references to loans.
                loans.clear();
                loans.extend(
                    self.loans.iter()
                              .enumerate()
                              .filter_map(|(loan_index, loan)| {
                                  if bits.get(loan_index) {
                                      Some(loan)
                                  } else {
                                      None
                                  }
                              }));

                // Invoke the callback.
                callback(point, action, &loans);
            });
        }
    }

    /// Iterates until a fixed point, computing the loans in scope
    /// after each block terminates.
    fn compute(&mut self) {
        let env = self.env();
        let mut bits = self.loans_in_scope_after_block.empty_buf();
        let mut changed = true;
        while changed {
            changed = false;

            for &block in &env.reverse_post_order {
                self.simulate_block(env, &mut bits, block, |_p, _a, _s| ());
                changed |= self.loans_in_scope_after_block
                               .insert_bits_from_slice(block, bits.as_slice());
            }
        }
    }

    fn simulate_block<CB>(&self,
                          env: &Environment,
                          buf: &mut BitBuf,
                          block: BasicBlockIndex,
                          mut callback: CB)
        where CB: FnMut(Point, Option<&repr::Action>, BitSlice)
    {
        buf.clear();

        // everything live at end of a pred  is live at the exit of the block
        for succ in env.graph.successors(block) {
            buf.set_from(self.loans_in_scope_after_block.bits(succ));
        }

        // walk through the actions on by one
        for (index, action) in env.graph.block_data(block).actions.iter().enumerate() {
            let point = Point { block, action: index };

            // kill any loans where `point` is not in their region
            for loan_index in self.loans_not_in_scope_at(point) {
                buf.kill(loan_index);
            }

            // callback at start of the action
            callback(point, Some(action), buf.as_slice());

            // bring the loan into scope after the borrow
            if let Some(&loan_index) = self.loans_by_point.get(&point) {
                buf.set(loan_index);
            }

            // figure out which path is overwritten by this action;
            // this may cancel out some loans
            if let Some(overwritten_path) = action.overwrites() {
                for loan_index in self.loans_killed_by_write_to(&overwritten_path) {
                    buf.kill(loan_index);
                }
            }
        }

        // final callback for the terminator
        let point = env.end_point(block);
        for loan_index in self.loans_not_in_scope_at(point) {
            buf.kill(loan_index);
        }
        callback(point, None, buf.as_slice());
    }

    fn loans_not_in_scope_at<'a>(&'a self, point: Point)
                                 -> impl Iterator<Item = usize> + 'a
    {
        self.loans.iter()
                  .enumerate()
                  .filter_map(move |(loan_index, loan)| {
                      let region = self.regionck.region(loan.region);
                      if !region.contains(point) {
                          Some(loan_index)
                      } else {
                          None
                      }
                  })
    }

    fn loans_killed_by_write_to<'a>(&'a self, path: &'a repr::Path)
                                         -> impl Iterator<Item = usize> + 'a
    {
        // When an assignment like `a.b.c = ...` occurs, we kill all
        // the loans for `a.b.c` or some subpath like `a.b.c.d`, since
        // the path no longer evaluates to the same thing.
        self.loans.iter()
                  .enumerate()
                  .filter_map(move |(index, loan)| {
                      if self.path_prefixes(loan.path).iter().any(|&p| p == path) {
                          Some(index)
                      } else {
                          None
                      }
                  })
    }

    fn path_prefixes<'a>(&self, mut path: &'a repr::Path) -> Vec<&'a repr::Path> {
        let mut result = vec![];
        loop {
            result.push(path);
            match *path {
                repr::Path::Base(_) => return result,
                repr::Path::Extension(ref base, _) => path = base,
            }
        }
    }
}

pub trait Overwrites {
    /// Returns path that this action overwrites, if any.
    fn overwrites(&self) -> Option<&repr::Path>;
}

impl Overwrites for repr::Action {
    fn overwrites(&self) -> Option<&repr::Path> {
        match self.kind {
            repr::ActionKind::Borrow(ref p, _name, _, _) => Some(p),
            repr::ActionKind::Init(ref a, _) => Some(a),
            repr::ActionKind::Assign(ref a, _) => Some(a),
            repr::ActionKind::Constraint(ref _c) => None,
            repr::ActionKind::Use(_) => None,
            repr::ActionKind::Drop(_) => None,
            repr::ActionKind::Noop => None,
            repr::ActionKind::StorageDead(_) => None,
        }
    }
}
<commit_msg>stop storing a pointer to `RegionCheck`, just `env`<commit_after>use env::{Environment, Point};
use graph::{BasicBlockIndex, FuncGraph};
use graph_algorithms::Graph;
use graph_algorithms::bit_set::{BitBuf, BitSet, BitSlice};
use nll_repr::repr;
use region::Region;
use regionck::RegionCheck;
use std::collections::HashMap;

pub struct LoansInScope<'rck> {
    env: &'rck Environment<'rck>,
    loans: Vec<Loan<'rck>>,
    loans_in_scope_after_block: BitSet<FuncGraph>,
    loans_by_point: HashMap<Point, usize>,
}

pub struct Loan<'rck> {
    point: Point,
    path: &'rck repr::Path,
    kind: repr::BorrowKind,
    region: &'rck Region,
}

impl<'rck> LoansInScope<'rck> {
    pub fn new(regionck: &'rck RegionCheck<'rck>) -> Self {
        let env = regionck.env();

        // Collect the full set of loans; these are just the set of
        // `&foo` expressions.
        let loans: Vec<_> =
            env.reverse_post_order
               .iter()
               .flat_map(|&block| {
                   env.graph.block_data(block)
                            .actions
                            .iter()
                            .enumerate()
                            .flat_map(move |(index, action)| match action.kind {
                                repr::ActionKind::Borrow(_, region, kind, ref path) => {
                                    let point = Point { block, action: index };
                                    let region = regionck.region(region);
                                    Some(Loan { point, region, kind, path })
                                }

                                _ => None,
                            })
               })
               .collect();

        // Make a convenient hash map for getting the index of a loan
        // based on where it appears.
        let loans_by_point: HashMap<_, _> =
            loans.iter()
                 .enumerate()
                 .map(|(index, loan)| (loan.point, index))
                 .collect();

        // Get a bit set with the set of in-scope loans at each point
        // in the graph. These correspond to the set of loans in scope
        // at the end of the block.
        let loans_in_scope_after_block = BitSet::new(env.graph, loans.len());

        // iterate until fixed point
        let mut this = LoansInScope { env, loans, loans_by_point, loans_in_scope_after_block };
        this.compute();

        this
    }

    /// Invokes `callback` with the loans in scope at each point.
    pub fn walk<CB>(&self, env: &Environment<'rck>, mut callback: CB)
        where CB: FnMut(Point, Option<&repr::Action>, &[&Loan])
    {
        let mut loans = Vec::with_capacity(self.loans.len());
        let mut bits = self.loans_in_scope_after_block.empty_buf();
        for &block in &env.reverse_post_order {
            self.simulate_block(&mut bits, block, |point, action, bits| {
                // Convert from the bitset into a vector of references to loans.
                loans.clear();
                loans.extend(
                    self.loans.iter()
                              .enumerate()
                              .filter_map(|(loan_index, loan)| {
                                  if bits.get(loan_index) {
                                      Some(loan)
                                  } else {
                                      None
                                  }
                              }));

                // Invoke the callback.
                callback(point, action, &loans);
            });
        }
    }

    /// Iterates until a fixed point, computing the loans in scope
    /// after each block terminates.
    fn compute(&mut self) {
        let mut bits = self.loans_in_scope_after_block.empty_buf();
        let mut changed = true;
        while changed {
            changed = false;

            for &block in &self.env.reverse_post_order {
                self.simulate_block(&mut bits, block, |_p, _a, _s| ());
                changed |= self.loans_in_scope_after_block
                               .insert_bits_from_slice(block, bits.as_slice());
            }
        }
    }

    fn simulate_block<CB>(&self,
                          buf: &mut BitBuf,
                          block: BasicBlockIndex,
                          mut callback: CB)
        where CB: FnMut(Point, Option<&repr::Action>, BitSlice)
    {
        buf.clear();

        // everything live at end of a pred  is live at the exit of the block
        for succ in self.env.graph.successors(block) {
            buf.set_from(self.loans_in_scope_after_block.bits(succ));
        }

        // walk through the actions on by one
        for (index, action) in self.env.graph.block_data(block).actions.iter().enumerate() {
            let point = Point { block, action: index };

            // kill any loans where `point` is not in their region
            for loan_index in self.loans_not_in_scope_at(point) {
                buf.kill(loan_index);
            }

            // callback at start of the action
            callback(point, Some(action), buf.as_slice());

            // bring the loan into scope after the borrow
            if let Some(&loan_index) = self.loans_by_point.get(&point) {
                buf.set(loan_index);
            }

            // figure out which path is overwritten by this action;
            // this may cancel out some loans
            if let Some(overwritten_path) = action.overwrites() {
                for loan_index in self.loans_killed_by_write_to(&overwritten_path) {
                    buf.kill(loan_index);
                }
            }
        }

        // final callback for the terminator
        let point = self.env.end_point(block);
        for loan_index in self.loans_not_in_scope_at(point) {
            buf.kill(loan_index);
        }
        callback(point, None, buf.as_slice());
    }

    fn loans_not_in_scope_at<'a>(&'a self, point: Point)
                                 -> impl Iterator<Item = usize> + 'a
    {
        self.loans.iter()
                  .enumerate()
                  .filter_map(move |(loan_index, loan)| {
                      if !loan.region.contains(point) {
                          Some(loan_index)
                      } else {
                          None
                      }
                  })
    }

    fn loans_killed_by_write_to<'a>(&'a self, path: &'a repr::Path)
                                         -> impl Iterator<Item = usize> + 'a
    {
        // When an assignment like `a.b.c = ...` occurs, we kill all
        // the loans for `a.b.c` or some subpath like `a.b.c.d`, since
        // the path no longer evaluates to the same thing.
        self.loans.iter()
                  .enumerate()
                  .filter_map(move |(index, loan)| {
                      if self.path_prefixes(loan.path).iter().any(|&p| p == path) {
                          Some(index)
                      } else {
                          None
                      }
                  })
    }

    fn path_prefixes<'a>(&self, mut path: &'a repr::Path) -> Vec<&'a repr::Path> {
        let mut result = vec![];
        loop {
            result.push(path);
            match *path {
                repr::Path::Base(_) => return result,
                repr::Path::Extension(ref base, _) => path = base,
            }
        }
    }
}

pub trait Overwrites {
    /// Returns path that this action overwrites, if any.
    fn overwrites(&self) -> Option<&repr::Path>;
}

impl Overwrites for repr::Action {
    fn overwrites(&self) -> Option<&repr::Path> {
        match self.kind {
            repr::ActionKind::Borrow(ref p, _name, _, _) => Some(p),
            repr::ActionKind::Init(ref a, _) => Some(a),
            repr::ActionKind::Assign(ref a, _) => Some(a),
            repr::ActionKind::Constraint(ref _c) => None,
            repr::ActionKind::Use(_) => None,
            repr::ActionKind::Drop(_) => None,
            repr::ActionKind::Noop => None,
            repr::ActionKind::StorageDead(_) => None,
        }
    }
}
<|endoftext|>


<commit_before>use std::hash::Hash;
use std::collections::HashMap;
use std::collections::HashSet;

/// A grid node for the Dijkstra map.
pub trait DijkstraNode: Eq+Clone+Hash {
    /// List the neighbor nodes of this graph node.
    fn neighbors(&self) -> Vec<Self>;
}

/// A pathfinding map structure.
///
/// A Dijkstra map lets you run pathfinding from any graph node it covers
/// towards or away from the target nodes of the map. Currently the structure
/// only supports underlying graphs with a fixed grid graph where the
/// neighbors of each node must be the adjacent grid cells of that node.
pub struct Dijkstra<N> {
    weights: HashMap<N, u32>,
}

impl<N: DijkstraNode> Dijkstra<N> {
    /// Create a new Dijkstra map up to limit distance from goals, omitting
    /// nodes for which the is_valid predicate returns false.
    pub fn new<F: Fn(&N) -> bool>(goals: Vec<N>, is_valid: F, limit: u32) -> Dijkstra<N> {
        assert!(goals.len() > 0);

        let mut weights = HashMap::new();
        let mut edge = HashSet::new();

        for n in goals.into_iter() {
            edge.insert(n);
        }

        for dist in 0..(limit) {
            for n in edge.iter() {
                weights.insert(n.clone(), dist);
            }

            let mut new_edge = HashSet::new();
            for n in edge.iter() {
                for m in n.neighbors().into_iter() {
                    if is_valid(&m) && !weights.contains_key(&m) {
                        new_edge.insert(m);
                    }
                }
            }

            edge = new_edge;
        }

        Dijkstra {
            weights: weights,
        }
    }

    /// Return the neighbors of a cell (if any), sorted from downhill to
    /// uphill.
    pub fn sorted_neighbors(& self, node: &N) -> Vec<N> {
        let mut ret = Vec::new();
        for n in node.neighbors().iter() {
            if let Some(w) = self.weights.get(n) {
                ret.push((w, n.clone()));
            }
        }
        ret.sort_by(|&(w1, _), &(w2, _)| w1.cmp(w2));
        ret.into_iter().map(|(_, n)| n).collect()
    }
}
<commit_msg>Terminate Dijkstra map iteration if there is no open space<commit_after>use std::hash::Hash;
use std::collections::HashMap;
use std::collections::HashSet;

/// A grid node for the Dijkstra map.
pub trait DijkstraNode: Eq+Clone+Hash {
    /// List the neighbor nodes of this graph node.
    fn neighbors(&self) -> Vec<Self>;
}

/// A pathfinding map structure.
///
/// A Dijkstra map lets you run pathfinding from any graph node it covers
/// towards or away from the target nodes of the map. Currently the structure
/// only supports underlying graphs with a fixed grid graph where the
/// neighbors of each node must be the adjacent grid cells of that node.
pub struct Dijkstra<N> {
    weights: HashMap<N, u32>,
}

impl<N: DijkstraNode> Dijkstra<N> {
    /// Create a new Dijkstra map up to limit distance from goals, omitting
    /// nodes for which the is_valid predicate returns false.
    pub fn new<F: Fn(&N) -> bool>(goals: Vec<N>, is_valid: F, limit: u32) -> Dijkstra<N> {
        assert!(goals.len() > 0);

        let mut weights = HashMap::new();
        let mut edge = HashSet::new();

        for n in goals.into_iter() {
            edge.insert(n);
        }

        for dist in 0..(limit) {
            for n in edge.iter() {
                weights.insert(n.clone(), dist);
            }

            let mut new_edge = HashSet::new();
            for n in edge.iter() {
                for m in n.neighbors().into_iter() {
                    if is_valid(&m) && !weights.contains_key(&m) {
                        new_edge.insert(m);
                    }
                }
            }

            edge = new_edge;

            if edge.is_empty() { break; }
        }

        Dijkstra {
            weights: weights,
        }
    }

    /// Return the neighbors of a cell (if any), sorted from downhill to
    /// uphill.
    pub fn sorted_neighbors(& self, node: &N) -> Vec<N> {
        let mut ret = Vec::new();
        for n in node.neighbors().iter() {
            if let Some(w) = self.weights.get(n) {
                ret.push((w, n.clone()));
            }
        }
        ret.sort_by(|&(w1, _), &(w2, _)| w1.cmp(w2));
        ret.into_iter().map(|(_, n)| n).collect()
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2017 Sreejith Krishnan R
 *
 * 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.
*/

mod wrapper;                pub use self::wrapper::*;
mod text;                   pub use self::text::*;
mod absolute_layout;        pub use self::absolute_layout::*;
mod linear_layout;          pub use self::linear_layout::*;
mod fixed;                  pub use self::fixed::*;
mod padding_box;            pub use self::padding_box::*;

use ::paint::{Canvas, Point, Rect};
use ::platform::Context;

#[derive(Debug, Clone)]
pub struct BoundingBox {
    rect: Rect,
    baseline: f32,
    axis: f32
}

impl BoundingBox {
    pub fn new(rect: Rect, baseline: f32, axis: f32) -> BoundingBox {
        BoundingBox { rect, baseline, axis }
    }

    pub fn rect(&self) -> &Rect {
        &self.rect
    }

    pub fn baseline(&self) -> f32 {
        self.baseline
    }

    pub fn axis(&self) -> f32 {
        self.axis
    }

    pub fn width(&self) -> f32 {
        self.rect.width()
    }

    pub fn height(&self) -> f32 {
        self.rect.height()
    }

    pub fn ascent(&self) -> f32 { self.height()-self.baseline }

    pub fn descent(&self) -> f32 { -self.baseline }

    pub fn baseline_pos(&self) -> f32 {
        self.height()-self.baseline()
    }

    pub fn axis_pos(&self) -> f32 {
        self.height()-self.axis()
    }
}

impl Default for BoundingBox {
    fn default() -> Self {
        BoundingBox {
            rect: Rect::new(0., 0.),
            baseline: 0.0,
            axis: 0.0,
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum MeasureMode {
    UpTo,
    Wrap
}

pub trait Drawable {
    fn draw(&self, canvas: &Canvas, pen_pos: &Point);
    fn calculate(&mut self, context: &Context, width: f32, width_mode: &MeasureMode, height: f32,
                 height_mode: &MeasureMode);

    fn bounding_box(&self) -> &BoundingBox;
}<commit_msg>Export Symbol and Glyph<commit_after>/*
 * Copyright 2017 Sreejith Krishnan R
 *
 * 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.
*/

mod wrapper;                pub use self::wrapper::*;
mod text;                   pub use self::text::*;
mod absolute_layout;        pub use self::absolute_layout::*;
mod linear_layout;          pub use self::linear_layout::*;
mod fixed;                  pub use self::fixed::*;
mod padding_box;            pub use self::padding_box::*;
mod symbol;                 pub use self::symbol::*;
mod glyph;                  pub use self::glyph::*;

use ::paint::{Canvas, Point, Rect};
use ::platform::Context;

#[derive(Debug, Clone)]
pub struct BoundingBox {
    rect: Rect,
    baseline: f32,
    axis: f32
}

impl BoundingBox {
    pub fn new(rect: Rect, baseline: f32, axis: f32) -> BoundingBox {
        BoundingBox { rect, baseline, axis }
    }

    pub fn rect(&self) -> &Rect {
        &self.rect
    }

    pub fn baseline(&self) -> f32 {
        self.baseline
    }

    pub fn axis(&self) -> f32 {
        self.axis
    }

    pub fn width(&self) -> f32 {
        self.rect.width()
    }

    pub fn height(&self) -> f32 {
        self.rect.height()
    }

    pub fn ascent(&self) -> f32 { self.height()-self.baseline }

    pub fn descent(&self) -> f32 { -self.baseline }

    pub fn baseline_pos(&self) -> f32 {
        self.height()-self.baseline()
    }

    pub fn axis_pos(&self) -> f32 {
        self.height()-self.axis()
    }
}

impl Default for BoundingBox {
    fn default() -> Self {
        BoundingBox {
            rect: Rect::new(0., 0.),
            baseline: 0.0,
            axis: 0.0,
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum MeasureMode {
    UpTo,
    Wrap
}

pub trait Drawable {
    fn draw(&self, canvas: &Canvas, pen_pos: &Point);
    fn calculate(&mut self, context: &Context, width: f32, width_mode: &MeasureMode, height: f32,
                 height_mode: &MeasureMode);

    fn bounding_box(&self) -> &BoundingBox;
}<|endoftext|>


<commit_before>const MAX: usize = 10_000_000;

const SQUARE: [usize; 10] = [0, 1, 4, 9, 16, 25, 36, 49,  64, 81];

fn fill(array: &mut Vec<u8>, index: usize) -> u8 {
    let next = index
                .to_string()
                .chars()
                .map(|c| SQUARE[c.to_digit(10).unwrap() as usize] )
                .fold(0, |acc, n| acc + n);
    if array[next] == 0 {
        array[next] = fill(array, next);
    }
    return array[next];
}

pub fn main() {
    let mut numbers = vec![0; MAX];
    numbers[1] = 1;
    numbers[89] = 89;
    for i in 2..MAX {
        if numbers[i] != 0 { continue }
        numbers[i] = fill(&mut numbers, i);
    }
    println!("{}", numbers.iter().filter(|&n| *n == 89).count());
}<commit_msg>use a lookup table for problem 92b<commit_after>const MAX: usize = 10_000_000;

fn fill(array: &mut Vec<u8>, index: usize) -> u8 {
    let next = index
                .to_string()
                .chars()
                .map(|c| match c {
                   '0' => 0,
                   '1' => 1,
                   '2' => 4,
                   '3' => 9,
                   '4' => 16,
                   '5' => 25,
                   '6' => 36,
                   '7' => 49,
                   '8' => 64,
                   '9' => 81,
                   _ => panic!()
                })
                .fold(0, |acc, n| acc + n);
    if array[next] == 0 {
        array[next] = fill(array, next);
    }
    return array[next];
}

pub fn main() {
    let mut numbers = vec![0; MAX];
    numbers[1] = 1;
    numbers[89] = 89;
    for i in 2..MAX {
        if numbers[i] != 0 { continue }
        numbers[i] = fill(&mut numbers, i);
    }
    println!("{}", numbers.iter().filter(|&n| *n == 89).count());
}<|endoftext|>


<commit_before>extern crate tls;
use std::io::{Read, Write};
use tls::{new_client,init};
use std::net::TcpStream;

#[test]
fn test_client() {
    assert!(init());

    let mut c = new_client()
        .connect("google.com", "443", None).unwrap();
    c.handshake().unwrap();

    let notbefore = c.peer_cert_notbefore().unwrap();
    let notafter = c.peer_cert_notafter().unwrap();
    assert!(notbefore < notafter);
    assert!(c.peer_cert_provided());
    assert!(c.peer_cert_contains_name("google.com"));

    // Start an HTTP request just to check read/write
    c.write("GET / HTTP/1.1\n\n".as_bytes()).unwrap();
    let mut buf = [0u8; 256];
    c.read(&mut buf).unwrap();
    println!("{}", String::from_utf8_lossy(&buf));
    assert!(buf.starts_with(b"HTTP/1.1 "));
}

#[test]
fn stream_write_read() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    cli.write("GET / HTTP/1.1\n\n".as_bytes()).unwrap();
    let mut buf = [0u8; 256];
    cli.read(&mut buf).unwrap();
    assert!(buf.starts_with(b"HTTP/1.1 "));
}

#[test]
fn shutdown_twice_fails() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    cli.handshake().unwrap();
    cli.shutdown().unwrap();
    assert!(cli.shutdown().is_err());
}

#[test]
fn shutdown_without_handshake_fails() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    assert!(cli.shutdown().is_err());
}

#[test]
fn ca_invalid() {
    assert!(init());
    // This will fail because there is no CA file
    let cli = new_client()
                .ca_path(".")
                .ca_file("")
                .connect("www.google.com", "443", None);
    assert!(cli.is_err());
}

#[test]
fn ca_string() {
    assert!(init());

    let pem = include_str!("cert.pem");
    let mut cli = new_client()
                .ca(&pem)
                .connect("www.google.com", "443", None)
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn ca_string_invalid() {
    assert!(init());

    let cli = new_client()
                .ca("--INVALID PEM")
                .connect("www.google.com", "443", None);
    assert!(cli.is_err());
}

#[test]
fn connect_hostport() {
    assert!(init());
    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com:443", "", None)
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn connect_servername() {
    assert!(init());
    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", Some("www.google.com"))
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn connect_socket() {
    let tcp = TcpStream::connect("google.com:443").unwrap();
    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect_socket(tcp, "www.google.com")
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn double_handshake_is_error() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    cli.handshake().unwrap();
    assert!(cli.handshake().is_err());
}

#[test]
fn verify_depth() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .verify_depth(0)
                .connect("www.google.com", "443", None)
                .unwrap();
    assert!(cli.handshake().is_err());
}
<commit_msg>Add missing CA setting to test_client<commit_after>extern crate tls;
use std::io::{Read, Write};
use tls::{new_client,init};
use std::net::TcpStream;

#[test]
fn test_client() {
    assert!(init());

    let mut c = new_client()
        .ca_file("tests/cert.pem")
        .connect("google.com", "443", None).unwrap();
    c.handshake().unwrap();

    let notbefore = c.peer_cert_notbefore().unwrap();
    let notafter = c.peer_cert_notafter().unwrap();
    assert!(notbefore < notafter);
    assert!(c.peer_cert_provided());
    assert!(c.peer_cert_contains_name("google.com"));

    // Start an HTTP request just to check read/write
    c.write("GET / HTTP/1.1\n\n".as_bytes()).unwrap();
    let mut buf = [0u8; 256];
    c.read(&mut buf).unwrap();
    println!("{}", String::from_utf8_lossy(&buf));
    assert!(buf.starts_with(b"HTTP/1.1 "));
}

#[test]
fn stream_write_read() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    cli.write("GET / HTTP/1.1\n\n".as_bytes()).unwrap();
    let mut buf = [0u8; 256];
    cli.read(&mut buf).unwrap();
    assert!(buf.starts_with(b"HTTP/1.1 "));
}

#[test]
fn shutdown_twice_fails() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    cli.handshake().unwrap();
    cli.shutdown().unwrap();
    assert!(cli.shutdown().is_err());
}

#[test]
fn shutdown_without_handshake_fails() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    assert!(cli.shutdown().is_err());
}

#[test]
fn ca_invalid() {
    assert!(init());
    // This will fail because there is no CA file
    let cli = new_client()
                .ca_path(".")
                .ca_file("")
                .connect("www.google.com", "443", None);
    assert!(cli.is_err());
}

#[test]
fn ca_string() {
    assert!(init());

    let pem = include_str!("cert.pem");
    let mut cli = new_client()
                .ca(&pem)
                .connect("www.google.com", "443", None)
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn ca_string_invalid() {
    assert!(init());

    let cli = new_client()
                .ca("--INVALID PEM")
                .connect("www.google.com", "443", None);
    assert!(cli.is_err());
}

#[test]
fn connect_hostport() {
    assert!(init());
    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com:443", "", None)
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn connect_servername() {
    assert!(init());
    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", Some("www.google.com"))
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn connect_socket() {
    let tcp = TcpStream::connect("google.com:443").unwrap();
    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect_socket(tcp, "www.google.com")
                .unwrap();
    cli.handshake().unwrap();
}

#[test]
fn double_handshake_is_error() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .connect("www.google.com", "443", None)
                .unwrap();

    cli.handshake().unwrap();
    assert!(cli.handshake().is_err());
}

#[test]
fn verify_depth() {
    assert!(init());

    let mut cli = new_client()
                .ca_file("tests/cert.pem")
                .verify_depth(0)
                .connect("www.google.com", "443", None)
                .unwrap();
    assert!(cli.handshake().is_err());
}
<|endoftext|>


<commit_before>use std::result::Result;
use std::convert::From;
use std::borrow::Cow;

use serde_json;

use varlink::server::ErrorDetails;
use varlink::server::Interface as VarlinkInterface;
use varlink::server::Error as VarlinkError;

pub trait Interface: VarlinkInterface {
    fn info(&self, i64) -> Result<InfoReply, Error>;
    fn list(&self) -> Result<ListReply, Error>;
}

#[macro_export]
macro_rules! IoSystemdNetwork {
	(
		()
		$(pub)* struct $name:ident $($_tail:tt)*
	) => {
use varlink::server::{Request};
use varlink::server::Interface as VarlinkInterface;
use varlink::server::Error as VarlinkError;
use serde_json::Value as SerdeValue;

impl VarlinkInterface for $name {
    fn get_description(&self) -> &'static str {
        r#"
# Provides information about network state
interface io.systemd.network

type NetdevInfo (
  ifindex: int,
  ifname: string
)

type Netdev (
  ifindex: int,
  ifname: string
)

# Returns information about a network device
method Info(ifindex: int) -> (info: NetdevInfo)

# Lists all network devices
method List() -> (netdevs: Netdev[])

error UnknownNetworkDevice
error InvalidParameter
	"#
    }

    fn get_name(&self) -> &'static str {
        "io.systemd.network"
    }

    fn call(&self, req: Request) -> Result<SerdeValue, VarlinkError> {
        match req.method.as_ref() {
            "Info" => {
                if let Some(args) = req.arguments {
                    let infoargs: Result<InfoArgs, serde_json::Error> =
                        serde_json::from_value(args);
                    match infoargs {
                        Ok(args) => Ok(serde_json::to_value(self.info(args.ifindex)?)?),
                        Err(_) => Err(Error::InvalidParameter.into()),
                    }
                } else {
                    Err(Error::InvalidParameter.into())
                }
            }
            "List" => Ok(serde_json::to_value(self.list()?)?),
            _ => Err(Error::MethodNotFound.into()),
        }
    }
}
};
}

#[derive(Debug)]
pub enum Error {
    UnknownNetworkDevice,
    InvalidParameter,
    MethodNotFound,
    UnknownError(Option<Cow<'static, str>>),
}

impl From<serde_json::Error> for Error {
    fn from(e: serde_json::Error) -> Self {
        Error::UnknownError(Some(e.to_string().into()))
    }
}

impl From<Error> for VarlinkError {
    fn from(e: Error) -> Self {
        VarlinkError {
            error: ErrorDetails {
                id: {
                    match e {
                        Error::UnknownNetworkDevice => "UnknownNetworkDevice".into(),
                        Error::InvalidParameter => "InvalidParameter".into(),
                        _ => "UnknownError".into(),
                    }
                },
                ..Default::default()
            },
        }
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct NetdevInfo {
    pub ifindex: i64,
    pub ifname: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Netdev {
    pub ifindex: i64,
    pub ifname: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct InfoArgs {
    pub ifindex: i64,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct InfoReply {
    pub info: NetdevInfo,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct ListReply {
    pub netdevs: Vec<Netdev>,
}
<commit_msg>fix server example<commit_after>use std::result::Result;
use std::convert::From;
use std::borrow::Cow;

use serde_json;

use varlink::server::ErrorDetails;
use varlink::server::Interface as VarlinkInterface;
use varlink::server::Error as VarlinkError;

pub trait Interface: VarlinkInterface {
    fn info(&self, i64) -> Result<InfoReply, Error>;
    fn list(&self) -> Result<ListReply, Error>;
}

#[macro_export]
macro_rules! IoSystemdNetwork {
	(
		()
		$(pub)* struct $name:ident $($_tail:tt)*
	) => {
use varlink::server::{Request};
use varlink::server::Interface as VarlinkInterface;
use varlink::server::Error as VarlinkError;
use serde_json::Value as SerdeValue;

impl VarlinkInterface for $name {
    fn get_description(&self) -> &'static str {
        r#"
# Provides information about network state
interface io.systemd.network

type NetdevInfo (
  ifindex: int,
  ifname: string
)

type Netdev (
  ifindex: int,
  ifname: string
)

# Returns information about a network device
method Info(ifindex: int) -> (info: NetdevInfo)

# Lists all network devices
method List() -> (netdevs: Netdev[])

error UnknownNetworkDevice ()
error InvalidParameter (field: string)
	"#
    }

    fn get_name(&self) -> &'static str {
        "io.systemd.network"
    }

    fn call(&self, req: Request) -> Result<SerdeValue, VarlinkError> {
        match req.method.as_ref() {
            "Info" => {
                if let Some(args) = req.arguments {
                    let infoargs: Result<InfoArgs, serde_json::Error> =
                        serde_json::from_value(args);
                    match infoargs {
                        Ok(args) => Ok(serde_json::to_value(self.info(args.ifindex)?)?),
                        Err(_) => Err(Error::InvalidParameter.into()),
                    }
                } else {
                    Err(Error::InvalidParameter.into())
                }
            }
            "List" => Ok(serde_json::to_value(self.list()?)?),
            _ => Err(Error::MethodNotFound.into()),
        }
    }
}
};
}

#[derive(Debug)]
pub enum Error {
    UnknownNetworkDevice,
    InvalidParameter,
    MethodNotFound,
    UnknownError(Option<Cow<'static, str>>),
}

impl From<serde_json::Error> for Error {
    fn from(e: serde_json::Error) -> Self {
        Error::UnknownError(Some(e.to_string().into()))
    }
}

impl From<Error> for VarlinkError {
    fn from(e: Error) -> Self {
        VarlinkError {
            error: ErrorDetails {
                id: {
                    match e {
                        Error::UnknownNetworkDevice => "UnknownNetworkDevice".into(),
                        Error::InvalidParameter => "InvalidParameter".into(),
                        _ => "UnknownError".into(),
                    }
                },
                ..Default::default()
            },
        }
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct NetdevInfo {
    pub ifindex: i64,
    pub ifname: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Netdev {
    pub ifindex: i64,
    pub ifname: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct InfoArgs {
    pub ifindex: i64,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct InfoReply {
    pub info: NetdevInfo,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct ListReply {
    pub netdevs: Vec<Netdev>,
}
<|endoftext|>


<commit_before><commit_msg>remove usage of bit_field<commit_after><|endoftext|>


<commit_before>extern mod std;

use std::*;
use io::{ReaderUtil,WriterUtil};

enum Result {
  Nil,
  Int(int),
  Data(~[u8]),
  List(~[Result]),
  Error(~str),
  Status(~str)
}

priv fn parse_data(len: uint, sb: net::tcp::TcpSocketBuf) -> Result {
  let res =
    if (len > 0) {
      let bytes = sb.read_bytes(len as uint);
      assert bytes.len() == len;
      Data(bytes)
    } else {
      Data(~[])
    };
  assert sb.read_char() == '\r';
  assert sb.read_char() == '\n';
  return res;
}

priv fn parse_list(len: uint, sb: net::tcp::TcpSocketBuf) -> Result {
  let mut list: ~[Result] = ~[];
  for len.times {
    let v =
      match sb.read_char() {
        '$' => parse_bulk(sb),
        ':' => parse_int(sb),
         _  => fail
      };
    list.push(v);
  }
  return List(list);
}

priv fn chop(s: ~str) -> ~str {
  s.slice(0, s.len() - 1)
}

priv fn parse_bulk(sb: net::tcp::TcpSocketBuf) -> Result {
  match int::from_str(chop(sb.read_line())) {
    None => fail,
    Some(-1) => Nil,
    Some(len) if len >= 0 => parse_data(len as uint, sb),
    Some(_) => fail
  }
}

priv fn parse_multi(sb: net::tcp::TcpSocketBuf) -> Result {
  match int::from_str(chop(sb.read_line())) {
    None => fail,
    Some(-1) => Nil,
    Some(0) => List(~[]),
    Some(len) if len >= 0 => parse_list(len as uint, sb),
    Some(_) => fail
  }
}

priv fn parse_int(sb: net::tcp::TcpSocketBuf) -> Result {
  match int::from_str(chop(sb.read_line())) {
    None => fail,
    Some(i) => Int(i)
  }
}

priv fn parse_response(sb: net::tcp::TcpSocketBuf) -> Result {
  match sb.read_char() {
    '$' => parse_bulk(sb),
    '*' => parse_multi(sb),
    '+' => Status(chop(sb.read_line())),
    '-' => Error(chop(sb.read_line())),
    ':' => parse_int(sb),
    _   => fail
  }
}

priv fn cmd_to_str(cmd: ~[~str]) -> ~str {
  let mut res = ~"*";
  str::push_str(&mut res, cmd.len().to_str());
  str::push_str(&mut res, "\r\n");
  for cmd.each |s| {
    str::push_str(&mut res, str::concat(~[~"$", s.len().to_str(), ~"\r\n", *s, ~"\r\n"]));
  }
  res
}

fn query(cmd: ~[~str], sb: net::tcp::TcpSocketBuf) -> Result {
  let cmd = cmd_to_str(cmd);
  //io::println(cmd);
  sb.write_str(cmd);
  let res = parse_response(sb);
  io::println(fmt!("%?", res));
  res
}

fn main() {
  let server_ip_addr = net::ip::v4::parse_addr("127.0.0.1");
  let server_port = 6379;
  let iotask = uv::global_loop::get();
  let connect_result = net::tcp::connect(server_ip_addr, server_port, iotask);
  let sock = result::unwrap(connect_result);
  let sb = net::tcp::socket_buf(sock);

/*  for 10_000.times {
    query(~[~"GET", ~"abc"], sb);
  }
*/

  query(~[~"MULTI"], sb);
  query(~[~"GET", ~"def"], sb);
  query(~[~"INCR", ~"def"], sb);
  query(~[~"INCR", ~"def"], sb);
  query(~[~"GET", ~"def"], sb);
  query(~[~"EXEC"], sb);

  query(~[~"SET", ~"abc", ~"XXX"], sb);
  query(~[~"SET", ~"def", ~"123"], sb);
  query(~[~"GET", ~"abc"], sb);
  query(~[~"MGET", ~"abc", ~"def", ~"non"], sb);
}
<commit_msg>TcpSocketBuf -> io::Reader<commit_after>extern mod std;

use std::*;
use io::{ReaderUtil,WriterUtil};

enum Result {
  Nil,
  Int(int),
  Data(~[u8]),
  List(~[Result]),
  Error(~str),
  Status(~str)
}

priv fn parse_data(len: uint, io: io::Reader) -> Result {
  let res =
    if (len > 0) {
      let bytes = io.read_bytes(len as uint);
      assert bytes.len() == len;
      Data(bytes)
    } else {
      Data(~[])
    };
  assert io.read_char() == '\r';
  assert io.read_char() == '\n';
  return res;
}

priv fn parse_list(len: uint, io: io::Reader) -> Result {
  let mut list: ~[Result] = ~[];
  for len.times {
    let v =
      match io.read_char() {
        '$' => parse_bulk(io),
        ':' => parse_int(io),
         _  => fail
      };
    list.push(v);
  }
  return List(list);
}

priv fn chop(s: ~str) -> ~str {
  s.slice(0, s.len() - 1)
}

priv fn parse_bulk(io: io::Reader) -> Result {
  match int::from_str(chop(io.read_line())) {
    None => fail,
    Some(-1) => Nil,
    Some(len) if len >= 0 => parse_data(len as uint, io),
    Some(_) => fail
  }
}

priv fn parse_multi(io: io::Reader) -> Result {
  match int::from_str(chop(io.read_line())) {
    None => fail,
    Some(-1) => Nil,
    Some(0) => List(~[]),
    Some(len) if len >= 0 => parse_list(len as uint, io),
    Some(_) => fail
  }
}

priv fn parse_int(io: io::Reader) -> Result {
  match int::from_str(chop(io.read_line())) {
    None => fail,
    Some(i) => Int(i)
  }
}

priv fn parse_response(io: io::Reader) -> Result {
  match io.read_char() {
    '$' => parse_bulk(io),
    '*' => parse_multi(io),
    '+' => Status(chop(io.read_line())),
    '-' => Error(chop(io.read_line())),
    ':' => parse_int(io),
    _   => fail
  }
}

priv fn cmd_to_str(cmd: ~[~str]) -> ~str {
  let mut res = ~"*";
  str::push_str(&mut res, cmd.len().to_str());
  str::push_str(&mut res, "\r\n");
  for cmd.each |s| {
    str::push_str(&mut res, str::concat(~[~"$", s.len().to_str(), ~"\r\n", *s, ~"\r\n"]));
  }
  res
}

fn query(cmd: ~[~str], sb: net::tcp::TcpSocketBuf) -> Result {
  let cmd = cmd_to_str(cmd);
  sb.write_str(cmd);
  let res = parse_response(sb as io::Reader);
  //io::println(fmt!("%?", res));
  res
}

fn main() {
  let server_ip_addr = net::ip::v4::parse_addr("127.0.0.1");
  let server_port = 6379;
  let iotask = uv::global_loop::get();
  let connect_result = net::tcp::connect(server_ip_addr, server_port, iotask);
  let sock = result::unwrap(connect_result);
  let sb = net::tcp::socket_buf(sock);

  query(~[~"MULTI"], sb);
  query(~[~"GET", ~"def"], sb);
  query(~[~"INCR", ~"def"], sb);
  query(~[~"INCR", ~"def"], sb);
  query(~[~"GET", ~"def"], sb);
  query(~[~"EXEC"], sb);

  query(~[~"SET", ~"abc", ~"XXX"], sb);
  query(~[~"SET", ~"def", ~"123"], sb);
  query(~[~"GET", ~"abc"], sb);
  query(~[~"MGET", ~"abc", ~"def", ~"non"], sb);
}
<|endoftext|>