<commit_before>use std::sync::Arc;

use fp::Ieee754;
use light_arena::Allocator;
use num::zero;

use {Normal3f, Point2f, Point3f, Transform, Vector2f, Vector3f};
use bsdf::BSDF;
use geometry::face_forward_n;
use material::TransportMode;
use primitive::Primitive;
use ray::Ray;
use shapes::Shape;
use spectrum::Spectrum;
use stats;
use transform;

// TODO Find a better design for this mess of inheritance...

#[derive(Copy, Clone)]
pub struct Interaction {
    /// The point where the ray hit the primitive
    pub p: Point3f,
    /// Error bound for the intersection point
    pub p_error: Vector3f,
    /// Outgoing direction of the light at the intersection point (usually `-ray.d`)
    pub wo: Vector3f,
    /// Normal
    pub n: Normal3f,
}

impl Interaction {
    pub fn empty() -> Self {
        Interaction {
            p: zero(),
            p_error: zero(),
            wo: zero(),
            n: zero(),
        }
    }

    pub fn new(p: Point3f, p_error: Vector3f, wo: Vector3f, n: Normal3f) -> Interaction {
        Interaction {
            p: p,
            p_error: p_error,
            wo: wo.normalize(),
            n: n,
        }
    }

    pub fn from_point(p: &Point3f) -> Interaction {
        Interaction {
            p: *p,
            p_error: zero(),
            wo: zero(),
            n: zero(),
        }
    }

    pub fn spawn_ray(&self, dir: &Vector3f) -> Ray {
        assert!(dir.x != 0.0 && dir.y != 0.0 && dir.z != 0.0);
        stats::inc_secondary_ray();
        let o = offset_origin(&self.p, &self.p_error, &self.n, dir);
        Ray::new(o, *dir)
    }

    pub fn spawn_ray_to(&self, p: &Point3f) -> Ray {
        let o = offset_origin(&self.p, &self.p_error, &self.n, &(*p - self.p));
        let d = *p - self.p;
        assert!(d.x != 0.0 && d.y != 0.0 && d.z != 0.0);
        stats::inc_secondary_ray();
        Ray::segment(o, d, 1.0 - 1e-4)
    }

    pub fn spawn_ray_to_interaction(&self, it: &Interaction) -> Ray {
        stats::inc_secondary_ray();
        let origin = offset_origin(&self.p, &self.p_error, &self.n, &(it.p - self.p));
        let target = offset_origin(&it.p, &it.p_error, &it.n, &(origin - it.p));
        let d = target - origin;
        Ray::segment(origin, d, 1.0 - 1e-4)
    }
}

#[derive(Clone)]
pub struct SurfaceInteraction<'a, 'b> {
    pub hit: Interaction,
    /// Texture coordinates
    pub uv: Point2f,
    /// Partial derivatives at the intersection point
    pub dpdu: Vector3f,
    pub dpdv: Vector3f,
    /// Partial derivatives of the normal
    pub dndu: Normal3f,
    pub dndv: Normal3f,
    /// Ray differentials
    pub dpdx: Vector3f,
    pub dpdy: Vector3f,
    ///
    pub dudx: f32,
    pub dvdx: f32,
    pub dudy: f32,
    pub dvdy: f32,
    /// Hit shape
    pub shape: &'a Shape,
    /// Hit primitive
    pub primitive: Option<&'a Primitive>,
    /// Shading information
    pub shading: Shading,
    /// BSDF of the surface at the intersection point
    pub bsdf: Option<Arc<BSDF<'b>>>,
}

impl<'a, 'b> SurfaceInteraction<'a, 'b> {
    pub fn new(p: Point3f,
               p_error: Vector3f,
               uv: Point2f,
               wo: Vector3f,
               dpdu: Vector3f,
               dpdv: Vector3f,
               dndu: Normal3f,
               dndv: Normal3f,
               shape: &Shape)
               -> SurfaceInteraction {
        let mut n = Normal3f::from(dpdu.cross(&dpdv).normalize());
        if shape.reverse_orientation() ^ shape.transform_swaps_handedness() {
            n *= -1.0;
        }
        SurfaceInteraction {
            hit: Interaction::new(p, p_error, wo.normalize(), n),
            uv,
            dpdu,
            dpdv,
            dndu,
            dndv,
            dpdx: zero(),
            dpdy: zero(),
            dudx: 0.0,
            dvdx: 0.0,
            dudy: 0.0,
            dvdy: 0.0,
            shape: shape,
            primitive: None,
            // Initialize shading geometry from true geometry
            shading: Shading {
                n: n,
                dpdu: dpdu,
                dpdv: dpdv,
                dndu: dndu,
                dndv: dndv,
            },
            bsdf: None,
        }
    }

    pub fn le(&self, w: &Vector3f) -> Spectrum {
        self.primitive
            .and_then(|p| p.area_light())
            .map(|light| light.l(self.into(), w))
            .unwrap_or_else(Spectrum::black)
    }

    pub fn transform(&self, t: &Transform) -> SurfaceInteraction<'a, 'b> {
        let (p, p_err) = t.transform_point_with_error(&self.hit.p, &self.hit.p_error);
        let mut si = SurfaceInteraction {
            hit: Interaction::new(p,
                                  p_err,
                                  (t * &self.hit.wo).normalize(),
                                  t.transform_normal(&self.hit.n).normalize()),
            uv: self.uv,
            dpdu: t * &self.dpdu,
            dpdv: t * &self.dpdv,
            dndu: zero(),
            dndv: zero(),
            dpdx: zero(),
            dpdy: zero(),
            dudx: 0.0,
            dvdx: 0.0,
            dudy: 0.0,
            dvdy: 0.0,
            shape: self.shape,
            primitive: self.primitive,
            shading: Shading {
                n: t.transform_normal(&self.shading.n).normalize(),
                dpdu: t * &self.shading.dpdu,
                dpdv: t * &self.shading.dpdv,
                dndu: zero(),
                dndv: zero(),
            },
            bsdf: self.bsdf.clone(),
        };
        si.shading.n = face_forward_n(&si.shading.n, &si.hit.n);

        si
    }

    pub fn compute_scattering_functions(&mut self,
                                        ray: &Ray,
                                        transport: TransportMode,
                                        allow_multiple_lobes: bool,
                                        arena: &'b Allocator) {
        self.compute_differential(ray);
        if let Some(primitive) = self.primitive {
            primitive.compute_scattering_functions(self, transport, allow_multiple_lobes, arena);
        }
    }

    pub fn spawn_ray(&self, dir: &Vector3f) -> Ray {
        assert!(dir.x != 0.0 || dir.y != 0.0 || dir.z != 0.0);
        stats::inc_secondary_ray();
        let o = offset_origin(&self.hit.p, &self.hit.p_error, &self.hit.n, dir);
        Ray::new(o, *dir)
    }

    pub fn spawn_ray_to(&self, p: &Point3f) -> Ray {
        let d = *p - self.hit.p;
        assert!(d.x != 0.0 || d.y != 0.0 || d.z != 0.0);
        stats::inc_secondary_ray();
        let o = offset_origin(&self.hit.p, &self.hit.p_error, &self.hit.n, &d);
        Ray::segment(o, d, 1.0 - 1e-4)
    }

    pub fn set_shading_geometry(&mut self,
                                dpdus: &Vector3f,
                                dpdvs: &Vector3f,
                                dndus: &Normal3f,
                                dndvs: &Normal3f,
                                is_orientation_authoritative: bool) {
        // Compute shading.n for SurfaceInteraction
        self.shading.n = Normal3f::from(dpdus.cross(dpdvs).normalize());
        if self.shape.reverse_orientation() ^ self.shape.transform_swaps_handedness() {
            self.shading.n *= -1.0;
        }
        if is_orientation_authoritative {
            self.hit.n = face_forward_n(&self.hit.n, &self.shading.n);
        } else {
            self.shading.n = face_forward_n(&self.shading.n, &self.hit.n);
        }

        // Initialize shading partial derivative values
        self.shading.dpdu = *dpdus;
        self.shading.dpdv = *dpdvs;
        self.shading.dndu = *dndus;
        self.shading.dndv = *dndvs;
    }

    #[allow(non_snake_case)]
    pub fn compute_differential(&mut self, ray: &Ray) {
        if let Some(ref diff) = ray.differential {
            // Estimate screen space change in p and (u,v)

            // Compute auxiliary intersection points with plane
            let d = self.hit
                .n
                .dot(&Vector3f::new(self.hit.p.x, self.hit.p.y, self.hit.p.z));
            let tx = -(self.hit.n.dot(&Vector3f::from(diff.rx_origin)) - d) /
                     self.hit.n.dot(&diff.rx_direction);
            let ty = -(self.hit.n.dot(&Vector3f::from(diff.ry_origin)) - d) /
                     self.hit.n.dot(&diff.ry_direction);
            if tx.is_infinite() || tx.is_nan() || ty.is_infinite() || ty.is_nan() {
                self.dudx = 0.0;
                self.dudy = 0.0;
                self.dvdx = 0.0;
                self.dvdy = 0.0;
                self.dpdx = zero();
                self.dpdy = zero();
                return;
            }

            let px = diff.rx_origin + tx * diff.rx_direction;
            let py = diff.ry_origin + ty * diff.ry_direction;
            self.dpdx = px - self.hit.p;
            self.dpdy = py - self.hit.p;
            // Compute (u,v) offsets at auxiliary points

            // Choose two dimensions to use for ray offset computation
            let mut dim: [usize; 2] = [0; 2];
            if self.hit.n.x.abs() > self.hit.n.y.abs() && self.hit.n.x.abs() > self.hit.n.z.abs() {
                dim[0] = 1;
                dim[1] = 2;
            } else if self.hit.n.y.abs() > self.hit.n.z.abs() {
                dim[0] = 0;
                dim[1] = 2;
            } else {
                dim[0] = 0;
                dim[1] = 1;
            }
            // Initialize A, Bx, and By matrices for offset computation
            let A = [[self.dpdu[dim[0]], self.dpdv[dim[0]]],
                     [self.dpdu[dim[1]], self.dpdv[dim[1]]]];
            let Bx = Vector2f::new(px[dim[0]] - self.hit.p[dim[0]],
                                   px[dim[1]] - self.hit.p[dim[1]]);
            let By = Vector2f::new(py[dim[0]] - self.hit.p[dim[0]],
                                   py[dim[1]] - self.hit.p[dim[1]]);

            let (dudx, dvdx) = transform::solve_linear_system2x2(&A, &Bx).unwrap_or((0.0, 0.0));
            let (dudy, dvdy) = transform::solve_linear_system2x2(&A, &By).unwrap_or((0.0, 0.0));
            self.dudx = dudx;
            self.dvdx = dvdx;
            self.dudy = dudy;
            self.dvdy = dvdy;
        } else {
            self.dudx = 0.0;
            self.dudy = 0.0;
            self.dvdx = 0.0;
            self.dvdy = 0.0;
            self.dpdx = zero();
            self.dpdy = zero();
        }
    }
}

fn offset_origin(p: &Point3f, p_err: &Vector3f, n: &Normal3f, w: &Vector3f) -> Point3f {
    let d = n.abs().dot(p_err);
    let mut offset = d * Vector3f::from(*n);
    if w.dotn(n) < 0.0 {
        offset = -offset;
    }
    let mut po = *p + offset;
    for i in 0..3 {
        if offset[i] > 0.0 {
            po[i] = po[i].next();
        } else if offset[i] < 0.0 {
            po[i] = po[i].prev();
        }
    }
    po
}

impl<'a, 'b> From<SurfaceInteraction<'a, 'b>> for Interaction {
    fn from(si: SurfaceInteraction) -> Interaction {
        si.hit
    }
}

