<commit_before>//#![deny(missing_docs)]

//! # Capsize
//!
//! Capsize provides conversions between units of capacity,
//! similar in nature to [Duration](https://doc.rust-lang.org/std/time/duration/), which provides conversions between units of time.
//!
//! All conversions are represented as an `i64` by default.
//!
//! This crate also provides FromStr implementations that parse values "1k" into
//! their corresponding capacity in `i64` format in bytes.

use std::convert::Into;
use std::str::FromStr;

const BYTE: i64     = 1;
const KILOBYTE: i64 = BYTE     << 10;
const MEGABYTE: i64 = KILOBYTE << 10;
const GIGABYTE: i64 = MEGABYTE << 10;
const TERABYTE: i64 = GIGABYTE << 10;
const PETABYTE: i64 = TERABYTE << 10;
const EXABYTE: i64  = PETABYTE << 10;

macro_rules! map(
  { $($key:expr => $value:expr),+ } => {
    {
      let mut m = ::std::collections::HashMap::new();
      $(
        m.insert($key, $value);
        )+
        m
    }
  };
);

/// Capacity provides a simple way to convert
/// values to corresponding units of capacity
pub trait Capacity {

  /// size in bytes
  fn bytes(&self) -> i64;

  /// size in kilobytes
  fn kilobytes(&self) -> i64 {
    self.bytes().rotate_left(10)
  }

  /// size in megabytes
  fn megabytes(&self) -> i64 {
    self.kilobytes().rotate_left(10)
  }

  /// size in gigabytes
  fn gigabytes(&self) -> i64 {
    self.megabytes().rotate_left(10)
  }

  /// size in terabytes
  fn terabytes(&self) -> i64 {
    self.gigabytes().rotate_left(10)
  }

  /// size in petabytes
  fn petabytes(&self) -> i64 {
    self.terabytes().rotate_left(10)
  }

  /// size in exabytes
  fn exabytes(&self) -> i64 {
    self.petabytes().rotate_left(10)
  }

  /// size as a human readable string
  fn capacity(&self) -> String {
    match self.bytes() {
      small if small < KILOBYTE =>
        stringify!(small).to_owned(),
      large => {
        let units = vec![
          ('E', EXABYTE),
          ('P', PETABYTE),
          ('T', TERABYTE),
          ('G', GIGABYTE),
          ('M', MEGABYTE),
          ('K', KILOBYTE)
        ];
        for (suffix, size) in units {
          if large == size {
            return format!("1{}", suffix)
          } else if large > size {
            let sized = (large as f64) / (size as f64);
            let round = (sized * 100.0).round() / 100.0;
            return format!("{:.1}{}", round, suffix)
          }
        }
        unreachable!()
      }
    }
  }
}

impl Capacity for i64 {
  fn bytes(&self) -> i64 {
    *self
  }
}

impl Capacity for Bytes {
  fn bytes(&self) -> i64 {
    (*self).size
  }
}

/// Bytes is a simple type
/// to extract a capacity size, in bytes,
/// from a string value
#[derive(Debug)]
pub struct Bytes {
  size: i64
}

impl Into<Bytes> for i64 {
  fn into(self) -> Bytes {
    Bytes { size: self }
  }
}

impl FromStr for Bytes {
  type Err = String;
  fn from_str(s: &str) -> Result<Bytes, String> {
    let units = map!(
      'E' => EXABYTE,
      'P' => PETABYTE,
      'T' => TERABYTE,
      'G' => GIGABYTE,
      'M' => MEGABYTE,
      'K' => KILOBYTE
    );
    if s.len() > 1 {
      let last = s.chars().last().unwrap();
      match units.get(&last) {
        Some(unit) => {
          let init: String = s.chars().take(s.chars().count() - 1).collect();
          init.parse::<i64>().map(|lit| {
            Bytes { size: lit * unit }
          }).or_else(|_| Err(s.to_owned()))
        },
        _ => {
          Err(s.to_owned())
        }
      }
    } else {
      s.parse::<i64>().map(|lit| {
        Bytes { size: lit }
      }).or_else(|_| Err(s.to_owned()))
    }
  }
}

#[test]
fn test_bytes() {
  assert_eq!(1.bytes(), 1);
}

#[test]
fn test_kilobytes() {
  assert_eq!(1.kilobytes(), 1024)
}

#[test]
fn test_megabytes() {
  assert_eq!(1.megabytes(), 1048576)
}

#[test]
fn test_gigabytes() {
  assert_eq!(1.gigabytes(), 1073741824)
}

#[test]
fn test_terabytes() {
  assert_eq!(1.terabytes(), 1099511627776)
}

#[test]
fn test_petabytes() {
  assert_eq!(1.petabytes(), 1125899906842624)
}

#[test]
fn test_exabytes() {
  assert_eq!(1.exabytes(), 1152921504606846976)
}

#[test]
fn test_kilobytes_capactity() {
  let half = 1.kilobytes() / 2;
  assert_eq!((1.kilobytes() + half).capacity(), "1.5K".to_owned())
}

#[test]
fn test_megabytes_capactity() {
  let half = 1.megabytes() / 2;
  assert_eq!((1.megabytes() + half).capacity(), "1.5M".to_owned())
}

#[test]
fn test_gigabytes_capactity() {
  let half = 1.gigabytes() / 2;
  assert_eq!((1.gigabytes() + half).capacity(), "1.5G".to_owned())
}

#[test]
fn test_terabytes_capactity() {
  let half = 1.terabytes() / 2;
  assert_eq!((1.terabytes() + half).capacity(), "1.5T".to_owned())
}

#[test]
fn test_petabytes_capactity() {
  let half = 1.petabytes() / 2;
  assert_eq!((1.petabytes() + half).capacity(), "1.5P".to_owned())
}

#[test]
fn test_exabytes_capactity() {
  let half = 1.exabytes() / 2;
  assert_eq!((1.exabytes() + half).capacity(), "1.5E".to_owned())
}

#[test]
fn test_kilobytes_parse() {
  let cap: String = 1.kilobytes().capacity();
  let bytes = cap.parse::<Bytes>().ok().unwrap();
  assert_eq!(bytes.size.capacity(), cap)
}
<commit_msg>don't need to reach for size here<commit_after>//#![deny(missing_docs)]

//! # Capsize
//!
//! Capsize provides conversions between units of capacity,
//! similar in nature to [Duration](https://doc.rust-lang.org/std/time/duration/), which provides conversions between units of time.
//!
//! All conversions are represented as an `i64` by default.
//!
//! This crate also provides FromStr implementations that parse values "1k" into
//! their corresponding capacity in `i64` format in bytes.

use std::convert::Into;
use std::str::FromStr;

const BYTE: i64     = 1;
const KILOBYTE: i64 = BYTE     << 10;
const MEGABYTE: i64 = KILOBYTE << 10;
const GIGABYTE: i64 = MEGABYTE << 10;
const TERABYTE: i64 = GIGABYTE << 10;
const PETABYTE: i64 = TERABYTE << 10;
const EXABYTE: i64  = PETABYTE << 10;

macro_rules! map(
  { $($key:expr => $value:expr),+ } => {
    {
      let mut m = ::std::collections::HashMap::new();
      $(
        m.insert($key, $value);
        )+
        m
    }
  };
);

/// Capacity provides a simple way to convert
/// values to corresponding units of capacity
pub trait Capacity {

  /// size in bytes
  fn bytes(&self) -> i64;

  /// size in kilobytes
  fn kilobytes(&self) -> i64 {
    self.bytes().rotate_left(10)
  }

  /// size in megabytes
  fn megabytes(&self) -> i64 {
    self.kilobytes().rotate_left(10)
  }

  /// size in gigabytes
  fn gigabytes(&self) -> i64 {
    self.megabytes().rotate_left(10)
  }

  /// size in terabytes
  fn terabytes(&self) -> i64 {
    self.gigabytes().rotate_left(10)
  }

  /// size in petabytes
  fn petabytes(&self) -> i64 {
    self.terabytes().rotate_left(10)
  }

  /// size in exabytes
  fn exabytes(&self) -> i64 {
    self.petabytes().rotate_left(10)
  }

  /// size as a human readable string
  fn capacity(&self) -> String {
    match self.bytes() {
      small if small < KILOBYTE =>
        stringify!(small).to_owned(),
      large => {
        let units = vec![
          ('E', EXABYTE),
          ('P', PETABYTE),
          ('T', TERABYTE),
          ('G', GIGABYTE),
          ('M', MEGABYTE),
          ('K', KILOBYTE)
        ];
        for (suffix, size) in units {
          if large == size {
            return format!("1{}", suffix)
          } else if large > size {
            let sized = (large as f64) / (size as f64);
            let round = (sized * 100.0).round() / 100.0;
            return format!("{:.1}{}", round, suffix)
          }
        }
        unreachable!()
      }
    }
  }
}

impl Capacity for i64 {
  fn bytes(&self) -> i64 {
    *self
  }
}

impl Capacity for Bytes {
  fn bytes(&self) -> i64 {
    (*self).size
  }
}

/// Bytes is a simple type
/// to extract a capacity size, in bytes,
/// from a string value
#[derive(Debug)]
pub struct Bytes {
  size: i64
}

impl Into<Bytes> for i64 {
  fn into(self) -> Bytes {
    Bytes { size: self }
  }
}

impl FromStr for Bytes {
  type Err = String;
  fn from_str(s: &str) -> Result<Bytes, String> {
    let units = map!(
      'E' => EXABYTE,
      'P' => PETABYTE,
      'T' => TERABYTE,
      'G' => GIGABYTE,
      'M' => MEGABYTE,
      'K' => KILOBYTE
    );
    if s.len() > 1 {
      let last = s.chars().last().unwrap();
      match units.get(&last) {
        Some(unit) => {
          let init: String = s.chars().take(s.chars().count() - 1).collect();
          init.parse::<i64>().map(|lit| {
            Bytes { size: lit * unit }
          }).or_else(|_| Err(s.to_owned()))
        },
        _ => {
          Err(s.to_owned())
        }
      }
    } else {
      s.parse::<i64>().map(|lit| {
        Bytes { size: lit }
      }).or_else(|_| Err(s.to_owned()))
    }
  }
}

#[test]
fn test_bytes() {
  assert_eq!(1.bytes(), 1);
}

#[test]
fn test_kilobytes() {
  assert_eq!(1.kilobytes(), 1024)
}

#[test]
fn test_megabytes() {
  assert_eq!(1.megabytes(), 1048576)
}

#[test]
fn test_gigabytes() {
  assert_eq!(1.gigabytes(), 1073741824)
}

#[test]
fn test_terabytes() {
  assert_eq!(1.terabytes(), 1099511627776)
}

#[test]
fn test_petabytes() {
  assert_eq!(1.petabytes(), 1125899906842624)
}

#[test]
fn test_exabytes() {
  assert_eq!(1.exabytes(), 1152921504606846976)
}

#[test]
fn test_kilobytes_capactity() {
  let half = 1.kilobytes() / 2;
  assert_eq!((1.kilobytes() + half).capacity(), "1.5K".to_owned())
}

#[test]
fn test_megabytes_capactity() {
  let half = 1.megabytes() / 2;
  assert_eq!((1.megabytes() + half).capacity(), "1.5M".to_owned())
}

#[test]
fn test_gigabytes_capactity() {
  let half = 1.gigabytes() / 2;
  assert_eq!((1.gigabytes() + half).capacity(), "1.5G".to_owned())
}

