<commit_before>//! The integrator module defines the Integrator trait implemented by
//! the various surface integrators used to render the scene with different
//! integration methods, eg. path tracing, photon mapping etc.

use std::f32;
use std::cmp;
use enum_set::EnumSet;
use rand::StdRng;

use scene::Scene;
use linalg::{self, Ray, Vector, Point};
use geometry::{Intersection, Emitter, Instance};
use film::Colorf;
use bxdf::{BSDF, BxDFType};
use light::Light;
use sampler::{Sampler, Sample};
use mc;

pub use self::whitted::Whitted;
pub use self::path::Path;

pub mod whitted;
pub mod path;

/// Trait implemented by the various integration methods that can be used to render
/// the scene.
pub trait Integrator {
    /// Compute the illumination at the intersection in the scene
    fn illumination(&self, scene: &Scene, light_list: &Vec<&Emitter>, ray: &Ray,
                    hit: &Intersection, sampler: &mut Sampler, rng: &mut StdRng) -> Colorf;
    /// Compute the color of specularly reflecting light off the intersection
    fn specular_reflection(&self, scene: &Scene, light_list: &Vec<&Emitter>, ray: &Ray,
                           bsdf: &BSDF, sampler: &mut Sampler, rng: &mut StdRng) -> Colorf {
        let w_o = -ray.d;
        let mut spec_refl = EnumSet::new();
        spec_refl.insert(BxDFType::Specular);
        spec_refl.insert(BxDFType::Reflection);
        let mut sample_2d = [(0.0, 0.0)];
        let mut sample_1d = [0.0];
        sampler.get_samples_2d(&mut sample_2d[..], rng);
        sampler.get_samples_1d(&mut sample_1d[..], rng);
        let sample = Sample::new(&sample_2d[0], sample_1d[0]);
        let (f, w_i, pdf, _) = bsdf.sample(&w_o, spec_refl, &sample);
        let mut refl = Colorf::broadcast(0.0);
        if pdf > 0.0 && !f.is_black() && f32::abs(linalg::dot(&w_i, &bsdf.n)) != 0.0 {
            let mut refl_ray = ray.child(&bsdf.p, &w_i);
            refl_ray.min_t = 0.001;
            if let Some(hit) = scene.intersect(&mut refl_ray) {
                let li = self.illumination(scene, light_list, &refl_ray, &hit, sampler, rng);
                refl = f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) / pdf;
            }
        }
        refl
    }
    /// Compute the color of specularly transmitted light through the intersection
    fn specular_transmission(&self, scene: &Scene, light_list: &Vec<&Emitter>, ray: &Ray,
                             bsdf: &BSDF, sampler: &mut Sampler, rng: &mut StdRng) -> Colorf {
        let w_o = -ray.d;
        let mut spec_trans = EnumSet::new();
        spec_trans.insert(BxDFType::Specular);
        spec_trans.insert(BxDFType::Transmission);
        let mut sample_2d = [(0.0, 0.0)];
        let mut sample_1d = [0.0];
        sampler.get_samples_2d(&mut sample_2d[..], rng);
        sampler.get_samples_1d(&mut sample_1d[..], rng);
        let sample = Sample::new(&sample_2d[0], sample_1d[0]);
        let (f, w_i, pdf, _) = bsdf.sample(&w_o, spec_trans, &sample);
        let mut transmit = Colorf::broadcast(0.0);
        if pdf > 0.0 && !f.is_black() && f32::abs(linalg::dot(&w_i, &bsdf.n)) != 0.0 {
            let mut trans_ray = ray.child(&bsdf.p, &w_i);
            trans_ray.min_t = 0.001;
            if let Some(hit) = scene.intersect(&mut trans_ray) {
                let li = self.illumination(scene, light_list, &trans_ray, &hit, sampler, rng);
                transmit = f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) / pdf;
            }
        }
        transmit
    }
    /// Uniformly sample the contribution of a randomly chosen light in the scene
    /// to the illumination of this BSDF at the point
    ///
    /// - `w_o` outgoing direction of the light that is incident from the light being
    ///         sampled and reflecting off the surface
    /// - `bsdf` surface properties of the surface being illuminated
    /// - `light_sample` 3 random samples for the light
    /// - `bsdf_sample` 3 random samples for the bsdf
    fn sample_one_light(&self, scene: &Scene, light_list: &Vec<&Emitter>, w_o: &Vector, p: &Point,
                        bsdf: &BSDF, light_sample: &Sample, bsdf_sample: &Sample) -> Colorf {
        let l = cmp::min((light_sample.one_d * light_list.len() as f32) as usize, light_list.len() - 1);
        self.estimate_direct(scene, w_o, p, bsdf, light_sample, bsdf_sample, light_list[l],
                             BxDFType::non_specular())
    }
    /// Estimate the direct light contribution to the surface being shaded by the light
    /// using multiple importance sampling
    ///
    /// - `w_o` outgoing direction of the light that is incident from the light being
    ///         sampled and reflecting off the surface
    /// - `bsdf` surface properties of the surface being illuminated
    /// - `light_sample` 3 random samples for the light
    /// - `bsdf_sample` 3 random samples for the bsdf
    /// - `light` light to sample contribution from
    /// - `flags` flags for which BxDF types to sample
    fn estimate_direct(&self, scene: &Scene, w_o: &Vector, p: &Point, bsdf: &BSDF, light_sample: &Sample,
                       bsdf_sample: &Sample, light: &Light, flags: EnumSet<BxDFType>) -> Colorf {
        let mut direct_light = Colorf::black();
        // Sample the light first
        let (li, w_i, pdf_light, occlusion) = light.sample_incident(&bsdf.p, &light_sample.two_d);
        if pdf_light > 0.0 && !li.is_black() && !occlusion.occluded(scene) {
            let f = bsdf.eval(w_o, &w_i, flags);
            if !f.is_black() {
                if light.delta_light() {
                    direct_light = direct_light + f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) / pdf_light;
                } else {
                    let pdf_bsdf = bsdf.pdf(w_o, &w_i, flags);
                    let w = mc::power_heuristic(1.0, pdf_light, 1.0, pdf_bsdf);
                    direct_light = direct_light + f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) * w / pdf_light;
                }
            }
        }
        // Now sample the BSDF
        if !light.delta_light() {
            let (f, w_i, pdf_bsdf, sampled_type) = bsdf.sample(w_o, flags, bsdf_sample);
            if pdf_bsdf > 0.0 && !f.is_black() {
                // Handle delta distributions the same way we did for the light
                let mut w = 1.0;
                if !sampled_type.contains(&BxDFType::Specular) {
                    let pdf_light = light.pdf(p, &w_i);
                    if pdf_light == 0.0 {
                        return direct_light;
                    }
                    w = mc::power_heuristic(1.0, pdf_bsdf, 1.0, pdf_light);
                }
                // Find out if the ray along w_i actually hits the light source
                let mut ray = Ray::segment(p, &w_i, 0.001, f32::INFINITY);
                let mut li = Colorf::black();
                match scene.intersect(&mut ray) {
                    Some(h) => {
                        if let &Instance::Emitter(ref e) = h.instance {
                            if e as *const Light == light as *const Light {
                                li = e.radiance(&-w_i, &h.dg.p, &h.dg.n)
                            }
                        }
                    },
                    None => {}
                }
                if !li.is_black() {
                    direct_light = direct_light + f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) * w / pdf_bsdf;
                }
            }
        }
        direct_light
    }
}

<commit_msg>Temporary workaround for ICE<commit_after>//! The integrator module defines the Integrator trait implemented by
//! the various surface integrators used to render the scene with different
//! integration methods, eg. path tracing, photon mapping etc.

use std::f32;
use std::cmp;
use enum_set::EnumSet;
use rand::StdRng;

use scene::Scene;
use linalg::{self, Ray, Vector, Point};
use geometry::{Intersection, Emitter, Instance};
use film::Colorf;
use bxdf::{BSDF, BxDFType};
use light::Light;
use sampler::{Sampler, Sample};
use mc;

pub use self::whitted::Whitted;
pub use self::path::Path;

pub mod whitted;
pub mod path;