impl<'a, 'b> From<&'a SurfaceInteraction<'a, 'b>> for &'a Interaction {
    fn from(si: &'a SurfaceInteraction<'a, 'b>) -> &'a Interaction {
        &si.hit
    }
}

/// Normal and partial derivatives used for shading. Can be different from geometric ones due to
/// bump mapping, etc.
#[derive(Clone)]
pub struct Shading {
    pub n: Normal3f,
    pub dpdu: Vector3f,
    pub dpdv: Vector3f,
    pub dndu: Normal3f,
    pub dndv: Normal3f,
}

impl Default for Shading {
    fn default() -> Self {
        Shading {
            n: zero(),
            dpdu: zero(),
            dpdv: zero(),
            dndu: zero(),
            dndv: zero(),
        }
    }
}
<commit_msg>Fix stupidly incorrect assertions ...<commit_after>use std::sync::Arc;

use fp::Ieee754;
use light_arena::Allocator;
use num::zero;

use {Normal3f, Point2f, Point3f, Transform, Vector2f, Vector3f};
use bsdf::BSDF;
use geometry::face_forward_n;
use material::TransportMode;
use primitive::Primitive;
use ray::Ray;
use shapes::Shape;
use spectrum::Spectrum;
use stats;
use transform;

// TODO Find a better design for this mess of inheritance...

#[derive(Copy, Clone)]
pub struct Interaction {
    /// The point where the ray hit the primitive
    pub p: Point3f,
    /// Error bound for the intersection point
    pub p_error: Vector3f,
    /// Outgoing direction of the light at the intersection point (usually `-ray.d`)
    pub wo: Vector3f,
    /// Normal
    pub n: Normal3f,
}

impl Interaction {
    pub fn empty() -> Self {
        Interaction {
            p: zero(),
            p_error: zero(),
            wo: zero(),
            n: zero(),
        }
    }

    pub fn new(p: Point3f, p_error: Vector3f, wo: Vector3f, n: Normal3f) -> Interaction {
        Interaction {
            p: p,
            p_error: p_error,
            wo: wo.normalize(),
            n: n,
        }
    }

    pub fn from_point(p: &Point3f) -> Interaction {
        Interaction {
            p: *p,
            p_error: zero(),
            wo: zero(),
            n: zero(),
        }
    }

    pub fn spawn_ray(&self, dir: &Vector3f) -> Ray {
        assert!(dir.x != 0.0 || dir.y != 0.0 || dir.z != 0.0);
        stats::inc_secondary_ray();
        let o = offset_origin(&self.p, &self.p_error, &self.n, dir);
        Ray::new(o, *dir)
    }

    pub fn spawn_ray_to(&self, p: &Point3f) -> Ray {
        let o = offset_origin(&self.p, &self.p_error, &self.n, &(*p - self.p));
        let d = *p - self.p;
        assert!(d.x != 0.0 || d.y != 0.0 || d.z != 0.0);
        stats::inc_secondary_ray();
        Ray::segment(o, d, 1.0 - 1e-4)
    }

    pub fn spawn_ray_to_interaction(&self, it: &Interaction) -> Ray {
        stats::inc_secondary_ray();
        let origin = offset_origin(&self.p, &self.p_error, &self.n, &(it.p - self.p));
        let target = offset_origin(&it.p, &it.p_error, &it.n, &(origin - it.p));
        let d = target - origin;
        Ray::segment(origin, d, 1.0 - 1e-4)
    }
}

#[derive(Clone)]
pub struct SurfaceInteraction<'a, 'b> {
    pub hit: Interaction,
    /// Texture coordinates
    pub uv: Point2f,
    /// Partial derivatives at the intersection point
    pub dpdu: Vector3f,
    pub dpdv: Vector3f,
    /// Partial derivatives of the normal
    pub dndu: Normal3f,
    pub dndv: Normal3f,
    /// Ray differentials
    pub dpdx: Vector3f,
    pub dpdy: Vector3f,
    ///
    pub dudx: f32,
    pub dvdx: f32,
    pub dudy: f32,
    pub dvdy: f32,
    /// Hit shape
    pub shape: &'a Shape,
    /// Hit primitive
    pub primitive: Option<&'a Primitive>,
    /// Shading information
    pub shading: Shading,
    /// BSDF of the surface at the intersection point
    pub bsdf: Option<Arc<BSDF<'b>>>,
}

impl<'a, 'b> SurfaceInteraction<'a, 'b> {
    pub fn new(p: Point3f,
               p_error: Vector3f,
               uv: Point2f,
               wo: Vector3f,
               dpdu: Vector3f,
               dpdv: Vector3f,
               dndu: Normal3f,
               dndv: Normal3f,
               shape: &Shape)
               -> SurfaceInteraction {
        let mut n = Normal3f::from(dpdu.cross(&dpdv).normalize());
        if shape.reverse_orientation() ^ shape.transform_swaps_handedness() {
            n *= -1.0;
        }
        SurfaceInteraction {
            hit: Interaction::new(p, p_error, wo.normalize(), n),
            uv,
            dpdu,
            dpdv,
            dndu,
            dndv,
            dpdx: zero(),
            dpdy: zero(),
            dudx: 0.0,
            dvdx: 0.0,
            dudy: 0.0,
            dvdy: 0.0,
            shape: shape,
            primitive: None,
            // Initialize shading geometry from true geometry
            shading: Shading {
                n: n,
                dpdu: dpdu,
                dpdv: dpdv,
                dndu: dndu,
                dndv: dndv,
            },
            bsdf: None,
        }
    }

    pub fn le(&self, w: &Vector3f) -> Spectrum {
        self.primitive
            .and_then(|p| p.area_light())
            .map(|light| light.l(self.into(), w))
            .unwrap_or_else(Spectrum::black)
    }

    pub fn transform(&self, t: &Transform) -> SurfaceInteraction<'a, 'b> {
        let (p, p_err) = t.transform_point_with_error(&self.hit.p, &self.hit.p_error);
        let mut si = SurfaceInteraction {
            hit: Interaction::new(p,
                                  p_err,
                                  (t * &self.hit.wo).normalize(),
                                  t.transform_normal(&self.hit.n).normalize()),
            uv: self.uv,
            dpdu: t * &self.dpdu,
            dpdv: t * &self.dpdv,
            dndu: zero(),
            dndv: zero(),
            dpdx: zero(),
            dpdy: zero(),
            dudx: 0.0,
            dvdx: 0.0,
            dudy: 0.0,
            dvdy: 0.0,
            shape: self.shape,
            primitive: self.primitive,
            shading: Shading {
                n: t.transform_normal(&self.shading.n).normalize(),
                dpdu: t * &self.shading.dpdu,
                dpdv: t * &self.shading.dpdv,
                dndu: zero(),
                dndv: zero(),
            },
            bsdf: self.bsdf.clone(),
        };
        si.shading.n = face_forward_n(&si.shading.n, &si.hit.n);

        si
    }

    pub fn compute_scattering_functions(&mut self,
                                        ray: &Ray,
                                        transport: TransportMode,
                                        allow_multiple_lobes: bool,
                                        arena: &'b Allocator) {
        self.compute_differential(ray);
        if let Some(primitive) = self.primitive {
            primitive.compute_scattering_functions(self, transport, allow_multiple_lobes, arena);
        }
    }

    pub fn spawn_ray(&self, dir: &Vector3f) -> Ray {
        assert!(dir.x != 0.0 || dir.y != 0.0 || dir.z != 0.0);
        stats::inc_secondary_ray();
        let o = offset_origin(&self.hit.p, &self.hit.p_error, &self.hit.n, dir);
        Ray::new(o, *dir)
    }

    pub fn spawn_ray_to(&self, p: &Point3f) -> Ray {
        let d = *p - self.hit.p;
        assert!(d.x != 0.0 || d.y != 0.0 || d.z != 0.0);
        stats::inc_secondary_ray();
        let o = offset_origin(&self.hit.p, &self.hit.p_error, &self.hit.n, &d);
        Ray::segment(o, d, 1.0 - 1e-4)
    }

    pub fn set_shading_geometry(&mut self,
                                dpdus: &Vector3f,
                                dpdvs: &Vector3f,
                                dndus: &Normal3f,
                                dndvs: &Normal3f,
                                is_orientation_authoritative: bool) {
        // Compute shading.n for SurfaceInteraction
        self.shading.n = Normal3f::from(dpdus.cross(dpdvs).normalize());
        if self.shape.reverse_orientation() ^ self.shape.transform_swaps_handedness() {
            self.shading.n *= -1.0;
        }
        if is_orientation_authoritative {
            self.hit.n = face_forward_n(&self.hit.n, &self.shading.n);
        } else {
            self.shading.n = face_forward_n(&self.shading.n, &self.hit.n);
        }

        // Initialize shading partial derivative values
        self.shading.dpdu = *dpdus;
        self.shading.dpdv = *dpdvs;
        self.shading.dndu = *dndus;
        self.shading.dndv = *dndvs;
    }