#[test]
fn test_terabytes_capactity() {
  let half = 1.terabytes() / 2;
  assert_eq!((1.terabytes() + half).capacity(), "1.5T".to_owned())
}

#[test]
fn test_petabytes_capactity() {
  let half = 1.petabytes() / 2;
  assert_eq!((1.petabytes() + half).capacity(), "1.5P".to_owned())
}

#[test]
fn test_exabytes_capactity() {
  let half = 1.exabytes() / 2;
  assert_eq!((1.exabytes() + half).capacity(), "1.5E".to_owned())
}

#[test]
fn test_kilobytes_parse() {
  let cap: String = 1.kilobytes().capacity();
  let bytes = cap.parse::<Bytes>().ok().unwrap();
  assert_eq!(bytes.capacity(), cap)
}
<|endoftext|>


<commit_before>/*!
# nalgebra

[![Build Status](https://travis-ci.org/sebcrozet/nalgebra.png?branch=master)](https://travis-ci.org/sebcrozet/nalgebra)

**nalgebra** is a linear algebra library written for Rust targeting:

* general-purpose linear algebra (still misses a lot of features…).
* real time computer graphics.
* real time computer physics.

An on-line version of this documentation is available [here](http://crozet.re/nalgebra/index.html).

## Using **nalgebra**
All the functionalities of **nalgebra** are grouped in one place: the `na` module.
This module re-exports everything and includes free functions for all traits methods doing
out-of-place modifications.

* You can import the whole prelude, including free functions, using:

```.rust
use nalgebra::na::*;
```

* If you dont want to import everything but only every trait:

```.rust
use nalgebra::traits::*;
```

* If you dont want to import everything but only every structure:

```.rust
use nalgebra::structs::*;
```
The preffered way to use **nalgebra** is to import types and traits explicitly, and call
free-functions using the `na::` prefix:

```.rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Rot3, Rotation};
use nalgebra::na;

fn main() {
    let     a = Vec3::new(1.0f64, 1.0, 1.0);
    let mut b = Rot3::new(na::zero());

    b.append_rotation(&a);

    assert!(na::rotation(&b).approx_eq(&a));
}
```

## Features
**nalgebra** is meant to be a general-purpose linear algebra library (but is very far from that…),
and keeps an optimized set of tools for computational graphics and physics. Those features include:

* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
* Isometries: `Iso2`, `Iso3`, `Iso4`.
* Dynamically sized vector: `DVec`.
* Dynamically sized (square or rectangular) matrix: `DMat`.
* A few methods for data analysis: `Cov`, `Mean`.
* Almost one trait per functionality: useful for generic programming.
* Operator overloading using the double trait dispatch
  [trick](http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/).
  For example, the following works:

```rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Mat3};
use nalgebra::na;

fn main() {
    let v: Vec3<f64> = na::zero();
    let m: Mat3<f64> = na::one();

    let _ = m * v;   // matrix-vector multiplication.
    let _ = v * m;   // vector-matrix multiplication.
    let _ = m * m;   // matrix-matrix multiplication.
    let _ = v * 2.0; // vector-scalar multiplication.
}
```

## Compilation
You will need the last rust compiler from the master branch.
If you encounter problems, make sure you have the last version before creating an issue.

    git clone git://github.com/sebcrozet/nalgebra.git
    cd nalgebra
    make

You can build the documentation on the `doc` folder using:

```.rust
make doc
```

## **nalgebra** in use
Here are some projects using **nalgebra**.
Feel free to add your project to this list if you happen to use **nalgebra**!

* [nphysics](https://github.com/sebcrozet/nphysics): a real-time physics engine.
* [ncollide](https://github.com/sebcrozet/ncollide): a collision detection library.
* [kiss3d](https://github.com/sebcrozet/kiss3d): a minimalistic graphics engine.
* [frog](https://github.com/natal/frog): a machine learning library.

*/
#[link(name = "nalgebra"
       , vers = "0.1"
       , author = "Sébastien Crozet"
       , uuid = "1e96070f-4778-4ec1-b080-bf69f7048216"
       , url = "https://gitub.com/sebcrozet/nalgebra.git")];
#[crate_id = "github.com/sebcrozet/nalgebra"];
#[crate_type = "lib"];
#[deny(non_camel_case_types)];
#[deny(non_uppercase_statics)];
#[deny(unnecessary_qualification)];
#[warn(missing_doc)];
#[feature(macro_rules)];

extern mod std;
extern mod extra;

pub mod na;
pub mod structs;
pub mod traits;

// mod lower_triangular;
// mod chol;

#[cfg(test)]
mod tests {
    mod vec;
    mod mat;
}

#[cfg(test)]
mod bench {
    mod vec;
    mod mat;
}
<commit_msg>Update to the last Rust.<commit_after>/*!
# nalgebra

[![Build Status](https://travis-ci.org/sebcrozet/nalgebra.png?branch=master)](https://travis-ci.org/sebcrozet/nalgebra)

**nalgebra** is a linear algebra library written for Rust targeting:

* general-purpose linear algebra (still misses a lot of features…).
* real time computer graphics.
* real time computer physics.

An on-line version of this documentation is available [here](http://crozet.re/nalgebra/index.html).

## Using **nalgebra**
All the functionalities of **nalgebra** are grouped in one place: the `na` module.
This module re-exports everything and includes free functions for all traits methods doing
out-of-place modifications.

* You can import the whole prelude, including free functions, using:

```.rust
use nalgebra::na::*;
```

* If you dont want to import everything but only every trait:

```.rust
use nalgebra::traits::*;
```

* If you dont want to import everything but only every structure:

```.rust
use nalgebra::structs::*;
```
The preffered way to use **nalgebra** is to import types and traits explicitly, and call
free-functions using the `na::` prefix:

```.rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Rot3, Rotation};
use nalgebra::na;

fn main() {
    let     a = Vec3::new(1.0f64, 1.0, 1.0);
    let mut b = Rot3::new(na::zero());

    b.append_rotation(&a);

    assert!(na::rotation(&b).approx_eq(&a));
}
```

## Features
**nalgebra** is meant to be a general-purpose linear algebra library (but is very far from that…),
and keeps an optimized set of tools for computational graphics and physics. Those features include:

* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
* Isometries: `Iso2`, `Iso3`, `Iso4`.
* Dynamically sized vector: `DVec`.
* Dynamically sized (square or rectangular) matrix: `DMat`.
* A few methods for data analysis: `Cov`, `Mean`.
* Almost one trait per functionality: useful for generic programming.
* Operator overloading using the double trait dispatch
  [trick](http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/).
  For example, the following works:

```rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Mat3};
use nalgebra::na;

fn main() {
    let v: Vec3<f64> = na::zero();
    let m: Mat3<f64> = na::one();

    let _ = m * v;   // matrix-vector multiplication.
    let _ = v * m;   // vector-matrix multiplication.
    let _ = m * m;   // matrix-matrix multiplication.
    let _ = v * 2.0; // vector-scalar multiplication.
}
```

## Compilation
You will need the last rust compiler from the master branch.
If you encounter problems, make sure you have the last version before creating an issue.

    git clone git://github.com/sebcrozet/nalgebra.git
    cd nalgebra
    make

You can build the documentation on the `doc` folder using:

```.rust
make doc
```

## **nalgebra** in use
Here are some projects using **nalgebra**.
Feel free to add your project to this list if you happen to use **nalgebra**!

* [nphysics](https://github.com/sebcrozet/nphysics): a real-time physics engine.
* [ncollide](https://github.com/sebcrozet/ncollide): a collision detection library.
* [kiss3d](https://github.com/sebcrozet/kiss3d): a minimalistic graphics engine.
* [frog](https://github.com/natal/frog): a machine learning library.
*/

#[crate_id = "nalgebra#0.1"];
#[crate_type = "lib"];
#[deny(non_camel_case_types)];
#[deny(non_uppercase_statics)];
#[deny(unnecessary_qualification)];
#[warn(missing_doc)];
#[feature(macro_rules)];

extern mod std;
extern mod extra;

pub mod na;
pub mod structs;
pub mod traits;

// mod lower_triangular;
// mod chol;

#[cfg(test)]
mod tests {
    mod vec;
    mod mat;
}

#[cfg(test)]
mod bench {
    mod vec;
    mod mat;
}
<|endoftext|>


<commit_before>#![feature(fs, io)]

extern crate xml;

use std::ascii::AsciiExt;
use std::default::Default;
use std::iter::IteratorExt;
use std::io;
use xml::{Element, ElementBuilder, Parser, Xml};

fn elem_with_text(tag_name: &'static str, chars: &str) -> Element {
    let mut elem = Element::new(tag_name, None, &[]);
    elem.text(chars);
    elem
}

trait ViaXml {
    fn to_xml(&self) -> Element;
    fn from_xml(element: Element) -> Result<Self, &'static str>;
}

/// RSS
///
/// "At the top level, a RSS document is a \<rss\> element, with a mandatory attribute called
/// version, that specifies the version of RSS that the document conforms to. If it conforms to
/// this specification, the version attribute must be 2.0."
///
/// [RSS 2.0 Specification § RSS]
/// (http://cyber.law.harvard.edu/rss/rss.html#whatIsRss)
#[derive(Default)]
pub struct Rss(pub Channel);

impl ViaXml for Rss {
    fn to_xml(&self) -> Element {
        let mut rss = Element::new("rss", None, &[("version", None, "2.0")]);

        let &Rss(ref channel) = self;
        rss.tag(channel.to_xml());

        rss
    }

    fn from_xml(element: Element) -> Result<Self, &'static str> {
        if element.name.to_ascii_lowercase() != "rss" {
            panic!("Expected <rss>, found <{}>", element.name);
        }

        let channel_element = element.get_child("channel", None).unwrap();
        let channel = try!(ViaXml::from_xml(channel_element.clone()));

        Ok(Rss(channel))
    }
}

impl Rss {
    fn to_string(&self) -> String {
        let mut ret = format!("{}", Xml::PINode("xml version='1.0' encoding='UTF-8'".to_string()));
        ret.push_str(&format!("{}", self.to_xml()));
        ret
    }

    fn from_read(reader: &mut io::Read) -> Result<Self, &'static str> {
        let mut rss_string = String::new();

        match reader.read_to_string(&mut rss_string) {
            Ok(..) => (),
            Err(..) => return Err("Error reading string from reader"),
        }

        let mut parser = Parser::new();
        parser.feed_str(&rss_string);

        let mut builder = ElementBuilder::new();

        for event in parser {
            match builder.push_event(event) {
                Ok(Some(element)) => return ViaXml::from_xml(element),
                _ => (),
            }
        }

        Err("RSS read error")
    }
}

/// Channel
///
/// "Subordinate to the \<rss\> element is a single \<channel\> element, which contains information
/// about the channel (metadata) and its contents."
///
/// [RSS 2.0 Specification § Channel]
/// (http://cyber.law.harvard.edu/rss/rss.html#requiredChannelElements)
///
/// ## Examples
///
/// ```
/// use rss::Channel;
///
/// let channel = Channel {
///     title: "My Blog".to_string(),
///     link: "http://myblog.com".to_string(),
///     description: "Where I write stuff".to_string(),
///     items: vec![],
/// };
/// ```
#[derive(Default)]
pub struct Channel {
    pub title: String,
    pub link: String,
    pub description: String,
    pub items: Vec<Item>,
    // pub language: Option<String>,
    // pub copyright: Option<String>,
    // pub managing_editor: Option<String>,
    // pub web_master: Option<String>,
    // pub pub_date: Option<String>,
    // pub last_build_date: Option<String>,
    // pub category:
    // pub generator: Option<String>,
    // pub docs: Option<String>,
    // pub cloud:
    // pub ttl:
    // pub image: Option<String>,
    // pub rating: Option<String>,
    // pub text_input:
    // pub skip_hours: Option<String>,
    // pub skip_days: Option<String>,
}