/// Trait implemented by the various integration methods that can be used to render
/// the scene.
pub trait Integrator {
    /// Compute the illumination at the intersection in the scene
    fn illumination(&self, scene: &Scene, light_list: &Vec<&Emitter>, ray: &Ray,
                    hit: &Intersection, sampler: &mut Sampler, rng: &mut StdRng) -> Colorf;
    /// Compute the color of specularly reflecting light off the intersection
    fn specular_reflection(&self, scene: &Scene, light_list: &Vec<&Emitter>, ray: &Ray,
                           bsdf: &BSDF, sampler: &mut Sampler, rng: &mut StdRng) -> Colorf {
        let w_o = -ray.d;
        let mut spec_refl = EnumSet::new();
        spec_refl.insert(BxDFType::Specular);
        spec_refl.insert(BxDFType::Reflection);
        let mut sample_2d = [(0.0, 0.0)];
        let mut sample_1d = [0.0];
        sampler.get_samples_2d(&mut sample_2d[..], rng);
        sampler.get_samples_1d(&mut sample_1d[..], rng);
        let sample = Sample::new(&sample_2d[0], sample_1d[0]);
        let (f, w_i, pdf, _) = bsdf.sample(&w_o, spec_refl, &sample);
        let mut refl = Colorf::broadcast(0.0);
        if pdf > 0.0 && !f.is_black() && f32::abs(linalg::dot(&w_i, &bsdf.n)) != 0.0 {
            let mut refl_ray = ray.child(&bsdf.p, &w_i);
            refl_ray.min_t = 0.001;
            if let Some(hit) = scene.intersect(&mut refl_ray) {
                let li = self.illumination(scene, light_list, &refl_ray, &hit, sampler, rng);
                refl = f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) / pdf;
            }
        }
        refl
    }
    /// Compute the color of specularly transmitted light through the intersection
    fn specular_transmission(&self, scene: &Scene, light_list: &Vec<&Emitter>, ray: &Ray,
                             bsdf: &BSDF, sampler: &mut Sampler, rng: &mut StdRng) -> Colorf {
        let w_o = -ray.d;
        let mut spec_trans = EnumSet::new();
        spec_trans.insert(BxDFType::Specular);
        spec_trans.insert(BxDFType::Transmission);
        let mut sample_2d = [(0.0, 0.0)];
        let mut sample_1d = [0.0];
        sampler.get_samples_2d(&mut sample_2d[..], rng);
        sampler.get_samples_1d(&mut sample_1d[..], rng);
        let sample = Sample::new(&sample_2d[0], sample_1d[0]);
        let (f, w_i, pdf, _) = bsdf.sample(&w_o, spec_trans, &sample);
        let mut transmit = Colorf::broadcast(0.0);
        if pdf > 0.0 && !f.is_black() && f32::abs(linalg::dot(&w_i, &bsdf.n)) != 0.0 {
            let mut trans_ray = ray.child(&bsdf.p, &w_i);
            trans_ray.min_t = 0.001;
            if let Some(hit) = scene.intersect(&mut trans_ray) {
                let li = self.illumination(scene, light_list, &trans_ray, &hit, sampler, rng);
                transmit = f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) / pdf;
            }
        }
        transmit
    }
    /// Uniformly sample the contribution of a randomly chosen light in the scene
    /// to the illumination of this BSDF at the point
    ///
    /// - `w_o` outgoing direction of the light that is incident from the light being
    ///         sampled and reflecting off the surface
    /// - `bsdf` surface properties of the surface being illuminated
    /// - `light_sample` 3 random samples for the light
    /// - `bsdf_sample` 3 random samples for the bsdf
    fn sample_one_light(&self, scene: &Scene, light_list: &Vec<&Emitter>, w_o: &Vector, p: &Point,
                        bsdf: &BSDF, light_sample: &Sample, bsdf_sample: &Sample) -> Colorf {
        let l = cmp::min((light_sample.one_d * light_list.len() as f32) as usize, light_list.len() - 1);
        self.estimate_direct(scene, w_o, p, bsdf, light_sample, bsdf_sample, light_list[l],
                             BxDFType::non_specular())
    }
    /// Estimate the direct light contribution to the surface being shaded by the light
    /// using multiple importance sampling
    ///
    /// - `w_o` outgoing direction of the light that is incident from the light being
    ///         sampled and reflecting off the surface
    /// - `bsdf` surface properties of the surface being illuminated
    /// - `light_sample` 3 random samples for the light
    /// - `bsdf_sample` 3 random samples for the bsdf
    /// - `light` light to sample contribution from
    /// - `flags` flags for which BxDF types to sample
    fn estimate_direct(&self, scene: &Scene, w_o: &Vector, p: &Point, bsdf: &BSDF, light_sample: &Sample,
                       bsdf_sample: &Sample, light: &Light, flags: EnumSet<BxDFType>) -> Colorf {
        let mut direct_light = Colorf::black();
        // Sample the light first
        let (li, w_i, pdf_light, occlusion) = light.sample_incident(&bsdf.p, &light_sample.two_d);
        if pdf_light > 0.0 && !li.is_black() && !occlusion.occluded(scene) {
            let f = bsdf.eval(w_o, &w_i, flags);
            if !f.is_black() {
                if light.delta_light() {
                    direct_light = direct_light + f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) / pdf_light;
                } else {
                    let pdf_bsdf = bsdf.pdf(w_o, &w_i, flags);
                    let w = mc::power_heuristic(1.0, pdf_light, 1.0, pdf_bsdf);
                    direct_light = direct_light + f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) * w / pdf_light;
                }
            }
        }
        // Now sample the BSDF
        if !light.delta_light() {
            let (f, w_i, pdf_bsdf, sampled_type) = bsdf.sample(w_o, flags, bsdf_sample);
            if pdf_bsdf > 0.0 && !f.is_black() {
                // Handle delta distributions the same way we did for the light
                let mut w = 1.0;
                if !sampled_type.contains(&BxDFType::Specular) {
                    let pdf_light = light.pdf(p, &w_i);
                    if pdf_light == 0.0 {
                        return direct_light;
                    }
                    w = mc::power_heuristic(1.0, pdf_bsdf, 1.0, pdf_light);
                }
                // Find out if the ray along w_i actually hits the light source
                let mut ray = Ray::segment(p, &w_i, 0.001, f32::INFINITY);
                let mut li = Colorf::black();
                match scene.intersect(&mut ray) {
                    Some(h) => {
                        if let &Instance::Emitter(ref e) = h.instance {
                            // TODO: The extra case to *const () is to workaround the ICE I
                            // encountered writing this code: https://github.com/rust-lang/rust/issues/2744/
                            if e as *const Light as *const () == light as *const Light as *const () {
                                li = e.radiance(&-w_i, &h.dg.p, &h.dg.n)
                            }
                        }
                    },
                    None => {}
                }
                if !li.is_black() {
                    direct_light = direct_light + f * li * f32::abs(linalg::dot(&w_i, &bsdf.n)) * w / pdf_bsdf;
                }
            }
        }
        direct_light
    }
}

<|endoftext|>


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

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

#[macro_use]
extern crate itertools;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
<commit_msg>Test for linspace<commit_after>#![cfg_attr(feature = "qc", feature(plugin, custom_attribute))]
#![cfg_attr(feature="qc", plugin(quickcheck_macros))]
#![allow(dead_code)]

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

#[macro_use]
extern crate itertools;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
<|endoftext|>


<commit_before>extern crate postgres;
extern crate rustc_serialize;

use postgres::{Connection, SslMode};
use rustc_serialize::json::Json;

#[derive(Debug)]
struct TestRecord {
    id:   i32,
    name: String,
}

#[test]
fn sanity_test() {
    with_clean_database(|c| {
        let records = vec![
            TestRecord { id: 1, name: "Michael Baker".to_string() },
            TestRecord { id: 2, name: "Josh Cheek".to_string()   },
        ];

        for record in records.iter() {
            create_record(c, &record);
        }

        fetch_records(c);
    });
}

#[test]
fn basic_insert() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 1);
        let data = Json::from_str(&updates[0][..]).unwrap();
        let change = data.as_object().unwrap();
        let variant = change.get("variant").unwrap().as_string().unwrap();
        assert_eq!(variant, "Insert");
    });
}

#[test]
fn basic_delete() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string() };
        create_record(c, &record);
        delete_record(c, 1);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let data = Json::from_str(&updates[1][..]).unwrap();
        let change = data.as_object().unwrap();
        let variant = change.get("variant").unwrap().as_string().unwrap();
        assert_eq!(variant, "Delete");
    });
}

#[test]
fn basic_update() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string() };
        create_record(c, &record);
        update_record(c, TestRecord { id: 1, name: "Bichael Maker".to_string() });
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let data = Json::from_str(&updates[1][..]).unwrap();
        let change = data.as_object().unwrap();
        let variant = change.get("variant").unwrap().as_string().unwrap();
        assert_eq!(variant, "Update");
    });
}

//
// [TODO] I want to move a lot of these into a utility module when I can figure out how to do that
//

fn fetch_updates(c: &Connection) -> Vec<String> {
    let stmt = c.prepare("SELECT * FROM pg_logical_slot_peek_changes('slot', NULL, NULL)").unwrap();
    let mut result = vec![];
    for r in stmt.query(&[]).unwrap() {
        result.push(r.get(2));
    }
    result
}

fn create_slot(c: &Connection) {
    let stmt = c.prepare("select * from pg_create_logical_replication_slot('slot', 'thingy')").unwrap();
    stmt.execute(&[]).unwrap();
}

