<commit_before>//! Functions for computing [integral images](https://en.wikipedia.org/wiki/Summed_area_table)
//! and running sums of rows and columns.

extern crate image;

use image::{
    Luma,
    GenericImage,
    ImageBuffer
};

use definitions::{
    VecBuffer
};

/// Computes the integral image of an 8bpp grayscale image.
/// I is the integral image of an image F if I(x, y) is the
/// sum of F(x', y') for x' <= x, y' <= y. i.e. each pixel
/// in the integral image contains the sum of the pixel intensities
/// of all input pixels that are above it and to its left.
/// The integral image has the helpful property that it lets us
/// compute the sum of pixel intensities from any rectangular region
/// in the input image in constant time.
/// Specifically, given a rectangle in F with clockwise corners
/// A, B, C, D, with A at the upper left, the total pixel intensity
/// of this rectangle is I(C) - I(B) - I(D) + I(A).
// TODO: Support more formats.
// TODO: This is extremely slow. Fix that!
pub fn integral_image<I>(image: &I) -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>> {
    padded_integral_image(image, 0, 0)
}

/// Computes the integral image of the result of padding image
/// with its boundary pixels for x_padding columns on either
/// side and y_padding rows at its top and bottom.
/// Returned image has width image.width() + 2 * x_padding
/// and height image.height() + 2 * y_padding.
pub fn padded_integral_image<I>(image: &I, x_padding: u32, y_padding: u32) -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>>
{
    let (in_width, in_height) = image.dimensions();
    let out_width = in_width + 2 * x_padding;
    let out_height = in_height + 2 * y_padding;

    let mut out: ImageBuffer<Luma<u32>, Vec<u32>> = ImageBuffer::new(out_width, out_height);

    for y in 0..out_height {
        let y_in: u32;
        if y < y_padding {
            y_in = 0;
        }
        else if y >= in_height + y_padding {
            y_in = in_height - 1;
        }
        else {
            y_in = y - y_padding;
        }

        for x in 0..out_width {
            let x_in: u32;
            if x < x_padding {
                x_in = 0;
            }
            else if x >= in_width + x_padding {
                x_in = in_width - 1;
            }
            else {
                x_in = x - x_padding;
            }

            unsafe {
                let p = image.unsafe_get_pixel(x_in, y_in);
                out.unsafe_put_pixel(x, y, Luma([p[0] as u32]));
            }
        }
    }

    for x in 1..out_width {
        (*out.get_pixel_mut(x, 0))[0] += unsafe { out.unsafe_get_pixel(x - 1, 0)[0] };
    }

    for y in 1..out_height {
        (*out.get_pixel_mut(0, y))[0] += unsafe { out.unsafe_get_pixel(0, y - 1)[0] };

        for x in 1..out_width {
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x, y - 1)[0] };
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x - 1, y)[0] };
            (*out.get_pixel_mut(x, y))[0] -= unsafe { out.unsafe_get_pixel(x - 1, y - 1)[0] };
        }
    }

    out
}

/// Computes the running sum of one row of image, padded
/// at the beginning and end. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all rows in an image.
// TODO: faster, more formats
pub fn row_running_sum<I>(image: &I, row: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let width = image.width();
    assert!(buffer.len() >= (width + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), width, padding));
    assert!(row < image.height(),
        format!("row out of bound: {} >= {}", row, image.height()));

    for x in 0..padding {
        buffer[x as usize] = unsafe { image.unsafe_get_pixel(0, row)[0] as u32 };
    }

    for x in 0..width {
        let idx = (x + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(x, row)[0] as u32 };
    }

    for x in 0..padding {
        let idx = (x + width + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(width - 1, row)[0] as u32 };
    }

    for x in 1..width + 2 * padding {
        buffer[x as usize] += buffer[(x - 1) as usize] as u32;
    }
}

/// Computes the running sum of one column of image, padded
/// at the top and bottom. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all columns in an image.
// TODO: faster, more formats
pub fn column_running_sum<I>(image: &I, column: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let height = image.height();
    assert!(buffer.len() >= (height + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), height, padding));
    assert!(column < image.width(),
        format!("column out of bound: {} >= {}", column, image.width()));

    for y in 0..padding {
        buffer[y as usize] = unsafe { image.unsafe_get_pixel(column, 0)[0] as u32 };
    }

    for y in 0..height {
        let idx = (y + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, y)[0] as u32 };
    }

    for y in 0..padding {
        let idx = (y + height + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, height - 1)[0] as u32 };
    }

    for y in 1..height + 2 * padding {
        buffer[y as usize] += buffer[(y - 1) as usize] as u32;
    }
}

#[cfg(test)]
mod test {

    use super::{
        column_running_sum,
        integral_image,
        padded_integral_image,
        row_running_sum
    };
    use utils::{
        gray_bench_image
    };
    use image::{
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(3, 2, vec![
            1,  3,  6,
            5, 12, 21]).unwrap();

        assert_pixels_eq!(integral_image(&image), expected);
    }

    #[bench]
    fn bench_integral_image(b: &mut test::Bencher) {
        let image = gray_bench_image(500, 500);
        b.iter(|| {
            let integral = integral_image(&image);
            test::black_box(integral);
            });
    }

    #[test]
    fn test_padded_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(5, 4, vec![
              1,  2,   4,   7,  10,
              2,  4,   8,  14,  20,
              6, 12,  21,  33,  45,
             10, 20,  34,  52,  70]).unwrap();

        assert_pixels_eq!(padded_integral_image(&image, 1, 1), expected);
    }

    #[test]
    fn test_row_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        row_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_row_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(1000, 1);
        let mut buffer = [0; 1010];
        b.iter(|| {
            row_running_sum(&image, 0, &mut buffer, 5);
            });
    }

    #[test]
    fn test_column_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(2, 3, vec![
            1, 4,
            2, 5,
            3, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        column_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_column_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(100, 1000);
        let mut buffer = [0; 1010];
        b.iter(|| {
            column_running_sum(&image, 0, &mut buffer, 5);
            });
    }
}
<commit_msg>Add reference implementation of integral_image and add quickcheck validating against it<commit_after>//! Functions for computing [integral images](https://en.wikipedia.org/wiki/Summed_area_table)
//! and running sums of rows and columns.

extern crate image;

use image::{
    Luma,
    GenericImage,
    ImageBuffer
};

use definitions::{
    VecBuffer
};

/// Computes the integral image of an 8bpp grayscale image.
/// I is the integral image of an image F if I(x, y) is the
/// sum of F(x', y') for x' <= x, y' <= y. i.e. each pixel
/// in the integral image contains the sum of the pixel intensities
/// of all input pixels that are above it and to its left.
/// The integral image has the helpful property that it lets us
/// compute the sum of pixel intensities from any rectangular region
/// in the input image in constant time.
/// Specifically, given a rectangle in F with clockwise corners
/// A, B, C, D, with A at the upper left, the total pixel intensity
/// of this rectangle is I(C) - I(B) - I(D) + I(A).
// TODO: Support more formats.
// TODO: This is extremely slow. Fix that!
pub fn integral_image<I>(image: &I) -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>> {
    padded_integral_image(image, 0, 0)
}

/// Computes the integral image of the result of padding image
/// with its boundary pixels for x_padding columns on either
/// side and y_padding rows at its top and bottom.
/// Returned image has width image.width() + 2 * x_padding
/// and height image.height() + 2 * y_padding.
pub fn padded_integral_image<I>(image: &I, x_padding: u32, y_padding: u32) -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>>
{
    let (in_width, in_height) = image.dimensions();
    let out_width = in_width + 2 * x_padding;
    let out_height = in_height + 2 * y_padding;

    let mut out: ImageBuffer<Luma<u32>, Vec<u32>> = ImageBuffer::new(out_width, out_height);

    if in_width == 0 || in_height == 0 {
        return out;
    }

    for y in 0..out_height {
        let y_in: u32;
        if y < y_padding {
            y_in = 0;
        }
        else if y >= in_height + y_padding {
            y_in = in_height - 1;
        }
        else {
            y_in = y - y_padding;
        }

        for x in 0..out_width {
            let x_in: u32;
            if x < x_padding {
                x_in = 0;
            }
            else if x >= in_width + x_padding {
                x_in = in_width - 1;
            }
            else {
                x_in = x - x_padding;
            }

            unsafe {
                let p = image.unsafe_get_pixel(x_in, y_in);
                out.unsafe_put_pixel(x, y, Luma([p[0] as u32]));
            }
        }
    }

    for x in 1..out_width {
        (*out.get_pixel_mut(x, 0))[0] += unsafe { out.unsafe_get_pixel(x - 1, 0)[0] };
    }

    for y in 1..out_height {
        (*out.get_pixel_mut(0, y))[0] += unsafe { out.unsafe_get_pixel(0, y - 1)[0] };

        for x in 1..out_width {
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x, y - 1)[0] };
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x - 1, y)[0] };
            (*out.get_pixel_mut(x, y))[0] -= unsafe { out.unsafe_get_pixel(x - 1, y - 1)[0] };
        }
    }

    out
}