impl ViaXml for Channel {
    fn to_xml(&self) -> Element {
        let mut channel = Element::new("channel", None, &[]);

        channel.tag(elem_with_text("title", &self.title));
        channel.tag(elem_with_text("link", &self.link));
        channel.tag(elem_with_text("description", &self.description));

        for item in &self.items {
            channel.tag(item.to_xml());
        }

        channel
    }

    fn from_xml(element: Element) -> Result<Self, &'static str> {
        let mut channel: Channel = Default::default();

        match element.get_child("title", None) {
            Some(element) => channel.title = element.content_str(),
            None => return Err("<channel> is missing required <title> element"),
        }

        match element.get_child("link", None) {
            Some(element) => channel.link = element.content_str(),
            None => return Err("<channel> is missing required <link> element"),
        }

        match element.get_child("description", None) {
            Some(element) => channel.description = element.content_str(),
            None => return Err("<channel> is missing required <description> element"),
        }

        channel.items = element.get_children("item", None)
            .into_iter()
            .map(|e| ViaXml::from_xml(e.clone()).unwrap())
            .collect();

        Ok(channel)
    }
}

#[derive(Default)]
pub struct Item {
    pub title: Option<String>,
    pub link: Option<String>,
    pub description: Option<String>,
    // pub author
    // pub category
    // pub comments
    // pub enclosure
    // pub guid
    // pub pubDate
    // pub source
}

impl ViaXml for Item {
    fn to_xml(&self) -> Element {
        let mut item = Element::new("item", None, &[]);

        if let Some(ref s) = self.title {
            item.tag(elem_with_text("title", s));
        }

        if let Some(ref s) = self.link {
            item.tag(elem_with_text("link", s));
        }

        if let Some(ref s) = self.description {
            item.tag(elem_with_text("description", s));
        }

        item
    }

    fn from_xml(element: Element) -> Result<Self, &'static str> {
        let mut item: Item = Default::default();

        match element.get_child("title", None) {
            Some(element) => item.title = Some(element.content_str()),
            None => (),
        }

        match element.get_child("link", None) {
            Some(element) => item.link = Some(element.content_str()),
            None => (),
        }

        match element.get_child("description", None) {
            Some(element) => item.description = Some(element.content_str()),
            None => (),
        }

        Ok(item)
    }
}

#[cfg(test)]
mod test {
    use std::fs::File;
    use super::{Rss, Item, Channel};

    #[test]
    fn test_basic_to_string() {
        let item = Item {
            title: Some("My first post!".to_string()),
            link: Some("http://myblog.com/post1".to_string()),
            description: Some("This is my first post".to_string()),
        };

        let channel = Channel {
            title: "My Blog".to_string(),
            link: "http://myblog.com".to_string(),
            description: "Where I write stuff".to_string(),
            items: vec![item],
        };

        let rss = Rss(channel);
        assert_eq!(rss.to_string(), "<?xml version=\'1.0\' encoding=\'UTF-8\'?><rss version=\'2.0\'><channel><title>My Blog</title><link>http://myblog.com</link><description>Where I write stuff</description><item><title>My first post!</title><link>http://myblog.com/post1</link><description>This is my first post</description></item></channel></rss>");
    }

    #[test]
    fn test_from_file() {
        let mut file = File::open("test-data/pinboard.xml").unwrap();
        let Rss(_) = Rss::from_read(&mut file).unwrap();
    }

    #[test]
    #[should_fail]
    fn test_from_read_no_channels() {
        let mut rss_bytes = "<rss></rss>".as_bytes();
        let Rss(_) = Rss::from_read(&mut rss_bytes).unwrap();
    }

    #[test]
    #[should_fail]
    fn test_from_read_one_channel() {
        let mut rss_bytes = "<rss><channel></channel></rss>".as_bytes();
        let Rss(_) = Rss::from_read(&mut rss_bytes).unwrap();
    }

    #[test]
    fn test_from_read_one_channel_with_title() {
        let mut rss_bytes = "<rss><channel><title>Hello world!</title><description></description><link></link></channel></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes).unwrap();
        assert_eq!("Hello world!", channel.title);
    }
}
<commit_msg>Better variable names, fewer panics<commit_after>#![feature(fs, io)]

extern crate xml;

use std::ascii::AsciiExt;
use std::default::Default;
use std::iter::IteratorExt;
use std::io;
use xml::{Element, ElementBuilder, Parser, Xml};

fn elem_with_text(tag_name: &'static str, chars: &str) -> Element {
    let mut elem = Element::new(tag_name, None, &[]);
    elem.text(chars);
    elem
}

trait ViaXml {
    fn to_xml(&self) -> Element;
    fn from_xml(element: Element) -> Result<Self, &'static str>;
}

/// RSS
///
/// "At the top level, a RSS document is a \<rss\> element, with a mandatory attribute called
/// version, that specifies the version of RSS that the document conforms to. If it conforms to
/// this specification, the version attribute must be 2.0."
///
/// [RSS 2.0 Specification § RSS]
/// (http://cyber.law.harvard.edu/rss/rss.html#whatIsRss)
#[derive(Default)]
pub struct Rss(pub Channel);

impl ViaXml for Rss {
    fn to_xml(&self) -> Element {
        let mut rss = Element::new("rss", None, &[("version", None, "2.0")]);

        let &Rss(ref channel) = self;
        rss.tag(channel.to_xml());

        rss
    }

    fn from_xml(rss_elem: Element) -> Result<Self, &'static str> {
        if rss_elem.name.to_ascii_lowercase() != "rss" {
            panic!("Expected <rss>, found <{}>", rss_elem.name);
        }

        let channel_elem = match rss_elem.get_child("channel", None) {
            Some(elem) => elem,
            None => return Err("No <channel> element found in <rss>"),
        };

        let channel = try!(ViaXml::from_xml(channel_elem.clone()));

        Ok(Rss(channel))
    }
}

impl Rss {
    fn to_string(&self) -> String {
        let mut ret = format!("{}", Xml::PINode("xml version='1.0' encoding='UTF-8'".to_string()));
        ret.push_str(&format!("{}", self.to_xml()));
        ret
    }

    fn from_read(reader: &mut io::Read) -> Result<Self, &'static str> {
        let mut rss_string = String::new();

        match reader.read_to_string(&mut rss_string) {
            Ok(..) => (),
            Err(..) => return Err("Error reading string from reader"),
        }

        let mut parser = Parser::new();
        parser.feed_str(&rss_string);

        let mut builder = ElementBuilder::new();

        for event in parser {
            match builder.push_event(event) {
                Ok(Some(element)) => return ViaXml::from_xml(element),
                _ => (),
            }
        }

        Err("RSS read error")
    }
}

/// Channel
///
/// "Subordinate to the \<rss\> element is a single \<channel\> element, which contains information
/// about the channel (metadata) and its contents."
///
/// [RSS 2.0 Specification § Channel]
/// (http://cyber.law.harvard.edu/rss/rss.html#requiredChannelElements)
///
/// ## Examples
///
/// ```
/// use rss::Channel;
///
/// let channel = Channel {
///     title: "My Blog".to_string(),
///     link: "http://myblog.com".to_string(),
///     description: "Where I write stuff".to_string(),
///     items: vec![],
/// };
/// ```
#[derive(Default)]
pub struct Channel {
    pub title: String,
    pub link: String,
    pub description: String,
    pub items: Vec<Item>,
    // pub language: Option<String>,
    // pub copyright: Option<String>,
    // pub managing_editor: Option<String>,
    // pub web_master: Option<String>,
    // pub pub_date: Option<String>,
    // pub last_build_date: Option<String>,
    // pub category:
    // pub generator: Option<String>,
    // pub docs: Option<String>,
    // pub cloud:
    // pub ttl:
    // pub image: Option<String>,
    // pub rating: Option<String>,
    // pub text_input:
    // pub skip_hours: Option<String>,
    // pub skip_days: Option<String>,
}

impl ViaXml for Channel {
    fn to_xml(&self) -> Element {
        let mut channel = Element::new("channel", None, &[]);

        channel.tag(elem_with_text("title", &self.title));
        channel.tag(elem_with_text("link", &self.link));
        channel.tag(elem_with_text("description", &self.description));

        for item in &self.items {
            channel.tag(item.to_xml());
        }

        channel
    }

    fn from_xml(element: Element) -> Result<Self, &'static str> {
        let mut channel: Channel = Default::default();

        match element.get_child("title", None) {
            Some(element) => channel.title = element.content_str(),
            None => return Err("<channel> is missing required <title> element"),
        }

        match element.get_child("link", None) {
            Some(element) => channel.link = element.content_str(),
            None => return Err("<channel> is missing required <link> element"),
        }

        match element.get_child("description", None) {
            Some(element) => channel.description = element.content_str(),
            None => return Err("<channel> is missing required <description> element"),
        }

        channel.items = element.get_children("item", None)
            .into_iter()
            .map(|e| ViaXml::from_xml(e.clone()).unwrap())
            .collect();

        Ok(channel)
    }
}

#[derive(Default)]
pub struct Item {
    pub title: Option<String>,
    pub link: Option<String>,
    pub description: Option<String>,
    // pub author
    // pub category
    // pub comments
    // pub enclosure
    // pub guid
    // pub pubDate
    // pub source
}

impl ViaXml for Item {
    fn to_xml(&self) -> Element {
        let mut item = Element::new("item", None, &[]);

        if let Some(ref s) = self.title {
            item.tag(elem_with_text("title", s));
        }

        if let Some(ref s) = self.link {
            item.tag(elem_with_text("link", s));
        }

        if let Some(ref s) = self.description {
            item.tag(elem_with_text("description", s));
        }

        item
    }

    fn from_xml(element: Element) -> Result<Self, &'static str> {
        let mut item: Item = Default::default();

        match element.get_child("title", None) {
            Some(element) => item.title = Some(element.content_str()),
            None => (),
        }

        match element.get_child("link", None) {
            Some(element) => item.link = Some(element.content_str()),
            None => (),
        }

        match element.get_child("description", None) {
            Some(element) => item.description = Some(element.content_str()),
            None => (),
        }

        Ok(item)
    }
}

#[cfg(test)]
mod test {
    use std::fs::File;
    use super::{Rss, Item, Channel};

    #[test]
    fn test_basic_to_string() {
        let item = Item {
            title: Some("My first post!".to_string()),
            link: Some("http://myblog.com/post1".to_string()),
            description: Some("This is my first post".to_string()),
        };

        let channel = Channel {
            title: "My Blog".to_string(),
            link: "http://myblog.com".to_string(),
            description: "Where I write stuff".to_string(),
            items: vec![item],
        };

        let rss = Rss(channel);
        assert_eq!(rss.to_string(), "<?xml version=\'1.0\' encoding=\'UTF-8\'?><rss version=\'2.0\'><channel><title>My Blog</title><link>http://myblog.com</link><description>Where I write stuff</description><item><title>My first post!</title><link>http://myblog.com/post1</link><description>This is my first post</description></item></channel></rss>");
    }