fn drop_slot(c: &Connection) {
    let stmt = c.prepare("select pg_drop_replication_slot('slot')").unwrap();
    match stmt.execute(&[]) {
        _ => {},
    }
}

fn with_slot<F>(f: F) where F:Fn(&Connection) -> () {
    with_clean_database(|c| {
        drop_slot(c);
        create_slot(c);
        f(c);
        drop_slot(c);
    });
}

fn with_clean_database<F>(f: F) where F:Fn(&Connection) -> () {
    let c = connection();
    reset_database(&c);
    f(&c);
    drop_database(&c);
}

fn reset_database(c: &Connection) {
    drop_database(&c);
    create_database(&c);
}

fn create_database(c: &Connection) {
    let stmt = c.prepare("create table test_table (id int primary key, name text)").unwrap();
    stmt.execute(&[]).unwrap();
}

fn fetch_records(c: &Connection) -> Vec<TestRecord> {
    let stmt = c.prepare("select id, name from test_table").unwrap();
    let results = stmt.query(&[]).unwrap();
    results.iter().map(|r| {
        TestRecord {
            id:   r.get(0),
            name: r.get(1),
        }
    }).collect()
}

fn create_record(c: &Connection, r: &TestRecord) {
    let stmt = c.prepare("insert into test_table (id, name) values ($1, $2)").unwrap();
    stmt.execute(&[
        &r.id,
        &r.name,
    ]).unwrap();
}

fn delete_record(c: &Connection, id: i32) {
    let stmt = c.prepare("delete from test_table where id = $1").unwrap();
    stmt.execute(&[&id]).unwrap();
}

fn update_record(c: &Connection, new_record: TestRecord) {
    let stmt = c.prepare("update test_table set name = $2 where id = $1").unwrap();
    stmt.execute(&[&new_record.id, &new_record.name]).unwrap();
}

fn drop_database(c: &Connection) {
    let stmt = c.prepare("drop table if exists test_table").unwrap();
    stmt.execute(&[]).unwrap();
}

fn connection_string() -> String {
    match std::env::var("POSTGRES_URL") {
        Ok(val) => val,
        Err(e)  => panic!(format!("You must set the POSTGRES_URL environment variable to point to a running Postgres test database when running automated tests: {}", e)),
    }
}

fn connection() -> Connection {
    match Connection::connect(&connection_string()[..], &SslMode::None) {
        Ok(c)  => c,
        Err(e) => panic!(format!("Could not connect to the test database: {}", e)),
    }
}
<commit_msg>Adds the execute sql helpers<commit_after>extern crate postgres;
extern crate rustc_serialize;

use postgres::{Connection, SslMode};
use postgres::types::{ToSql};
use rustc_serialize::json::Json;

#[derive(Debug)]
struct TestRecord {
    id:   i32,
    name: String,
}

#[test]
fn sanity_test() {
    with_clean_database(|c| {
        let records = vec![
            TestRecord { id: 1, name: "Michael Baker".to_string() },
            TestRecord { id: 2, name: "Josh Cheek".to_string()   },
        ];

        for record in records.iter() {
            create_record(c, &record);
        }

        fetch_records(c);
    });
}

#[test]
fn basic_insert() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 1);
        let data = Json::from_str(&updates[0][..]).unwrap();
        let change = data.as_object().unwrap();
        let variant = change.get("variant").unwrap().as_string().unwrap();
        assert_eq!(variant, "Insert");
    });
}

#[test]
fn basic_delete() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string() };
        create_record(c, &record);
        delete_record(c, 1);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let data = Json::from_str(&updates[1][..]).unwrap();
        let change = data.as_object().unwrap();
        let variant = change.get("variant").unwrap().as_string().unwrap();
        assert_eq!(variant, "Delete");
    });
}

#[test]
fn basic_update() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string() };
        create_record(c, &record);
        update_record(c, TestRecord { id: 1, name: "Bichael Maker".to_string() });
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let data = Json::from_str(&updates[1][..]).unwrap();
        let change = data.as_object().unwrap();
        let variant = change.get("variant").unwrap().as_string().unwrap();
        assert_eq!(variant, "Update");
    });
}

//
// [TODO] I want to move a lot of these into a utility module when I can figure out how to do that
//

fn execute(c: &Connection, command: &str, args: &[&ToSql]) {
    let stmt = c.prepare(command).unwrap();
    stmt.execute(args).unwrap();
}

fn execute_silent(c: &Connection, command: &str, args: &[&ToSql]) {
    let stmt = c.prepare(command).unwrap();
    match stmt.execute(args) { _ => {} };
}

fn fetch_updates(c: &Connection) -> Vec<String> {
    let stmt = c.prepare("SELECT * FROM pg_logical_slot_peek_changes('slot', NULL, NULL)").unwrap();
    let mut result = vec![];
    for r in stmt.query(&[]).unwrap() {
        result.push(r.get(2));
    }
    result
}

fn create_slot(c: &Connection) {
    execute(c, "select * from pg_create_logical_replication_slot('slot', 'thingy')", &[]);
}

fn drop_slot(c: &Connection) {
    execute_silent(c, "select pg_drop_replication_slot('slot')", &[]);
}

fn with_slot<F>(f: F) where F:Fn(&Connection) -> () {
    with_clean_database(|c| {
        drop_slot(c);
        create_slot(c);
        f(c);
        drop_slot(c);
    });
}

fn with_clean_database<F>(f: F) where F:Fn(&Connection) -> () {
    let c = connection();
    reset_database(&c);
    f(&c);
    drop_database(&c);
}

fn reset_database(c: &Connection) {
    drop_database(&c);
    create_database(&c);
}

fn create_database(c: &Connection) {
    execute(c, "create table test_table (id int primary key, name text)", &[]);
}

fn fetch_records(c: &Connection) -> Vec<TestRecord> {
    let stmt = c.prepare("select id, name from test_table").unwrap();
    let results = stmt.query(&[]).unwrap();
    results.iter().map(|r| {
        TestRecord {
            id:   r.get(0),
            name: r.get(1),
        }
    }).collect()
}

fn create_record(c: &Connection, r: &TestRecord) {
    let stmt = c.prepare("insert into test_table (id, name) values ($1, $2)").unwrap();
    stmt.execute(&[
        &r.id,
        &r.name,
    ]).unwrap();
}

fn delete_record(c: &Connection, id: i32) {
    execute(c, "delete from test_table where id = $1", &[&id]);
}

fn update_record(c: &Connection, new_record: TestRecord) {
    let stmt = c.prepare("update test_table set name = $2 where id = $1").unwrap();
    stmt.execute(&[&new_record.id, &new_record.name]).unwrap();
}

fn drop_database(c: &Connection) {
    execute(c, "drop table if exists test_table", &[]);
}

fn connection_string() -> String {
    match std::env::var("POSTGRES_URL") {
        Ok(val) => val,
        Err(e)  => panic!(format!("You must set the POSTGRES_URL environment variable to point to a running Postgres test database when running automated tests: {}", e)),
    }
}

fn connection() -> Connection {
    match Connection::connect(&connection_string()[..], &SslMode::None) {
        Ok(c)  => c,
        Err(e) => panic!(format!("Could not connect to the test database: {}", e)),
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(missing_copy_implementations)]

use io::{self, Read, Write, ErrorKind, BufRead};

/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `reader` and then
/// write it into `writer` in a streaming fashion until `reader`
/// returns EOF.
///
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
///
/// # Examples
///
/// ```
/// use std::io;
///
/// # fn foo() -> io::Result<()> {
/// let mut reader: &[u8] = b"hello";
/// let mut writer: Vec<u8> = vec![];
///
/// try!(io::copy(&mut reader, &mut writer));
///
/// assert_eq!(reader, &writer[..]);
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
    where R: Read, W: Write
{
    let mut buf = [0; super::DEFAULT_BUF_SIZE];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        writer.write_all(&buf[..len])?;
        written += len as u64;
    }
}

/// A reader which is always at EOF.
///
/// This struct is generally created by calling [`empty()`][empty]. Please see
/// the documentation of `empty()` for more details.
///
/// [empty]: fn.empty.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// use std::io;
/// use std::io::Read;
///
/// # fn foo() -> io::Result<String> {
/// let mut buffer = String::new();
/// try!(io::empty().read_to_string(&mut buffer));
/// # Ok(buffer)
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
    fn consume(&mut self, _n: usize) {}
}

/// A reader which yields one byte over and over and over and over and over and...
///
/// This struct is generally created by calling [`repeat()`][repeat]. Please
/// see the documentation of `repeat()` for more details.
///
/// [repeat]: fn.repeat.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }

/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        for slot in &mut *buf {
            *slot = self.byte;
        }
        Ok(buf.len())
    }
}

/// A writer which will move data into the void.
///
/// This struct is generally created by calling [`sink()`][sink]. Please
/// see the documentation of `sink()` for more details.
///
/// [sink]: fn.sink.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }

/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

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

    use io::prelude::*;
    use io::{copy, sink, empty, repeat};

    #[test]
    fn copy_copies() {
        let mut r = repeat(0).take(4);
        let mut w = sink();
        assert_eq!(copy(&mut r, &mut w).unwrap(), 4);

        let mut r = repeat(0).take(1 << 17);
        assert_eq!(copy(&mut r as &mut Read, &mut w as &mut Write).unwrap(), 1 << 17);
    }

    #[test]
    fn sink_sinks() {
        let mut s = sink();
        assert_eq!(s.write(&[]).unwrap(), 0);
        assert_eq!(s.write(&[0]).unwrap(), 1);
        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
    }

    #[test]
    fn empty_reads() {
        let mut e = empty();
        assert_eq!(e.read(&mut []).unwrap(), 0);
        assert_eq!(e.read(&mut [0]).unwrap(), 0);
        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
    }

    #[test]
    fn repeat_repeats() {
        let mut r = repeat(4);
        let mut b = [0; 1024];
        assert_eq!(r.read(&mut b).unwrap(), 1024);
        assert!(b.iter().all(|b| *b == 4));
    }

    #[test]
    fn take_some_bytes() {
        assert_eq!(repeat(4).take(100).bytes().count(), 100);
        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
    }
}
<commit_msg>Rollup merge of #34517 - frewsxcv:empty, r=GuillaumeGomez<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(missing_copy_implementations)]

use io::{self, Read, Write, ErrorKind, BufRead};

/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `reader` and then
/// write it into `writer` in a streaming fashion until `reader`
/// returns EOF.
///
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
///
/// # Examples
///
/// ```
/// use std::io;
///
/// # fn foo() -> io::Result<()> {
/// let mut reader: &[u8] = b"hello";
/// let mut writer: Vec<u8> = vec![];
///
/// try!(io::copy(&mut reader, &mut writer));
///
/// assert_eq!(reader, &writer[..]);
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
    where R: Read, W: Write
{
    let mut buf = [0; super::DEFAULT_BUF_SIZE];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        writer.write_all(&buf[..len])?;
        written += len as u64;
    }
}

/// A reader which is always at EOF.
///
/// This struct is generally created by calling [`empty()`][empty]. Please see
/// the documentation of `empty()` for more details.
///
/// [empty]: fn.empty.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// use std::io::{self, Read};
///
/// let mut buffer = String::new();
/// io::empty().read_to_string(&mut buffer).unwrap();
/// assert!(buffer.is_empty());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
    fn consume(&mut self, _n: usize) {}
}

/// A reader which yields one byte over and over and over and over and over and...
///
/// This struct is generally created by calling [`repeat()`][repeat]. Please
/// see the documentation of `repeat()` for more details.
///
/// [repeat]: fn.repeat.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }

/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        for slot in &mut *buf {
            *slot = self.byte;
        }
        Ok(buf.len())
    }
}

/// A writer which will move data into the void.
///
/// This struct is generally created by calling [`sink()`][sink]. Please
/// see the documentation of `sink()` for more details.
///
/// [sink]: fn.sink.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }

/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

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

    use io::prelude::*;
    use io::{copy, sink, empty, repeat};

    #[test]
    fn copy_copies() {
        let mut r = repeat(0).take(4);
        let mut w = sink();
        assert_eq!(copy(&mut r, &mut w).unwrap(), 4);

        let mut r = repeat(0).take(1 << 17);
        assert_eq!(copy(&mut r as &mut Read, &mut w as &mut Write).unwrap(), 1 << 17);
    }

    #[test]
    fn sink_sinks() {
        let mut s = sink();
        assert_eq!(s.write(&[]).unwrap(), 0);
        assert_eq!(s.write(&[0]).unwrap(), 1);
        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
    }

    #[test]
    fn empty_reads() {
        let mut e = empty();
        assert_eq!(e.read(&mut []).unwrap(), 0);
        assert_eq!(e.read(&mut [0]).unwrap(), 0);
        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
    }

    #[test]
    fn repeat_repeats() {
        let mut r = repeat(4);
        let mut b = [0; 1024];
        assert_eq!(r.read(&mut b).unwrap(), 1024);
        assert!(b.iter().all(|b| *b == 4));
    }

    #[test]
    fn take_some_bytes() {
        assert_eq!(repeat(4).take(100).bytes().count(), 100);
        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

//! Global storage for command line arguments
//!
//! The current incarnation of the Rust runtime expects for
//! the processes `argc` and `argv` arguments to be stored
//! in a globally-accessible location for use by the `os` module.
//!
//! XXX: Would be nice for this to not exist.
//! XXX: This has a lot of C glue for lack of globals.

use libc;
use option::{Option, Some, None};
use str;
use uint;
use unstable::finally::Finally;
use util;

/// One-time global initialization.
pub unsafe fn init(argc: int, argv: **u8) {
    let args = load_argc_and_argv(argc, argv);
    put(args);
}

/// One-time global cleanup.
pub fn cleanup() {
    rtassert!(take().is_some());
}

/// Take the global arguments from global storage.
pub fn take() -> Option<~[~str]> {
    with_lock(|| unsafe {
        let ptr = get_global_ptr();
        let val = util::replace(&mut *ptr, None);
        val.map(|s: &~~[~str]| (**s).clone())
    })
}

/// Give the global arguments to global storage.
///
/// It is an error if the arguments already exist.
pub fn put(args: ~[~str]) {
    with_lock(|| unsafe {
        let ptr = get_global_ptr();
        rtassert!((*ptr).is_none());
        (*ptr) = Some(~args.clone());
    })
}

/// Make a clone of the global arguments.
pub fn clone() -> Option<~[~str]> {
    with_lock(|| unsafe {
        let ptr = get_global_ptr();
        (*ptr).map(|s: &~~[~str]| (**s).clone())
    })
}

fn with_lock<T>(f: &fn() -> T) -> T {
    do (|| {
        unsafe {
            rust_take_global_args_lock();
            f()
        }
    }).finally {
        unsafe {
            rust_drop_global_args_lock();
        }
    }
}

fn get_global_ptr() -> *mut Option<~~[~str]> {
    unsafe { rust_get_global_args_ptr() }
}

// Copied from `os`.
unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
    let mut args = ~[];
    for uint::range(0, argc as uint) |i| {
        args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i)));
    }
    return args;
}

extern {
    fn rust_take_global_args_lock();
    fn rust_drop_global_args_lock();
    fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
}

#[cfg(test)]
mod tests {
    use option::{Some, None};
    use super::*;
    use unstable::finally::Finally;

    #[test]
    fn smoke_test() {
        // Preserve the actual global state.
        let saved_value = take();

        let expected = ~[~"happy", ~"today?"];

        put(expected.clone());
        assert!(clone() == Some(expected.clone()));
        assert!(take() == Some(expected.clone()));
        assert!(take() == None);

        do (|| {
        }).finally {
            // Restore the actual global state.
            match saved_value {
                Some(ref args) => put(args.clone()),
                None => ()
            }
        }
    }
}
<commit_msg>std:rt: args module is not used by win/mac. #7951<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

//! Global storage for command line arguments
//!
//! The current incarnation of the Rust runtime expects for
//! the processes `argc` and `argv` arguments to be stored
//! in a globally-accessible location for use by the `os` module.
//!
//! Only valid to call on linux. Mac and Windows use syscalls to
//! discover the command line arguments.
//!
//! XXX: Would be nice for this to not exist.
//! XXX: This has a lot of C glue for lack of globals.

use option::Option;

/// One-time global initialization.
pub unsafe fn init(argc: int, argv: **u8) {
    imp::init(argc, argv)
}

/// One-time global cleanup.
pub fn cleanup() {
    imp::cleanup()
}

/// Take the global arguments from global storage.
pub fn take() -> Option<~[~str]> {
    imp::take()
}

/// Give the global arguments to global storage.
///
/// It is an error if the arguments already exist.
pub fn put(args: ~[~str]) {
    imp::put(args)
}

/// Make a clone of the global arguments.
pub fn clone() -> Option<~[~str]> {
    imp::clone()
}

#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")]
mod imp {

    use libc;
    use option::{Option, Some, None};
    use str;
    use uint;
    use unstable::finally::Finally;
    use util;

    pub unsafe fn init(argc: int, argv: **u8) {
        let args = load_argc_and_argv(argc, argv);
        put(args);
    }

    pub fn cleanup() {
        rtassert!(take().is_some());
    }

    pub fn take() -> Option<~[~str]> {
        with_lock(|| unsafe {
            let ptr = get_global_ptr();
            let val = util::replace(&mut *ptr, None);
            val.map(|s: &~~[~str]| (**s).clone())
        })
    }