/// Computes the running sum of one row of image, padded
/// at the beginning and end. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all rows in an image.
// TODO: faster, more formats
pub fn row_running_sum<I>(image: &I, row: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let width = image.width();
    assert!(buffer.len() >= (width + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), width, padding));
    assert!(row < image.height(),
        format!("row out of bound: {} >= {}", row, image.height()));

    for x in 0..padding {
        buffer[x as usize] = unsafe { image.unsafe_get_pixel(0, row)[0] as u32 };
    }

    for x in 0..width {
        let idx = (x + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(x, row)[0] as u32 };
    }

    for x in 0..padding {
        let idx = (x + width + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(width - 1, row)[0] as u32 };
    }

    for x in 1..width + 2 * padding {
        buffer[x as usize] += buffer[(x - 1) as usize] as u32;
    }
}

/// Computes the running sum of one column of image, padded
/// at the top and bottom. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all columns in an image.
// TODO: faster, more formats
pub fn column_running_sum<I>(image: &I, column: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let height = image.height();
    assert!(buffer.len() >= (height + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), height, padding));
    assert!(column < image.width(),
        format!("column out of bound: {} >= {}", column, image.width()));

    for y in 0..padding {
        buffer[y as usize] = unsafe { image.unsafe_get_pixel(column, 0)[0] as u32 };
    }

    for y in 0..height {
        let idx = (y + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, y)[0] as u32 };
    }

    for y in 0..padding {
        let idx = (y + height + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, height - 1)[0] as u32 };
    }

    for y in 1..height + 2 * padding {
        buffer[y as usize] += buffer[(y - 1) as usize] as u32;
    }
}

#[cfg(test)]
mod test {

    use super::{
        column_running_sum,
        integral_image,
        padded_integral_image,
        row_running_sum
    };
    use utils::{
        gray_bench_image,
        GrayTestImage
    };
    use image::{
        GenericImage,
        GrayImage,
        ImageBuffer,
        Luma
    };
    use quickcheck::{
        quickcheck
    };
    use definitions::{
        VecBuffer
    };
    use test;

    #[test]
    fn test_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(3, 2, vec![
            1,  3,  6,
            5, 12, 21]).unwrap();

        assert_pixels_eq!(integral_image(&image), expected);
    }

    #[bench]
    fn bench_integral_image(b: &mut test::Bencher) {
        let image = gray_bench_image(500, 500);
        b.iter(|| {
            let integral = integral_image(&image);
            test::black_box(integral);
            });
    }

    #[test]
    fn test_padded_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(5, 4, vec![
              1,  2,   4,   7,  10,
              2,  4,   8,  14,  20,
              6, 12,  21,  33,  45,
             10, 20,  34,  52,  70]).unwrap();

        assert_pixels_eq!(padded_integral_image(&image, 1, 1), expected);
    }

    #[test]
    fn test_row_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        row_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_row_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(1000, 1);
        let mut buffer = [0; 1010];
        b.iter(|| {
            row_running_sum(&image, 0, &mut buffer, 5);
            });
    }

    #[test]
    fn test_column_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(2, 3, vec![
            1, 4,
            2, 5,
            3, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        column_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_column_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(100, 1000);
        let mut buffer = [0; 1010];
        b.iter(|| {
            column_running_sum(&image, 0, &mut buffer, 5);
            });
    }

    /// Simple implementation of integral_image to validate faster versions against.
    fn integral_image_ref<I>(image: &I) -> VecBuffer<Luma<u32>>
        where I: GenericImage<Pixel=Luma<u8>>
    {
        let (width, height) = image.dimensions();
        let mut out = ImageBuffer::new(width, height);

        for y in 0..height {
            for x in 0..width {
                let mut sum = 0u32;

                for iy in 0..(y + 1) {
                    for ix in 0..(x + 1) {
                        sum += image.get_pixel(ix, iy)[0] as u32;
                    }
                }

                out.put_pixel(x, y, Luma([sum]));
            }
        }

        out
    }

    #[test]
    fn test_integral_image_matches_reference_implementation() {
        fn prop(image: GrayTestImage) -> bool {
            let expected = integral_image_ref(&image.0);
            let actual = integral_image(&image.0);
            actual.pixels().eq(expected.pixels())
        }
        quickcheck(prop as fn(GrayTestImage) -> bool);
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box, Bencher};
use itertools::Itertools;

// aproximate 100_000 iterations for each combination
const N1: usize = 100_000;
const N2: usize = 448;
const N3: usize = 86;
const N4: usize = 41;

#[bench]
fn comb_for1(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N1 {
            black_box(i);
        }
    });
}

#[bench]
fn comb_for2(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N2 {
            for j in (i + 1)..N2 {
                black_box(i + j);
            }
        }
    });
}

#[bench]
fn comb_for3(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N3 {
            for j in (i + 1)..N3 {
                for k in (j + 1)..N3 {
                    black_box(i + j + k);
                }
            }
        }
    });
}

#[bench]
fn comb_for4(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N4 {
            for j in (i + 1)..N4 {
                for k in (j + 1)..N4 {
                    for l in (k + 1)..N4 {
                        black_box(i + j + k + l);
                    }
                }
            }
        }
    });
}

#[bench]
fn comb_c1(b: &mut Bencher) {
    b.iter(|| {
        for (i,) in (0..N1).tuple_combinations() {
            black_box(i);
        }
    });
}

#[bench]
fn comb_c2(b: &mut Bencher) {
    b.iter(|| {
        for (i, j) in (0..N2).tuple_combinations() {
            black_box(i + j);
        }
    });
}

#[bench]
fn comb_c3(b: &mut Bencher) {
    b.iter(|| {
        for (i, j, k) in (0..N3).tuple_combinations() {
            black_box(i + j + k);
        }
    });
}

#[bench]
fn comb_c4(b: &mut Bencher) {
    b.iter(|| {
        for (i, j, k, l) in (0..N4).tuple_combinations() {
            black_box(i + j + k + l);
        }
    });
}

#[bench]
fn comb_pairs(b: &mut Bencher) {
    b.iter(|| {
        for (i, j) in (0..N2).pair_combinations() {
            black_box(i + j);
        }
    });
}
<commit_msg>Remove pair_combinations from benches<commit_after>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box, Bencher};
use itertools::Itertools;

// aproximate 100_000 iterations for each combination
const N1: usize = 100_000;
const N2: usize = 448;
const N3: usize = 86;
const N4: usize = 41;

#[bench]
fn comb_for1(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N1 {
            black_box(i);
        }
    });
}

#[bench]
fn comb_for2(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N2 {
            for j in (i + 1)..N2 {
                black_box(i + j);
            }
        }
    });
}

#[bench]
fn comb_for3(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N3 {
            for j in (i + 1)..N3 {
                for k in (j + 1)..N3 {
                    black_box(i + j + k);
                }
            }
        }
    });
}

#[bench]
fn comb_for4(b: &mut Bencher) {
    b.iter(|| {
        for i in 0..N4 {
            for j in (i + 1)..N4 {
                for k in (j + 1)..N4 {
                    for l in (k + 1)..N4 {
                        black_box(i + j + k + l);
                    }
                }
            }
        }
    });
}

#[bench]
fn comb_c1(b: &mut Bencher) {
    b.iter(|| {
        for (i,) in (0..N1).tuple_combinations() {
            black_box(i);
        }
    });
}

#[bench]
fn comb_c2(b: &mut Bencher) {
    b.iter(|| {
        for (i, j) in (0..N2).tuple_combinations() {
            black_box(i + j);
        }
    });
}

#[bench]
fn comb_c3(b: &mut Bencher) {
    b.iter(|| {
        for (i, j, k) in (0..N3).tuple_combinations() {
            black_box(i + j + k);
        }
    });
}

#[bench]
fn comb_c4(b: &mut Bencher) {
    b.iter(|| {
        for (i, j, k, l) in (0..N4).tuple_combinations() {
            black_box(i + j + k + l);
        }
    });
}
<|endoftext|>


<commit_before>use result::Result;
use error::StatsError;

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Cauchy {}<commit_msg>wip: impl distribution, univariate for cauchy<commit_after>use std::f64;
use rand::Rng;
use rand::distributions::{Sample, IndependentSample};
use statistics::*;
use distribution::{Univariate, Continuous, Distribution};
use result::Result;
use error::StatsError;

/// Implements the [Cauchy](https://en.wikipedia.org/wiki/Cauchy_distribution)
/// distribution, also known as the Lorentz distribution.
///
/// # Examples
///
/// ```
/// ```
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Cauchy {
    location: f64,
    scale: f64,
}