    #[test]
    fn test_from_file() {
        let mut file = File::open("test-data/pinboard.xml").unwrap();
        let Rss(_) = Rss::from_read(&mut file).unwrap();
    }

    #[test]
    #[should_fail]
    fn test_from_read_no_channels() {
        let mut rss_bytes = "<rss></rss>".as_bytes();
        let Rss(_) = Rss::from_read(&mut rss_bytes).unwrap();
    }

    #[test]
    #[should_fail]
    fn test_from_read_one_channel() {
        let mut rss_bytes = "<rss><channel></channel></rss>".as_bytes();
        let Rss(_) = Rss::from_read(&mut rss_bytes).unwrap();
    }

    #[test]
    fn test_from_read_one_channel_with_title() {
        let mut rss_bytes = "<rss><channel><title>Hello world!</title><description></description><link></link></channel></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes).unwrap();
        assert_eq!("Hello world!", channel.title);
    }
}
<|endoftext|>


<commit_before>extern crate conduit;

use std::error::Error;

use conduit::{Handler, Request, Response};

pub trait Middleware: Send + Sync + 'static {
    fn before(&self, _: &mut dyn Request) -> Result<(), Box<dyn Error + Send>> {
        Ok(())
    }

    fn after(
        &self,
        _: &mut dyn Request,
        res: Result<Response, Box<dyn Error + Send>>,
    ) -> Result<Response, Box<dyn Error + Send>> {
        res
    }
}

pub trait AroundMiddleware: Handler {
    fn with_handler(&mut self, handler: Box<dyn Handler>);
}

pub struct MiddlewareBuilder {
    middlewares: Vec<Box<dyn Middleware>>,
    handler: Option<Box<dyn Handler>>,
}

impl MiddlewareBuilder {
    pub fn new<H: Handler>(handler: H) -> MiddlewareBuilder {
        MiddlewareBuilder {
            middlewares: vec![],
            handler: Some(Box::new(handler) as Box<dyn Handler>),
        }
    }

    pub fn add<M: Middleware>(&mut self, middleware: M) {
        self.middlewares
            .push(Box::new(middleware) as Box<dyn Middleware>);
    }

    pub fn around<M: AroundMiddleware>(&mut self, mut middleware: M) {
        let handler = self.handler.take().unwrap();
        middleware.with_handler(handler);
        self.handler = Some(Box::new(middleware) as Box<dyn Handler>);
    }
}

impl Handler for MiddlewareBuilder {
    fn call(&self, req: &mut dyn Request) -> Result<Response, Box<dyn Error + Send>> {
        let mut error = None;

        for (i, middleware) in self.middlewares.iter().enumerate() {
            match middleware.before(req) {
                Ok(_) => (),
                Err(err) => {
                    error = Some((err, i));
                    break;
                }
            }
        }

        match error {
            Some((err, i)) => {
                let middlewares = &self.middlewares[..i];
                run_afters(middlewares, req, Err(err))
            }
            None => {
                let res = { self.handler.as_ref().unwrap().call(req) };
                let middlewares = &self.middlewares;

                run_afters(middlewares, req, res)
            }
        }
    }
}

fn run_afters(
    middleware: &[Box<dyn Middleware>],
    req: &mut dyn Request,
    res: Result<Response, Box<dyn Error + Send>>,
) -> Result<Response, Box<dyn Error + Send>> {
    middleware
        .iter()
        .rev()
        .fold(res, |res, m| m.after(req, res))
}

#[cfg(test)]
mod tests {
    extern crate semver;

    use {AroundMiddleware, Middleware, MiddlewareBuilder};

    use std::any::Any;
    use std::collections::HashMap;
    use std::error::Error;
    use std::io::prelude::*;
    use std::io::{self, Cursor};
    use std::net::SocketAddr;

    use conduit;
    use conduit::{Extensions, Headers, Host, Method, Request, Response, Scheme};
    use conduit::{Handler, TypeMap};

    struct RequestSentinel {
        path: String,
        extensions: TypeMap,
        method: Method,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method: method,
            }
        }
    }

    impl conduit::Request for RequestSentinel {
        fn http_version(&self) -> semver::Version {
            unimplemented!()
        }
        fn conduit_version(&self) -> semver::Version {
            unimplemented!()
        }
        fn method(&self) -> Method {
            self.method.clone()
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host<'a>(&'a self) -> Host<'a> {
            unimplemented!()
        }
        fn virtual_root<'a>(&'a self) -> Option<&'a str> {
            unimplemented!()
        }
        fn path<'a>(&'a self) -> &'a str {
            &self.path
        }
        fn query_string<'a>(&'a self) -> Option<&'a str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers<'a>(&'a self) -> &'a dyn Headers {
            unimplemented!()
        }
        fn body<'a>(&'a mut self) -> &'a mut dyn Read {
            unimplemented!()
        }
        fn extensions<'a>(&'a self) -> &'a Extensions {
            &self.extensions
        }
        fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
            &mut self.extensions
        }
    }

    struct MyMiddleware;

    impl Middleware for MyMiddleware {
        fn before<'a>(&self, req: &'a mut dyn Request) -> Result<(), Box<dyn Error + Send>> {
            req.mut_extensions().insert("hello".to_string());
            Ok(())
        }
    }

    struct ErrorRecovery;

    impl Middleware for ErrorRecovery {
        fn after(
            &self,
            _: &mut dyn Request,
            res: Result<Response, Box<dyn Error + Send>>,
        ) -> Result<Response, Box<dyn Error + Send>> {
            res.or_else(|e| {
                let e = e.to_string();
                Ok(Response {
                    status: (500, "Internal Server Error"),
                    headers: HashMap::new(),
                    body: Box::new(Cursor::new(e.into_bytes())),
                })
            })
        }
    }

    struct ProducesError;

    impl Middleware for ProducesError {
        fn before(&self, _: &mut dyn Request) -> Result<(), Box<dyn Error + Send>> {
            Err(Box::new(io::Error::new(io::ErrorKind::Other, "")))
        }
    }

    struct NotReached;

    impl Middleware for NotReached {
        fn after(
            &self,
            _: &mut dyn Request,
            _: Result<Response, Box<dyn Error + Send>>,
        ) -> Result<Response, Box<dyn Error + Send>> {
            Ok(Response {
                status: (200, "OK"),
                headers: HashMap::new(),
                body: Box::new(Cursor::new(vec![])),
            })
        }
    }

    struct MyAroundMiddleware {
        handler: Option<Box<dyn Handler>>,
    }

    impl MyAroundMiddleware {
        fn new() -> MyAroundMiddleware {
            MyAroundMiddleware { handler: None }
        }
    }

    impl Middleware for MyAroundMiddleware {}

    impl AroundMiddleware for MyAroundMiddleware {
        fn with_handler(&mut self, handler: Box<dyn Handler>) {
            self.handler = Some(handler)
        }
    }

    impl Handler for MyAroundMiddleware {
        fn call(&self, req: &mut dyn Request) -> Result<Response, Box<dyn Error + Send>> {
            req.mut_extensions().insert("hello".to_string());
            self.handler.as_ref().unwrap().call(req)
        }
    }

    fn get_extension<'a, T: Any>(req: &'a dyn Request) -> &'a T {
        req.extensions().find::<T>().unwrap()
    }

    fn response(string: String) -> Response {
        Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: Box::new(Cursor::new(string.into_bytes())),
        }
    }

    fn handler(req: &mut dyn Request) -> io::Result<Response> {
        let hello = get_extension::<String>(req);
        Ok(response(hello.clone()))
    }

    fn error_handler(_: &mut dyn Request) -> io::Result<Response> {
        Err(io::Error::new(io::ErrorKind::Other, "Error in handler"))
    }

    fn middle_handler(req: &mut dyn Request) -> io::Result<Response> {
        let hello = get_extension::<String>(req);
        let middle = get_extension::<String>(req);

        Ok(response(format!("{} {}", hello, middle)))
    }

    #[test]
    fn test_simple_middleware() {
        let mut builder = MiddlewareBuilder::new(handler);
        builder.add(MyMiddleware);

        let mut req = RequestSentinel::new(Method::Get, "/");
        let mut res = builder.call(&mut req).ok().expect("No response");

        let mut s = Vec::new();
        res.body.write_body(&mut s).unwrap();
        assert_eq!(s, b"hello");
    }

    #[test]
    fn test_error_recovery() {
        let mut builder = MiddlewareBuilder::new(handler);
        builder.add(ErrorRecovery);
        builder.add(ProducesError);
        // the error bubbles up from ProducesError and shouldn't reach here
        builder.add(NotReached);

        let mut req = RequestSentinel::new(Method::Get, "/");
        let res = builder.call(&mut req).ok().expect("Error not handled");

        assert_eq!(res.status, (500, "Internal Server Error"));
    }

    #[test]
    fn test_error_recovery_in_handlers() {
        let mut builder = MiddlewareBuilder::new(error_handler);
        builder.add(ErrorRecovery);

        let mut req = RequestSentinel::new(Method::Get, "/");
        let mut res = builder.call(&mut req).ok().expect("Error not handled");

        assert_eq!(res.status, (500, "Internal Server Error"));
        let mut s = Vec::new();
        res.body.write_body(&mut s).unwrap();
        assert_eq!(s, b"Error in handler");
    }

    #[test]
    fn test_around_middleware() {
        let mut builder = MiddlewareBuilder::new(middle_handler);
        builder.add(MyMiddleware);
        builder.around(MyAroundMiddleware::new());

        let mut req = RequestSentinel::new(Method::Get, "/");
        let mut res = builder.call(&mut req).ok().expect("No response");

        let mut s = Vec::new();
        res.body.write_body(&mut s).unwrap();
        assert_eq!(s, b"hello hello");
    }
}
<commit_msg>Enable warnings for 2018 idioms<commit_after>#![warn(rust_2018_idioms)]
extern crate conduit;

use std::error::Error;

use conduit::{Handler, Request, Response};

pub trait Middleware: Send + Sync + 'static {
    fn before(&self, _: &mut dyn Request) -> Result<(), Box<dyn Error + Send>> {
        Ok(())
    }

    fn after(
        &self,
        _: &mut dyn Request,
        res: Result<Response, Box<dyn Error + Send>>,
    ) -> Result<Response, Box<dyn Error + Send>> {
        res
    }
}

pub trait AroundMiddleware: Handler {
    fn with_handler(&mut self, handler: Box<dyn Handler>);
}

pub struct MiddlewareBuilder {
    middlewares: Vec<Box<dyn Middleware>>,
    handler: Option<Box<dyn Handler>>,
}

impl MiddlewareBuilder {
    pub fn new<H: Handler>(handler: H) -> MiddlewareBuilder {
        MiddlewareBuilder {
            middlewares: vec![],
            handler: Some(Box::new(handler) as Box<dyn Handler>),
        }
    }

    pub fn add<M: Middleware>(&mut self, middleware: M) {
        self.middlewares
            .push(Box::new(middleware) as Box<dyn Middleware>);
    }

    pub fn around<M: AroundMiddleware>(&mut self, mut middleware: M) {
        let handler = self.handler.take().unwrap();
        middleware.with_handler(handler);
        self.handler = Some(Box::new(middleware) as Box<dyn Handler>);
    }
}