    pub fn put(args: ~[~str]) {
        with_lock(|| unsafe {
            let ptr = get_global_ptr();
            rtassert!((*ptr).is_none());
            (*ptr) = Some(~args.clone());
        })
    }

    pub fn clone() -> Option<~[~str]> {
        with_lock(|| unsafe {
            let ptr = get_global_ptr();
            (*ptr).map(|s: &~~[~str]| (**s).clone())
        })
    }

    fn with_lock<T>(f: &fn() -> T) -> T {
        do (|| {
            unsafe {
                rust_take_global_args_lock();
                f()
            }
        }).finally {
            unsafe {
                rust_drop_global_args_lock();
            }
        }
    }

    fn get_global_ptr() -> *mut Option<~~[~str]> {
        unsafe { rust_get_global_args_ptr() }
    }

    // Copied from `os`.
    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
        let mut args = ~[];
        for uint::range(0, argc as uint) |i| {
            args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i)));
        }
        return args;
    }

    extern {
        fn rust_take_global_args_lock();
        fn rust_drop_global_args_lock();
        fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
    }

    #[cfg(test)]
    mod tests {
        use option::{Some, None};
        use super::*;
        use unstable::finally::Finally;

        #[test]
        fn smoke_test() {
            // Preserve the actual global state.
            let saved_value = take();

            let expected = ~[~"happy", ~"today?"];

            put(expected.clone());
            assert!(clone() == Some(expected.clone()));
            assert!(take() == Some(expected.clone()));
            assert!(take() == None);

            do (|| {
            }).finally {
                // Restore the actual global state.
                match saved_value {
                    Some(ref args) => put(args.clone()),
                    None => ()
                }
            }
        }
    }
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "win32")]
mod imp {

    pub unsafe fn init(_argc: int, _argv: **u8) {
    }

    pub fn cleanup() {
    }

    pub fn take() -> Option<~[~str]> {
        fail!()
    }

    pub fn put(_args: ~[~str]) {
        fail!()
    }

    pub fn clone() -> Option<~[~str]> {
        fail!()
    }
}<|endoftext|>


<commit_before>use num::Num;
use num::Zero;
use num::One;

/// Vector whose dimension is known at runtime
///
/// Assumes the `Vector` is represented as a
/// tuple of numbers representing its projection
/// along orthogonal base vectors
pub trait Vector: Clone {
    /// Underlying scalar type of `Vector` type
    type Scalar: Num + Zero + One + Copy;
    /// Maximum allowed index for `at` and `mut_at`
    fn dimension(&self) -> usize;
    /// Length of projection along `i`-th base
    fn at(&self, i: usize) -> Self::Scalar;
    /// Mutable access to length of projection along `i`-th base
    fn mut_at(& mut self, i: usize) -> & mut Self::Scalar;
    /// Scalar product
    ///
    /// Default implementation using `at` and `dimension` is provided
    fn dot(&self, other: &Self) -> Self::Scalar {
        let mut result = Self::Scalar::zero();
        for i in 0..self.dimension() {
            result = result + self.at(i) * other.at(i)
        }
        result
    }
}

impl Vector for f64 {
    type Scalar = f64;

    fn dimension(&self) -> usize {
        1
    }

    fn at(&self, _: usize) -> f64 {
        *self
    }

    fn mut_at(&mut self, _: usize) -> &mut f64 {
        self
    }

    fn dot(&self, other: &f64) -> f64 {
        self * other
    }
}

impl Vector for [f64; 2] {
    type Scalar = f64;

    fn dimension(&self) -> usize {
        2
    }

    fn at(&self, index: usize) -> f64 {
        self[index]
    }

    fn mut_at(&mut self, index: usize) -> &mut f64 {
        &mut self[index]
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn dot() {

        use linear_algebra::Vector;

        let a = [1.0, 2.0];
        let b = [3.0, 4.0];

        assert_eq!(11.0, a.dot(&b))
    }
}
<commit_msg>rustfmt<commit_after>use num::Num;
use num::Zero;
use num::One;

/// Vector whose dimension is known at runtime
///
/// Assumes the `Vector` is represented as a
/// tuple of numbers representing its projection
/// along orthogonal base vectors
pub trait Vector: Clone {
    /// Underlying scalar type of `Vector` type
    type Scalar: Num + Zero + One + Copy;
    /// Maximum allowed index for `at` and `mut_at`
    fn dimension(&self) -> usize;
    /// Length of projection along `i`-th base
    fn at(&self, i: usize) -> Self::Scalar;
    /// Mutable access to length of projection along `i`-th base
    fn mut_at(&mut self, i: usize) -> &mut Self::Scalar;
    /// Scalar product
    ///
    /// Default implementation using `at` and `dimension` is provided
    fn dot(&self, other: &Self) -> Self::Scalar {
        let mut result = Self::Scalar::zero();
        for i in 0..self.dimension() {
            result = result + self.at(i) * other.at(i)
        }
        result
    }
}

impl Vector for f64 {
    type Scalar = f64;

    fn dimension(&self) -> usize {
        1
    }

    fn at(&self, _: usize) -> f64 {
        *self
    }

    fn mut_at(&mut self, _: usize) -> &mut f64 {
        self
    }

    fn dot(&self, other: &f64) -> f64 {
        self * other
    }
}

impl Vector for [f64; 2] {
    type Scalar = f64;

    fn dimension(&self) -> usize {
        2
    }

    fn at(&self, index: usize) -> f64 {
        self[index]
    }