impl Cauchy {
    /// Constructs a new cauchy distribution with the given
    /// location and scale.
    ///
    /// # Errors
    ///
    /// Returns an error if location is `NaN` or `rate <= 0.0`
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Cauchy;
    ///
    /// let mut result = Cauchy::new(0.0, 1.0);
    /// assert!(result.is_ok());
    ///
    /// result = Cauchy::new(0.0, -1.0);
    /// assert!(result.is_err());
    /// ```
    pub fn new(location: f64, scale: f64) -> Result<Cauchy> {
        if location.is_nan() || scale <= 0.0 {
            Err(StatsError::BadParams)
        } else {
            Ok(Cauchy {
                location: location,
                scale: scale,
            })
        }
    }

    /// Returns the location of the cauchy distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Cauchy;
    ///
    /// let n = Cauchy::new(0.0, 1.0).unwrap();
    /// assert_eq!(n.location(), 0.0);
    /// ```
    pub fn location(&self) -> f64 {
        self.location
    }

    /// Returns the scale of the cauchy distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Cauchy;
    ///
    /// let n = Cauchy::new(0.0, 1.0).unwrap();
    /// assert_eq!(n.scale(), 1.0);
    /// ```
    pub fn scale(&self) -> f64 {
        self.scale
    }
}

impl Sample<f64> for Cauchy {
    /// Generate a random sample from a cauchy
    /// distribution using `r` as the source of randomness.
    /// Refer [here](#method.sample-1) for implementation details
    fn sample<R: Rng>(&mut self, r: &mut R) -> f64 {
        super::Distribution::sample(self, r)
    }
}

impl IndependentSample<f64> for Cauchy {
    /// Generate a random independent sample from a cauchy
    /// distribution using `r` as the source of randomness.
    /// Refer [here](#method.sample-1) for implementation details
    fn ind_sample<R: Rng>(&self, r: &mut R) -> f64 {
        super::Distribution::sample(self, r)
    }
}

impl Distribution<f64> for Cauchy {
    /// Generate a random sample from the cauchy distribution
    /// using `r` as the source of randomness
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate rand;
    /// # extern crate statrs;
    /// use rand::StdRng;
    /// use statrs::distribution::{Cauchy, Distribution};
    ///
    /// # fn main() {
    /// let mut r = rand::StdRng::new().unwrap();
    /// let n = Cauchy.new(0.0, 1.0).unwrap();
    /// print!("{}", n.sample::<StdRng>(&mut r));
    /// # }
    /// ```
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        self.location + self.scale * (f64::consts::PI * (r.next_f64() - 0.5)).tan()
    }
}

impl Univariate<f64, f64> for Cauchy {
    /// Calculates the cumulative distribution function for the
    /// cauchy distribution at `x`
    ///
    /// # Formula
    ///
    /// ```ignore
    /// (1 / π) * arctan((x - x_0) / γ) + 0.5
    /// ```
    /// where `x_0` is the location and `γ` is the scale
    fn cdf(&self, x: f64) -> f64 {
        (1.0 / f64::consts::PI) * ((x - self.location) / self.scale).atan() + 0.5
    }
}

impl Min<f64> for Cauchy {
    /// Returns the minimum value in the domain of the cauchy
    /// distribution representable by a double precision float
    ///
    /// # Formula
    ///
    /// ```ignore
    /// NEG_INF
    /// ```
    fn min(&self) -> f64 {
        f64::NEG_INFINITY
    }
}

impl Max<f64> for Cauchy {
    /// Returns the maximum value in the domain of the cauchy
    /// distribution representable by a double precision float
    ///
    /// # Formula
    ///
    /// ```ignore
    /// INF
    /// ```
    fn max(&self) -> f64 {
        f64::INFINITY
    }
}
<|endoftext|>


<commit_before>/**
  # AST DEFINITION

  ## Symbols

  ⁞literal⁞ means the token must be a literal, but it also has additional
  mandatory hygiene metadata that must be carried along (i.e. the token
  cannot be synthesized in the macro).

  «bool» one of the literal true or false
  «ident» a Rust identifier
  «ty» a Rust type
  «block» a Rust block
  «CamelCased» is the name of a production defined in the grammar

  ‹production1 | production2 (| productionN)*› is a union of several
  productions, all of which are valid.

  All other literals are literal Rust tokens.

  ## Grammar

  Class :
    {
        type: class,
        name: «ident»,
        meta: «Meta»,
        struct: ‹() | { «Field»,* }›
        methods: [ «Method»,* ]
    }

  Meta :
    {
        pub: «bool»,
        reopen: «bool»,
    }

  Field :
    «ident» : «ty»

  Method :
    {
        type: «MethodType»,
        name: «ident»,
        self: ‹() | «MethodSelf»›,
        args: «MethodArgs»,
        ret: { «ty» },
        body: «block»
    }

  MethodType : ‹initializer | instance_method | class_method›

  MethodSelf :
    {
        ownership: { «Ownership» },
        name: ‹⁞helix⁞ | ⁞self⁞›
    }

  MethodArgs :
    [ «MethodArg»,* ]

  MethodArg :
    «Name» : «ty»

  Name : ‹_ | «ident»›
*/