    #[allow(non_snake_case)]
    pub fn compute_differential(&mut self, ray: &Ray) {
        if let Some(ref diff) = ray.differential {
            // Estimate screen space change in p and (u,v)

            // Compute auxiliary intersection points with plane
            let d = self.hit
                .n
                .dot(&Vector3f::new(self.hit.p.x, self.hit.p.y, self.hit.p.z));
            let tx = -(self.hit.n.dot(&Vector3f::from(diff.rx_origin)) - d) /
                     self.hit.n.dot(&diff.rx_direction);
            let ty = -(self.hit.n.dot(&Vector3f::from(diff.ry_origin)) - d) /
                     self.hit.n.dot(&diff.ry_direction);
            if tx.is_infinite() || tx.is_nan() || ty.is_infinite() || ty.is_nan() {
                self.dudx = 0.0;
                self.dudy = 0.0;
                self.dvdx = 0.0;
                self.dvdy = 0.0;
                self.dpdx = zero();
                self.dpdy = zero();
                return;
            }

            let px = diff.rx_origin + tx * diff.rx_direction;
            let py = diff.ry_origin + ty * diff.ry_direction;
            self.dpdx = px - self.hit.p;
            self.dpdy = py - self.hit.p;
            // Compute (u,v) offsets at auxiliary points

            // Choose two dimensions to use for ray offset computation
            let mut dim: [usize; 2] = [0; 2];
            if self.hit.n.x.abs() > self.hit.n.y.abs() && self.hit.n.x.abs() > self.hit.n.z.abs() {
                dim[0] = 1;
                dim[1] = 2;
            } else if self.hit.n.y.abs() > self.hit.n.z.abs() {
                dim[0] = 0;
                dim[1] = 2;
            } else {
                dim[0] = 0;
                dim[1] = 1;
            }
            // Initialize A, Bx, and By matrices for offset computation
            let A = [[self.dpdu[dim[0]], self.dpdv[dim[0]]],
                     [self.dpdu[dim[1]], self.dpdv[dim[1]]]];
            let Bx = Vector2f::new(px[dim[0]] - self.hit.p[dim[0]],
                                   px[dim[1]] - self.hit.p[dim[1]]);
            let By = Vector2f::new(py[dim[0]] - self.hit.p[dim[0]],
                                   py[dim[1]] - self.hit.p[dim[1]]);

            let (dudx, dvdx) = transform::solve_linear_system2x2(&A, &Bx).unwrap_or((0.0, 0.0));
            let (dudy, dvdy) = transform::solve_linear_system2x2(&A, &By).unwrap_or((0.0, 0.0));
            self.dudx = dudx;
            self.dvdx = dvdx;
            self.dudy = dudy;
            self.dvdy = dvdy;
        } else {
            self.dudx = 0.0;
            self.dudy = 0.0;
            self.dvdx = 0.0;
            self.dvdy = 0.0;
            self.dpdx = zero();
            self.dpdy = zero();
        }
    }
}

fn offset_origin(p: &Point3f, p_err: &Vector3f, n: &Normal3f, w: &Vector3f) -> Point3f {
    let d = n.abs().dot(p_err);
    let mut offset = d * Vector3f::from(*n);
    if w.dotn(n) < 0.0 {
        offset = -offset;
    }
    let mut po = *p + offset;
    for i in 0..3 {
        if offset[i] > 0.0 {
            po[i] = po[i].next();
        } else if offset[i] < 0.0 {
            po[i] = po[i].prev();
        }
    }
    po
}

impl<'a, 'b> From<SurfaceInteraction<'a, 'b>> for Interaction {
    fn from(si: SurfaceInteraction) -> Interaction {
        si.hit
    }
}

impl<'a, 'b> From<&'a SurfaceInteraction<'a, 'b>> for &'a Interaction {
    fn from(si: &'a SurfaceInteraction<'a, 'b>) -> &'a Interaction {
        &si.hit
    }
}

/// Normal and partial derivatives used for shading. Can be different from geometric ones due to
/// bump mapping, etc.
#[derive(Clone)]
pub struct Shading {
    pub n: Normal3f,
    pub dpdu: Vector3f,
    pub dpdv: Vector3f,
    pub dndu: Normal3f,
    pub dndv: Normal3f,
}

impl Default for Shading {
    fn default() -> Self {
        Shading {
            n: zero(),
            dpdu: zero(),
            dpdv: zero(),
            dndu: zero(),
            dndv: zero(),
        }
    }
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![allow(unused_variable)]
use std::io::{File};

macro_rules! unwrap(
    ($inp: expr) => (
        match $inp {
            Ok(r) => r,
            Err(e) => fail!("{}",e)
        }
    );
)

fn main() {
    let path = Path::new("/home/alex/.bitcoin/blocks/blk00000.dat");
    let mut file = unwrap!(File::open(&path));

    verify_block(&mut file);
    parse_block(&mut file);
}

fn parse_block(file: &mut File) {
    let header = unwrap!(file.read_le_u32());
    //println!("header={}",header);

    let version = unwrap!(file.read_le_u32());
    println!("version={}",version);

    let sha = unwrap!(file.read_exact(32));
    //println!("sha={}",sha);

    let merkle = unwrap!(file.read_exact(32));
    //println!("merkle={}",merkle);

    let timestamp = unwrap!(file.read_le_u32());
    println!("timestamp={}",timestamp);

    let difficulty = unwrap!(file.read_le_u32());
    //println!("difficulty={}",difficulty);

    let nonce = unwrap!(file.read_le_u32());
    println!("nonce={}",nonce);

    let transaction_count = read_vli(file);
    println!("transaction_count={}",transaction_count);

    for _ in range(0, transaction_count) {
        let transaction_version = unwrap!(file.read_le_u32());

        let input_count = read_vli(file);
        println!("{} inputs", input_count);
        for _ in range(0, input_count) {
            let transaction_hash = unwrap!(file.read_exact(32));
            println!("tx hash={}",transaction_hash);
            let transaction_index = unwrap!(file.read_le_u32());
            let script_length = read_vli(file) as uint; // is this okay?
            let script = unwrap!(file.read_exact(script_length));
            let sequence_number = unwrap!(file.read_le_u32());
            assert!(sequence_number == 0xFFFFFFFFu32);
        }

        let output_count = read_vli(file);
        println!("{} outputs", output_count);
        for _ in range(0, output_count) {
            let value = unwrap!(file.read_le_u64());
            println!("value={}", value);
            let script_length = read_vli(file) as uint;
            let script = unwrap!(file.read_exact(script_length));
        }

        let lock_time = unwrap!(file.read_le_u32());
        assert!(lock_time == 0u32);
    }

    // Now, we should be done with the block.
    assert!(file.eof());
}

fn read_vli(file: &mut File) -> u64 {
    let flag = unwrap!(file.read_u8());
    if flag < 0xfd {
        flag as u64
    } else if flag == 0xfd {
        (unwrap!(file.read_le_u16())) as u64
    } else if flag == 0xfe {
        (unwrap!(file.read_le_u32())) as u64
    } else {
        unwrap!(file.read_le_u64())
    }
}

fn verify_block(file: &mut File) {
    print!("verifying block...");

    let magic_uint : u32 = 0xD9B4BEF9;
    let file_uint = unwrap!(file.read_le_u32());
    assert!(magic_uint == file_uint);

    println!("verify passed...");
}
<commit_msg>think parsing is done<commit_after>#![feature(macro_rules)]
#![allow(unused_variable)]
use std::io::{File};

macro_rules! unwrap(
    ($inp: expr) => (
        match $inp {
            Ok(r) => r,
            Err(e) => fail!("{}",e)
        }
    );
)

fn main() {
    let path = Path::new("/home/alex/.bitcoin/blocks/blk00000.dat");
    let mut file = unwrap!(File::open(&path));

    verify_block(&mut file);
    parse_block(&mut file);
}

fn string_of_hex(hex: & Vec<u8>) -> Vec<String>{
    hex.iter().map(|h| {
        let base16 = ['0', '1', '2', '3',
                      '4', '5', '6', '7',
                      '8', '9', 'A', 'B',
                      'C', 'D', 'E', 'F'];
        let mut s = String::new();
        s.push(base16[(h/16) as uint]);
        s.push(base16[(h%16) as uint]);
        s
    }).collect()
}

fn parse_block(file: &mut File) {
    let header = unwrap!(file.read_le_u32());
    //println!("header={}",header);

    let version = unwrap!(file.read_le_u32());
    println!("version={}",version);

    let sha = unwrap!(file.read_exact(32));
    //println!("sha={}",sha);

    let merkle = unwrap!(file.read_exact(32));
    println!("merkle={}",string_of_hex(&merkle));

    let timestamp = unwrap!(file.read_le_u32());
    //println!("timestamp={}",timestamp);

    let difficulty = unwrap!(file.read_le_u32());
    //println!("difficulty={}",difficulty);

    let nonce = unwrap!(file.read_le_u32());
    println!("nonce={}",nonce);

    let transaction_count = read_vli(file);
    println!("transaction_count={}",transaction_count);

    for _ in range(0, transaction_count) {
        let transaction_version = unwrap!(file.read_le_u32());

        let input_count = read_vli(file);
        println!("{} inputs", input_count);
        for _ in range(0, input_count) {
            let transaction_hash = unwrap!(file.read_exact(32));
            println!("tx hash={}",string_of_hex(&transaction_hash));
            let transaction_index = unwrap!(file.read_le_u32());
            let script_length = read_vli(file) as uint; // is this okay?
            let script = unwrap!(file.read_exact(script_length));
            let sequence_number = unwrap!(file.read_le_u32());
            assert!(sequence_number == 0xFFFFFFFFu32);
        }

        let output_count = read_vli(file);
        println!("{} outputs", output_count);
        for _ in range(0, output_count) {
            let value = unwrap!(file.read_le_u64());
            println!("value={}", value);
            let script_length = read_vli(file) as uint;
            let script = unwrap!(file.read_exact(script_length));
        }

        let lock_time = unwrap!(file.read_le_u32());
        assert!(lock_time == 0u32);
    }

    // Now, we should be done with the block.
    assert!(file.eof());
}

fn read_vli(file: &mut File) -> u64 {
    let flag = unwrap!(file.read_u8());
    if flag < 0xfd {
        flag as u64
    } else if flag == 0xfd {
        (unwrap!(file.read_le_u16())) as u64
    } else if flag == 0xfe {
        (unwrap!(file.read_le_u32())) as u64
    } else {
        unwrap!(file.read_le_u64())
    }
}

fn verify_block(file: &mut File) {
    print!("verifying block...");

    let magic_uint : u32 = 0xD9B4BEF9;
    let file_uint = unwrap!(file.read_le_u32());
    assert!(magic_uint == file_uint);

    println!("verify passed...");
}
<|endoftext|>


<commit_before>use ide_db::helpers::FamousDefs;
use syntax::{
    ast::{self, edit::AstNodeEdit, make, ArgListOwner},
    AstNode,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

/// Assist: convert_iter_for_each_to_for
//
/// Converts an Iterator::for_each function into a for loop.
///
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     x.iter().for_each(|(x, y)| {
///         println!("x: {}, y: {}", x, y);
///    })
/// }
/// ```
/// ->
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     for (x, y) in x.iter() {
///         println!("x: {}, y: {}", x, y);
///     });
/// }
/// ```
pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let method;

    let stmt = if let Some(stmt) = ctx.find_node_at_offset::<ast::ExprStmt>() {
        method = ast::MethodCallExpr::cast(stmt.syntax().first_child()?)?;
        Some(stmt)
    } else {
        method = match ctx.find_node_at_offset::<ast::Expr>()? {
            ast::Expr::MethodCallExpr(expr) => expr,
            ast::Expr::ClosureExpr(expr) => {
                ast::MethodCallExpr::cast(expr.syntax().ancestors().nth(2)?)?
            }
            _ => {
                return None;
            }
        };
        None
    };

    let closure = match method.arg_list()?.args().next()? {
        ast::Expr::ClosureExpr(expr) => expr,
        _ => {
            return None;
        }
    };

    let (method, parent) = validate_method_call_expr(&ctx.sema, method)?;

    let param_list = closure.param_list()?;
    let param = param_list.params().next()?.pat()?;
    let body = closure.body()?;

    let indent = stmt.as_ref().map_or(method.indent_level(), |stmt| stmt.indent_level());
    let syntax = stmt.as_ref().map_or(method.syntax(), |stmt| stmt.syntax());

    acc.add(
        AssistId("convert_iter_for_each_to_for", AssistKind::RefactorRewrite),
        "Replace this `Iterator::for_each` with a for loop",
        syntax.text_range(),
        |builder| {
            let block = match body {
                ast::Expr::BlockExpr(block) => block,
                _ => make::block_expr(Vec::new(), Some(body)),
            }
            .reset_indent()
            .indent(indent);

            let expr_for_loop = make::expr_for_loop(param, parent, block);
            builder.replace(syntax.text_range(), expr_for_loop.syntax().text())
        },
    )
}

fn validate_method_call_expr(
    sema: &hir::Semantics<ide_db::RootDatabase>,
    expr: ast::MethodCallExpr,
) -> Option<(ast::Expr, ast::Expr)> {
    if expr.name_ref()?.text() != "for_each" {
        return None;
    }

    let expr = ast::Expr::MethodCallExpr(expr);
    let parent = ast::Expr::cast(expr.syntax().first_child()?)?;

    let it_type = sema.type_of_expr(&parent)?;
    let module = sema.scope(parent.syntax()).module()?;
    let krate = module.krate();

    let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
    it_type.impls_trait(sema.db, iter_trait, &[]).then(|| (expr, parent))
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    const EMPTY_ITER_FIXTURE: &'static str = r"
//- /lib.rs deps:core crate:empty_iter
pub struct EmptyIter;
impl Iterator for EmptyIter {
    type Item = usize;
    fn next(&mut self) -> Option<Self::Item> { None }
}
pub struct Empty;
impl Empty {
    pub fn iter(&self) -> EmptyIter { EmptyIter }
}
";

    fn check_assist_with_fixtures(before: &str, after: &str) {
        let before = &format!(
            "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
            before,
            EMPTY_ITER_FIXTURE,
            FamousDefs::FIXTURE,
        );
        check_assist(convert_iter_for_each_to_for, before, after);
    }

    #[test]
    fn test_for_each_in_method_stmt() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    });
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y);
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_in_method() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    })
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y);
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_without_braces_stmt() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_in_closure_stmt() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().for_each($0|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_not_applicable() {
        check_assist_not_applicable(
            convert_iter_for_each_to_for,
            r#"
fn main() {
    value.$0for_each(|x| println!("{}", x));
}"#,
        )
    }
}
<commit_msg>refactor: refactored and reduced assist code<commit_after>use ide_db::helpers::FamousDefs;
use syntax::{
    ast::{self, edit::AstNodeEdit, make, ArgListOwner},
    AstNode,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

/// Assist: convert_iter_for_each_to_for
//
/// Converts an Iterator::for_each function into a for loop.
///
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     x.iter().for_each(|(x, y)| {
///         println!("x: {}, y: {}", x, y);
///    })
/// }
/// ```
/// ->
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     for (x, y) in x.iter() {
///         println!("x: {}, y: {}", x, y);
///     });
/// }
/// ```
pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let method = ctx.find_node_at_offset::<ast::MethodCallExpr>()?;
    let stmt = method.syntax().parent().and_then(ast::ExprStmt::cast);

    let closure = match method.arg_list()?.args().next()? {
        ast::Expr::ClosureExpr(expr) => expr,
        _ => return None,
    };

    let (method, receiver) = validate_method_call_expr(&ctx.sema, method)?;

    let param_list = closure.param_list()?;
    let param = param_list.params().next()?.pat()?;
    let body = closure.body()?;

    let syntax = stmt.as_ref().map_or(method.syntax(), |stmt| stmt.syntax());

    acc.add(
        AssistId("convert_iter_for_each_to_for", AssistKind::RefactorRewrite),
        "Replace this `Iterator::for_each` with a for loop",
        syntax.text_range(),
        |builder| {
            let indent = stmt.as_ref().map_or(method.indent_level(), |stmt| stmt.indent_level());

            let block = match body {
                ast::Expr::BlockExpr(block) => block,
                _ => make::block_expr(Vec::new(), Some(body)),
            }
            .reset_indent()
            .indent(indent);

            let expr_for_loop = make::expr_for_loop(param, receiver, block);
            builder.replace(syntax.text_range(), expr_for_loop.syntax().text())
        },
    )
}

fn validate_method_call_expr(
    sema: &hir::Semantics<ide_db::RootDatabase>,
    expr: ast::MethodCallExpr,
) -> Option<(ast::Expr, ast::Expr)> {
    if expr.name_ref()?.text() != "for_each" {
        return None;
    }

    let receiver = expr.receiver()?;
    let expr = ast::Expr::MethodCallExpr(expr);

    let it_type = sema.type_of_expr(&receiver)?;
    let module = sema.scope(receiver.syntax()).module()?;
    let krate = module.krate();

    let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
    it_type.impls_trait(sema.db, iter_trait, &[]).then(|| (expr, receiver))
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    const EMPTY_ITER_FIXTURE: &'static str = r"
//- /lib.rs deps:core crate:empty_iter
pub struct EmptyIter;
impl Iterator for EmptyIter {
    type Item = usize;
    fn next(&mut self) -> Option<Self::Item> { None }
}
pub struct Empty;
impl Empty {
    pub fn iter(&self) -> EmptyIter { EmptyIter }
}
";

    fn check_assist_with_fixtures(before: &str, after: &str) {
        let before = &format!(
            "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
            before,
            EMPTY_ITER_FIXTURE,
            FamousDefs::FIXTURE,
        );
        check_assist(convert_iter_for_each_to_for, before, after);
    }

    #[test]
    fn test_for_each_in_method_stmt() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    });
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y);
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_in_method() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    })
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y);
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_in_iter_stmt() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty.iter();
    x.$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    });
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty.iter();
    for (x, y) in x {
        println!("x: {}, y: {}", x, y);
    }
}
"#,
        )
    }

    #[test]
    fn test_for_each_without_braces_stmt() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    }
}
"#,
        )
    }
    #[test]
    fn test_for_each_not_applicable() {
        check_assist_not_applicable(
            convert_iter_for_each_to_for,
            r#"
fn main() {
    value.$0for_each(|x| println!("{}", x));
}"#,
        )
    }
}
<|endoftext|>