    fn mut_at(&mut self, index: usize) -> &mut f64 {
        &mut self[index]
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn dot() {

        use linear_algebra::Vector;

        let a = [1.0, 2.0];
        let b = [3.0, 4.0];

        assert_eq!(11.0, a.dot(&b))
    }
}
<|endoftext|>


<commit_before>// Test helpers.

extern crate pencil;
extern crate url;
extern crate hyper;

use std::path::PathBuf;

use hyper::header::Location;

use pencil::{PenHTTPError, PenUserError};
use pencil::{PenString, PenResponse};
use pencil::{abort, redirect, safe_join, escape};

#[test]
fn test_abort() {
    let result = abort(404);
    let pencil_error = result.err().unwrap();
    let http_error = match pencil_error {
        PenHTTPError(e) => Some(e),
        PenUserError(_) => None,
    };
    assert!(http_error.unwrap().code() == 404);
}

#[test]
fn test_redirect() {
    let result = redirect("http://localhost/füübär", 302);
    let pencil_value = result.ok().unwrap();
    let response = match pencil_value {
        PenString(_) => None,
        PenResponse(response) => Some(response),
    };
    let response = response.unwrap();
    assert!(response.body.contains("/füübär"));
    let location: Option<&Location> = response.headers.get();
    let location_str = url::percent_encoding::lossy_utf8_percent_decode(location.unwrap().as_bytes());
    assert!(location_str.contains("/füübär"));
    assert!(response.status_code == 302);

    let result = redirect("http://example.com/", 301);
    let pencil_value = result.ok().unwrap();
    let response = match pencil_value {
        PenString(_) => None,
        PenResponse(response) => Some(response),
    };
    let response = response.unwrap();
    let location: Option<&Location> = response.headers.get();
    assert!(*location.unwrap() == Location("http://example.com/".to_owned()));
    assert!(response.status_code == 301);
}

#[test]
fn test_safe_join() {
    let path = safe_join("foo", "bar/baz").unwrap();
    assert!(path == PathBuf::from("foo/bar/baz"));
    assert!(safe_join("foo", "../bar/baz").is_none());
}

#[test]
fn test_escape() {
    assert!(escape(String::from("42")) == "42");
    assert!(escape(String::from("<>")) == "<>");
    assert!(escape(String::from("\"foo\"")) == ""foo"");
}
<commit_msg>Fixed tests<commit_after>// Test helpers.

extern crate pencil;
extern crate url;
extern crate hyper;

use std::path::PathBuf;

use hyper::header::Location;

use pencil::{PenHTTPError, PenUserError};
use pencil::{PenString, PenResponse};
use pencil::{abort, redirect, safe_join, escape};

#[test]
fn test_abort() {
    let result = abort(404);
    let pencil_error = result.err().unwrap();
    let http_error = match pencil_error {
        PenHTTPError(e) => Some(e),
        PenUserError(_) => None,
    };
    assert!(http_error.unwrap().code() == 404);
}

#[test]
fn test_redirect() {
    let result = redirect("http://localhost/füübär", 302);
    let pencil_value = result.ok().unwrap();
    let response = match pencil_value {
        PenString(_) => None,
        PenResponse(response) => Some(response),
    };
    let response = response.unwrap();
    let location: Option<&Location> = response.headers.get();
    let location_str = url::percent_encoding::lossy_utf8_percent_decode(location.unwrap().as_bytes());
    assert!(location_str.contains("/füübär"));
    assert!(response.status_code == 302);

    let result = redirect("http://example.com/", 301);
    let pencil_value = result.ok().unwrap();
    let response = match pencil_value {
        PenString(_) => None,
        PenResponse(response) => Some(response),
    };
    let response = response.unwrap();
    let location: Option<&Location> = response.headers.get();
    assert!(*location.unwrap() == Location("http://example.com/".to_owned()));
    assert!(response.status_code == 301);
}

#[test]
fn test_safe_join() {
    let path = safe_join("foo", "bar/baz").unwrap();
    assert!(path == PathBuf::from("foo/bar/baz"));
    assert!(safe_join("foo", "../bar/baz").is_none());
}

#[test]
fn test_escape() {
    assert!(escape(String::from("42")) == "42");
    assert!(escape(String::from("<>")) == "<>");
    assert!(escape(String::from("\"foo\"")) == ""foo"");
}
<|endoftext|>


<commit_before>use std::ptr;
use nix::sys::signal::Signal;
use nix::sys::ptrace::{ptrace, ptrace_setoptions};
use nix::sys::ptrace::ptrace::*;
use nix::libc::{c_void, c_long};
use nix::unistd::Pid;
use nix::Result;
use std::mem;

const RIP: u8 = 128;

pub fn trace_children(pid: Pid) -> Result<()> {
    //TODO need to check support.
    let options: PtraceOptions = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT |
        PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK;
    ptrace_setoptions(pid, options)
}

pub fn detach_child(pid: Pid) -> Result<c_long> {
    ptrace(PTRACE_DETACH, pid, ptr::null_mut(), ptr::null_mut())
}

pub fn continue_exec(pid: Pid, sig: Option<Signal>) -> Result<c_long> {
    match sig {
        Some(s) => ptrace(PTRACE_CONT, pid, ptr::null_mut(), (s as i32) as * mut c_void),
        None => ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut()),
    }
}

pub fn single_step(pid: Pid) -> Result<c_long> {
    ptrace(PTRACE_SINGLESTEP, pid, ptr::null_mut(), ptr::null_mut())
}

pub fn read_address(pid: Pid, address:u64) -> Result<c_long> {
    ptrace(PTRACE_PEEKDATA, pid, address as * mut c_void, ptr::null_mut())
}

pub fn write_to_address(pid: Pid,
                        address: u64,
                        data: i64) -> Result<c_long> {
    ptrace(PTRACE_POKEDATA, pid, address as * mut c_void, data as * mut c_void)
}

pub fn current_instruction_pointer(pid: Pid) -> Result<c_long> {
    ptrace(PTRACE_PEEKUSER, pid, RIP as * mut c_void, ptr::null_mut())
}

pub fn set_instruction_pointer(pid: Pid, pc: u64) -> Result<c_long> {
    ptrace(PTRACE_POKEUSER, pid, RIP as * mut c_void, pc as * mut c_void)
}

pub fn request_trace() -> Result<c_long> {
    ptrace(PTRACE_TRACEME, Pid::from_raw(0), ptr::null_mut(), ptr::null_mut())
}

pub fn get_event_data(pid: Pid) -> Result<c_long> {
    let data = Box::new(0u64 as c_long);
    let temp: *mut c_void = unsafe { mem::transmute(data) };
    let res = ptrace(PTRACE_GETEVENTMSG, pid, ptr::null_mut(), temp);
    match res {
        Ok(_) => {
            let data: Box<c_long> = unsafe { mem::transmute(temp) };
            Ok(*data)
        },
        err @ Err(..) => err,
    }
}

<commit_msg>Use ptrace_getevent<commit_after>use std::ptr;
use nix::sys::signal::Signal;
use nix::sys::ptrace::{ptrace, ptrace_getevent, ptrace_setoptions};
use nix::sys::ptrace::ptrace::*;
use nix::libc::{c_void, c_long};
use nix::unistd::Pid;
use nix::Result;

const RIP: u8 = 128;

pub fn trace_children(pid: Pid) -> Result<()> {
    //TODO need to check support.
    let options: PtraceOptions = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT |
        PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK;
    ptrace_setoptions(pid, options)
}

pub fn detach_child(pid: Pid) -> Result<c_long> {
    ptrace(PTRACE_DETACH, pid, ptr::null_mut(), ptr::null_mut())
}

pub fn continue_exec(pid: Pid, sig: Option<Signal>) -> Result<c_long> {
    match sig {
        Some(s) => ptrace(PTRACE_CONT, pid, ptr::null_mut(), (s as i32) as * mut c_void),
        None => ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut()),
    }
}

pub fn single_step(pid: Pid) -> Result<c_long> {
    ptrace(PTRACE_SINGLESTEP, pid, ptr::null_mut(), ptr::null_mut())
}

pub fn read_address(pid: Pid, address:u64) -> Result<c_long> {
    ptrace(PTRACE_PEEKDATA, pid, address as * mut c_void, ptr::null_mut())
}

pub fn write_to_address(pid: Pid,
                        address: u64,
                        data: i64) -> Result<c_long> {
    ptrace(PTRACE_POKEDATA, pid, address as * mut c_void, data as * mut c_void)
}

pub fn current_instruction_pointer(pid: Pid) -> Result<c_long> {
    ptrace(PTRACE_PEEKUSER, pid, RIP as * mut c_void, ptr::null_mut())
}

pub fn set_instruction_pointer(pid: Pid, pc: u64) -> Result<c_long> {
    ptrace(PTRACE_POKEUSER, pid, RIP as * mut c_void, pc as * mut c_void)
}

pub fn request_trace() -> Result<c_long> {
    ptrace(PTRACE_TRACEME, Pid::from_raw(0), ptr::null_mut(), ptr::null_mut())
}

pub fn get_event_data(pid: Pid) -> Result<c_long> {
    ptrace_getevent(pid)
}

<|endoftext|>


<commit_before>// Copyright (c) 2017 Anatoly Ikorsky
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use mysql_common::{
    constants::MAX_PAYLOAD_LEN,
    named_params::parse_named_params,
    packets::{
        column_from_payload, parse_stmt_packet, ComStmtClose, ComStmtExecuteRequestBuilder,
        ComStmtSendLongData, StmtPacket,
    },
};

use std::{borrow::Cow, sync::Arc};

use crate::{
    connection_like::ConnectionLike,
    consts::{CapabilityFlags, Command},
    error::*,
    queryable::{
        query_result::{read_result_set, QueryResult},
        BinaryProtocol,
    },
    Column, Params, Value,
};

pub enum ToStatementResult<'a> {
    Immediate(Statement),
    Mediate(crate::BoxFuture<'a, Statement>),
}

pub trait StatementLike: Send + Sync {
    /// Returns statement.
    fn to_statement<'a>(&'a self, conn: &'a mut crate::Conn) -> ToStatementResult<'a>;
}

impl StatementLike for str {
    /// Returns statement.
    fn to_statement<'a>(&'a self, conn: &'a mut crate::Conn) -> ToStatementResult<'a> {
        let fut = crate::BoxFuture(Box::pin(async move {
            let (named_params, raw_query) = parse_named_params(self)?;
            let inner_stmt = match conn.get_cached_stmt(&*raw_query) {
                Some(inner_stmt) => inner_stmt,
                None => conn.prepare_statement(raw_query).await?,
            };
            Ok(Statement::new(inner_stmt, named_params))
        }));
        ToStatementResult::Mediate(fut)
    }
}

impl StatementLike for Statement {
    fn to_statement<'a>(&'a self, _conn: &'a mut crate::Conn) -> ToStatementResult<'static> {
        ToStatementResult::Immediate(self.clone())
    }
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct StmtInner {
    pub(crate) raw_query: Arc<str>,
    columns: Option<Box<[Column]>>,
    params: Option<Box<[Column]>>,
    stmt_packet: StmtPacket,
    connection_id: u32,
}

impl StmtInner {
    pub(crate) fn from_payload(
        pld: &[u8],
        connection_id: u32,
        raw_query: Arc<str>,
    ) -> std::io::Result<Self> {
        let stmt_packet = parse_stmt_packet(pld)?;

        Ok(Self {
            raw_query,
            columns: None,
            params: None,
            stmt_packet,
            connection_id,
        })
    }

    pub(crate) fn with_params(mut self, params: Vec<Column>) -> Self {
        self.params = if params.is_empty() {
            None
        } else {
            Some(params.into_boxed_slice())
        };
        self
    }

    pub(crate) fn with_columns(mut self, columns: Vec<Column>) -> Self {
        self.columns = if columns.is_empty() {
            None
        } else {
            Some(columns.into_boxed_slice())
        };
        self
    }

    pub(crate) fn columns(&self) -> &[Column] {
        self.columns.as_ref().map(AsRef::as_ref).unwrap_or(&[])
    }

    pub(crate) fn params(&self) -> &[Column] {
        self.params.as_ref().map(AsRef::as_ref).unwrap_or(&[])
    }