impl Handler for MiddlewareBuilder {
    fn call(&self, req: &mut dyn Request) -> Result<Response, Box<dyn Error + Send>> {
        let mut error = None;

        for (i, middleware) in self.middlewares.iter().enumerate() {
            match middleware.before(req) {
                Ok(_) => (),
                Err(err) => {
                    error = Some((err, i));
                    break;
                }
            }
        }

        match error {
            Some((err, i)) => {
                let middlewares = &self.middlewares[..i];
                run_afters(middlewares, req, Err(err))
            }
            None => {
                let res = { self.handler.as_ref().unwrap().call(req) };
                let middlewares = &self.middlewares;

                run_afters(middlewares, req, res)
            }
        }
    }
}

fn run_afters(
    middleware: &[Box<dyn Middleware>],
    req: &mut dyn Request,
    res: Result<Response, Box<dyn Error + Send>>,
) -> Result<Response, Box<dyn Error + Send>> {
    middleware
        .iter()
        .rev()
        .fold(res, |res, m| m.after(req, res))
}

#[cfg(test)]
mod tests {
    extern crate semver;

    use {AroundMiddleware, Middleware, MiddlewareBuilder};

    use std::any::Any;
    use std::collections::HashMap;
    use std::error::Error;
    use std::io::prelude::*;
    use std::io::{self, Cursor};
    use std::net::SocketAddr;

    use conduit;
    use conduit::{Extensions, Headers, Host, Method, Request, Response, Scheme};
    use conduit::{Handler, TypeMap};