<commit_before>use std::vec;
use std::libc::size_t;
use std::ptr;
use std::libc::{c_uint, c_int, c_void};
use std::cast;

use common::*;

#[fixed_stack_segment]
#[inline(never)]
pub fn quadrature(f: & &fn(&[R]) -> R, // OK for this to be a closure address
                  min_corner: &[R],
                  max_corner: &[R],
                  rel_err: R, abs_err: R) -> R {
  let (val, status) = unsafe {
    let f_dom_dim = min_corner.len() as c_uint;
    let f_range_dim = 1 as c_uint;
    let f_pv: *c_void = cast::transmute(f);
    let integrand_caller_pv: *c_void = cast::transmute(integrand_caller);
    let min_bounds = vec::raw::to_ptr(min_corner);
    let max_bounds = vec::raw::to_ptr(max_corner);
    let max_evals = 0 as size_t;
    let norm_unused = 0u32;
    let mut val = 0 as R;
    let mut err = 0 as R;
    let status =
      hquadrature(f_range_dim,
                  integrand_caller_pv,
                  f_pv,
                  f_dom_dim, min_bounds, max_bounds,
                  max_evals, rel_err, abs_err,
                  norm_unused, &mut val, &mut err);
    (val, status)
  };

  if (status != 0) { fail!("quadrature call returned non-zero status"); }

  val
}

// This is the integrand callback function called directly by the C integration routine, whose job
// is to calculate the integrand value using f_ptr and set that value in *fval.
#[inline(never)]
extern fn integrand_caller(ndim: c_uint, x: *R,
                           f_ptr: *mut (&fn(x:&[R]) -> R),
                           _: c_uint, fval: *mut R) -> c_int {
  unsafe {
    let f = ptr::read_ptr(f_ptr);
    *fval = vec::raw::buf_as_slice(x, ndim as uint, f);
  }
  0 as c_int
}

// The external C integration routine.
#[link_args = "lib/quadrature.o"]
extern {

  fn hquadrature(fdim: c_uint,
                 f: *c_void, fdata: *c_void,
                 dim: c_uint, xmin: *R, xmax: *R,
                 maxEval: size_t, reqAbsError: R, reqRelError: R,
                 norm: u32,
                 val: *mut R, err: *mut R) -> c_int;
}

#[fixed_stack_segment]
#[test]
fn main() {
  let f1 = |_: &[f64]| 2.0;
  let f2 = |x: &[f64]| 2.0*x[0]*x[1];
  let min_bounds = ~[0.,0.];
  let max_bounds = ~[1.,1.];
  assert_eq!(quadrature(&f1, min_bounds, max_bounds, 1e-5, 1e-5), 2.0)
  assert_eq!(quadrature(&f2, min_bounds, max_bounds, 1e-5, 1e-5), 0.5)
  assert_eq!(quadrature(&f1, min_bounds, max_bounds, 1e-5, 1e-5), 2.0)
}

<commit_msg>Changed test fun name.<commit_after>use std::vec;
use std::libc::size_t;
use std::ptr;
use std::libc::{c_uint, c_int, c_void};
use std::cast;

use common::*;

#[fixed_stack_segment]
#[inline(never)]
pub fn quadrature(f: & &fn(&[R]) -> R, // OK for this to be a closure address
                  min_corner: &[R],
                  max_corner: &[R],
                  rel_err: R, abs_err: R) -> R {
  let (val, status) = unsafe {
    let f_dom_dim = min_corner.len() as c_uint;
    let f_range_dim = 1 as c_uint;
    let f_pv: *c_void = cast::transmute(f);
    let integrand_caller_pv: *c_void = cast::transmute(integrand_caller);
    let min_bounds = vec::raw::to_ptr(min_corner);
    let max_bounds = vec::raw::to_ptr(max_corner);
    let max_evals = 0 as size_t;
    let norm_unused = 0u32;
    let mut val = 0 as R;
    let mut err = 0 as R;
    let status =
      hquadrature(f_range_dim,
                  integrand_caller_pv,
                  f_pv,
                  f_dom_dim, min_bounds, max_bounds,
                  max_evals, rel_err, abs_err,
                  norm_unused, &mut val, &mut err);
    (val, status)
  };

  if (status != 0) { fail!("quadrature call returned non-zero status"); }

  val
}

// This is the integrand callback function called directly by the C integration routine, whose job
// is to calculate the integrand value using f_ptr and set that value in *fval.
#[inline(never)]
extern fn integrand_caller(ndim: c_uint, x: *R,
                           f_ptr: *mut (&fn(x:&[R]) -> R),
                           _: c_uint, fval: *mut R) -> c_int {
  unsafe {
    let f = ptr::read_ptr(f_ptr);
    *fval = vec::raw::buf_as_slice(x, ndim as uint, f);
  }
  0 as c_int
}

// The external C integration routine.
#[link_args = "lib/quadrature.o"]
extern {

  fn hquadrature(fdim: c_uint,
                 f: *c_void, fdata: *c_void,
                 dim: c_uint, xmin: *R, xmax: *R,
                 maxEval: size_t, reqAbsError: R, reqRelError: R,
                 norm: u32,
                 val: *mut R, err: *mut R) -> c_int;
}

#[fixed_stack_segment]
#[test]
fn test_quadrature() {
  let f1 = |_: &[f64]| 2.0;
  let f2 = |x: &[f64]| 2.0*x[0]*x[1];
  let min_bounds = ~[0.,0.];
  let max_bounds = ~[1.,1.];
  assert_eq!(quadrature(&f1, min_bounds, max_bounds, 1e-5, 1e-5), 2.0)
  assert_eq!(quadrature(&f2, min_bounds, max_bounds, 1e-5, 1e-5), 0.5)
  assert_eq!(quadrature(&f1, min_bounds, max_bounds, 1e-5, 1e-5), 2.0)
}

<|endoftext|>


<commit_before>//! Discrete Morse Flow solver of the 1D wave equation.
extern crate gnuplot;

extern crate linear_space;

use gnuplot::{Figure, Caption, Color, Fix, AxesCommon, PlotOption, DashType};
use linear_space::lin::{Lin,Rn};
use linear_space::ncg::{NonlinearCG};
use std::f64::consts::PI;

// Discrete Morse Flow energy for the wave equation.
fn wave_energy(u: &Rn<f64>, u_n: &Rn<f64>, u_n_1: &Rn<f64>,
               grad_u: &mut Rn<f64>, h: f64, kappa: f64) -> f64 {
    let mut v = u.clone();
    v.ray_to(&u_n, -2.);
    v.add_mut(&u_n_1);

    grad_u[0] = 0.;
    grad_u[u.len() - 1] = 0.;
    for i in 1..u.len() - 1 {
       grad_u[i] = (4. * v[i] + v[i-1] + v[i+1]) / (6. * h * h)
           + kappa * (2. * u[i] - u[i-1] - u[i+1]);
    }

    let mut e = 0.;
    for i in 1..u.len() {
        e += (v[i-1].powi(2) + v[i-1] * v[i] + v[i].powi(2)) / (6. * h * h)
            + (kappa / 2.) * (u[i - 1] - u[i]).powi(2);
    }
    e
}

fn main() {
    let domain = (0., 1.);
    let gamma = 1;
    let k = 32 * gamma;
    let h_dx_ratio = 0.1;
    let h = 1. / k as f64 * h_dx_ratio; // time-step
    let kappa = 1. * (k as f64 / (domain.1 - domain.0)).powi(2);
    let t_final = 1.5;
    let n_max = (t_final / h) as i32;
    let xi: Vec<f64> = (0..k+1).map(|i| domain.0 + (domain.1 - domain.0) * i as f64 / k as f64)
                               .collect();
    let u_n: Vec<f64> = xi.iter().map(|x| (PI * x).sin() + (4. * PI * x).sin()).collect();
    let mut u_n = Rn::new(u_n);
    let mut u_n_1 = u_n.clone();

    let mut ncg = NonlinearCG::new();
    let mut fg = Figure::new();

    for n in 1..n_max + 1 {
        let r = {
            let mut f = |x: &Rn<f64>, g: &mut Rn<f64>| wave_energy(x, &u_n, &u_n_1, g, h, kappa);
            ncg.minimize(&u_n, &mut f)
        };

        match r {
            Ok(v) => {
                println!("{:?}", v);
                let t = n as f64 * h;
                let exact_u = xi.iter().map(|x| (PI * x).sin() * (PI * t).cos()
                                            + (4. * PI * x).sin() * (4. * PI * t).cos());
                fg.clear_axes();
                fg.axes2d()
                    .set_y_range(Fix(-1.0), Fix(1.0))
                    .lines(xi.iter(), v.iter(), &[])
                    .lines(xi.iter(), exact_u, &[PlotOption::LineStyle(DashType::Dash)]);
                fg.show();
                u_n_1 = u_n;
                u_n = v;
            },
            Err(e) => {
                println!("Error: {:?}", e);
                return;
            },
        }
    }
}
<commit_msg>Add a conservative form of wave eq. energy<commit_after>//! Discrete Morse Flow solver of the 1D wave equation.
extern crate gnuplot;

extern crate linear_space;

use gnuplot::{Figure, Caption, Color, Fix, AxesCommon, PlotOption, DashType};
use linear_space::lin::{Lin,Rn};
use linear_space::ncg::{NonlinearCG};
use std::f64::consts::PI;

// Discrete Morse Flow energy for the wave equation.
fn wave_energy(u: &Rn<f64>, u_n: &Rn<f64>, u_n_1: &Rn<f64>,
               grad_u: &mut Rn<f64>, h: f64, kappa: f64) -> f64 {
    let mut v = u.clone();
    v.ray_to(&u_n, -2.);
    v.add_mut(&u_n_1);

    grad_u[0] = 0.;
    grad_u[u.len() - 1] = 0.;
    for i in 1..u.len() - 1 {
       grad_u[i] = (4. * v[i] + v[i-1] + v[i+1]) / (6. * h * h)
           + kappa * (2. * u[i] - u[i-1] - u[i+1]);
    }

    let mut e = 0.;
    for i in 1..u.len() {
        e += (v[i-1].powi(2) + v[i-1] * v[i] + v[i].powi(2)) / (6. * h * h)
            + (kappa / 2.) * (u[i - 1] - u[i]).powi(2);
    }
    e
}