    pub(crate) fn id(&self) -> u32 {
        self.stmt_packet.statement_id()
    }

    pub(crate) const fn connection_id(&self) -> u32 {
        self.connection_id
    }

    pub(crate) fn num_params(&self) -> u16 {
        self.stmt_packet.num_params()
    }

    pub(crate) fn num_columns(&self) -> u16 {
        self.stmt_packet.num_columns()
    }
}

/// Prepared statement.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Statement {
    pub(crate) inner: Arc<StmtInner>,
    pub(crate) named_params: Option<Vec<String>>,
}

impl Statement {
    pub(crate) fn new(inner: Arc<StmtInner>, named_params: Option<Vec<String>>) -> Self {
        Self {
            inner,
            named_params,
        }
    }

    pub fn columns(&self) -> &[Column] {
        self.inner.columns()
    }

    pub fn params(&self) -> &[Column] {
        self.inner.params()
    }

    pub fn id(&self) -> u32 {
        self.inner.id()
    }

    pub fn connection_id(&self) -> u32 {
        self.inner.connection_id()
    }

    pub fn num_params(&self) -> u16 {
        self.inner.num_params()
    }

    pub fn num_columns(&self) -> u16 {
        self.inner.num_columns()
    }
}

impl crate::Conn {
    /// Low-level helpers, that reads the given number of column packets from server.
    ///
    /// Requires `num > 0`.
    async fn read_column_defs<U>(&mut self, num: U) -> Result<Vec<Column>>
    where
        U: Into<usize>,
    {
        let num = num.into();
        debug_assert!(num > 0);
        let packets = self.read_packets(num).await?;
        let defs = packets
            .into_iter()
            .map(column_from_payload)
            .collect::<std::result::Result<Vec<Column>, _>>()
            .map_err(Error::from)?;

        if !self
            .conn_ref()
            .capabilities()
            .contains(CapabilityFlags::CLIENT_DEPRECATE_EOF)
        {
            self.read_packet().await?;
        }

        Ok(defs)
    }

    /// Helper, that retrieves `Statement` from `StatementLike`.
    pub(crate) async fn get_statement<U>(&mut self, stmt_like: &U) -> Result<Statement>
    where
        U: StatementLike + ?Sized,
    {
        match stmt_like.to_statement(self) {
            ToStatementResult::Immediate(statement) => Ok(statement),
            ToStatementResult::Mediate(statement) => statement.await,
        }
    }

    /// Low-level helper, that prepares the given statement.
    ///
    /// `raw_query` is a query with `?` placeholders (if any).
    async fn prepare_statement(&mut self, raw_query: Cow<'_, str>) -> Result<Arc<StmtInner>> {
        let raw_query: Arc<str> = raw_query.into_owned().into_boxed_str().into();

        self.write_command_data(Command::COM_STMT_PREPARE, raw_query.as_bytes())
            .await?;

        let packet = self.read_packet().await?;
        let mut inner_stmt = StmtInner::from_payload(&*packet, self.conn_ref().id(), raw_query)?;

        if inner_stmt.num_params() > 0 {
            let params = self.read_column_defs(inner_stmt.num_params()).await?;
            inner_stmt = inner_stmt.with_params(params);
        }

        if inner_stmt.num_columns() > 0 {
            let columns = self.read_column_defs(inner_stmt.num_columns()).await?;
            inner_stmt = inner_stmt.with_columns(columns);
        }

        let inner_stmt = Arc::new(inner_stmt);

        if let Some(old_stmt) = self.conn_mut().cache_stmt(&inner_stmt) {
            self.close_statement(old_stmt.id()).await?;
        }

        Ok(inner_stmt)
    }

    /// Helper, that executes the given statement with the given params.
    pub(crate) async fn execute_statement<P>(
        &mut self,
        statement: &Statement,
        params: P,
    ) -> Result<QueryResult<'_, Self, BinaryProtocol>>
    where
        P: Into<Params>,
    {
        let mut params = params.into();
        loop {
            match params {
                Params::Positional(params) => {
                    if statement.num_params() as usize != params.len() {
                        Err(DriverError::StmtParamsMismatch {
                            required: statement.num_params(),
                            supplied: params.len() as u16,
                        })?
                    }

                    let params = params.into_iter().collect::<Vec<_>>();

                    let (body, as_long_data) =
                        ComStmtExecuteRequestBuilder::new(statement.id()).build(&*params);

                    if as_long_data {
                        self.send_long_data(statement.id(), params.iter()).await?;
                    }

                    self.write_command_raw(body).await?;
                    break read_result_set(self).await;
                }
                Params::Named(_) => {
                    if statement.named_params.is_none() {
                        let error = DriverError::NamedParamsForPositionalQuery.into();
                        return Err(error);
                    }

                    params = match params.into_positional(statement.named_params.as_ref().unwrap())
                    {
                        Ok(positional_params) => positional_params,
                        Err(error) => return Err(error.into()),
                    };

                    continue;
                }
                Params::Empty => {
                    if statement.num_params() > 0 {
                        let error = DriverError::StmtParamsMismatch {
                            required: statement.num_params(),
                            supplied: 0,
                        }
                        .into();
                        return Err(error);
                    }

                    let (body, _) = ComStmtExecuteRequestBuilder::new(statement.id()).build(&[]);
                    self.write_command_raw(body).await?;
                    break read_result_set(self).await;
                }
            }
        }
    }

    /// Helper, that sends all `Value::Bytes` in the given list of paramenters as long data.
    async fn send_long_data<'a, I>(&mut self, statement_id: u32, params: I) -> Result<()>
    where
        I: Iterator<Item = &'a Value>,
    {
        for (i, value) in params.enumerate() {
            if let Value::Bytes(bytes) = value {
                let chunks = bytes.chunks(MAX_PAYLOAD_LEN - 6);
                let chunks = chunks.chain(if bytes.is_empty() {
                    Some(&[][..])
                } else {
                    None
                });
                for chunk in chunks {
                    let com = ComStmtSendLongData::new(statement_id, i, chunk);
                    self.write_command_raw(com.into()).await?;
                }
            }
        }

        Ok(())
    }

    /// Helper, that closes statement with the given id.
    pub(crate) async fn close_statement(&mut self, id: u32) -> Result<()> {
        self.write_command_raw(ComStmtClose::new(id).into()).await
    }
}
<commit_msg>Remove statement from cache on COM_STMT_CLOSE<commit_after>// Copyright (c) 2017 Anatoly Ikorsky
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use mysql_common::{
    constants::MAX_PAYLOAD_LEN,
    named_params::parse_named_params,
    packets::{
        column_from_payload, parse_stmt_packet, ComStmtClose, ComStmtExecuteRequestBuilder,
        ComStmtSendLongData, StmtPacket,
    },
};

use std::{borrow::Cow, sync::Arc};

use crate::{
    connection_like::ConnectionLike,
    consts::{CapabilityFlags, Command},
    error::*,
    queryable::{
        query_result::{read_result_set, QueryResult},
        BinaryProtocol,
    },
    Column, Params, Value,
};

pub enum ToStatementResult<'a> {
    Immediate(Statement),
    Mediate(crate::BoxFuture<'a, Statement>),
}

pub trait StatementLike: Send + Sync {
    /// Returns statement.
    fn to_statement<'a>(&'a self, conn: &'a mut crate::Conn) -> ToStatementResult<'a>;
}

impl StatementLike for str {
    /// Returns statement.
    fn to_statement<'a>(&'a self, conn: &'a mut crate::Conn) -> ToStatementResult<'a> {
        let fut = crate::BoxFuture(Box::pin(async move {
            let (named_params, raw_query) = parse_named_params(self)?;
            let inner_stmt = match conn.get_cached_stmt(&*raw_query) {
                Some(inner_stmt) => inner_stmt,
                None => conn.prepare_statement(raw_query).await?,
            };
            Ok(Statement::new(inner_stmt, named_params))
        }));
        ToStatementResult::Mediate(fut)
    }
}

impl StatementLike for Statement {
    fn to_statement<'a>(&'a self, _conn: &'a mut crate::Conn) -> ToStatementResult<'static> {
        ToStatementResult::Immediate(self.clone())
    }
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct StmtInner {
    pub(crate) raw_query: Arc<str>,
    columns: Option<Box<[Column]>>,
    params: Option<Box<[Column]>>,
    stmt_packet: StmtPacket,
    connection_id: u32,
}

impl StmtInner {
    pub(crate) fn from_payload(
        pld: &[u8],
        connection_id: u32,
        raw_query: Arc<str>,
    ) -> std::io::Result<Self> {
        let stmt_packet = parse_stmt_packet(pld)?;

        Ok(Self {
            raw_query,
            columns: None,
            params: None,
            stmt_packet,
            connection_id,
        })
    }

    pub(crate) fn with_params(mut self, params: Vec<Column>) -> Self {
        self.params = if params.is_empty() {
            None
        } else {
            Some(params.into_boxed_slice())
        };
        self
    }