    struct RequestSentinel {
        path: String,
        extensions: TypeMap,
        method: Method,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method: method,
            }
        }
    }

    impl conduit::Request for RequestSentinel {
        fn http_version(&self) -> semver::Version {
            unimplemented!()
        }
        fn conduit_version(&self) -> semver::Version {
            unimplemented!()
        }
        fn method(&self) -> Method {
            self.method.clone()
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host<'a>(&'a self) -> Host<'a> {
            unimplemented!()
        }
        fn virtual_root<'a>(&'a self) -> Option<&'a str> {
            unimplemented!()
        }
        fn path<'a>(&'a self) -> &'a str {
            &self.path
        }
        fn query_string<'a>(&'a self) -> Option<&'a str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers<'a>(&'a self) -> &'a dyn Headers {
            unimplemented!()
        }
        fn body<'a>(&'a mut self) -> &'a mut dyn Read {
            unimplemented!()
        }
        fn extensions<'a>(&'a self) -> &'a Extensions {
            &self.extensions
        }
        fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
            &mut self.extensions
        }
    }

    struct MyMiddleware;

    impl Middleware for MyMiddleware {
        fn before<'a>(&self, req: &'a mut dyn Request) -> Result<(), Box<dyn Error + Send>> {
            req.mut_extensions().insert("hello".to_string());
            Ok(())
        }
    }

    struct ErrorRecovery;

    impl Middleware for ErrorRecovery {
        fn after(
            &self,
            _: &mut dyn Request,
            res: Result<Response, Box<dyn Error + Send>>,
        ) -> Result<Response, Box<dyn Error + Send>> {
            res.or_else(|e| {
                let e = e.to_string();
                Ok(Response {
                    status: (500, "Internal Server Error"),
                    headers: HashMap::new(),
                    body: Box::new(Cursor::new(e.into_bytes())),
                })
            })
        }
    }

    struct ProducesError;

    impl Middleware for ProducesError {
        fn before(&self, _: &mut dyn Request) -> Result<(), Box<dyn Error + Send>> {
            Err(Box::new(io::Error::new(io::ErrorKind::Other, "")))
        }
    }

    struct NotReached;

    impl Middleware for NotReached {
        fn after(
            &self,
            _: &mut dyn Request,
            _: Result<Response, Box<dyn Error + Send>>,
        ) -> Result<Response, Box<dyn Error + Send>> {
            Ok(Response {
                status: (200, "OK"),
                headers: HashMap::new(),
                body: Box::new(Cursor::new(vec![])),
            })
        }
    }

    struct MyAroundMiddleware {
        handler: Option<Box<dyn Handler>>,
    }

    impl MyAroundMiddleware {
        fn new() -> MyAroundMiddleware {
            MyAroundMiddleware { handler: None }
        }
    }

    impl Middleware for MyAroundMiddleware {}

    impl AroundMiddleware for MyAroundMiddleware {
        fn with_handler(&mut self, handler: Box<dyn Handler>) {
            self.handler = Some(handler)
        }
    }

    impl Handler for MyAroundMiddleware {
        fn call(&self, req: &mut dyn Request) -> Result<Response, Box<dyn Error + Send>> {
            req.mut_extensions().insert("hello".to_string());
            self.handler.as_ref().unwrap().call(req)
        }
    }

    fn get_extension<'a, T: Any>(req: &'a dyn Request) -> &'a T {
        req.extensions().find::<T>().unwrap()
    }

    fn response(string: String) -> Response {
        Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: Box::new(Cursor::new(string.into_bytes())),
        }
    }

    fn handler(req: &mut dyn Request) -> io::Result<Response> {
        let hello = get_extension::<String>(req);
        Ok(response(hello.clone()))
    }

    fn error_handler(_: &mut dyn Request) -> io::Result<Response> {
        Err(io::Error::new(io::ErrorKind::Other, "Error in handler"))
    }

    fn middle_handler(req: &mut dyn Request) -> io::Result<Response> {
        let hello = get_extension::<String>(req);
        let middle = get_extension::<String>(req);

        Ok(response(format!("{} {}", hello, middle)))
    }

    #[test]
    fn test_simple_middleware() {
        let mut builder = MiddlewareBuilder::new(handler);
        builder.add(MyMiddleware);

        let mut req = RequestSentinel::new(Method::Get, "/");
        let mut res = builder.call(&mut req).ok().expect("No response");

        let mut s = Vec::new();
        res.body.write_body(&mut s).unwrap();
        assert_eq!(s, b"hello");
    }

    #[test]
    fn test_error_recovery() {
        let mut builder = MiddlewareBuilder::new(handler);
        builder.add(ErrorRecovery);
        builder.add(ProducesError);
        // the error bubbles up from ProducesError and shouldn't reach here
        builder.add(NotReached);

        let mut req = RequestSentinel::new(Method::Get, "/");
        let res = builder.call(&mut req).ok().expect("Error not handled");

        assert_eq!(res.status, (500, "Internal Server Error"));
    }

    #[test]
    fn test_error_recovery_in_handlers() {
        let mut builder = MiddlewareBuilder::new(error_handler);
        builder.add(ErrorRecovery);

        let mut req = RequestSentinel::new(Method::Get, "/");
        let mut res = builder.call(&mut req).ok().expect("Error not handled");

        assert_eq!(res.status, (500, "Internal Server Error"));
        let mut s = Vec::new();
        res.body.write_body(&mut s).unwrap();
        assert_eq!(s, b"Error in handler");
    }

    #[test]
    fn test_around_middleware() {
        let mut builder = MiddlewareBuilder::new(middle_handler);
        builder.add(MyMiddleware);
        builder.around(MyAroundMiddleware::new());

        let mut req = RequestSentinel::new(Method::Get, "/");
        let mut res = builder.call(&mut req).ok().expect("No response");

        let mut s = Vec::new();
        res.body.write_body(&mut s).unwrap();
        assert_eq!(s, b"hello hello");
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

pub fn translate_char(current : char, previous : char) -> char
{
  // TODO: FIXME.
  'a'
}

pub fn translate(text : &str) -> String
{
  let mut result = String::with_capacity(text.len() * std::mem::size_of::<char>());

  let mut previous = ' ';
  for c in text.chars()
  {
    previous = translate_char(c, previous);
    result.push(previous);
  }

  result
}

pub fn test()
{
  println!("transliterator!")

  let mut test = HashMap::new();

  test.insert(('a', 'a'), 'a');
  test.insert(('a', 'b'), 'b');
}
<commit_msg>'Translator' struct instead of free functions<commit_after>use std::collections::HashMap;

struct Translator
{
  rules: HashMap<(char, char), char>,
}

impl Translator
{
  fn new() -> Translator
  {
    Translator
    {
      rules: HashMap::new(),
    }
  }

  fn default() -> Translator
  {
    Translator
    {
      rules: HashMap::new(),
    }
  }

  fn translate_char(&self, current : char, previous : char) -> char
  {
    // TODO: FIXME.
    'a'
  }

  pub fn translate(&self, text : &str) -> String
  {
    let mut result = String::with_capacity(text.len() * std::mem::size_of::<char>());

    let mut previous = ' ';
    for c in text.chars()
    {
      previous = self.translate_char(c, previous);
      result.push(previous);
    }

    result
  }
}

pub fn test()
{
  println!("transliterator!")

  let mut test = HashMap::new();

  test.insert(('a', 'a'), 'a');
  test.insert(('a', 'b'), 'b');
}
<|endoftext|>


<commit_before>//! Multi-producer multi-consumer channels for message passing.
//!
//! Channels are concurrent FIFO queues used for passing messages between threads.
//!
//! Crossbeam's channels are an alternative to the [`std::sync::mpsc`] channels provided by the
//! standard library. They are an improvement in pretty much all aspects: ergonomics, flexibility,
//! features, performance.
//!
//! # Types of channels
//!
//! A channel can be constructed by calling functinos [`unbounded`] and [`bounded`]. The former
//! creates a channel of unbounded capacity (i.e. it can contain an arbitrary number of messages),
//! while the latter creates a channel of bounded capacity (i.e. there is a limit to how many
//! messages it can hold at a time).
//!
//! Both constructors returns a pair of two values: a sender and a receiver. Senders and receivers
//! represent two opposite sides of a channel. Messages are sent using senders and received using
//! receivers.
//!
//! Creating an unbounded channel:
//!
//! ```
//! // Create an unbounded channel.
//! let (tx, rx) = channel::unbounded();
//!
//! // Can send an arbitrarily large number of messages.
//! for i in 0..1000 {
//!     tx.try_send(i).unwrap();
//! }
//! ```
//!
//! Creating a bounded channel:
//!
//! ```
//! // Create a channel that can hold at most 5 messages at a time.
//! let (tx, rx) = channel::bounded(5);
//!
//! // Can send only 5 messages.
//! for i in 0..5 {
//!     tx.try_send(i).unwrap();
//! }
//!
//! // An attempt to send one more message will fail.
//! assert!(tx.try_send(5).is_err());
//! ```
//!
//! An interesting special case is a bounded, zero-capacity channel. This kind of channel cannot
//! hold any messages at all! In order to send a message through the channel, another thread must
//! be waiting at the other end of it at the same time:
//!
//! ```
//! use std::thread;
//!
//! // Create a zero-capacity channel.
//! let (tx, rx) = channel::bounded(0);
//!
//! // Spawn a thread that sends a message into the channel.
//! thread::spawn(move || tx.send("Hi!").unwrap());
//!
//! // Receive the message.
//! assert_eq!(rx.recv(), Ok("Hi!"));
//! ```
//!
//! # Sharing channels
//!
//! Senders and receivers can be either shared by reference or cloned and then sent to other
//! threads. Feel free to use any of these two approaches as you like.
//!
//! Sharing by reference:
//!
//! ```
//! extern crate channel;
//! extern crate crossbeam_utils;
//!
//! let (tx, rx) = channel::unbounded();
//!
//! crossbeam_utils::scoped::scope(|s| {
//!     // Spawn a thread that sends one message and then receives one.
//!     s.spawn(|| {
//!         tx.send(1).unwrap();
//!         rx.recv().unwrap();
//!     });
//!
//!     // Spawn another thread that does the same thing.
//!     // Both closures capture `tx` and `rx` by reference.
//!     s.spawn(|| {
//!         tx.send(2).unwrap();
//!         rx.recv().unwrap();
//!     });
//! });
//! ```
//!
//! Sharing by sending:
//!
//! ```
//! use std::thread;
//!
//! let (tx, rx) = channel::unbounded();
//! let (tx2, rx2) = (tx.clone(), rx.clone());
//!
//! // Spawn a thread that sends one message and then receives one.
//! // Here, `tx` and `rx` are moved into the closure (sent into the thread).
//! thread::spawn(move || {
//!     tx.send(1).unwrap();
//!     rx.recv().unwrap();
//! });
//!
//! // Spawn another thread that does the same thing.
//! // Here, `tx2` and `rx2` are moved into the closure (sent into the thread).
//! thread::spawn(move || {
//!     tx2.send(2).unwrap();
//!     rx2.recv().unwrap();
//! });
//! ```
//!
//! # Disconnection
//!
//! As soon as all senders or all receivers associated with a channel are dropped, it becomes
//! disconnected. Messages cannot be sent into a disconnected channel anymore, but the remaining
//! messages can still be received.
//!
//! ```
//! use channel::TrySendError;
//!
//! let (tx, rx) = channel::unbounded();
//!
//! // The only receiver is dropped, disconnecting the channel.
//! drop(rx);
//!
//! // Attempting to send a message will result in an error.
//! assert_eq!(tx.try_send("hello"), Err(TrySendError::Disconnected("hello")));
//! ```
//!
//! ```
//! use channel::TryRecvError;
//!
//! let (tx, rx) = channel::unbounded();
//! tx.try_send(1).unwrap();
//! tx.try_send(2).unwrap();
//! tx.try_send(3).unwrap();
//!
//! // The only sender is dropped, disconnecting the channel.
//! drop(tx);
//!
//! // The remaining messages can be received.
//! assert_eq!(rx.try_recv(), Ok(1));
//! assert_eq!(rx.try_recv(), Ok(2));
//! assert_eq!(rx.try_recv(), Ok(3));
//!
//! // However, attempting to receive another message will result in an error.
//! assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
//! ```
//!
//! # Blocking and non-blocking operations
//!
//! Send and receive operations come in three variants:
//!
//! 1. Non-blocking: [`try_send`] and [`try_recv`].
//! 2. Blocking: [`try_send`] and [`try_recv`].
//! 3. Blocking with a timeout: [`send_timeout`] and [`recv_timeout`].
//!
//! The non-blocking variant attempts to perform the operation, but doesn't block the current
//! thread on failure (e.g. if receiving a message from an empty channel).
//!
//! The blocking variant will wait until the operation can be performed or the channel becomes
//! disconnected.
//!
//! Blocking with a timeout does the same thing, but blocks the current thread only for a limited
//! amount time.
//!
//! # Iteration
//!
//! Receivers can be turned into iterators. For example, calling [`iter`] creates an iterator that
//! returns messages until the channel is disconnected. Note that iteration may block while waiting
//! for the next message.
//!
//! ```
//! let (tx, rx) = channel::unbounded();
//! tx.send(1).unwrap();
//! tx.send(2).unwrap();
//! tx.send(3).unwrap();
//!
//! // Drop the sender in order to disconnect the channel.
//! drop(tx);
//!
//! // Receive all remaining messages.
//! let v: Vec<_> = rx.iter().collect();
//! assert_eq!(v, [1, 2, 3]);
//! ```
//!
//! By calling [`try_iter`] it is also possible to create an iterator that returns messages until
//! the channel is empty. This iterator will never block the current thread.
//!
//! ```
//! let (tx, rx) = channel::unbounded();
//! tx.send(1).unwrap();
//! tx.send(2).unwrap();
//! tx.send(3).unwrap();
//! // No need to drop the sender.
//!
//! // Receive all messages currently in the channel.
//! let v: Vec<_> = rx.try_iter().collect();
//! assert_eq!(v, [1, 2, 3]);
//! ```
//!
//! Finally, there is the [`into_iter`] method, which is equivalent to [`iter`], except it takes
//! ownership of the receiver instead of borrowing it.
//!
//! # Selection
//!
//! Selection allows you to declare a set of operations on channels and perform exactly one of
//! them, whichever becomes ready first, possibly blocking until that happens.
//!
//! For example, selection can be used to receive a message from one of the two channels, blocking
//! until a message appears on either of them:
//!
//! ```ignore TODO
//! #[macro_use]
//! extern crate channel;
//!
//! use std::thread;
//!
//! let (tx1, rx1) = channel::unbounded();
//! let (tx2, rx2) = channel::unbounded();
//!
//! thread::spawn(move || tx1.send("foo").unwrap());
//! thread::spawn(move || tx2.send("bar").unwrap());
//!
//! select_loop! {
//!     recv(rx1, msg) => {
//!         println!("Received a message from the first channel: {}", msg);
//!     }
//!     recv(rx2, msg) => {
//!         println!("Received a message from the second channel: {}", msg);
//!     }
//! }
//! ```
//!
//! The syntax of [`select_loop!`] is very similar to the one used by `match`.
//!
//! Here is another, more complicated example of selection. Here we are selecting over two
//! operations on the opposite ends of the same channel: a send and a receive operation.
//!
//! ```ignore TODO
//! use channel::{Sender, Receiver, Select};
//! use std::thread;
//!
//! // Either send my name into the channel or receive someone else's, whatever happens first.
//! fn seek<'a>(name: &'a str, tx: Sender<&'a str>, rx: Receiver<&'a str>) {
//!     select_loop! {
//!         recv(rx, peer) => println!("{} received a message from {}.", name, peer),
//!         send(tx, name) => {},
//!     }
//! }
//!
//! let (tx, rx) = channel::bounded(1); // Make room for one unmatched send.
//!
//! // Pair up five people by exchanging messages over the channel.
//! // Since there is an odd number of them, one person won't have its match.
//! ["Anna", "Bob", "Cody", "Dave", "Eva"].iter()
//!     .map(|name| {
//!         let tx = tx.clone();
//!         let rx = rx.clone();
//!         thread::spawn(move || seek(name, tx, rx))
//!     })
//!     .collect::<Vec<_>>()
//!     .into_iter()
//!     .for_each(|t| t.join().unwrap());
//!
//! // Let's send a message to the remaining person who doesn't have a match.
//! if let Ok(name) = rx.try_recv() {
//!     println!("No one received {}’s message.", name);
//! }
//! ```
//!
//! For more details, take a look at the documentation of [`select_loop!`].
//!
//! [`std::sync::mpsc`]: https://doc.rust-lang.org/std/sync/mpsc/index.html
//! [`unbounded`]: fn.unbounded.html
//! [`bounded`]: fn.bounded.html
//! [`try_send`]: struct.Sender.html#method.try_send
//! [`send`]: struct.Sender.html#method.send
//! [`send_timeout`]: struct.Sender.html#method.send_timeout
//! [`try_recv`]: struct.Receiver.html#method.try_recv
//! [`recv`]: struct.Receiver.html#method.recv
//! [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
//! [`iter`]: struct.Receiver.html#method.iter
//! [`try_iter`]: struct.Receiver.html#method.try_iter
//! [`into_iter`]: struct.Receiver.html#method.into_iter
//! [`select_loop!`]: macro.select_loop.html

#![cfg_attr(feature = "nightly", feature(hint_core_should_pause))]

extern crate crossbeam_epoch;
extern crate crossbeam_utils;
extern crate parking_lot;
extern crate rand;

mod channel;
mod err;
mod exchanger;
mod flavors;
mod monitor;
mod select;
mod util;

pub use channel::{bounded, unbounded};
pub use channel::{Receiver, Sender};
pub use channel::{IntoIter, Iter, TryIter};
pub use err::{RecvError, RecvTimeoutError, TryRecvError};
pub use err::{SendError, SendTimeoutError, TrySendError};
pub use err::{SelectRecvError, SelectSendError};
pub use select::Select;
<commit_msg>Enable select_loop tests in lib.rs<commit_after>//! Multi-producer multi-consumer channels for message passing.
//!
//! Channels are concurrent FIFO queues used for passing messages between threads.
//!
//! Crossbeam's channels are an alternative to the [`std::sync::mpsc`] channels provided by the
//! standard library. They are an improvement in pretty much all aspects: ergonomics, flexibility,
//! features, performance.
//!
//! # Types of channels
//!
//! A channel can be constructed by calling functinos [`unbounded`] and [`bounded`]. The former
//! creates a channel of unbounded capacity (i.e. it can contain an arbitrary number of messages),
//! while the latter creates a channel of bounded capacity (i.e. there is a limit to how many
//! messages it can hold at a time).
//!
//! Both constructors returns a pair of two values: a sender and a receiver. Senders and receivers
//! represent two opposite sides of a channel. Messages are sent using senders and received using
//! receivers.
//!
//! Creating an unbounded channel:
//!
//! ```
//! // Create an unbounded channel.
//! let (tx, rx) = channel::unbounded();
//!
//! // Can send an arbitrarily large number of messages.
//! for i in 0..1000 {
//!     tx.try_send(i).unwrap();
//! }
//! ```
//!
//! Creating a bounded channel:
//!
//! ```
//! // Create a channel that can hold at most 5 messages at a time.
//! let (tx, rx) = channel::bounded(5);
//!
//! // Can send only 5 messages.
//! for i in 0..5 {
//!     tx.try_send(i).unwrap();
//! }
//!
//! // An attempt to send one more message will fail.
//! assert!(tx.try_send(5).is_err());
//! ```
//!
//! An interesting special case is a bounded, zero-capacity channel. This kind of channel cannot
//! hold any messages at all! In order to send a message through the channel, another thread must
//! be waiting at the other end of it at the same time:
//!
//! ```
//! use std::thread;
//!
//! // Create a zero-capacity channel.
//! let (tx, rx) = channel::bounded(0);
//!
//! // Spawn a thread that sends a message into the channel.
//! thread::spawn(move || tx.send("Hi!").unwrap());
//!
//! // Receive the message.
//! assert_eq!(rx.recv(), Ok("Hi!"));
//! ```
//!
//! # Sharing channels
//!
//! Senders and receivers can be either shared by reference or cloned and then sent to other
//! threads. Feel free to use any of these two approaches as you like.
//!
//! Sharing by reference:
//!
//! ```
//! extern crate channel;
//! extern crate crossbeam_utils;
//!
//! let (tx, rx) = channel::unbounded();
//!
//! crossbeam_utils::scoped::scope(|s| {
//!     // Spawn a thread that sends one message and then receives one.
//!     s.spawn(|| {
//!         tx.send(1).unwrap();
//!         rx.recv().unwrap();
//!     });
//!
//!     // Spawn another thread that does the same thing.
//!     // Both closures capture `tx` and `rx` by reference.
//!     s.spawn(|| {
//!         tx.send(2).unwrap();
//!         rx.recv().unwrap();
//!     });
//! });
//! ```
//!
//! Sharing by sending:
//!
//! ```
//! use std::thread;
//!
//! let (tx, rx) = channel::unbounded();
//! let (tx2, rx2) = (tx.clone(), rx.clone());
//!
//! // Spawn a thread that sends one message and then receives one.
//! // Here, `tx` and `rx` are moved into the closure (sent into the thread).
//! thread::spawn(move || {
//!     tx.send(1).unwrap();
//!     rx.recv().unwrap();
//! });
//!
//! // Spawn another thread that does the same thing.
//! // Here, `tx2` and `rx2` are moved into the closure (sent into the thread).
//! thread::spawn(move || {
//!     tx2.send(2).unwrap();
//!     rx2.recv().unwrap();
//! });
//! ```
//!
//! # Disconnection
//!
//! As soon as all senders or all receivers associated with a channel are dropped, it becomes
//! disconnected. Messages cannot be sent into a disconnected channel anymore, but the remaining
//! messages can still be received.
//!
//! ```
//! use channel::TrySendError;
//!
//! let (tx, rx) = channel::unbounded();
//!
//! // The only receiver is dropped, disconnecting the channel.
//! drop(rx);
//!
//! // Attempting to send a message will result in an error.
//! assert_eq!(tx.try_send("hello"), Err(TrySendError::Disconnected("hello")));
//! ```
//!
//! ```
//! use channel::TryRecvError;
//!
//! let (tx, rx) = channel::unbounded();
//! tx.try_send(1).unwrap();
//! tx.try_send(2).unwrap();
//! tx.try_send(3).unwrap();
//!
//! // The only sender is dropped, disconnecting the channel.
//! drop(tx);
//!
//! // The remaining messages can be received.
//! assert_eq!(rx.try_recv(), Ok(1));
//! assert_eq!(rx.try_recv(), Ok(2));
//! assert_eq!(rx.try_recv(), Ok(3));
//!
//! // However, attempting to receive another message will result in an error.
//! assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
//! ```
//!
//! # Blocking and non-blocking operations
//!
//! Send and receive operations come in three variants:
//!
//! 1. Non-blocking: [`try_send`] and [`try_recv`].
//! 2. Blocking: [`try_send`] and [`try_recv`].
//! 3. Blocking with a timeout: [`send_timeout`] and [`recv_timeout`].
//!
//! The non-blocking variant attempts to perform the operation, but doesn't block the current
//! thread on failure (e.g. if receiving a message from an empty channel).
//!
//! The blocking variant will wait until the operation can be performed or the channel becomes
//! disconnected.
//!
//! Blocking with a timeout does the same thing, but blocks the current thread only for a limited
//! amount time.
//!
//! # Iteration
//!
//! Receivers can be turned into iterators. For example, calling [`iter`] creates an iterator that
//! returns messages until the channel is disconnected. Note that iteration may block while waiting
//! for the next message.
//!
//! ```
//! let (tx, rx) = channel::unbounded();
//! tx.send(1).unwrap();
//! tx.send(2).unwrap();
//! tx.send(3).unwrap();
//!
//! // Drop the sender in order to disconnect the channel.
//! drop(tx);
//!
//! // Receive all remaining messages.
//! let v: Vec<_> = rx.iter().collect();
//! assert_eq!(v, [1, 2, 3]);
//! ```
//!
//! By calling [`try_iter`] it is also possible to create an iterator that returns messages until
//! the channel is empty. This iterator will never block the current thread.
//!
//! ```
//! let (tx, rx) = channel::unbounded();
//! tx.send(1).unwrap();
//! tx.send(2).unwrap();
//! tx.send(3).unwrap();
//! // No need to drop the sender.
//!
//! // Receive all messages currently in the channel.
//! let v: Vec<_> = rx.try_iter().collect();
//! assert_eq!(v, [1, 2, 3]);
//! ```
//!
//! Finally, there is the [`into_iter`] method, which is equivalent to [`iter`], except it takes
//! ownership of the receiver instead of borrowing it.
//!
//! # Selection
//!
//! Selection allows you to declare a set of operations on channels and perform exactly one of
//! them, whichever becomes ready first, possibly blocking until that happens.
//!
//! For example, selection can be used to receive a message from one of the two channels, blocking
//! until a message appears on either of them:
//!
//! ```
//! # #[macro_use]
//! # extern crate channel;
//! # fn main() {
//!
//! use std::thread;
//!
//! let (tx1, rx1) = channel::unbounded();
//! let (tx2, rx2) = channel::unbounded();
//!
//! thread::spawn(move || tx1.send("foo").unwrap());
//! thread::spawn(move || tx2.send("bar").unwrap());
//!
//! select_loop! {
//!     recv(rx1, msg) => {
//!         println!("Received a message from the first channel: {}", msg);
//!     }
//!     recv(rx2, msg) => {
//!         println!("Received a message from the second channel: {}", msg);
//!     }
//! }
//!
//! # }
//! ```
//!
//! The syntax of [`select_loop!`] is very similar to the one used by `match`.
//!
//! Here is another, more complicated example of selection. Here we are selecting over two
//! operations on the opposite ends of the same channel: a send and a receive operation.
//!
//! ```
//! # #[macro_use]
//! # extern crate channel;
//! # fn main() {
//!
//! use channel::{Sender, Receiver, Select};
//! use std::thread;
//!
//! // Either send my name into the channel or receive someone else's, whatever happens first.
//! fn seek<'a>(name: &'a str, tx: Sender<&'a str>, rx: Receiver<&'a str>) {
//!     select_loop! {
//!         recv(rx, peer) => println!("{} received a message from {}.", name, peer),
//!         send(tx, name) => {},
//!     }
//! }
//!
//! let (tx, rx) = channel::bounded(1); // Make room for one unmatched send.
//!
//! // Pair up five people by exchanging messages over the channel.
//! // Since there is an odd number of them, one person won't have its match.
//! ["Anna", "Bob", "Cody", "Dave", "Eva"].iter()
//!     .map(|name| {
//!         let tx = tx.clone();
//!         let rx = rx.clone();
//!         thread::spawn(move || seek(name, tx, rx))
//!     })
//!     .collect::<Vec<_>>()
//!     .into_iter()
//!     .for_each(|t| t.join().unwrap());
//!
//! // Let's send a message to the remaining person who doesn't have a match.
//! if let Ok(name) = rx.try_recv() {
//!     println!("No one received {}’s message.", name);
//! }
//!
//! # }
//! ```
//!
//! For more details, take a look at the documentation of [`select_loop!`].
//!
//! [`std::sync::mpsc`]: https://doc.rust-lang.org/std/sync/mpsc/index.html
//! [`unbounded`]: fn.unbounded.html
//! [`bounded`]: fn.bounded.html
//! [`try_send`]: struct.Sender.html#method.try_send
//! [`send`]: struct.Sender.html#method.send
//! [`send_timeout`]: struct.Sender.html#method.send_timeout
//! [`try_recv`]: struct.Receiver.html#method.try_recv
//! [`recv`]: struct.Receiver.html#method.recv
//! [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
//! [`iter`]: struct.Receiver.html#method.iter
//! [`try_iter`]: struct.Receiver.html#method.try_iter
//! [`into_iter`]: struct.Receiver.html#method.into_iter
//! [`select_loop!`]: macro.select_loop.html

#![cfg_attr(feature = "nightly", feature(hint_core_should_pause))]

extern crate crossbeam_epoch;
extern crate crossbeam_utils;
extern crate parking_lot;
extern crate rand;

mod channel;
mod err;
mod exchanger;
mod flavors;
mod monitor;
mod select;
mod util;

pub use channel::{bounded, unbounded};
pub use channel::{Receiver, Sender};
pub use channel::{IntoIter, Iter, TryIter};
pub use err::{RecvError, RecvTimeoutError, TryRecvError};
pub use err::{SendError, SendTimeoutError, TrySendError};
pub use err::{SelectRecvError, SelectSendError};
pub use select::Select;
<|endoftext|>


<commit_before>extern crate serde;
#[macro_use]
extern crate serde_derive;

// we get an unused import when using macro use, but a
// "this has no effect without macro_use" message otherwise
#[allow(unused_imports)]
#[macro_use]
extern crate snapshot_proc_macro;

pub use snapshot_proc_macro::*;

use std::ffi::OsString;
use std::fmt::Debug;
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};