// Discrete Morse Flow energy for the wave equation with less energy dissipation.
fn wave_energy_conservative(u: &Rn<f64>, u_n: &Rn<f64>, u_n_1: &Rn<f64>,
               grad_u: &mut Rn<f64>, h: f64, kappa: f64) -> f64 {
    let mut v = u.clone();
    v.ray_to(&u_n, -2.);
    v.add_mut(&u_n_1);

    grad_u[0] = 0.;
    grad_u[u.len() - 1] = 0.;
    for i in 1..u.len() - 1 {
       grad_u[i] = (4. * v[i] + v[i-1] + v[i+1]) / (6. * h * h)
           + (kappa / 2.) * (2. * u[i] - u[i-1] - u[i+1])
           + (kappa / 2.) * (2. * u_n_1[i] - u_n_1[i-1] - u_n_1[i+1]);
    }

    let mut e = 0.;
    for i in 1..u.len() {
        e += (v[i-1].powi(2) + v[i-1] * v[i] + v[i].powi(2)) / (6. * h * h)
            + (kappa / 4.) * (u[i - 1] - u[i]).powi(2);
    }
    for i in 1..u.len() - 1 {
        e += (kappa / 2.) * u[i] * (2. * u_n_1[i] - u_n_1[i-1] - u_n_1[i+1]);
    }
    e
}

fn main() {
    let domain = (0., 1.);
    let gamma = 1;
    let k = 32 * gamma;
    let h_dx_ratio = 0.5;
    let h = 1. / k as f64 * h_dx_ratio; // time-step
    let kappa = 1. * (k as f64 / (domain.1 - domain.0)).powi(2);
    let t_final = 15.;
    let n_max = (t_final / h) as i32;
    let xi: Vec<f64> = (0..k+1).map(|i| domain.0 + (domain.1 - domain.0) * i as f64 / k as f64)
                               .collect();
    let u_n: Vec<f64> = xi.iter().map(|x| (PI * x).sin() + (4. * PI * x).sin()).collect();
    let mut u_n = Rn::new(u_n);
    let mut u_n_1 = u_n.clone();

    let mut ncg = NonlinearCG::new();
    let mut fg = Figure::new();

    for n in 1..n_max + 1 {
        let r = {
            let mut f = |x: &Rn<f64>, g: &mut Rn<f64>| wave_energy_conservative(x, &u_n, &u_n_1, g, h, kappa);
            ncg.minimize(&u_n, &mut f)
        };

        match r {
            Ok(v) => {
                println!("{:?}", v);
                let t = n as f64 * h;
                let exact_u = xi.iter().map(|x| (PI * x).sin() * (PI * t).cos()
                                            + (4. * PI * x).sin() * (4. * PI * t).cos());
                fg.clear_axes();
                fg.axes2d()
                    .set_y_range(Fix(-1.0), Fix(1.0))
                    .lines(xi.iter(), v.iter(), &[])
                    .lines(xi.iter(), exact_u, &[PlotOption::LineStyle(DashType::Dash)]);
                fg.show();
                u_n_1 = u_n;
                u_n = v;
            },
            Err(e) => {
                println!("Error: {:?}", e);
                return;
            },
        }
    }
}
<|endoftext|>


<commit_before>extern crate ndarray;
extern crate numpy;
extern crate pyo3;

use ndarray::*;
use numpy::*;
use pyo3::prelude::*;

#[test]
fn new() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::<f64>::new(gil.python(), &np, &[n, m]);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);
}

#[test]
fn zeros() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], false);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);

    let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], true);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [8, n as isize * 8]);
}

#[test]
fn arange() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::<f64>::arange(gil.python(), &np, 0.0, 1.0, 0.1);
    println!("ndim = {:?}", arr.ndim());
    println!("dims = {:?}", arr.dims());
    println!("array = {:?}", arr.as_slice().unwrap());
}

#[test]
fn as_array() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::<f64>::zeros(gil.python(), &np, &[3, 2, 4], false);
    let a = arr.as_array().unwrap();
    assert_eq!(arr.shape(), a.shape());
    assert_eq!(
        arr.strides().iter().map(|x| x / 8).collect::<Vec<_>>(),
        a.strides()
    );
}

#[test]
fn into_pyarray_vec() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();

    let a = vec![1, 2, 3];
    let arr = a.into_pyarray(gil.python(), &np);
    println!("arr.shape = {:?}", arr.shape());
    println!("arr = {:?}", arr.as_slice().unwrap());
    assert_eq!(arr.shape(), [3]);
}

#[test]
fn into_pyarray_array() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();

    let a = Array3::<f64>::zeros((3, 4, 2));
    let shape = a.shape().iter().cloned().collect::<Vec<_>>();
    let strides = a.strides().iter().map(|d| d * 8).collect::<Vec<_>>();
    println!("a.shape   = {:?}", a.shape());
    println!("a.strides = {:?}", a.strides());
    let pa = a.into_pyarray(gil.python(), &np);
    println!("pa.shape   = {:?}", pa.shape());
    println!("pa.strides = {:?}", pa.strides());
    assert_eq!(pa.shape(), shape.as_slice());
    assert_eq!(pa.strides(), strides.as_slice());
}

#[test]
fn iter_to_pyarray() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::from_iter(gil.python(), &np, (0..10).map(|x| x * x));
    assert_eq!(
        arr.as_slice().unwrap(),
        &[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    );
}

#[test]
fn is_instance() {
    let gil = pyo3::Python::acquire_gil();
    let py = gil.python();
    let np = PyArrayModule::import(py).unwrap();
    let arr = PyArray::<f64>::new(gil.python(), &np, &[3, 5]);
    assert!(py.is_instance::<PyArray<f64>, _>(&arr).unwrap());
    assert!(!py.is_instance::<pyo3::PyList, _>(&arr).unwrap());
}

#[test]
fn from_vec2() {
    let vec2 = vec![vec![1, 2, 3]; 2];
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let pyarray = PyArray::from_vec2(gil.python(), &np, &vec2).unwrap();
    assert_eq!(
        pyarray.as_array().unwrap(),
        array![[1, 2, 3], [1, 2, 3]].into_dyn()
    );
    assert!(PyArray::from_vec2(gil.python(), &np, &vec![vec![1], vec![2, 3]]).is_err());
}

#[test]
fn from_vec3() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let vec3 = vec![vec![vec![1, 2]; 2]; 2];
    let pyarray = PyArray::from_vec3(gil.python(), &np, &vec3).unwrap();
    assert_eq!(
        pyarray.as_array().unwrap(),
        array![[[1, 2], [1, 2]], [[1, 2], [1, 2]]].into_dyn()
    );
}

#[test]
fn from_eval() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let dict = PyDict::new(gil.python());
    dict.set_item("np", np.as_pymodule()).unwrap();
    let pyarray: &PyArray<i32> = gil
        .python()
        .eval("np.array([1, 2, 3], dtype='int32')", Some(&dict), None)
        .unwrap()
        .extract()
        .unwrap();
    assert_eq!(pyarray.as_slice().unwrap(), &[1, 2, 3]);
}

#[test]
fn from_eval_fail() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let dict = PyDict::new(gil.python());
    dict.set_item("np", np.as_pymodule()).unwrap();
    let converted: Result<&PyArray<i32>, _> = gil
        .python()
        .eval("np.array([1, 2, 3], dtype='float64')", Some(&dict), None)
        .unwrap()
        .extract();
    assert!(converted.is_err());
}

macro_rules! small_array_test {
    ($($t: ident)+) => {
        #[test]
        fn from_small_array() {
            let gil = pyo3::Python::acquire_gil();
            let np = PyArrayModule::import(gil.python()).unwrap();
            $({
                let array: [$t; 2] = [$t::min_value(), $t::max_value()];
                let pyarray = array.into_pyarray(gil.python(), &np);
                assert_eq!(
                    pyarray.as_slice().unwrap(),
                    &[$t::min_value(), $t::max_value()]
                );
            })+
        }
    };
}

small_array_test!(i8 u8 i16 u16 i32 u32 i64 u64);
<commit_msg>Add array_cast test for 2 dimentional array<commit_after>extern crate ndarray;
extern crate numpy;
extern crate pyo3;

use ndarray::*;
use numpy::*;
use pyo3::prelude::*;

#[test]
fn new() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::<f64>::new(gil.python(), &np, &[n, m]);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);
}

#[test]
fn zeros() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let n = 3;
    let m = 5;
    let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], false);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [m as isize * 8, 8]);

    let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], true);
    assert!(arr.ndim() == 2);
    assert!(arr.dims() == [n, m]);
    assert!(arr.strides() == [8, n as isize * 8]);
}

#[test]
fn arange() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::<f64>::arange(gil.python(), &np, 0.0, 1.0, 0.1);
    println!("ndim = {:?}", arr.ndim());
    println!("dims = {:?}", arr.dims());
    println!("array = {:?}", arr.as_slice().unwrap());
}

#[test]
fn as_array() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::<f64>::zeros(gil.python(), &np, &[3, 2, 4], false);
    let a = arr.as_array().unwrap();
    assert_eq!(arr.shape(), a.shape());
    assert_eq!(
        arr.strides().iter().map(|x| x / 8).collect::<Vec<_>>(),
        a.strides()
    );
}

#[test]
fn into_pyarray_vec() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();

    let a = vec![1, 2, 3];
    let arr = a.into_pyarray(gil.python(), &np);
    println!("arr.shape = {:?}", arr.shape());
    println!("arr = {:?}", arr.as_slice().unwrap());
    assert_eq!(arr.shape(), [3]);
}

#[test]
fn into_pyarray_array() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();

    let a = Array3::<f64>::zeros((3, 4, 2));
    let shape = a.shape().iter().cloned().collect::<Vec<_>>();
    let strides = a.strides().iter().map(|d| d * 8).collect::<Vec<_>>();
    println!("a.shape   = {:?}", a.shape());
    println!("a.strides = {:?}", a.strides());
    let pa = a.into_pyarray(gil.python(), &np);
    println!("pa.shape   = {:?}", pa.shape());
    println!("pa.strides = {:?}", pa.strides());
    assert_eq!(pa.shape(), shape.as_slice());
    assert_eq!(pa.strides(), strides.as_slice());
}

#[test]
fn iter_to_pyarray() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let arr = PyArray::from_iter(gil.python(), &np, (0..10).map(|x| x * x));
    assert_eq!(
        arr.as_slice().unwrap(),
        &[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    );
}

#[test]
fn is_instance() {
    let gil = pyo3::Python::acquire_gil();
    let py = gil.python();
    let np = PyArrayModule::import(py).unwrap();
    let arr = PyArray::<f64>::new(gil.python(), &np, &[3, 5]);
    assert!(py.is_instance::<PyArray<f64>, _>(&arr).unwrap());
    assert!(!py.is_instance::<pyo3::PyList, _>(&arr).unwrap());
}

#[test]
fn from_vec2() {
    let vec2 = vec![vec![1, 2, 3]; 2];
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let pyarray = PyArray::from_vec2(gil.python(), &np, &vec2).unwrap();
    assert_eq!(
        pyarray.as_array().unwrap(),
        array![[1, 2, 3], [1, 2, 3]].into_dyn()
    );
    assert!(PyArray::from_vec2(gil.python(), &np, &vec![vec![1], vec![2, 3]]).is_err());
}

#[test]
fn from_vec3() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let vec3 = vec![vec![vec![1, 2]; 2]; 2];
    let pyarray = PyArray::from_vec3(gil.python(), &np, &vec3).unwrap();
    assert_eq!(
        pyarray.as_array().unwrap(),
        array![[[1, 2], [1, 2]], [[1, 2], [1, 2]]].into_dyn()
    );
}

#[test]
fn from_eval() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let dict = PyDict::new(gil.python());
    dict.set_item("np", np.as_pymodule()).unwrap();
    let pyarray: &PyArray<i32> = gil
        .python()
        .eval("np.array([1, 2, 3], dtype='int32')", Some(&dict), None)
        .unwrap()
        .extract()
        .unwrap();
    assert_eq!(pyarray.as_slice().unwrap(), &[1, 2, 3]);
}

#[test]
fn from_eval_fail() {
    let gil = pyo3::Python::acquire_gil();
    let np = PyArrayModule::import(gil.python()).unwrap();
    let dict = PyDict::new(gil.python());
    dict.set_item("np", np.as_pymodule()).unwrap();
    let converted: Result<&PyArray<i32>, _> = gil
        .python()
        .eval("np.array([1, 2, 3], dtype='float64')", Some(&dict), None)
        .unwrap()
        .extract();
    assert!(converted.is_err());
}