    pub(crate) fn with_columns(mut self, columns: Vec<Column>) -> Self {
        self.columns = if columns.is_empty() {
            None
        } else {
            Some(columns.into_boxed_slice())
        };
        self
    }

    pub(crate) fn columns(&self) -> &[Column] {
        self.columns.as_ref().map(AsRef::as_ref).unwrap_or(&[])
    }

    pub(crate) fn params(&self) -> &[Column] {
        self.params.as_ref().map(AsRef::as_ref).unwrap_or(&[])
    }

    pub(crate) fn id(&self) -> u32 {
        self.stmt_packet.statement_id()
    }

    pub(crate) const fn connection_id(&self) -> u32 {
        self.connection_id
    }

    pub(crate) fn num_params(&self) -> u16 {
        self.stmt_packet.num_params()
    }

    pub(crate) fn num_columns(&self) -> u16 {
        self.stmt_packet.num_columns()
    }
}

/// Prepared statement.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Statement {
    pub(crate) inner: Arc<StmtInner>,
    pub(crate) named_params: Option<Vec<String>>,
}

impl Statement {
    pub(crate) fn new(inner: Arc<StmtInner>, named_params: Option<Vec<String>>) -> Self {
        Self {
            inner,
            named_params,
        }
    }

    pub fn columns(&self) -> &[Column] {
        self.inner.columns()
    }

    pub fn params(&self) -> &[Column] {
        self.inner.params()
    }

    pub fn id(&self) -> u32 {
        self.inner.id()
    }

    pub fn connection_id(&self) -> u32 {
        self.inner.connection_id()
    }

    pub fn num_params(&self) -> u16 {
        self.inner.num_params()
    }

    pub fn num_columns(&self) -> u16 {
        self.inner.num_columns()
    }
}

impl crate::Conn {
    /// Low-level helpers, that reads the given number of column packets from server.
    ///
    /// Requires `num > 0`.
    async fn read_column_defs<U>(&mut self, num: U) -> Result<Vec<Column>>
    where
        U: Into<usize>,
    {
        let num = num.into();
        debug_assert!(num > 0);
        let packets = self.read_packets(num).await?;
        let defs = packets
            .into_iter()
            .map(column_from_payload)
            .collect::<std::result::Result<Vec<Column>, _>>()
            .map_err(Error::from)?;

        if !self
            .conn_ref()
            .capabilities()
            .contains(CapabilityFlags::CLIENT_DEPRECATE_EOF)
        {
            self.read_packet().await?;
        }

        Ok(defs)
    }

    /// Helper, that retrieves `Statement` from `StatementLike`.
    pub(crate) async fn get_statement<U>(&mut self, stmt_like: &U) -> Result<Statement>
    where
        U: StatementLike + ?Sized,
    {
        match stmt_like.to_statement(self) {
            ToStatementResult::Immediate(statement) => Ok(statement),
            ToStatementResult::Mediate(statement) => statement.await,
        }
    }

    /// Low-level helper, that prepares the given statement.
    ///
    /// `raw_query` is a query with `?` placeholders (if any).
    async fn prepare_statement(&mut self, raw_query: Cow<'_, str>) -> Result<Arc<StmtInner>> {
        let raw_query: Arc<str> = raw_query.into_owned().into_boxed_str().into();

        self.write_command_data(Command::COM_STMT_PREPARE, raw_query.as_bytes())
            .await?;

        let packet = self.read_packet().await?;
        let mut inner_stmt = StmtInner::from_payload(&*packet, self.conn_ref().id(), raw_query)?;

        if inner_stmt.num_params() > 0 {
            let params = self.read_column_defs(inner_stmt.num_params()).await?;
            inner_stmt = inner_stmt.with_params(params);
        }

        if inner_stmt.num_columns() > 0 {
            let columns = self.read_column_defs(inner_stmt.num_columns()).await?;
            inner_stmt = inner_stmt.with_columns(columns);
        }

        let inner_stmt = Arc::new(inner_stmt);

        if let Some(old_stmt) = self.conn_mut().cache_stmt(&inner_stmt) {
            self.close_statement(old_stmt.id()).await?;
        }

        Ok(inner_stmt)
    }

    /// Helper, that executes the given statement with the given params.
    pub(crate) async fn execute_statement<P>(
        &mut self,
        statement: &Statement,
        params: P,
    ) -> Result<QueryResult<'_, Self, BinaryProtocol>>
    where
        P: Into<Params>,
    {
        let mut params = params.into();
        loop {
            match params {
                Params::Positional(params) => {
                    if statement.num_params() as usize != params.len() {
                        Err(DriverError::StmtParamsMismatch {
                            required: statement.num_params(),
                            supplied: params.len() as u16,
                        })?
                    }

                    let params = params.into_iter().collect::<Vec<_>>();

                    let (body, as_long_data) =
                        ComStmtExecuteRequestBuilder::new(statement.id()).build(&*params);

                    if as_long_data {
                        self.send_long_data(statement.id(), params.iter()).await?;
                    }

                    self.write_command_raw(body).await?;
                    break read_result_set(self).await;
                }
                Params::Named(_) => {
                    if statement.named_params.is_none() {
                        let error = DriverError::NamedParamsForPositionalQuery.into();
                        return Err(error);
                    }

                    params = match params.into_positional(statement.named_params.as_ref().unwrap())
                    {
                        Ok(positional_params) => positional_params,
                        Err(error) => return Err(error.into()),
                    };

                    continue;
                }
                Params::Empty => {
                    if statement.num_params() > 0 {
                        let error = DriverError::StmtParamsMismatch {
                            required: statement.num_params(),
                            supplied: 0,
                        }
                        .into();
                        return Err(error);
                    }

                    let (body, _) = ComStmtExecuteRequestBuilder::new(statement.id()).build(&[]);
                    self.write_command_raw(body).await?;
                    break read_result_set(self).await;
                }
            }
        }
    }

    /// Helper, that sends all `Value::Bytes` in the given list of paramenters as long data.
    async fn send_long_data<'a, I>(&mut self, statement_id: u32, params: I) -> Result<()>
    where
        I: Iterator<Item = &'a Value>,
    {
        for (i, value) in params.enumerate() {
            if let Value::Bytes(bytes) = value {
                let chunks = bytes.chunks(MAX_PAYLOAD_LEN - 6);
                let chunks = chunks.chain(if bytes.is_empty() {
                    Some(&[][..])
                } else {
                    None
                });
                for chunk in chunks {
                    let com = ComStmtSendLongData::new(statement_id, i, chunk);
                    self.write_command_raw(com.into()).await?;
                }
            }
        }

        Ok(())
    }

    /// Helper, that closes statement with the given id.
    pub(crate) async fn close_statement(&mut self, id: u32) -> Result<()> {
        self.stmt_cache_mut().remove(id);
        self.write_command_raw(ComStmtClose::new(id).into()).await
    }
}
<|endoftext|>


<commit_before>use super::renderer;
use fastup::Document;

#[derive(Debug, Copy, Clone, Default)]
pub struct Renderer;

impl renderer::Renderer for Renderer {
    fn render(&self, doc: &Document) -> String {
        format!("{:?}", doc)
    }
}

<commit_msg>commit: better dump renderer<commit_after>use super::renderer;
use fastup::{Document, Node};
use fastup::Node::*;

#[derive(Debug, Copy, Clone, Default)]
pub struct Renderer;

impl renderer::Renderer for Renderer {
    fn render(&self, doc: &Document) -> String {
        dump_from_document(doc, "")
    }
}

fn dump_from_document(doc: &Document, indent: &str) -> String {
    doc.0
        .iter()
        .map(|node| dump_from_node(node, indent))
        .collect::<Vec<_>>()
        .join(&format!("\n{}", indent))
}

const INDENTATION: &'static str = "    ";

fn dump_from_document_followed(doc: &Document, indent: &str) -> String {
    assert!(doc.0.len() > 0);

    if doc.0.len() == 1 {
        " ".to_string() + &dump_from_document(doc, indent)
    } else {
        let indent = format!("{}{}", INDENTATION, indent);
        format!(":\n{}", indent) + &dump_from_document(doc, &indent)
    }
}

fn dump_from_node(node: &Node, indent: &str) -> String {
    match *node {
        Text(ref text) => format!("{:?}", text),
        Foreground(color, ref doc) => {
            format!("({}){}",
                    color.clamp_to_888(),
                    dump_from_document_followed(doc, indent))
        }
        Background(color, ref doc) => {
            format!("[{}]{}",
                    color.clamp_to_888(),
                    dump_from_document_followed(doc, indent))
        }
        Bold(ref doc) => format!("{{}}{}", dump_from_document_followed(doc, indent)),
        Widget(..) => unreachable!(),
    }
}

<|endoftext|>