pub trait Snapable {}
impl<'de, T> Snapable for T where T: Debug + Deserialize<'de> + Serialize {}

#[derive(Debug, Deserialize, Serialize)]
pub struct Snapshot<'a, S: Snapable> {
    pub file: &'a str,
    pub module_path: &'a str,
    pub test_function: &'a str,
    pub recorded_value: S,
}

impl<'a, S> Snapshot<'a, S>
    where S: Snapable
{
    pub fn path(&self, crate_root: &str) -> (PathBuf, OsString) {
        let file_path = &Path::new(self.file);

        let mut components = file_path.components();

        // strip the filename
        let mut file_to_write = components.next_back().unwrap().as_os_str().to_owned();
        file_to_write.push(".snap");

        let mut ret = PathBuf::from(crate_root);
        for dir in components {
            ret.push(dir.as_os_str());
        }

        ret.push("__snapshots__");

        (ret, file_to_write)
    }

    pub fn check_snapshot(&self, manifest_dir: &str) {
        unimplemented!();
    }

    pub fn update_snapshot(&self, manifest_dir: &str) {
        unimplemented!();
    }
}
<commit_msg>Snapshot metadata boilerplate.<commit_after>extern crate serde;
#[macro_use]
extern crate serde_derive;

// we get an unused import when using macro use, but a
// "this has no effect without macro_use" message otherwise
#[allow(unused_imports)]
#[macro_use]
extern crate snapshot_proc_macro;

pub use snapshot_proc_macro::*;

use std::ffi::OsString;
use std::fmt::Debug;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};

pub trait Snapable {}
impl<'de, T> Snapable for T where T: Debug + Deserialize<'de> + Serialize {}

#[derive(Debug, Deserialize, Serialize)]
pub struct Snapshot<'a, S: Snapable> {
    pub file: &'a str,
    pub module_path: &'a str,
    pub test_function: &'a str,
    pub recorded_value: S,
}

impl<'a, S> Snapshot<'a, S>
    where S: Snapable
{
    fn path(&self, manifest_dir: &str) -> SnapFileSpec {
        let file_path = &Path::new(self.file);

        let mut components = file_path.components();

        // strip the filename
        let mut filename = components.next_back().unwrap().as_os_str().to_owned();
        filename.push(".snap");

        let mut dir = PathBuf::new();
        for directory in components {
            dir.push(directory.as_os_str());
        }

        dir.push("__snapshots__");

        let mut absolute_path = PathBuf::from(manifest_dir);
        absolute_path.push(dir.clone());
        absolute_path.push(filename.clone());

        let mut relative_path = PathBuf::from(dir.clone());
        relative_path.push(filename.clone());

        SnapFileSpec {
            dir,
            filename,
            absolute_path,
            relative_path,
        }
    }

    pub fn check_snapshot(&self, manifest_dir: &str) {
        let SnapFileSpec {
            dir: snap_dir,
            filename: snap_filename,
            absolute_path,
            relative_path,
        } = self.path(manifest_dir);

        let snap_file = match File::open(&absolute_path) {
            Ok(f) => f,
            Err(why) => {
                panic!("Unable to open snapshot file {:?}: {:?}",
                       relative_path,
                       why.kind())
            }
        };

        unimplemented!();
    }

    pub fn update_snapshot(&self, manifest_dir: &str) {
        let SnapFileSpec {
            dir: snap_dir,
            filename: snap_filename,
            absolute_path,
            relative_path,
        } = self.path(manifest_dir);

        let snap_file = match File::open(&absolute_path) {
            Ok(f) => f,
            Err(why) => {
                panic!("Unable to create snapshot file {:?}: {:?}",
                       relative_path,
                       why.kind())
            }
        };

        unimplemented!();
    }
}