macro_rules! small_array_test {
    ($($t: ident)+) => {
        #[test]
        fn from_small_array() {
            let gil = pyo3::Python::acquire_gil();
            let np = PyArrayModule::import(gil.python()).unwrap();
            $({
                let array: [$t; 2] = [$t::min_value(), $t::max_value()];
                let pyarray = array.into_pyarray(gil.python(), &np);
                assert_eq!(
                    pyarray.as_slice().unwrap(),
                    &[$t::min_value(), $t::max_value()]
                );
            })+
        }
    };
}

small_array_test!(i8 u8 i16 u16 i32 u32 i64 u64);

#[test]
fn array_cast() {
    let gil = pyo3::Python::acquire_gil();
    let py = gil.python();
    let np = PyArrayModule::import(py).unwrap();
    let vec2 = vec![vec![1.0, 2.0, 3.0]; 2];
    let arr_f64 = PyArray::from_vec2(gil.python(), &np, &vec2).unwrap();
    let arr_i32: PyArray<i32> = arr_f64.cast(py, &np, false).unwrap();
    assert_eq!(
        arr_i32.as_array().unwrap(),
        array![[1, 2, 3], [1, 2, 3]].into_dyn()
    );
}
<|endoftext|>


<commit_before>//! A bunch of ways to use async/await syntax.
//!
//! This is mostly a test for this repository itself, not necessarily serving
//! much more purpose than that.

#![feature(proc_macro, conservative_impl_trait, generators)]

extern crate futures_await as futures;

use std::io;

use futures::prelude::*;

#[async]
fn foo() -> Result<i32, i32> {
    Ok(1)
}

#[async]
extern fn _foo1() -> Result<i32, i32> {
    Ok(1)
}

#[async]
unsafe fn _foo2() -> io::Result<i32> {
    Ok(1)
}

#[async]
unsafe extern fn _foo3() -> io::Result<i32> {
    Ok(1)
}

#[async]
pub fn _foo4() -> io::Result<i32> {
    Ok(1)
}

#[async]
fn _foo5<T: Clone + 'static>(t: T) -> Result<T, i32> {
    Ok(t.clone())
}

#[async]
fn _foo6(ref a: i32) -> Result<i32, i32> {
    Err(*a)
}

#[async]
fn _foo7<T>(t: T) -> Result<T, i32>
    where T: Clone + 'static,
{
    Ok(t.clone())
}

#[async(boxed)]
fn _foo8(a: i32, b: i32) -> Result<i32, i32> {
    return Ok(a + b)
}

#[async]
fn _bar() -> Result<i32, i32> {
    await!(foo())
}

#[async]
fn _bar2() -> Result<i32, i32> {
    let a = await!(foo())?;
    let b = await!(foo())?;
    Ok(a + b)
}

#[async]
fn _bar3() -> Result<i32, i32> {
    let (a, b) = await!(foo().join(foo()))?;
    Ok(a + b)
}

#[async]
fn _bar4() -> Result<i32, i32> {
    let mut cnt = 0;
    #[async]
    for x in futures::stream::iter_ok::<_, i32>(vec![1, 2, 3, 4]) {
        cnt += x;
    }
    Ok(cnt)
}

#[async_stream(item = u64)]
fn _stream1() -> Result<(), i32> {
    stream_yield!(Ok(0));
    stream_yield!(Ok(1));
    Ok(())
}

#[async_stream(item = T)]
fn _stream2<T: Clone + 'static>(t: T) -> Result<(), i32> {
    stream_yield!(Ok(t.clone()));
    stream_yield!(Ok(t.clone()));
    Ok(())
}

#[async_stream(item = i32)]
fn _stream3() -> Result<(), i32> {
    let mut cnt = 0;
    #[async]
    for x in futures::stream::iter_ok::<_, i32>(vec![1, 2, 3, 4]) {
        cnt += x;
        stream_yield!(Ok(x));
    }
    Err(cnt)
}

#[async_stream(boxed, item = u64)]
fn _stream4() -> Result<(), i32> {
    stream_yield!(Ok(0));
    stream_yield!(Ok(1));
    Ok(())
}

mod foo { pub struct Foo(pub i32); }

#[async_stream(boxed, item = foo::Foo)]
pub fn _stream5() -> Result<(), i32> {
    stream_yield!(Ok(foo::Foo(0)));
    stream_yield!(Ok(foo::Foo(1)));
    Ok(())
}

// struct A(i32);
//
// impl A {
//     #[async]
//     fn a_foo(self) -> Result<i32, i32> {
//         Ok(self.0)
//     }
//
//     #[async]
//     fn _a_foo2(self: Box<Self>) -> Result<i32, i32> {
//         Ok(self.0)
//     }
// }

// trait B {
//     #[async]
//     fn b(self) -> Result<i32, i32>;
// }
//
// impl B for A {
//     #[async]
//     fn b(self) -> Result<i32, i32> {
//         Ok(self.0)
//     }
// }

#[test]
fn main() {
    assert_eq!(foo().wait(), Ok(1));
    assert_eq!(_bar().wait(), Ok(1));
    assert_eq!(_bar2().wait(), Ok(2));
    assert_eq!(_bar3().wait(), Ok(2));
    assert_eq!(_bar4().wait(), Ok(10));
    assert_eq!(_foo6(8).wait(), Err(8));
    // assert_eq!(A(11).a_foo().wait(), Ok(11));
    assert_eq!(loop_in_loop().wait(), Ok(true));
}

#[async]
fn loop_in_loop() -> Result<bool, i32> {
    let mut cnt = 0;
    let vec = vec![1, 2, 3, 4];
    #[async]
    for x in futures::stream::iter_ok::<_, i32>(vec.clone()) {
        #[async]
        for y in futures::stream::iter_ok::<_, i32>(vec.clone()) {
            cnt += x * y;
        }
    }

    let sum = (1..5).map(|x| (1..5).map(|y| x * y).sum::<i32>()).sum::<i32>();
    Ok(cnt == sum)
}
<commit_msg>Add test ensuring polling stream after returning error doesn't panic<commit_after>//! A bunch of ways to use async/await syntax.
//!
//! This is mostly a test for this repository itself, not necessarily serving
//! much more purpose than that.

#![feature(proc_macro, conservative_impl_trait, generators)]

extern crate futures_await as futures;

use std::io;

use futures::prelude::*;

#[async]
fn foo() -> Result<i32, i32> {
    Ok(1)
}

#[async]
extern fn _foo1() -> Result<i32, i32> {
    Ok(1)
}

#[async]
unsafe fn _foo2() -> io::Result<i32> {
    Ok(1)
}

#[async]
unsafe extern fn _foo3() -> io::Result<i32> {
    Ok(1)
}

#[async]
pub fn _foo4() -> io::Result<i32> {
    Ok(1)
}

#[async]
fn _foo5<T: Clone + 'static>(t: T) -> Result<T, i32> {
    Ok(t.clone())
}

#[async]
fn _foo6(ref a: i32) -> Result<i32, i32> {
    Err(*a)
}

#[async]
fn _foo7<T>(t: T) -> Result<T, i32>
    where T: Clone + 'static,
{
    Ok(t.clone())
}

#[async(boxed)]
fn _foo8(a: i32, b: i32) -> Result<i32, i32> {
    return Ok(a + b)
}

#[async]
fn _bar() -> Result<i32, i32> {
    await!(foo())
}

#[async]
fn _bar2() -> Result<i32, i32> {
    let a = await!(foo())?;
    let b = await!(foo())?;
    Ok(a + b)
}

#[async]
fn _bar3() -> Result<i32, i32> {
    let (a, b) = await!(foo().join(foo()))?;
    Ok(a + b)
}

#[async]
fn _bar4() -> Result<i32, i32> {
    let mut cnt = 0;
    #[async]
    for x in futures::stream::iter_ok::<_, i32>(vec![1, 2, 3, 4]) {
        cnt += x;
    }
    Ok(cnt)
}

#[async_stream(item = u64)]
fn _stream1() -> Result<(), i32> {
    stream_yield!(Ok(0));
    stream_yield!(Ok(1));
    Ok(())
}

#[async_stream(item = T)]
fn _stream2<T: Clone + 'static>(t: T) -> Result<(), i32> {
    stream_yield!(Ok(t.clone()));
    stream_yield!(Ok(t.clone()));
    Ok(())
}

#[async_stream(item = i32)]
fn _stream3() -> Result<(), i32> {
    let mut cnt = 0;
    #[async]
    for x in futures::stream::iter_ok::<_, i32>(vec![1, 2, 3, 4]) {
        cnt += x;
        stream_yield!(Ok(x));
    }
    Err(cnt)
}

#[async_stream(boxed, item = u64)]
fn _stream4() -> Result<(), i32> {
    stream_yield!(Ok(0));
    stream_yield!(Ok(1));
    Ok(())
}

mod foo { pub struct Foo(pub i32); }

#[async_stream(boxed, item = foo::Foo)]
pub fn _stream5() -> Result<(), i32> {
    stream_yield!(Ok(foo::Foo(0)));
    stream_yield!(Ok(foo::Foo(1)));
    Ok(())
}

// struct A(i32);
//
// impl A {
//     #[async]
//     fn a_foo(self) -> Result<i32, i32> {
//         Ok(self.0)
//     }
//
//     #[async]
//     fn _a_foo2(self: Box<Self>) -> Result<i32, i32> {
//         Ok(self.0)
//     }
// }

// trait B {
//     #[async]
//     fn b(self) -> Result<i32, i32>;
// }
//
// impl B for A {
//     #[async]
//     fn b(self) -> Result<i32, i32> {
//         Ok(self.0)
//     }
// }

#[test]
fn main() {
    assert_eq!(foo().wait(), Ok(1));
    assert_eq!(_bar().wait(), Ok(1));
    assert_eq!(_bar2().wait(), Ok(2));
    assert_eq!(_bar3().wait(), Ok(2));
    assert_eq!(_bar4().wait(), Ok(10));
    assert_eq!(_foo6(8).wait(), Err(8));
    // assert_eq!(A(11).a_foo().wait(), Ok(11));
    assert_eq!(loop_in_loop().wait(), Ok(true));
}

#[async]
fn loop_in_loop() -> Result<bool, i32> {
    let mut cnt = 0;
    let vec = vec![1, 2, 3, 4];
    #[async]
    for x in futures::stream::iter_ok::<_, i32>(vec.clone()) {
        #[async]
        for y in futures::stream::iter_ok::<_, i32>(vec.clone()) {
            cnt += x * y;
        }
    }

    let sum = (1..5).map(|x| (1..5).map(|y| x * y).sum::<i32>()).sum::<i32>();
    Ok(cnt == sum)
}

#[async_stream(item = i32)]
fn poll_stream_after_error_stream() -> Result<(), ()> {
    stream_yield!(Ok(5));
    Err(())
}

#[test]
fn poll_stream_after_error() {
    let mut s = poll_stream_after_error_stream();
    assert_eq!(s.poll(), Ok(Async::Ready(Some(5))));
    assert_eq!(s.poll(), Err(()));
    assert_eq!(s.poll(), Ok(Async::Ready(None)));
}
<|endoftext|>


<commit_before>use json::parse;
use std::io::Read;
use album::Album;

#[derive(Debug)]
pub struct Artist {
    pub name: String,
    pub gender: String,
    pub id: String,
    pub tags: Vec<String>,
    pub albums: Vec<Album>
}

impl Artist {
    pub fn new(name: String, gender: String) -> Artist {
        Artist {
            name: name,
            gender: gender,
            id: String::new(),
            tags: Vec::new(),
            albums: Vec::new(),
        }
    }
}

pub trait ArtistTrait {
    fn search(self, query: &str) -> Option<Vec<Artist>>;
    fn lookup(self, id: &str) -> Option<Artist>;
}