#[doc(hidden)]
#[macro_export]
macro_rules! parse {
    // STATE: top_level

    {
        state: top_level,
        buffer: {},
        stack: { ast: $ast:tt }
    } => {
        codegen! { $ast }
    };

    {
        state: top_level,
        buffer: $buffer:tt,
        stack: { $($stack: tt)* }
    } => {
        parse! {
            state: parse_class,
            buffer: $buffer,
            stack: {
                pub: false,
                reopen: false,
                $($stack)*
            }
        }
    };

    // STATE: parse_class

    {
        state: parse_class,
        buffer: { pub $($rest:tt)* },
        stack: {
            pub: false,
            reopen: false,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_class,
            buffer: { $($rest)* },
            stack: {
                pub: true,
                reopen: false,
                $($stack)*
            }
        }
    };

    {
        state: parse_class,
        buffer: { reopen $($rest:tt)* },
        stack: {
            pub: $pub:tt,
            reopen: false,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_class,
            buffer: { $($rest)* },
            stack: {
                pub: $pub,
                reopen: true,
                $($stack)*
            }
        }
    };

    {
        state: parse_class,
        buffer: { class $name:tt { $($body:tt)* } $($rest:tt)* },
        stack: {
            pub: $pub:tt,
            reopen: $reopen:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_class_body,
            buffer: { $($body)* },
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: { pub: $pub, reopen: $reopen },
                    struct: uninitialized,
                    methods: []
                },
                program: { $($rest)* },
                $($stack)*
            }
        }
    };

    // STATE: parse_class_body

    {
        state: parse_class_body,
        buffer: { struct { $($struct:tt)* } $($rest:tt)* },
        stack: {
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: uninitialized,
                methods : []
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_methods,
            buffer: { $($rest)* },
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: { $($struct)* },
                    methods: []
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_class_body,
        buffer: $buffer:tt,
        stack: {
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: uninitialized,
                methods : []
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_methods,
            buffer: $buffer,
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: (),
                    methods: []
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_methods

    {
        state: parse_methods,
        buffer: { #[ruby_name = $ruby_name:tt] def $name:tt $($rest:tt)* },
        stack: { $($stack:tt)* }
    } => {
        parse! {
            state: parse_method,
            buffer: { $($rest)* },
            stack: {
                rust_name: $name,
                ruby_name: { $ruby_name },
                $($stack)*
            }
        }
    };

    {
        state: parse_methods,
        buffer: { def $name:tt $($rest:tt)* },
        stack: { $($stack:tt)* }
    } => {
        parse! {
            state: parse_method,
            buffer: { $($rest)* },
            stack: {
                rust_name: $name,
                ruby_name: { stringify!($name) },
                $($stack)*
            }
        }
    };

    {
        state: parse_methods,
        buffer: {},
        stack: {
            class: $class:tt,
            program: $program:tt,
            ast: [ $($ast:tt)* ]
        }
    } => {
        parse! {
            state: top_level,
            buffer: $program,
            stack: {
                ast: [ $($ast)* $class ]
            }
        }
    };

    // STATE: parse_method

    {
        state: parse_method,
        buffer: { ( $($args:tt)* ) $($rest:tt)* },
        stack: {
            rust_name: initialize,
            ruby_name: $ruby_name:tt,
            class: $class:tt,
            $($stack:tt)*
        }
    } => {
        assert_struct!(true, $class);

        parse! {
            state: parse_arguments_helix,
            buffer: { $($args)* },
            stack: {
                class_body: { $($rest)* },
                class: $class,
                $($stack)*
            }
        }
    };

    {
        state: parse_method,
        buffer: { ( $($args:tt)* ) $($rest:tt)* },
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_arguments_self,
            buffer: { $($args)* },
            stack: {
                rust_name: $rust_name,
                ruby_name: $ruby_name,
                class_body: { $($rest)* },
                $($stack)*
            }
        }
    };

    // STATE: parse_arguments_helix

    {
        state: parse_arguments_helix,
        buffer: { $helix_arg:tt $($rest:tt)* },
        stack: { $($stack:tt)* }
    } => {
        parse! {
            state: parse_arguments_consume_possible_comma,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: initializer,
                    rust_name: initialize,
                    ruby_name: { "initialize" },
                    self: {
                        ownership: { },
                        name: $helix_arg
                    },
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_arguments_self

    {
        state: parse_arguments_self,
        buffer: { &mut $self_arg:tt $($rest:tt)* },
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        assert_valid_self_arg!($self_arg);

        parse! {
            state: parse_arguments_consume_possible_comma,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: instance_method,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: {
                        ownership: { &mut },
                        name: $self_arg
                    },
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_arguments_self,
        buffer: { & $self_arg:tt $($rest:tt)* },
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        assert_valid_self_arg!($self_arg);

        parse! {
            state: parse_arguments_consume_possible_comma,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: instance_method,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: {
                        ownership: { & },
                        name: $self_arg
                    },
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_arguments_self,
        buffer: $buffer:tt,
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_arguments,
            buffer: $buffer,
            stack: {
                method: {
                    type: class_method,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: (),
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_arguments_consume_possible_comma

    {
        state: parse_arguments_consume_possible_comma,
        buffer: { , $($rest:tt)+ },
        stack: $stack:tt
    } => {
        parse! {
            state: parse_arguments,
            buffer: { $($rest)+ },
            stack: $stack
        }
    };

    {
        state: parse_arguments_consume_possible_comma,
        buffer: { },
        stack: $stack:tt
    } => {
        parse! {
            state: parse_arguments,
            buffer: { },
            stack: $stack
        }
    };

    // STATE: parse_arguments

    {
        state: parse_arguments,
        buffer: { $($args:tt)* },
        stack: {
            method: {
                type: $type:tt,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: uninitialized,
                ret: uninitialized,
                body: uninitialized
            },
            class_body: $class_body:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_return_type,
            buffer: $class_body,
            stack: {
                method: {
                    type: $type,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: [ $($args)* ],
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_return_type

    {
        state: parse_return_type,
        buffer: { -> $ret:ty $body:block $($rest:tt)* },
        stack: {
            method: {
                type: $type:tt,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            $($stack:tt)*
        }
    } => {
        assert_no_explict_return_for_initializer!($type, ->);

        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: $type,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { $ret },
                    body: $body
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_return_type,
        buffer: { $body:block $($rest:tt)* },
        stack: {
            method: {
                type: initializer,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: $struct:tt,
                methods: $methods:tt
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: initializer,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { $name },
                    body: $body
                },
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: $struct,
                    methods: $methods
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_return_type,
        buffer: { $body:block $($rest:tt)* },
        stack: {
            method: {
                type: initializer,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            class: {
                type: class,
                meta: { pub: $pub:tt, reopen: $reopen:tt, name: $class_name:tt },
                struct: $struct:tt,
                methods: $methods:tt
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: initializer,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { $class_name },
                    body: $body
                },
                class: {
                    type: class,
                    meta: { pub: $pub, reopen: $reopen, name: $class_name },
                    struct: $struct,
                    methods: $methods
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_return_type,
        buffer: { $body:block $($rest:tt)* },
        stack: {
            method: {
                type: $type:tt,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: $type,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { () },
                    body: $body
                },
                $($stack)*
            }
        }
    };

    // STATE: finish_method

    {
        state: finish_method,
        buffer: $buffer:tt,
        stack: {
            method: $method:tt,
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: $struct:tt,
                methods: [ $($methods:tt)* ]
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_methods,
            buffer: $buffer,
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: $struct,
                    methods: [ $($methods)* $method ]
                },
                $($stack)*
            }
        }
    };
}
<commit_msg>Remove outdated/incorrect expansion rule in parser<commit_after>/**
  # AST DEFINITION

  ## Symbols

  ⁞literal⁞ means the token must be a literal, but it also has additional
  mandatory hygiene metadata that must be carried along (i.e. the token
  cannot be synthesized in the macro).

  «bool» one of the literal true or false
  «ident» a Rust identifier
  «ty» a Rust type
  «block» a Rust block
  «CamelCased» is the name of a production defined in the grammar

  ‹production1 | production2 (| productionN)*› is a union of several
  productions, all of which are valid.

  All other literals are literal Rust tokens.

  ## Grammar

  Class :
    {
        type: class,
        name: «ident»,
        meta: «Meta»,
        struct: ‹() | { «Field»,* }›
        methods: [ «Method»,* ]
    }

  Meta :
    {
        pub: «bool»,
        reopen: «bool»
    }

  Field :
    «ident» : «ty»

  Method :
    {
        type: «MethodType»,
        rust_name: «ident»,
        ruby_name: { string },
        self: ‹() | «MethodSelf»›,
        args: «MethodArgs»,
        ret: { «ty» },
        body: «block»
    }

  MethodType : ‹initializer | instance_method | class_method›

  MethodSelf :
    {
        ownership: { «Ownership» },
        name: ‹⁞helix⁞ | ⁞self⁞›
    }

  MethodArgs :
    [ «MethodArg»,* ]

  MethodArg :
    «Name» : «ty»

  Name : ‹_ | «ident»›
*/

#[doc(hidden)]
#[macro_export]
macro_rules! parse {
    // STATE: top_level

    {
        state: top_level,
        buffer: {},
        stack: { ast: $ast:tt }
    } => {
        codegen! { $ast }
    };

    {
        state: top_level,
        buffer: $buffer:tt,
        stack: { $($stack: tt)* }
    } => {
        parse! {
            state: parse_class,
            buffer: $buffer,
            stack: {
                pub: false,
                reopen: false,
                $($stack)*
            }
        }
    };

    // STATE: parse_class

    {
        state: parse_class,
        buffer: { pub $($rest:tt)* },
        stack: {
            pub: false,
            reopen: false,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_class,
            buffer: { $($rest)* },
            stack: {
                pub: true,
                reopen: false,
                $($stack)*
            }
        }
    };

    {
        state: parse_class,
        buffer: { reopen $($rest:tt)* },
        stack: {
            pub: $pub:tt,
            reopen: false,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_class,
            buffer: { $($rest)* },
            stack: {
                pub: $pub,
                reopen: true,
                $($stack)*
            }
        }
    };

    {
        state: parse_class,
        buffer: { class $name:tt { $($body:tt)* } $($rest:tt)* },
        stack: {
            pub: $pub:tt,
            reopen: $reopen:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_class_body,
            buffer: { $($body)* },
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: { pub: $pub, reopen: $reopen },
                    struct: uninitialized,
                    methods: []
                },
                program: { $($rest)* },
                $($stack)*
            }
        }
    };

    // STATE: parse_class_body

    {
        state: parse_class_body,
        buffer: { struct { $($struct:tt)* } $($rest:tt)* },
        stack: {
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: uninitialized,
                methods : []
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_methods,
            buffer: { $($rest)* },
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: { $($struct)* },
                    methods: []
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_class_body,
        buffer: $buffer:tt,
        stack: {
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: uninitialized,
                methods : []
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_methods,
            buffer: $buffer,
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: (),
                    methods: []
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_methods

    {
        state: parse_methods,
        buffer: { #[ruby_name = $ruby_name:tt] def $name:tt $($rest:tt)* },
        stack: { $($stack:tt)* }
    } => {
        parse! {
            state: parse_method,
            buffer: { $($rest)* },
            stack: {
                rust_name: $name,
                ruby_name: { $ruby_name },
                $($stack)*
            }
        }
    };

    {
        state: parse_methods,
        buffer: { def $name:tt $($rest:tt)* },
        stack: { $($stack:tt)* }
    } => {
        parse! {
            state: parse_method,
            buffer: { $($rest)* },
            stack: {
                rust_name: $name,
                ruby_name: { stringify!($name) },
                $($stack)*
            }
        }
    };

    {
        state: parse_methods,
        buffer: {},
        stack: {
            class: $class:tt,
            program: $program:tt,
            ast: [ $($ast:tt)* ]
        }
    } => {
        parse! {
            state: top_level,
            buffer: $program,
            stack: {
                ast: [ $($ast)* $class ]
            }
        }
    };

    // STATE: parse_method

    {
        state: parse_method,
        buffer: { ( $($args:tt)* ) $($rest:tt)* },
        stack: {
            rust_name: initialize,
            ruby_name: $ruby_name:tt,
            class: $class:tt,
            $($stack:tt)*
        }
    } => {
        assert_struct!(true, $class);

        parse! {
            state: parse_arguments_helix,
            buffer: { $($args)* },
            stack: {
                class_body: { $($rest)* },
                class: $class,
                $($stack)*
            }
        }
    };

    {
        state: parse_method,
        buffer: { ( $($args:tt)* ) $($rest:tt)* },
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_arguments_self,
            buffer: { $($args)* },
            stack: {
                rust_name: $rust_name,
                ruby_name: $ruby_name,
                class_body: { $($rest)* },
                $($stack)*
            }
        }
    };

    // STATE: parse_arguments_helix

    {
        state: parse_arguments_helix,
        buffer: { $helix_arg:tt $($rest:tt)* },
        stack: { $($stack:tt)* }
    } => {
        parse! {
            state: parse_arguments_consume_possible_comma,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: initializer,
                    rust_name: initialize,
                    ruby_name: { "initialize" },
                    self: {
                        ownership: { },
                        name: $helix_arg
                    },
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_arguments_self

    {
        state: parse_arguments_self,
        buffer: { &mut $self_arg:tt $($rest:tt)* },
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        assert_valid_self_arg!($self_arg);

        parse! {
            state: parse_arguments_consume_possible_comma,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: instance_method,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: {
                        ownership: { &mut },
                        name: $self_arg
                    },
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_arguments_self,
        buffer: { & $self_arg:tt $($rest:tt)* },
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        assert_valid_self_arg!($self_arg);

        parse! {
            state: parse_arguments_consume_possible_comma,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: instance_method,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: {
                        ownership: { & },
                        name: $self_arg
                    },
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_arguments_self,
        buffer: $buffer:tt,
        stack: {
            rust_name: $rust_name:tt,
            ruby_name: $ruby_name:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_arguments,
            buffer: $buffer,
            stack: {
                method: {
                    type: class_method,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: (),
                    args: uninitialized,
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_arguments_consume_possible_comma

    {
        state: parse_arguments_consume_possible_comma,
        buffer: { , $($rest:tt)+ },
        stack: $stack:tt
    } => {
        parse! {
            state: parse_arguments,
            buffer: { $($rest)+ },
            stack: $stack
        }
    };

    {
        state: parse_arguments_consume_possible_comma,
        buffer: { },
        stack: $stack:tt
    } => {
        parse! {
            state: parse_arguments,
            buffer: { },
            stack: $stack
        }
    };

    // STATE: parse_arguments

    {
        state: parse_arguments,
        buffer: { $($args:tt)* },
        stack: {
            method: {
                type: $type:tt,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: uninitialized,
                ret: uninitialized,
                body: uninitialized
            },
            class_body: $class_body:tt,
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_return_type,
            buffer: $class_body,
            stack: {
                method: {
                    type: $type,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: [ $($args)* ],
                    ret: uninitialized,
                    body: uninitialized
                },
                $($stack)*
            }
        }
    };

    // STATE: parse_return_type

    {
        state: parse_return_type,
        buffer: { -> $ret:ty $body:block $($rest:tt)* },
        stack: {
            method: {
                type: $type:tt,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            $($stack:tt)*
        }
    } => {
        assert_no_explict_return_for_initializer!($type, ->);

        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: $type,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { $ret },
                    body: $body
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_return_type,
        buffer: { $body:block $($rest:tt)* },
        stack: {
            method: {
                type: initializer,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: $struct:tt,
                methods: $methods:tt
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: initializer,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { $name },
                    body: $body
                },
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: $struct,
                    methods: $methods
                },
                $($stack)*
            }
        }
    };

    {
        state: parse_return_type,
        buffer: { $body:block $($rest:tt)* },
        stack: {
            method: {
                type: $type:tt,
                rust_name: $rust_name:tt,
                ruby_name: $ruby_name:tt,
                self: $self:tt,
                args: $args:tt,
                ret: uninitialized,
                body: uninitialized
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: finish_method,
            buffer: { $($rest)* },
            stack: {
                method: {
                    type: $type,
                    rust_name: $rust_name,
                    ruby_name: $ruby_name,
                    self: $self,
                    args: $args,
                    ret: { () },
                    body: $body
                },
                $($stack)*
            }
        }
    };

    // STATE: finish_method

    {
        state: finish_method,
        buffer: $buffer:tt,
        stack: {
            method: $method:tt,
            class: {
                type: class,
                name: $name:ident,
                meta: $meta:tt,
                struct: $struct:tt,
                methods: [ $($methods:tt)* ]
            },
            $($stack:tt)*
        }
    } => {
        parse! {
            state: parse_methods,
            buffer: $buffer,
            stack: {
                class: {
                    type: class,
                    name: $name,
                    meta: $meta,
                    struct: $struct,
                    methods: [ $($methods)* $method ]
                },
                $($stack)*
            }
        }
    };
}
<|endoftext|>


<commit_before>//! SOCKSv5 protocol support

use std::io::{IoError, IoResult, Reader, TcpStream};

static VERSION_NUMBER: u8 = 0x05;
static AUTH_NONE: u8 = 0x00;
static CONNECT_CMD: u8 = 0x01;

struct SocksConnection<'a> {
    stream: &'a mut TcpStream
}

impl <'a> SocksConnection<'a> {
    /// Make sure that the client sends the right version number at
    /// the start of the message, or fail
    fn do_client_version(&mut self) -> IoResult<()> {
        match try!(self.stream.read_byte()) {
            VERSION_NUMBER => Ok(()),
            _ => Err(IoError::last_error())
        }
    }

    /// Client -> Server:
    ///
    /// |VER | NMETHODS | METHODS  |
    /// |----+----------+----------|
    /// | 1  |    1     | 1 to 255 |
    ///
    /// Client <- Server:
    /// +----+--------+
    /// |VER | METHOD |
    /// +----+--------+
    /// | 1  |   1    |
    fn do_client_hello(&mut self) -> IoResult<()> {
        try!(self.do_client_version());

        // Number of authentication methods
        let nmethods = try!(self.stream.read_byte());

        // Authentication methods
        let methods = try!(self.stream.read_exact(nmethods as uint));

        // If the client doesn't respond to NULL-auth, we can't proceed.
        if !methods.contains(&AUTH_NONE) {
            // Send the error back
            try!(self.stream.write(&[VERSION_NUMBER, 0xFF]));

            return Err(IoError::last_error());
        }

        // Now respond
        try!(self.stream.write(&[VERSION_NUMBER, AUTH_NONE]));

        Ok(())
    }

    /// Client -> Server:
    /// +----+-----+-------+------+----------+----------+
    /// |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
    /// +----+-----+-------+------+----------+----------+
    /// | 1  |  1  | X'00' |  1   | Variable |    2     |
    ///
    /// o  VER    protocol version: X'05'
    /// o  CMD
    ///    o  CONNECT X'01'
    ///    o  BIND X'02'
    ///    o  UDP ASSOCIATE X'03'
    /// o  RSV    RESERVED
    /// o  ATYP   address type of following address
    ///    o  IP V4 address: X'01'
    ///    o  DOMAINNAME: X'03'
    ///    o  IP V6 address: X'04'
    /// o  DST.ADDR desired destination address
    /// o  DST.PORT desired destination port in network octet
    ///    order
    ///
    /// Client <- Server:
    /// +----+-----+-------+------+----------+----------+
    /// |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
    /// +----+-----+-------+------+----------+----------+
    /// | 1  |  1  | X'00' |  1   | Variable |    2     |
    ///
    ///   o  VER    protocol version: X'05'
    ///   o  REP    Reply field:
    ///      o  X'00' succeeded
    ///      o  X'01' general SOCKS server failure
    ///      o  X'02' connection not allowed by ruleset
    ///      o  X'03' Network unreachable
    ///      o  X'04' Host unreachable
    ///      o  X'05' Connection refused
    ///      o  X'06' TTL expired
    ///      o  X'07' Command not supported
    ///      o  X'08' Address type not supported
    ///      o  X'09' to X'FF' unassigned
    ///   o  RSV    RESERVED
    ///   o  ATYP   address type of following address
    ///
    ///      o  IP V4 address: X'01'
    ///      o  DOMAINNAME: X'03'
    ///      o  IP V6 address: X'04'
    ///   o  BND.ADDR       server bound address
    ///   o  BND.PORT       server bound port in network octet order
    fn do_client_request(&mut self) -> IoResult<()> {
        try!(self.do_client_version());

        // Commands (for now only connect is supported)
        match try!(self.stream.read_byte()) {
            CONNECT_CMD => (),
            _ => {
                // Tell client we don't support that command
                try!(self.stream.write(&[VERSION_NUMBER, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00]));
                return Err(IoError::last_error());
            }
        };

        // Reserved byte
        match try!(self.stream.read_byte()) {
            0u8 => (),
            _ => { return Err(IoError::last_error()); }
        };

        Ok(())
    }
}

pub fn handle_stream<'a>(stream: &'a mut TcpStream) -> () {
    let mut conn = SocksConnection { stream: stream };

    if conn.do_client_hello().is_err() {
        return;
    }

    loop {
        conn.do_client_request();
    }
}
<commit_msg>Add some more client message parsing<commit_after>//! SOCKSv5 protocol support

use std::str;
use std::io::{IoError, IoResult, Reader, TcpStream};
use std::io::net::ip::{Ipv4Addr, Ipv6Addr};
use std::io::net::addrinfo;

#[allow(dead_code)]
mod consts {
    pub static VERSION_NUMBER: u8 = 0x05;

    pub mod auth {
        pub static NONE: u8 = 0x00;
    }

    pub mod atype {
        pub static IPV4:   u8 = 0x1;
        pub static IPV6:   u8 = 0x4;
        pub static DOMAIN: u8 = 0x3;
    }

    pub mod command {
        pub static CONNECT:       u8 = 0x01;
        pub static BIND:          u8 = 0x02;
        pub static UDP_ASSOCIATE: u8 = 0x04;
    }

    pub mod reply {
        pub static SUCCESS:          u8 = 0x00;
        pub static GENERAL_FAILURE:  u8 = 0x01;
        pub static CONN_DENIED:      u8 = 0x02;
        pub static NET_UNREACHABLE:  u8 = 0x03;
        pub static HOST_UNREACHABLE: u8 = 0x04;
        pub static CONN_REFUSED:     u8 = 0x05;
        pub static TTL_EXPIRED:      u8 = 0x06;
        pub static CMD_UNSUPPORTED:  u8 = 0x07;
        pub static ADDR_UNSUPPORTED: u8 = 0x08;
    }
}

struct SocksConnection<'a> {
    stream: &'a mut TcpStream
}

impl <'a> SocksConnection<'a> {
    /// Make sure that the client sends the right version number at
    /// the start of the message, or fail
    fn do_client_version(&mut self) -> IoResult<()> {
        match try!(self.stream.read_byte()) {
            consts::VERSION_NUMBER => Ok(()),
            _ => Err(IoError::last_error())
        }
    }

    /// Client -> Server:
    ///
    /// |VER | NMETHODS | METHODS  |
    /// |----+----------+----------|
    /// | 1  |    1     | 1 to 255 |
    ///
    /// Client <- Server:
    /// +----+--------+
    /// |VER | METHOD |
    /// +----+--------+
    /// | 1  |   1    |
    fn do_client_hello(&mut self) -> IoResult<()> {
        try!(self.do_client_version());

        // Number of authentication methods
        let nmethods = try!(self.stream.read_byte());

        // Authentication methods
        let methods = try!(self.stream.read_exact(nmethods as uint));

        // If the client doesn't respond to NULL-auth, we can't proceed.
        if !methods.contains(&consts::auth::NONE) {
            // Send the error back
            try!(self.stream.write(&[consts::VERSION_NUMBER, 0xFF]));

            return Err(IoError::last_error());
        }

        // Now respond that we're using NULL auth.
        try!(self.stream.write(&[consts::VERSION_NUMBER, consts::auth::NONE]));

        Ok(())
    }

    /// Client -> Server:
    /// +----+-----+-------+------+----------+----------+
    /// |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
    /// +----+-----+-------+------+----------+----------+
    /// | 1  |  1  | X'00' |  1   | Variable |    2     |
    ///
    /// o  VER    protocol version: X'05'
    /// o  CMD
    /// o  RSV    RESERVED
    /// o  ATYP   address type of following address
    /// o  DST.ADDR desired destination address
    /// o  DST.PORT desired destination port in network octet
    ///    order
    fn do_client_request(&mut self) -> IoResult<()> {
        try!(self.do_client_version());

        // Commands (for now only connect is supported)
        match try!(self.stream.read_byte()) {
            consts::command::CONNECT => (),
            _ => {
                // Tell client we don't support that command
                try!(self.send_error_reply(consts::reply::CMD_UNSUPPORTED));
                return Err(IoError::last_error());
            }
        };

        // Reserved byte
        match try!(self.stream.read_byte()) {
            0u8 => (),
            _ => { return Err(IoError::last_error()); }
        };

        // Address type
        let _ = match try!(self.stream.read_byte()) {
            // 4 bytes
            consts::atype::IPV4 => {
                let a = try!(self.stream.read_byte());
                let b = try!(self.stream.read_byte());
                let c = try!(self.stream.read_byte());
                let d = try!(self.stream.read_byte());

                Ipv4Addr(a, b, c, d)
            },

            // 16 bytes
            consts::atype::IPV6 => {
                let a = try!(self.stream.read_be_u16());
                let b = try!(self.stream.read_be_u16());
                let c = try!(self.stream.read_be_u16());
                let d = try!(self.stream.read_be_u16());
                let e = try!(self.stream.read_be_u16());
                let f = try!(self.stream.read_be_u16());
                let g = try!(self.stream.read_be_u16());
                let h = try!(self.stream.read_be_u16());

                Ipv6Addr(a, b, c, d, e, f, g, h)
            },

            // len | hostname
            consts::atype::DOMAIN => {
                let len = try!(self.stream.read_byte());
                let hostname = try!(self.stream.read_exact(len as uint));

                let mut hosts = match str::from_utf8(hostname.as_slice()) {
                    Some(host) => try!(addrinfo::get_host_addresses(host)),
                    None => { return Err(IoError::last_error()); }
                };

                match hosts.shift() {
                    Some(host) => host,
                    None => { return Err(IoError::last_error()); }
                }
            },

            // Unsupported address type
            _ => {
                try!(self.send_error_reply(consts::reply::ADDR_UNSUPPORTED));
                return Err(IoError::last_error());
            }
        };

        // Network port
        let _ = try!(self.stream.read_be_u16());

        Ok(())
    }

    /// Client <- Server:
    /// +----+-----+-------+------+----------+----------+
    /// |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
    /// +----+-----+-------+------+----------+----------+
    /// | 1  |  1  | X'00' |  1   | Variable |    2     |
    ///
    ///   o  VER    protocol version: X'05'
    ///   o  REP    Reply field
    ///   o  RSV    RESERVED
    ///   o  ATYP   address type of following address
    ///   o  BND.ADDR       server bound address
    ///   o  BND.PORT       server bound port in network octet order
    fn send_reply(&mut self, rep: u8, atype: u8, addr: &[u8], port: u16) -> IoResult<()> {
        try!(self.stream.write(&[consts::VERSION_NUMBER, rep, 0x00, atype]));
        try!(self.stream.write(addr));
        try!(self.stream.write_be_u16(port));

        Ok(())
    }

    fn send_error_reply(&mut self, rep: u8) -> IoResult<()> {
        self.send_reply(rep, 0, &[0u8, 0, 0, 0], 0)
    }
}

pub fn handle_stream<'a>(stream: &'a mut TcpStream) -> () {
    let mut conn = SocksConnection { stream: stream };

    if conn.do_client_hello().is_err() {
        return;
    }

    conn.do_client_request();
}
<|endoftext|>


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

//! Rust helpers for Gecko's `nsCSSShadowItem`.

use app_units::Au;
use gecko::values::{convert_rgba_to_nscolor, convert_nscolor_to_rgba};
use gecko_bindings::structs::nsCSSShadowItem;
use values::computed::Color;
use values::computed::effects::{BoxShadow, SimpleShadow};

impl nsCSSShadowItem {
    /// Sets this item from the given box shadow.
    #[inline]
    pub fn set_from_box_shadow(&mut self, shadow: BoxShadow) {
        self.set_from_simple_shadow(shadow.base);
        self.mSpread = shadow.spread.0;
        self.mInset = shadow.inset;
    }

    /// Returns this item as a box shadow.
    #[inline]
    pub fn to_box_shadow(&self) -> BoxShadow {
        BoxShadow {
            base: SimpleShadow {
                color: Color::rgba(convert_nscolor_to_rgba(self.mColor)),
                horizontal: Au(self.mXOffset),
                vertical: Au(self.mYOffset),
                blur: Au(self.mRadius).into(),
            },
            spread: Au(self.mSpread),
            inset: self.mInset,
        }
    }

    /// Sets this item from the given simple shadow.
    #[inline]
    pub fn set_from_simple_shadow(&mut self, shadow: SimpleShadow) {
        self.mXOffset = shadow.horizontal.0;
        self.mYOffset = shadow.vertical.0;
        self.mRadius = shadow.blur.value();
        self.mSpread = 0;
        self.mInset = false;
        if shadow.color.is_currentcolor() {
            // TODO handle currentColor
            // https://bugzilla.mozilla.org/show_bug.cgi?id=760345
            self.mHasColor = false;
            self.mColor = 0;
        } else {
            self.mHasColor = true;
            self.mColor = convert_rgba_to_nscolor(&shadow.color.color);
        }
    }

    /// Returns this item as a simple shadow.
    #[inline]
    pub fn to_simple_shadow(&self) -> SimpleShadow {
        debug_assert_eq!(self.mSpread, 0);
        debug_assert_eq!(self.mInset, false);
        SimpleShadow {
            color: Color::rgba(convert_nscolor_to_rgba(self.mColor)),
            horizontal: Au(self.mXOffset),
            vertical: Au(self.mYOffset),
            blur: Au(self.mRadius).into(),
        }
    }
}
<commit_msg>Reuse to_simple_shadow() for box-shadow as well.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Rust helpers for Gecko's `nsCSSShadowItem`.

use app_units::Au;
use gecko::values::{convert_rgba_to_nscolor, convert_nscolor_to_rgba};
use gecko_bindings::structs::nsCSSShadowItem;
use values::computed::Color;
use values::computed::effects::{BoxShadow, SimpleShadow};

impl nsCSSShadowItem {
    /// Sets this item from the given box shadow.
    #[inline]
    pub fn set_from_box_shadow(&mut self, shadow: BoxShadow) {
        self.set_from_simple_shadow(shadow.base);
        self.mSpread = shadow.spread.0;
        self.mInset = shadow.inset;
    }

    /// Returns this item as a box shadow.
    #[inline]
    pub fn to_box_shadow(&self) -> BoxShadow {
        BoxShadow {
            base: self.extract_simple_shadow(),
            spread: Au(self.mSpread),
            inset: self.mInset,
        }
    }

    /// Sets this item from the given simple shadow.
    #[inline]
    pub fn set_from_simple_shadow(&mut self, shadow: SimpleShadow) {
        self.mXOffset = shadow.horizontal.0;
        self.mYOffset = shadow.vertical.0;
        self.mRadius = shadow.blur.value();
        self.mSpread = 0;
        self.mInset = false;
        if shadow.color.is_currentcolor() {
            // TODO handle currentColor
            // https://bugzilla.mozilla.org/show_bug.cgi?id=760345
            self.mHasColor = false;
            self.mColor = 0;
        } else {
            self.mHasColor = true;
            self.mColor = convert_rgba_to_nscolor(&shadow.color.color);
        }
    }

    /// Gets a simple shadow from this item.
    #[inline]
    fn extract_simple_shadow(&self) -> SimpleShadow {
        SimpleShadow {
            color: Color::rgba(convert_nscolor_to_rgba(self.mColor)),
            horizontal: Au(self.mXOffset),
            vertical: Au(self.mYOffset),
            blur: Au(self.mRadius).into(),
        }
    }

    /// Returns this item as a simple shadow.
    #[inline]
    pub fn to_simple_shadow(&self) -> SimpleShadow {
        debug_assert_eq!(self.mSpread, 0);
        debug_assert_eq!(self.mInset, false);
        self.extract_simple_shadow()
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Serde YAML Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! YAML Deserialization
//!
//! This module provides YAML deserialization with the type `Deserializer`.

use std::collections::btree_map;
use std::io;
use std::slice;
use std::str;

use yaml_rust::{Yaml, YamlLoader};
use yaml_rust::yaml;

use serde::de::{self, Deserialize};

use super::error::{Error, Result};

/// A structure for deserializing a YAML value into a Rust value.
pub struct Deserializer<'a> {
    /// YAML value being deserialized.
    doc: &'a Yaml,
}

impl<'a> Deserializer<'a> {
    /// Creates the YAML deserializer from an in-memory `Yaml`.
    pub fn new(doc: &'a Yaml) -> Self {
        Deserializer {
            doc: doc,
        }
    }
}

struct SeqVisitor<'a> {
    /// Iterator over the YAML array being visited.
    iter: slice::Iter<'a, Yaml>,
}

impl<'a> SeqVisitor<'a> {
    fn new(seq: &'a [Yaml]) -> Self {
        SeqVisitor {
            iter: seq.iter(),
        }
    }
}

impl<'a> de::SeqVisitor for SeqVisitor<'a> {
    type Error = Error;

    fn visit<T>(&mut self) -> Result<Option<T>>
        where T: Deserialize,
    {
        match self.iter.next() {
            None => Ok(None),
            Some(ref t) => {
                Deserialize::deserialize(&mut Deserializer::new(t)).map(Some)
            },
        }
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }
}

struct MapVisitor<'a> {
    /// Iterator over the YAML hash being visited.
    iter: btree_map::Iter<'a, Yaml, Yaml>,
    /// Value associated with the most recently visited key.
    v: Option<&'a Yaml>,
}

impl<'a> MapVisitor<'a> {
    fn new(hash: &'a yaml::Hash) -> Self {
        MapVisitor {
            iter: hash.iter(),
            v: None,
        }
    }
}

impl<'a> de::MapVisitor for MapVisitor<'a> {
    type Error = Error;

    fn visit_key<K>(&mut self) -> Result<Option<K>>
        where K: Deserialize,
    {
        match self.iter.next() {
            None => Ok(None),
            Some((ref k, ref v)) => {
                self.v = Some(v);
                Deserialize::deserialize(&mut Deserializer::new(k)).map(Some)
            },
        }
    }

    fn visit_value<V>(&mut self) -> Result<V>
        where V: Deserialize,
    {
        if let Some(v) = self.v {
            Deserialize::deserialize(&mut Deserializer::new(v))
        } else {
            panic!("must call visit_key before visit_value")
        }
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }

    fn missing_field<V>(&mut self, field: &'static str) -> Result<V>
        where V: de::Deserialize,
    {
        struct MissingFieldDeserializer(&'static str);

        impl de::Deserializer for MissingFieldDeserializer {
            type Error = Error;

            fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value>
                where V: de::Visitor,
            {
                let &mut MissingFieldDeserializer(field) = self;
                Err(de::Error::missing_field(field))
            }

            fn deserialize_option<V>(&mut self,
                                     mut visitor: V) -> Result<V::Value>
                where V: de::Visitor,
            {
                visitor.visit_none()
            }
        }

        let mut de = MissingFieldDeserializer(field);
        Ok(try!(de::Deserialize::deserialize(&mut de)))
    }
}

struct VariantVisitor<'a> {
    /// Representation of which variant it is.
    variant: &'a Yaml,
    /// Representation of the content of the variant.
    content: &'a Yaml,
}

impl<'a> VariantVisitor<'a> {
    fn new(variant: &'a Yaml, content: &'a Yaml) -> Self {
        VariantVisitor {
            variant: variant,
            content: content,
        }
    }
}

impl <'a> de::VariantVisitor for VariantVisitor<'a> {
    type Error = Error;

    fn visit_variant<V>(&mut self) -> Result<V>
        where V: Deserialize
    {
        Deserialize::deserialize(&mut Deserializer::new(self.variant))
    }

    fn visit_unit(&mut self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype<T>(&mut self) -> Result<T>
        where T: Deserialize,
    {
        Deserialize::deserialize(&mut Deserializer::new(self.content))
    }

    fn visit_tuple<V>(&mut self,
                      _len: usize,
                      visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        de::Deserializer::deserialize(&mut Deserializer::new(self.content), visitor)
    }

    fn visit_struct<V>(&mut self,
                       _fields: &'static [&'static str],
                       visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        de::Deserializer::deserialize(&mut Deserializer::new(self.content), visitor)
    }
}

impl<'a> de::Deserializer for Deserializer<'a> {
    type Error = Error;

    fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        match *self.doc {
            Yaml::Integer(i) => visitor.visit_i64(i),
            Yaml::Real(ref s) | Yaml::String(ref s) => visitor.visit_str(s),
            Yaml::Boolean(b) => visitor.visit_bool(b),
            Yaml::Array(ref seq) => visitor.visit_seq(SeqVisitor::new(seq)),
            Yaml::Hash(ref hash) => visitor.visit_map(MapVisitor::new(hash)),
            Yaml::Alias(_) => Err(Error::AliasUnsupported),
            Yaml::Null => visitor.visit_unit(),
            Yaml::BadValue => {
                // The yaml-rust library produces BadValue when a nonexistent
                // node is accessed by the Index trait, and when a type
                // conversion is invalid. Both of these are unexpected in our
                // usage.
                panic!("bad value")
            },
        }
    }

    /// Parses `null` as None and any other values as `Some(...)`.
    fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        match *self.doc {
            Yaml::Null => visitor.visit_none(),
            _ => visitor.visit_some(self),
        }
    }

    /// Parses a newtype struct as the underlying value.
    fn deserialize_newtype_struct<V>(&mut self,
                               _name: &str,
                               mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        visitor.visit_newtype_struct(self)
    }

    /// Parses an enum as a single key:value pair where the key identifies the
    /// variant and the value gives the content.
    fn deserialize_enum<V>(&mut self,
                     name: &str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value>
        where V: de::EnumVisitor,
    {
        if let Yaml::Hash(ref hash) = *self.doc {
            let mut iter = hash.iter();
            if let (Some(entry), None) = (iter.next(), iter.next()) {
                let (variant, content) = entry;
                visitor.visit(VariantVisitor::new(variant, content))
            } else {
                Err(Error::VariantMapWrongSize(String::from(name), hash.len()))
            }
        } else {
            Err(Error::VariantNotAMap(String::from(name)))
        }
    }
}

/// Decodes a YAML value from a `&str`.
pub fn from_str<T>(s: &str) -> Result<T>
    where T: Deserialize
{
    let docs = try!(YamlLoader::load_from_str(s));
    match docs.len() {
        0 => Err(Error::EndOfStream),
        1 => {
            let doc = &docs[0];
            Deserialize::deserialize(&mut Deserializer::new(doc))
        },
        n => Err(Error::TooManyDocuments(n)),
    }
}

pub fn from_iter<I, T>(iter: I) -> Result<T>
    where I: Iterator<Item=io::Result<u8>>,
          T: Deserialize,
{
    let bytes: Vec<u8> = try!(iter.collect());
    from_str(try!(str::from_utf8(&bytes)))
}

pub fn from_reader<R, T>(rdr: R) -> Result<T>
    where R: io::Read,
          T: Deserialize,
{
    from_iter(rdr.bytes())
}

pub fn from_slice<T>(v: &[u8]) -> Result<T>
    where T: Deserialize
{
    from_iter(v.iter().map(|byte| Ok(*byte)))
}
<commit_msg>Do not hardcode btree_map iterator<commit_after>// Copyright 2016 Serde YAML Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! YAML Deserialization
//!
//! This module provides YAML deserialization with the type `Deserializer`.

use std::io;
use std::iter;
use std::slice;
use std::str;

use yaml_rust::{Yaml, YamlLoader};
use yaml_rust::yaml;

use serde::de::{self, Deserialize};

use super::error::{Error, Result};

/// A structure for deserializing a YAML value into a Rust value.
pub struct Deserializer<'a> {
    /// YAML value being deserialized.
    doc: &'a Yaml,
}

impl<'a> Deserializer<'a> {
    /// Creates the YAML deserializer from an in-memory `Yaml`.
    pub fn new(doc: &'a Yaml) -> Self {
        Deserializer {
            doc: doc,
        }
    }
}

struct SeqVisitor<'a> {
    /// Iterator over the YAML array being visited.
    iter: slice::Iter<'a, Yaml>,
}

impl<'a> SeqVisitor<'a> {
    fn new(seq: &'a [Yaml]) -> Self {
        SeqVisitor {
            iter: seq.iter(),
        }
    }
}

impl<'a> de::SeqVisitor for SeqVisitor<'a> {
    type Error = Error;

    fn visit<T>(&mut self) -> Result<Option<T>>
        where T: Deserialize,
    {
        match self.iter.next() {
            None => Ok(None),
            Some(ref t) => {
                Deserialize::deserialize(&mut Deserializer::new(t)).map(Some)
            },
        }
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }
}

struct MapVisitor<'a> {
    /// Iterator over the YAML hash being visited.
    iter: <&'a yaml::Hash as iter::IntoIterator>::IntoIter,
    /// Value associated with the most recently visited key.
    v: Option<&'a Yaml>,
}

impl<'a> MapVisitor<'a> {
    fn new(hash: &'a yaml::Hash) -> Self {
        MapVisitor {
            iter: hash.into_iter(),
            v: None,
        }
    }
}

impl<'a> de::MapVisitor for MapVisitor<'a> {
    type Error = Error;

    fn visit_key<K>(&mut self) -> Result<Option<K>>
        where K: Deserialize,
    {
        match self.iter.next() {
            None => Ok(None),
            Some((ref k, ref v)) => {
                self.v = Some(v);
                Deserialize::deserialize(&mut Deserializer::new(k)).map(Some)
            },
        }
    }

    fn visit_value<V>(&mut self) -> Result<V>
        where V: Deserialize,
    {
        if let Some(v) = self.v {
            Deserialize::deserialize(&mut Deserializer::new(v))
        } else {
            panic!("must call visit_key before visit_value")
        }
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }

    fn missing_field<V>(&mut self, field: &'static str) -> Result<V>
        where V: de::Deserialize,
    {
        struct MissingFieldDeserializer(&'static str);

        impl de::Deserializer for MissingFieldDeserializer {
            type Error = Error;

            fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value>
                where V: de::Visitor,
            {
                let &mut MissingFieldDeserializer(field) = self;
                Err(de::Error::missing_field(field))
            }

            fn deserialize_option<V>(&mut self,
                                     mut visitor: V) -> Result<V::Value>
                where V: de::Visitor,
            {
                visitor.visit_none()
            }
        }

        let mut de = MissingFieldDeserializer(field);
        Ok(try!(de::Deserialize::deserialize(&mut de)))
    }
}

struct VariantVisitor<'a> {
    /// Representation of which variant it is.
    variant: &'a Yaml,
    /// Representation of the content of the variant.
    content: &'a Yaml,
}

impl<'a> VariantVisitor<'a> {
    fn new(variant: &'a Yaml, content: &'a Yaml) -> Self {
        VariantVisitor {
            variant: variant,
            content: content,
        }
    }
}

impl <'a> de::VariantVisitor for VariantVisitor<'a> {
    type Error = Error;

    fn visit_variant<V>(&mut self) -> Result<V>
        where V: Deserialize
    {
        Deserialize::deserialize(&mut Deserializer::new(self.variant))
    }

    fn visit_unit(&mut self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype<T>(&mut self) -> Result<T>
        where T: Deserialize,
    {
        Deserialize::deserialize(&mut Deserializer::new(self.content))
    }

    fn visit_tuple<V>(&mut self,
                      _len: usize,
                      visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        de::Deserializer::deserialize(&mut Deserializer::new(self.content), visitor)
    }

    fn visit_struct<V>(&mut self,
                       _fields: &'static [&'static str],
                       visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        de::Deserializer::deserialize(&mut Deserializer::new(self.content), visitor)
    }
}

impl<'a> de::Deserializer for Deserializer<'a> {
    type Error = Error;

    fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        match *self.doc {
            Yaml::Integer(i) => visitor.visit_i64(i),
            Yaml::Real(ref s) | Yaml::String(ref s) => visitor.visit_str(s),
            Yaml::Boolean(b) => visitor.visit_bool(b),
            Yaml::Array(ref seq) => visitor.visit_seq(SeqVisitor::new(seq)),
            Yaml::Hash(ref hash) => visitor.visit_map(MapVisitor::new(hash)),
            Yaml::Alias(_) => Err(Error::AliasUnsupported),
            Yaml::Null => visitor.visit_unit(),
            Yaml::BadValue => {
                // The yaml-rust library produces BadValue when a nonexistent
                // node is accessed by the Index trait, and when a type
                // conversion is invalid. Both of these are unexpected in our
                // usage.
                panic!("bad value")
            },
        }
    }

    /// Parses `null` as None and any other values as `Some(...)`.
    fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        match *self.doc {
            Yaml::Null => visitor.visit_none(),
            _ => visitor.visit_some(self),
        }
    }

    /// Parses a newtype struct as the underlying value.
    fn deserialize_newtype_struct<V>(&mut self,
                               _name: &str,
                               mut visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        visitor.visit_newtype_struct(self)
    }

    /// Parses an enum as a single key:value pair where the key identifies the
    /// variant and the value gives the content.
    fn deserialize_enum<V>(&mut self,
                     name: &str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value>
        where V: de::EnumVisitor,
    {
        if let Yaml::Hash(ref hash) = *self.doc {
            let mut iter = hash.iter();
            if let (Some(entry), None) = (iter.next(), iter.next()) {
                let (variant, content) = entry;
                visitor.visit(VariantVisitor::new(variant, content))
            } else {
                Err(Error::VariantMapWrongSize(String::from(name), hash.len()))
            }
        } else {
            Err(Error::VariantNotAMap(String::from(name)))
        }
    }
}

/// Decodes a YAML value from a `&str`.
pub fn from_str<T>(s: &str) -> Result<T>
    where T: Deserialize
{
    let docs = try!(YamlLoader::load_from_str(s));
    match docs.len() {
        0 => Err(Error::EndOfStream),
        1 => {
            let doc = &docs[0];
            Deserialize::deserialize(&mut Deserializer::new(doc))
        },
        n => Err(Error::TooManyDocuments(n)),
    }
}

pub fn from_iter<I, T>(iter: I) -> Result<T>
    where I: Iterator<Item=io::Result<u8>>,
          T: Deserialize,
{
    let bytes: Vec<u8> = try!(iter.collect());
    from_str(try!(str::from_utf8(&bytes)))
}

pub fn from_reader<R, T>(rdr: R) -> Result<T>
    where R: io::Read,
          T: Deserialize,
{
    from_iter(rdr.bytes())
}

pub fn from_slice<T>(v: &[u8]) -> Result<T>
    where T: Deserialize
{
    from_iter(v.iter().map(|byte| Ok(*byte)))
}
<|endoftext|>