struct SnapFileSpec {
    dir: PathBuf,
    filename: OsString,
    relative_path: PathBuf,
    absolute_path: PathBuf,
}
<|endoftext|>


<commit_before>extern crate rand;

use rand::{Rand, Rng};
use rand::Closed01 as RandClosed01;

/// Encapsulates a floating point number in the range [0, 1] including both endpoints.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Closed01<F>(F);

impl Closed01<f32> {
    #[inline(always)]
    pub fn new(f: f32) -> Closed01<f32> {
        assert!(f >= 0.0 && f <= 1.0);
        Closed01(f)
    }

    #[inline(always)]
    pub fn zero() -> Closed01<f32> {
        Closed01(0.0)
    }

    #[inline(always)]
    pub fn middle() -> Closed01<f32> {
        Closed01(0.5)
    }

    #[inline(always)]
    pub fn one() -> Closed01<f32> {
        Closed01(1.0)
    }

    #[inline(always)]
    /// Returns the smaller of the two.
    pub fn min(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 <= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the greater of the two.
    pub fn max(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 >= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the distance between the two numbers.
    pub fn distance(self, other: Closed01<f32>) -> Closed01<f32> {
        let d = (self.0 - other.0).abs();
        debug_assert!(d >= 0.0 && d <= 1.0);
        Closed01(d)
    }

    #[inline(always)]
    pub fn get(self) -> f32 {
        debug_assert!(self.0 >= 0.0 && self.0 <= 1.0);
        self.0
    }

    #[inline(always)]
    /// The average of two values.
    pub fn average(self: Closed01<f32>, other: Closed01<f32>) -> Closed01<f32> {
        let avg = (self.get() + other.get()) / 2.0;
        debug_assert!(avg >= 0.0 && avg <= 1.0);
        Closed01(avg)
    }

    #[inline(always)]
    /// Saturating add
    pub fn saturating_add(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sum = self.0 + other.0;
        if sum > 1.0 {
            sum = 1.0;
        }
        debug_assert!(sum >= 0.0 && sum <= 1.0);
        Closed01(sum)
    }

    #[inline(always)]
    /// Saturating sub
    pub fn saturating_sub(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sub = self.0 - other.0;
        if sub < 0.0 {
            sub = 0.0;
        }
        debug_assert!(sub >= 0.0 && sub <= 1.0);
        Closed01(sub)
    }

    #[inline(always)]
    /// Multiplies both numbers
    pub fn mul(self, scalar: Closed01<f32>) -> Closed01<f32> {
        let s = self.get() * scalar.get();
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    pub fn approx_eq(self, other: Closed01<f32>, eps: Closed01<f32>) -> bool {
        self.distance(other) < eps
    }

    #[inline(always)]
    /// This scales `self` towards 1.0
    pub fn scale_up(self, other: Closed01<f32>) -> Closed01<f32> {
        let s = self.0 + (1.0 - self.0) * other.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// This scales `self` towards 0.0
    pub fn scale_down(self, other: Closed01<f32>) -> Closed01<f32> {
        let s = self.0 - self.0 * other.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// Invert the number (Mirror at 0.5; 1.0 - number).
    pub fn inv(self) -> Closed01<f32> {
        let s = 1.0 - self.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }
}

impl Into<f32> for Closed01<f32> {
    fn into(self) -> f32 {
        self.get()
    }
}

impl Rand for Closed01<f32> {
    fn rand<R: Rng>(rng: &mut R) -> Closed01<f32> {
        Closed01::new(RandClosed01::<f32>::rand(rng).0)
    }
}

#[test]
fn test_into() {
    assert_eq!(0.5f32, Closed01::new(0.5).into());
}

#[test]
fn test_minmax() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    assert_eq!(a, a.min(b));
    assert_eq!(a, b.min(a));
    assert_eq!(b, a.max(b));
    assert_eq!(b, b.max(a));
}

#[test]
fn test_saturation() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    let c = Closed01::new(0.6);

    assert_eq!(0.9, a.saturating_add(b).get());
    assert_eq!(1.0, a.saturating_add(c).get());
    assert_eq!(1.0, b.saturating_add(c).get());

    assert_eq!(0.0, a.saturating_sub(b).get());
    assert_eq!(0.0, a.saturating_sub(c).get());
    assert_eq!(0.0, b.saturating_sub(c).get());

    let eps = Closed01::new(0.001);
    assert!(c.saturating_sub(b).approx_eq(Closed01::new(0.1), eps));
    assert!(c.saturating_sub(a).approx_eq(Closed01::new(0.2), eps));
}

#[test]
fn test_scale_up() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(b, a.scale_up(b));
    assert_eq!(c, a.scale_up(c));

    assert_eq!(c, c.scale_up(a));
    assert_eq!(b, c.scale_up(b));
}

#[test]
fn test_scale_down() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, c.scale_down(b));
    assert_eq!(b, b.scale_down(a));
    assert_eq!(c, b.scale_down(c));
}

#[test]
fn test_invert() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, a.inv().inv());
    assert_eq!(b, b.inv().inv());
    assert_eq!(c, c.inv().inv());

    assert_eq!(b, a.inv());
    assert_eq!(a, b.inv());
    assert_eq!(c, c.inv());
}
<commit_msg>Implement round()<commit_after>extern crate rand;

use rand::{Rand, Rng};
use rand::Closed01 as RandClosed01;

/// Encapsulates a floating point number in the range [0, 1] including both endpoints.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Closed01<F>(F);

impl Closed01<f32> {
    #[inline(always)]
    pub fn new(f: f32) -> Closed01<f32> {
        assert!(f >= 0.0 && f <= 1.0);
        Closed01(f)
    }

    #[inline(always)]
    pub fn zero() -> Closed01<f32> {
        Closed01(0.0)
    }

    #[inline(always)]
    pub fn middle() -> Closed01<f32> {
        Closed01(0.5)
    }

    #[inline(always)]
    pub fn one() -> Closed01<f32> {
        Closed01(1.0)
    }

    #[inline(always)]
    /// Returns the smaller of the two.
    pub fn min(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 <= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the greater of the two.
    pub fn max(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 >= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the distance between the two numbers.
    pub fn distance(self, other: Closed01<f32>) -> Closed01<f32> {
        let d = (self.0 - other.0).abs();
        debug_assert!(d >= 0.0 && d <= 1.0);
        Closed01(d)
    }

    #[inline(always)]
    pub fn get(self) -> f32 {
        debug_assert!(self.0 >= 0.0 && self.0 <= 1.0);
        self.0
    }

    #[inline(always)]
    /// The average of two values.
    pub fn average(self: Closed01<f32>, other: Closed01<f32>) -> Closed01<f32> {
        let avg = (self.get() + other.get()) / 2.0;
        debug_assert!(avg >= 0.0 && avg <= 1.0);
        Closed01(avg)
    }

    #[inline(always)]
    /// Saturating add
    pub fn saturating_add(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sum = self.0 + other.0;
        if sum > 1.0 {
            sum = 1.0;
        }
        debug_assert!(sum >= 0.0 && sum <= 1.0);
        Closed01(sum)
    }

    #[inline(always)]
    /// Saturating sub
    pub fn saturating_sub(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sub = self.0 - other.0;
        if sub < 0.0 {
            sub = 0.0;
        }
        debug_assert!(sub >= 0.0 && sub <= 1.0);
        Closed01(sub)
    }

    #[inline(always)]
    /// Multiplies both numbers
    pub fn mul(self, scalar: Closed01<f32>) -> Closed01<f32> {
        let s = self.get() * scalar.get();
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    pub fn approx_eq(self, other: Closed01<f32>, eps: Closed01<f32>) -> bool {
        self.distance(other) < eps
    }

    #[inline(always)]
    /// This scales `self` towards 1.0
    pub fn scale_up(self, other: Closed01<f32>) -> Closed01<f32> {
        let s = self.0 + (1.0 - self.0) * other.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// This scales `self` towards 0.0
    pub fn scale_down(self, other: Closed01<f32>) -> Closed01<f32> {
        let s = self.0 - self.0 * other.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// Invert the number (Mirror at 0.5; 1.0 - number).
    pub fn inv(self) -> Closed01<f32> {
        let s = 1.0 - self.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// Round the number to 0.0 or 1.0
    pub fn round(self) -> Closed01<f32> {
        if self.0 < 0.5 {
            Closed01::zero()
        } else {
            Closed01::one()
        }
    }
}

impl Into<f32> for Closed01<f32> {
    fn into(self) -> f32 {
        self.get()
    }
}

impl Rand for Closed01<f32> {
    fn rand<R: Rng>(rng: &mut R) -> Closed01<f32> {
        Closed01::new(RandClosed01::<f32>::rand(rng).0)
    }
}

#[test]
fn test_into() {
    assert_eq!(0.5f32, Closed01::new(0.5).into());
}

#[test]
fn test_minmax() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    assert_eq!(a, a.min(b));
    assert_eq!(a, b.min(a));
    assert_eq!(b, a.max(b));
    assert_eq!(b, b.max(a));
}

#[test]
fn test_saturation() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    let c = Closed01::new(0.6);

    assert_eq!(0.9, a.saturating_add(b).get());
    assert_eq!(1.0, a.saturating_add(c).get());
    assert_eq!(1.0, b.saturating_add(c).get());

    assert_eq!(0.0, a.saturating_sub(b).get());
    assert_eq!(0.0, a.saturating_sub(c).get());
    assert_eq!(0.0, b.saturating_sub(c).get());

    let eps = Closed01::new(0.001);
    assert!(c.saturating_sub(b).approx_eq(Closed01::new(0.1), eps));
    assert!(c.saturating_sub(a).approx_eq(Closed01::new(0.2), eps));
}

#[test]
fn test_scale_up() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(b, a.scale_up(b));
    assert_eq!(c, a.scale_up(c));

    assert_eq!(c, c.scale_up(a));
    assert_eq!(b, c.scale_up(b));
}

#[test]
fn test_scale_down() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, c.scale_down(b));
    assert_eq!(b, b.scale_down(a));
    assert_eq!(c, b.scale_down(c));
}

#[test]
fn test_invert() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, a.inv().inv());
    assert_eq!(b, b.inv().inv());
    assert_eq!(c, c.inv().inv());

    assert_eq!(b, a.inv());
    assert_eq!(a, b.inv());
    assert_eq!(c, c.inv());
}

#[test]
fn test_round() {
    assert_eq!(Closed01::zero(), Closed01::new(0.0).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.1).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.2).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.3).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.4).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.49999).round());
    assert_eq!(Closed01::one(), Closed01::new(0.5).round());
    assert_eq!(Closed01::one(), Closed01::new(0.6).round());
    assert_eq!(Closed01::one(), Closed01::new(0.8).round());
    assert_eq!(Closed01::one(), Closed01::new(0.9).round());
    assert_eq!(Closed01::one(), Closed01::new(1.0).round());
}
<|endoftext|>