impl ArtistTrait for super::MusicBrainz {
    fn search(self, name: &str) -> Option<Vec<Artist>> {
        let endpoint = format!("https://musicbrainz.org/ws/2/artist?query={}&fmt=json", name);
        let mut res = self.get(&endpoint).expect("failed to search for artist");

        let mut buf = String::new();
        res.read_to_string(&mut buf).expect("failed to read response to string");

        let data = parse(&buf).unwrap();
        let count = data["count"].as_i32().unwrap();

        if count == 0 {
            return None;
        }

        let artists = &data["artists"];
        let mut results: Vec<Artist> = Vec::new();

        for artist in artists.members() {
            if !artist["score"].is_null() {
                if artist["score"] == "100" {
                    if !artist["name"].is_null() {
                        let name = artist["name"].to_string();
                        let gender = artist["gender"].to_string();
                        let id = artist["id"].to_string();

                        let mut artist_obj = Artist::new(name, gender);
                        artist_obj.id = id;

                        for tag in artist["tags"].members() {
                            artist_obj.tags.push(tag["name"].to_string());
                        }

                        results.push(artist_obj);
                    }
                }
            }
        }
        Some(results)
    }

    fn lookup(self, id: &str) -> Option<Artist> {
        let endpoint = format!("https://musicbrainz.org/ws/2/artist/{id}?inc=release-groups&fmt=json", id=id);
        let mut res = self.get(&endpoint).expect("failed to lookup artist");

        let mut buf = String::new();
        res.read_to_string(&mut buf).expect("failed to read response to string");

        let data = parse(&buf).unwrap();
        let mut result = Artist::new(data["name"].to_string(), data["gender"].to_string());

        let albums = &data["release-groups"];
        for album in albums.members() {
            result.albums.push(Album {
                title: album["title"].to_string(),
                release_date: album["first-release-date"].to_string(),
                id: album["id"].to_string(),
                artist: data["id"].to_string()
            });
        }

        Some(result)
    }
}
<commit_msg>Change return type of search<commit_after>use json::parse;
use std::io::Read;
use album::Album;

#[derive(Debug)]
pub struct Artist {
    pub name: String,
    pub gender: String,
    pub id: String,
    pub tags: Vec<String>,
    pub albums: Vec<Album>
}

impl Artist {
    pub fn new(name: String, gender: String) -> Artist {
        Artist {
            name: name,
            gender: gender,
            id: String::new(),
            tags: Vec::new(),
            albums: Vec::new(),
        }
    }
}

pub trait ArtistTrait {
    fn search(self, query: &str) -> Vec<Artist>;
    fn lookup(self, id: &str) -> Option<Artist>;
}

impl ArtistTrait for super::MusicBrainz {
    fn search(self, name: &str) -> Vec<Artist> {
        let endpoint = format!("https://musicbrainz.org/ws/2/artist?query={}&fmt=json", name);
        let mut res = self.get(&endpoint).expect("failed to search for artist");

        let mut buf = String::new();
        res.read_to_string(&mut buf).expect("failed to read response to string");

        let data = parse(&buf).unwrap();
        let count = data["count"].as_i32().unwrap();

        if count == 0 {
            return Vec::new();
        }

        let artists = &data["artists"];
        let mut results: Vec<Artist> = Vec::new();

        for artist in artists.members() {
            if !artist["score"].is_null() {
                if artist["score"] == "100" {
                    if !artist["name"].is_null() {
                        let name = artist["name"].to_string();
                        let gender = artist["gender"].to_string();
                        let id = artist["id"].to_string();

                        let mut artist_obj = Artist::new(name, gender);
                        artist_obj.id = id;

                        for tag in artist["tags"].members() {
                            artist_obj.tags.push(tag["name"].to_string());
                        }

                        results.push(artist_obj);
                    }
                }
            }
        }
        results
    }

    fn lookup(self, id: &str) -> Option<Artist> {
        let endpoint = format!("https://musicbrainz.org/ws/2/artist/{id}?inc=release-groups&fmt=json", id=id);
        let mut res = self.get(&endpoint).expect("failed to lookup artist");

        let mut buf = String::new();
        res.read_to_string(&mut buf).expect("failed to read response to string");

        let data = parse(&buf).unwrap();
        let mut result = Artist::new(data["name"].to_string(), data["gender"].to_string());

        let albums = &data["release-groups"];
        for album in albums.members() {
            result.albums.push(Album {
                title: album["title"].to_string(),
                release_date: album["first-release-date"].to_string(),
                id: album["id"].to_string(),
                artist: data["id"].to_string()
            });
        }

        Some(result)
    }
}
<|endoftext|>


<commit_before>use parking_lot::{Mutex, MutexGuard};
use std::ops::{Deref, DerefMut};

use crate::gc::Address;
use crate::object::{Obj, Ref};
use crate::threads::current_thread;

pub const HANDLE_SIZE: usize = 256;

pub struct HandleMemory {
    inner: Mutex<HandleMemoryInner>,
}

impl HandleMemory {
    pub fn new() -> HandleMemory {
        HandleMemory {
            inner: Mutex::new(HandleMemoryInner::new()),
        }
    }

    pub fn handle<T>(&self, obj: Ref<T>) -> Handle<T> {
        self.inner.lock().handle(obj)
    }

    pub fn push_border(&self) {
        self.inner.lock().push_border();
    }

    pub fn pop_border(&self) {
        self.inner.lock().pop_border();
    }

    pub fn iter(&self) -> HandleMemoryIter {
        let inner = self.inner.lock();
        let len = inner.buffers.len();
        let free = inner.free;

        HandleMemoryIter {
            mem: inner,
            buffer_idx: 0,
            element_idx: 0,
            full_buffer_len: if len == 0 { 0 } else { len - 1 },
            last_buffer_len: free,
        }
    }
}

pub struct HandleMemoryInner {
    /// all buffers, Box is important since HandleBuffer
    /// is a big struct that needs to get moved/copied on resizes
    buffers: Vec<Box<HandleBuffer>>,

    // store addresses of inserted borders
    borders: Vec<BorderData>,

    // index of next free position in buffer
    free: usize,
}

impl HandleMemoryInner {
    pub fn new() -> HandleMemoryInner {
        let buffer = Box::new(HandleBuffer::new());

        HandleMemoryInner {
            buffers: vec![buffer],
            borders: Vec::new(),
            free: 0,
        }
    }

    pub fn handle<T>(&mut self, obj: Ref<T>) -> Handle<T> {
        debug_assert!(current_thread().is_running());

        if self.free >= HANDLE_SIZE {
            self.push_buffer();
            self.free = 0;
        }

        let buffer = self.buffers.last_mut().unwrap();

        let idx = self.free;
        let elem = &mut buffer.elements[idx];
        self.free = idx + 1;

        *elem = obj.cast::<Obj>();

        Handle(elem as *mut Ref<Obj> as *mut Ref<T>)
    }

    pub fn push_buffer(&mut self) {
        self.buffers.push(Box::new(HandleBuffer::new()));
    }

    pub fn push_border(&mut self) {
        let buffer = self.buffers.len();
        let element = self.free;

        self.borders.push(BorderData { buffer, element });
    }

    pub fn pop_border(&mut self) {
        let border = self.borders.pop().expect("no border left");

        self.buffers.truncate(border.buffer);
        self.free = border.element;
    }
}

pub fn handle<T>(obj: Ref<T>) -> Handle<T> {
    let thread = current_thread();
    debug_assert!(thread.state_relaxed().is_running());
    thread.handles.handle(obj)
}

struct HandleBuffer {
    elements: [Ref<Obj>; HANDLE_SIZE],
}

impl HandleBuffer {
    fn new() -> HandleBuffer {
        HandleBuffer {
            elements: [Ref::null(); HANDLE_SIZE],
        }
    }
}

struct BorderData {
    buffer: usize,
    element: usize,
}
#[repr(C)]
pub struct Handle<T>(*mut Ref<T>);

impl<T> Handle<T> {
    pub fn direct(self) -> Ref<T> {
        debug_assert!(current_thread().is_running());
        unsafe { *self.0 }
    }

    pub fn direct_ptr(self) -> Address {
        debug_assert!(current_thread().is_running());
        unsafe { *self.0 }.address()
    }

    pub fn location(&self) -> Address {
        Address::from_ptr(self.0)
    }

    pub fn from_address(location: Address) -> Handle<T> {
        Handle(location.to_mut_ptr())
    }

    pub fn cast<R>(self) -> Handle<R> {
        Handle(self.0 as *mut Ref<R>)
    }
}

impl<T> Deref for Handle<T> {
    type Target = T;

    fn deref(&self) -> &T {
        debug_assert!(current_thread().is_running());
        unsafe { &*self.0 }.deref()
    }
}

impl<T> DerefMut for Handle<T> {
    fn deref_mut(&mut self) -> &mut T {
        debug_assert!(current_thread().is_running());
        unsafe { &mut *self.0 }.deref_mut()
    }
}

// known limitation of #[derive(Copy, Clone)]
// traits need to be implemented manually
impl<T> Copy for Handle<T> {}
impl<T> Clone for Handle<T> {
    fn clone(&self) -> Handle<T> {
        *self
    }
}

pub struct HandleMemoryIter<'a> {
    mem: MutexGuard<'a, HandleMemoryInner>,
    buffer_idx: usize,
    element_idx: usize,
    full_buffer_len: usize,
    last_buffer_len: usize,
}

impl<'a> Iterator for HandleMemoryIter<'a> {
    type Item = Handle<Obj>;

    fn next(&mut self) -> Option<Handle<Obj>> {
        if self.buffer_idx < self.full_buffer_len {
            if self.element_idx < HANDLE_SIZE {
                let idx = self.element_idx;
                self.element_idx += 1;

                let buffer = &mut self.mem.buffers[self.buffer_idx];
                return Some(Handle(&mut buffer.elements[idx] as *mut Ref<Obj>));
            } else {
                self.buffer_idx += 1;
                self.element_idx = 0;
            }
        }

        if self.buffer_idx == self.full_buffer_len {
            if self.element_idx < self.last_buffer_len {
                let idx = self.element_idx;
                self.element_idx += 1;

                let buffer = &mut self.mem.buffers[self.buffer_idx];
                return Some(Handle(&mut buffer.elements[idx] as *mut Ref<Obj>));
            } else {
                return None;
            }
        }

        None
    }
}

pub fn handle_scope<F: FnOnce() -> R, R>(f: F) -> R {
    let thread = current_thread();
    thread.handles.push_border();
    let result = f();
    thread.handles.pop_border();
    result
}
<commit_msg>fix handle iteration<commit_after>use parking_lot::{Mutex, MutexGuard};
use std::ops::{Deref, DerefMut};

use crate::gc::Address;
use crate::object::{Obj, Ref};
use crate::threads::current_thread;

pub const HANDLE_SIZE: usize = 256;

pub struct HandleMemory {
    inner: Mutex<HandleMemoryInner>,
}

impl HandleMemory {
    pub fn new() -> HandleMemory {
        HandleMemory {
            inner: Mutex::new(HandleMemoryInner::new()),
        }
    }

    pub fn handle<T>(&self, obj: Ref<T>) -> Handle<T> {
        self.inner.lock().handle(obj)
    }

    pub fn push_border(&self) {
        self.inner.lock().push_border();
    }

    pub fn pop_border(&self) {
        self.inner.lock().pop_border();
    }

    pub fn iter(&self) -> HandleMemoryIter {
        let inner = self.inner.lock();
        let len = inner.buffers.len();
        let free = inner.free;

        HandleMemoryIter {
            mem: inner,
            buffer_idx: 0,
            element_idx: 0,
            full_buffer_len: if len == 0 { 0 } else { len - 1 },
            last_buffer_len: free,
        }
    }
}

pub struct HandleMemoryInner {
    /// all buffers, Box is important since HandleBuffer
    /// is a big struct that needs to get moved/copied on resizes
    buffers: Vec<Box<HandleBuffer>>,

    // store addresses of inserted borders
    borders: Vec<BorderData>,

    // index of next free position in buffer
    free: usize,
}

impl HandleMemoryInner {
    pub fn new() -> HandleMemoryInner {
        let buffer = Box::new(HandleBuffer::new());

        HandleMemoryInner {
            buffers: vec![buffer],
            borders: Vec::new(),
            free: 0,
        }
    }

    pub fn handle<T>(&mut self, obj: Ref<T>) -> Handle<T> {
        debug_assert!(current_thread().is_running());

        if self.free >= HANDLE_SIZE {
            self.push_buffer();
            self.free = 0;
        }

        let buffer = self.buffers.last_mut().unwrap();

        let idx = self.free;
        let elem = &mut buffer.elements[idx];
        self.free = idx + 1;

        *elem = obj.cast::<Obj>();

        Handle(elem as *mut Ref<Obj> as *mut Ref<T>)
    }

    pub fn push_buffer(&mut self) {
        self.buffers.push(Box::new(HandleBuffer::new()));
    }

    pub fn push_border(&mut self) {
        let buffer = self.buffers.len();
        let element = self.free;

        self.borders.push(BorderData { buffer, element });
    }

    pub fn pop_border(&mut self) {
        let border = self.borders.pop().expect("no border left");

        self.buffers.truncate(border.buffer);
        self.free = border.element;
    }
}

pub fn handle<T>(obj: Ref<T>) -> Handle<T> {
    let thread = current_thread();
    debug_assert!(thread.state_relaxed().is_running());
    thread.handles.handle(obj)
}

struct HandleBuffer {
    elements: [Ref<Obj>; HANDLE_SIZE],
}

impl HandleBuffer {
    fn new() -> HandleBuffer {
        HandleBuffer {
            elements: [Ref::null(); HANDLE_SIZE],
        }
    }
}

struct BorderData {
    buffer: usize,
    element: usize,
}
#[repr(C)]
pub struct Handle<T>(*mut Ref<T>);

impl<T> Handle<T> {
    pub fn direct(self) -> Ref<T> {
        debug_assert!(current_thread().is_running());
        unsafe { *self.0 }
    }

    pub fn direct_ptr(self) -> Address {
        debug_assert!(current_thread().is_running());
        unsafe { *self.0 }.address()
    }

    pub fn location(&self) -> Address {
        Address::from_ptr(self.0)
    }

    pub fn from_address(location: Address) -> Handle<T> {
        Handle(location.to_mut_ptr())
    }

    pub fn cast<R>(self) -> Handle<R> {
        Handle(self.0 as *mut Ref<R>)
    }
}

impl<T> Deref for Handle<T> {
    type Target = T;

    fn deref(&self) -> &T {
        debug_assert!(current_thread().is_running());
        unsafe { &*self.0 }.deref()
    }
}

impl<T> DerefMut for Handle<T> {
    fn deref_mut(&mut self) -> &mut T {
        debug_assert!(current_thread().is_running());
        unsafe { &mut *self.0 }.deref_mut()
    }
}

// known limitation of #[derive(Copy, Clone)]
// traits need to be implemented manually
impl<T> Copy for Handle<T> {}
impl<T> Clone for Handle<T> {
    fn clone(&self) -> Handle<T> {
        *self
    }
}

pub struct HandleMemoryIter<'a> {
    mem: MutexGuard<'a, HandleMemoryInner>,
    buffer_idx: usize,
    element_idx: usize,
    full_buffer_len: usize,
    last_buffer_len: usize,
}

impl<'a> Iterator for HandleMemoryIter<'a> {
    type Item = Handle<Obj>;

    fn next(&mut self) -> Option<Handle<Obj>> {
        while self.buffer_idx < self.full_buffer_len {
            if self.element_idx < HANDLE_SIZE {
                let idx = self.element_idx;
                self.element_idx += 1;

                let buffer = &mut self.mem.buffers[self.buffer_idx];
                return Some(Handle(&mut buffer.elements[idx] as *mut Ref<Obj>));
            } else {
                self.buffer_idx += 1;
                self.element_idx = 0;
            }
        }

        if self.buffer_idx == self.full_buffer_len {
            if self.element_idx < self.last_buffer_len {
                let idx = self.element_idx;
                self.element_idx += 1;

                let buffer = &mut self.mem.buffers[self.buffer_idx];
                Some(Handle(&mut buffer.elements[idx] as *mut Ref<Obj>))
            } else {
                None
            }
        } else {
            None
        }
    }
}

pub fn handle_scope<F: FnOnce() -> R, R>(f: F) -> R {
    let thread = current_thread();
    thread.handles.push_border();
    let result = f();
    thread.handles.pop_border();
    result
}
<|endoftext|>


<commit_before>#![feature(core)]

extern crate rustbox;

use std::error::Error;
use std::default::Default;

use rustbox::{Color, RustBox};
use rustbox::Key;

fn main() {
    let rustbox = match RustBox::init(Default::default()) {
        Result::Ok(v) => v,
        Result::Err(e) => panic!("{}", e),
    };

    rustbox.print(1, 1, rustbox::RB_BOLD, Color::White, Color::Black, "Hello, world!");
    rustbox.print(1, 3, rustbox::RB_BOLD, Color::White, Color::Black,
                  "Press 'q' to quit.");
    loop {
        rustbox.present();
        match rustbox.poll_event(false) {
            Ok(rustbox::Event::KeyEvent(key)) => {
                match key {
                    Some(Key::Char('q')) => { break; }
                    _ => { }
                }
            },
            Err(e) => panic!("{}", e.description()),
            _ => { }
        }
    }
}
<commit_msg>Fix example - #28<commit_after>extern crate rustbox;

use std::default::Default;

use rustbox::{Color, RustBox};
use rustbox::Key;

fn main() {
    let rustbox = match RustBox::init(Default::default()) {
        Result::Ok(v) => v,
        Result::Err(e) => panic!("{}", e),
    };

    rustbox.print(1, 1, rustbox::RB_BOLD, Color::White, Color::Black, "Hello, world!");
    rustbox.print(1, 3, rustbox::RB_BOLD, Color::White, Color::Black,
                  "Press 'q' to quit.");
    loop {
        rustbox.present();
        match rustbox.poll_event(false) {
            Ok(rustbox::Event::KeyEvent(key)) => {
                match key {
                    Some(Key::Char('q')) => { break; }
                    _ => { }
                }
            },
            Err(e) => panic!("{:?}", e),
            _ => { }
        }
    }
}
<|endoftext|>


<commit_before>extern crate collections;

use std::cmp::Ordering;
use std::os;

struct Forest{
       goats : i32,
       wolves : i32,
       lions : i32
}

impl Eq for Forest {
    fn eq(&self, other: &Forest) -> bool {
        other.goats == self.goats &&
	other.wolves == self.wolves &&
	other.lions == self.lions}
}

impl Clone for Forest{
    fn clone(&self) -> Forest{
       Forest{goats: self.goats, wolves: self.wolves, lions: self.lions}
    }
}

fn printForest(f : &Forest) {
     print!("Forest [goats= {}, wolves= {}, lions= {}]", f.goats, f.lions, f.wolves);
}

fn printForests(fors : &Vec<Forest>){
   let mut i = 0;
   while i < fors.len(){
   	 printForest(fors.get(i));
	 print!("\n");
	 i+=1;
   }
}

fn forestStable(forest : &Forest) -> bool {
  if forest.goats == 0{
   return (forest.wolves == 0) || (forest.lions == 0);
  }
  return (forest.wolves == 0) && (forest.lions == 0);
}

fn forestInvalid(forest : &Forest) ->  bool {
  return forest.goats < 0 || forest.wolves < 0 || forest.lions < 0;
}

fn forLessThan(f1: &Forest, f2: &Forest) -> Ordering{
  if f1.goats == f2.goats{
    if f1.wolves == f2.wolves {
      if f1.lions == f2.lions {
      	 Equal
      }else{
	f1.lions.cmp(&f2.lions)
      }
    }else {
	f1.wolves.cmp(&f2.wolves)
    }
  }else{
	f1.goats.cmp(&f2.goats)
  }
}

fn meal(forests: &Vec<Forest>) -> Vec<Forest> {
    let mut mealedForests: Vec<Forest> = Vec::with_capacity(forests.len()*3);
    let mut i = 0;
    while i < forests.len() {
    	  let x = &forests.get(i);
    	  mealedForests.push(Forest{goats : x.goats -1, wolves : x.wolves -1, lions: x.lions +1});
    	  mealedForests.push(Forest{goats : x.goats -1, wolves : x.wolves +1, lions: x.lions -1});
    	  mealedForests.push(Forest{goats : x.goats +1, wolves : x.wolves -1, lions: x.lions -1});
	  i+=1;
    }
    let (_, mut okForests) = mealedForests.clone().partition(|a| forestInvalid(a) );
    okForests.sort_by(|a,b| forLessThan(a,b) );
    okForests.dedup();
    return okForests;
}

fn devouringPossible(forests: &Vec<Forest>) -> bool {
  !(forests.len() < 1) && !(forests.iter().any(|x| forestStable(x)))
}

fn stableForests(forests: &Vec<Forest>) -> Vec<Forest> {
    let mut filteredForests: Vec<Forest> = Vec::with_capacity(3);
    let mut i = 0;
    while i < forests.len() {
    	  if forestStable(forests.get(i)){
	     let x = forests.get(i);
	     filteredForests.push(Forest{goats : x.goats, wolves : x.wolves, lions: x.lions});
	  }
	  i+=1;
    }
    filteredForests
}

fn findStableForests(forest: Forest) -> Vec<Forest>{
   let mut forests: Vec<Forest> = Vec::with_capacity(1);
   forests.push(forest);
   while devouringPossible(&forests){
    forests = meal(&forests);
  }
  return stableForests(&forests);
}

fn main(){
   let args = os::args();
   if args.len() != 4{
      print!("Error: input should be in the form of <goats> <wolves> <lions>\n");
      return;
   }
   let initialFor = Forest{goats: std::i32::parse_bytes(args[1].clone().into_bytes(),10).expect("Error: goats not an int.\n"),
       		          wolves: std::i32::parse_bytes(args[2].clone().into_bytes(),10).expect("Error: wolves not an int.\n"),
			  lions:  std::i32::parse_bytes(args[3].clone().into_bytes(),10).expect("Error: lions not an int.\n")};
   let stableFors = findStableForests(initialFor);
   if stableFors.len() < 1 {
      print!("No stable forests found.\n");
   }
   printForests(&stableFors);
}<commit_msg>Make the rust version more idiomatic<commit_after>extern crate collections;

use std::os;
use std::fmt;

#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
struct Forest {
    goats : i32,
    wolves : i32,
    lions : i32,
}

impl Forest {
    pub fn is_stable(&self) -> bool {
        match *self {
            Forest { goats: 0, wolves: 0, lions: _ } |
            Forest { goats: 0, wolves: _, lions: 0 } |
            Forest { goats: _, wolves: 0, lions: 0 }
              => true,
            _ => false
        }
    }

    pub fn is_valid(&self) -> bool {
        self.goats >= 0 && self.wolves >= 0 && self.lions >= 0
    }
}

impl fmt::Show for Forest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Forest [goats: {}, wolves= {}, lions= {}]", self.goats, self.wolves, self.lions)
    }
}

fn printForests(fors : &[Forest]){
    for f in fors.iter() {
        println!("{}", f);
    }
}

fn meal(forests: Vec<Forest>) -> Vec<Forest> {
    let mut mealedForests: Vec<Forest> = Vec::with_capacity(forests.len()*3);
    for x in forests.move_iter() {
        mealedForests.push(Forest{goats : x.goats -1, wolves : x.wolves -1, lions: x.lions +1});
        mealedForests.push(Forest{goats : x.goats -1, wolves : x.wolves +1, lions: x.lions -1});
        mealedForests.push(Forest{goats : x.goats +1, wolves : x.wolves -1, lions: x.lions -1});
    }
    let mut okForests: Vec<Forest> = mealedForests.move_iter().filter(|f| f.is_valid()).collect();
    okForests.sort();
    okForests.dedup();
    return okForests;
}

fn devouringPossible(forests: &[Forest]) -> bool {
    !(forests.len() < 1) && !(forests.iter().any(|x| x.is_stable()))
}

fn stableForests(forests: Vec<Forest>) -> Vec<Forest> {
    forests.move_iter().filter(|f| f.is_stable()).collect()
}

fn findStableForests(forest: Forest) -> Vec<Forest>{
    let mut forests: Vec<Forest> = Vec::with_capacity(1);
    forests.push(forest);
    while devouringPossible(forests.as_slice()){
        forests = meal(forests);
    }
    return stableForests(forests);
}

fn main(){
    let args = os::args();
    if args.len() != 4{
        print!("Error: input should be in the form of <goats> <wolves> <lions>\n");
        return;
    }
    let initialFor = Forest {
        goats: from_str(args.get(1).as_slice()).expect("Goats must be an int"),
        wolves: from_str(args.get(2).as_slice()).expect("Wolves must be an int"),
        lions: from_str(args.get(3).as_slice()).expect("Lions must be an int")
    };

    let stableFors = findStableForests(initialFor);
    if stableFors.len() < 1 {
        print!("No stable forests found.\n");
    }
    printForests(stableFors.as_slice());
}
<|endoftext|>