<commit_before>//!A raytracer.
#![feature(path, io)]
extern crate image;
extern crate rand;

use std::old_io::File;
use std::num::Float;
use std::f32::consts::PI_2;

use rand::distributions::IndependentSample;
use rand::Rng;

use point::Point3;
use vec::Vec3;

mod vec;
mod point;

#[derive(Copy)]
struct Ray3 {
    start: Point3,
    dir: Vec3
}

struct Intersection<ObjectId> {
    time: f32,
    point: Point3,
    normal: Vec3,
    emitted: f32,
    object: ObjectId
}

trait Scene {
    // TODO: Should this have a "not present" id?
    type ObjectId: Copy;

    fn intersect(&self, ray: Ray3, previous: Option<Self::ObjectId>) -> Option<Intersection<Self::ObjectId>>;
}

struct Material {
    emitted_radiance: f32
}

struct Sphere {
    center: Point3,
    radius: f32,
    material: Material
}

impl Scene for Sphere {
    type ObjectId = ();
    fn intersect(&self, ray: Ray3, previous: Option<()>) -> Option<Intersection<()>> {
        if let Some(()) = previous {
            return None;
        }

        let offset = ray.start - self.center;

        let a = ray.dir.mag2();
        let b = 2. * offset.dot(ray.dir);
        let c = offset.mag2() - self.radius*self.radius;

        let descrim = b*b - 4.*a*c;
        if descrim > 0. {
            let t1 = (-b - descrim.sqrt()) / (2. * a);
            let t2 = (-b + descrim.sqrt()) / (2. * a);
            if t1 > 0. {
                let p = ray.start + ray.dir * t1;
                let normal = p - self.center;
                Some(Intersection {
                    time: t1,
                    point: p,
                    normal: normal,
                    emitted: self.material.emitted_radiance,
                    object: ()
                })
            } else if t2 > 0. {
                let p = ray.start + ray.dir * t2;
                let normal = p - self.center;
                Some(Intersection {
                    time: t2,
                    point: p,
                    normal: normal,
                    emitted: self.material.emitted_radiance,
                    object: ()
                })
            } else {
                None
            }
        } else {
            None
        }
    }
}

struct Plane {
    origin: Point3,
    normal: Vec3,
    material: Material
}

impl Scene for Plane {
    type ObjectId = ();
    fn intersect(&self, ray: Ray3, previous: Option<()>) -> Option<Intersection<()>> {
        if let Some(()) = previous {
            return None;
        }

        let divisor = ray.dir.dot(self.normal);
        if divisor == 0. {
            None
        } else {
            let offset = ray.start - self.origin;
            let time = -offset.dot(self.normal) / divisor;
            if time > 0. {
                Some(Intersection {
                    time: time,
                    point: ray.start + ray.dir * time,
                    normal: self.normal,
                    emitted: self.material.emitted_radiance,
                    object: ()
                })
            } else {
                None
            }
        }
    }
}

#[derive(Copy)]
enum Choice<A, B> {
    OptA(A),
    OptB(B)
}

impl<A: Scene, B: Scene> Scene for (A, B) {
    type ObjectId = Choice<A::ObjectId, B::ObjectId>;
    fn intersect(&self, ray: Ray3, previous: Option<Choice<A::ObjectId, B::ObjectId>>) -> Option<Intersection<Choice<A::ObjectId, B::ObjectId>>> {
        let (aid, bid) = match previous {
            None => (None, None),
            Some(Choice::OptA(aid)) => (Some(aid), None),
            Some(Choice::OptB(bid)) => (None, Some(bid))
        };

        match self.0.intersect(ray, aid) {
            Some(ai) => {
                match self.1.intersect(ray, bid) {
                    Some(bi) => if ai.time < bi.time {
                        Some(Intersection {
                            time: ai.time,
                            normal: ai.normal,
                            point: ai.point,
                            emitted: ai.emitted,
                            object: Choice::OptA(ai.object)
                        })
                    } else {
                        Some(Intersection {
                            time: bi.time,
                            normal: bi.normal,
                            point: bi.point,
                            emitted: bi.emitted,
                            object: Choice::OptB(bi.object)
                        })
                    },
                    None => Some(Intersection {
                        time: ai.time,
                        normal: ai.normal,
                        point: ai.point,
                        emitted: ai.emitted,
                        object: Choice::OptA(ai.object)
                    })
                }
            },
            None => match self.1.intersect(ray, bid) {
                Some(bi) => Some(Intersection {
                    time: bi.time,
                    normal: bi.normal,
                    point: bi.point,
                    emitted: bi.emitted,
                    object: Choice::OptB(bi.object)
                }),
                None => None
            }
        }
    }
}

impl<T: Scene> Scene for [T] {
    type ObjectId = (usize, T::ObjectId);
    fn intersect(&self, ray: Ray3, previous: Option<(usize, T::ObjectId)>) -> Option<Intersection<(usize, T::ObjectId)>> {
        let mut best: Option<Intersection<(usize, T::ObjectId)>> = None;

        for (id, obj) in self.iter().enumerate() {
            let prev = match previous {
                Some((prev_index, prev_obj)) => if prev_index == id {
                    Some(prev_obj)
                } else {
                    None
                },
                None => None
            };

            if let Some(intersection) = obj.intersect(ray, prev) {
                let new_best = match best {
                    Some(ref cur_best) => intersection.time < cur_best.time,
                    None => true
                };

                if new_best {
                    best = Some(Intersection {
                        time: intersection.time,
                        normal: intersection.normal,
                        point: intersection.point,
                        emitted: intersection.emitted,
                        object: (id, intersection.object)
                    });
                }
            }
        }

        best
    }
}

impl<'a, T: ?Sized + Scene> Scene for &'a T {
    type ObjectId = T::ObjectId;
    fn intersect(&self, ray: Ray3, previous: Option<T::ObjectId>) -> Option<Intersection<T::ObjectId>> {
        (*self).intersect(ray, previous)
    }
}

fn clamp(val: f32) -> f32 {
    if val > 1. {
        1.
    } else if val < 0. {
        0.
    } else {
        val
    }
}

fn rand_sphere<R: rand::Rng>(rng: &mut R) -> Vec3 {
    let z = rand::distributions::Range::new(-1., 1.).ind_sample(rng);
    let r = (1. - z*z).sqrt();
    let angle = rand::distributions::Range::new(0., PI_2).ind_sample(rng);
    Vec3::new(r*angle.cos(), r*angle.sin(), z)
}

fn main() {
    let mut rng = rand::thread_rng();

    let rays_per_pixel = 100;
    let scene: (&[Sphere], &[Plane]) = (
        &[Sphere {
            center: Point3::new(1.2, 0.0, 5.0),
            radius: 0.3,
            material: Material { emitted_radiance: 0. }
        },
        Sphere {
            center: Point3::new(1.5, 0.0, 3.5),
            radius: 0.35,
            material: Material { emitted_radiance: 0. }
        },
        Sphere {
            center: Point3::new(1.0, 2.5, 0.5),
            radius: 1.0,
            material: Material { emitted_radiance: 20. }
        }],
        &[Plane {
            origin: Point3::new(0.0, 0.0, 8.0),
            normal: Vec3::new(2.0, 0.0, -1.0),
            material: Material { emitted_radiance: 0. }
        },
        Plane {
            origin: Point3::new(0.0, 0.0, 8.0),
            normal: Vec3::new(-1.0, 0.0, -2.0),
            material: Material { emitted_radiance: 0. }
        },
        Plane {
            origin: Point3::new(0.0, 2.0, 0.0),
            normal: Vec3::new(0.0, -1.0, 0.0),
            material: Material { emitted_radiance: 0. }
        },
        Plane {
            origin: Point3::new(0.0, -3.0, 0.0),
            normal: Vec3::new(0.0, 1.0, 0.0),
            material: Material { emitted_radiance: 0. }
        }]
    );

    let imgx = 800;
    let imgy = 800;

    let scalex = 4.0 / imgx as f32;
    let scaley = 4.0 / imgy as f32;

    // Create a new ImgBuf with width: imgx and height: imgy
    let mut imgbuf = image::ImageBuffer::new(imgx, imgy);

    // Iterate over the coordiantes and pixels of the image
    for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
        let cy = -(y as f32 * scaley - 2.0);
        let cx = x as f32 * scalex - 2.0;

        let mut total_light = 0.;
        for _ in 0..rays_per_pixel {
            let mut ray = Ray3 {
                start: Point3::new(0., 0., -8.0),
                dir: Vec3::new(cx, cy, 8.0)
            };
            let mut prev_object = None;
            let mut scale = 1.;
            loop {
                if let Some(intersection) = scene.intersect(ray, prev_object) {
                    prev_object = Some(intersection.object);

                    total_light += scale * intersection.emitted;

                    let cand_dir = rand_sphere(&mut rng);
                    let dir = if cand_dir.dot(intersection.normal) < 0. {
                        -cand_dir
                    } else {
                        cand_dir
                    };
                    ray = Ray3 {
                        start: intersection.point,
                        dir: dir
                    };

                    let p = dir.dot(intersection.normal) / intersection.normal.mag2().sqrt();
                    if scale > 0.2 {
                        scale *= p;
                    } else if rng.next_f32() > p {
                        break;
                    }
                } else {
                    break;
                }
            }
        }

        // Create an 8bit pixel of type Luma and value i
        // and assign in to the pixel at position (x, y)
        *pixel = image::Luma([(clamp(total_light / rays_per_pixel as f32)*255.) as u8]);
    }

    // Save the image as “out.png”
    let ref mut fout = File::create(&Path::new("out.png")).unwrap();

    // We must indicate the image’s color type and what format to save as
    let _ = image::ImageLuma8(imgbuf).save(fout, image::PNG);
}
<commit_msg>Switch to a faster RNG<commit_after>//!A raytracer.
#![feature(path, io)]
extern crate image;
extern crate rand;

use std::old_io::File;
use std::num::Float;
use std::f32::consts::PI_2;

use rand::distributions::IndependentSample;
use rand::Rng;

use point::Point3;
use vec::Vec3;

mod vec;
mod point;

#[derive(Copy)]
struct Ray3 {
    start: Point3,
    dir: Vec3
}

struct Intersection<ObjectId> {
    time: f32,
    point: Point3,
    normal: Vec3,
    emitted: f32,
    object: ObjectId
}

trait Scene {
    // TODO: Should this have a "not present" id?
    type ObjectId: Copy;

    fn intersect(&self, ray: Ray3, previous: Option<Self::ObjectId>) -> Option<Intersection<Self::ObjectId>>;
}

struct Material {
    emitted_radiance: f32
}

struct Sphere {
    center: Point3,
    radius: f32,
    material: Material
}

impl Scene for Sphere {
    type ObjectId = ();
    fn intersect(&self, ray: Ray3, previous: Option<()>) -> Option<Intersection<()>> {
        if let Some(()) = previous {
            return None;
        }

        let offset = ray.start - self.center;

        let a = ray.dir.mag2();
        let b = 2. * offset.dot(ray.dir);
        let c = offset.mag2() - self.radius*self.radius;

        let descrim = b*b - 4.*a*c;
        if descrim > 0. {
            let t1 = (-b - descrim.sqrt()) / (2. * a);
            let t2 = (-b + descrim.sqrt()) / (2. * a);
            if t1 > 0. {
                let p = ray.start + ray.dir * t1;
                let normal = p - self.center;
                Some(Intersection {
                    time: t1,
                    point: p,
                    normal: normal,
                    emitted: self.material.emitted_radiance,
                    object: ()
                })
            } else if t2 > 0. {
                let p = ray.start + ray.dir * t2;
                let normal = p - self.center;
                Some(Intersection {
                    time: t2,
                    point: p,
                    normal: normal,
                    emitted: self.material.emitted_radiance,
                    object: ()
                })
            } else {
                None
            }
        } else {
            None
        }
    }
}

struct Plane {
    origin: Point3,
    normal: Vec3,
    material: Material
}

impl Scene for Plane {
    type ObjectId = ();
    fn intersect(&self, ray: Ray3, previous: Option<()>) -> Option<Intersection<()>> {
        if let Some(()) = previous {
            return None;
        }

        let divisor = ray.dir.dot(self.normal);
        if divisor == 0. {
            None
        } else {
            let offset = ray.start - self.origin;
            let time = -offset.dot(self.normal) / divisor;
            if time > 0. {
                Some(Intersection {
                    time: time,
                    point: ray.start + ray.dir * time,
                    normal: self.normal,
                    emitted: self.material.emitted_radiance,
                    object: ()
                })
            } else {
                None
            }
        }
    }
}

#[derive(Copy)]
enum Choice<A, B> {
    OptA(A),
    OptB(B)
}

impl<A: Scene, B: Scene> Scene for (A, B) {
    type ObjectId = Choice<A::ObjectId, B::ObjectId>;
    fn intersect(&self, ray: Ray3, previous: Option<Choice<A::ObjectId, B::ObjectId>>) -> Option<Intersection<Choice<A::ObjectId, B::ObjectId>>> {
        let (aid, bid) = match previous {
            None => (None, None),
            Some(Choice::OptA(aid)) => (Some(aid), None),
            Some(Choice::OptB(bid)) => (None, Some(bid))
        };

        match self.0.intersect(ray, aid) {
            Some(ai) => {
                match self.1.intersect(ray, bid) {
                    Some(bi) => if ai.time < bi.time {
                        Some(Intersection {
                            time: ai.time,
                            normal: ai.normal,
                            point: ai.point,
                            emitted: ai.emitted,
                            object: Choice::OptA(ai.object)
                        })
                    } else {
                        Some(Intersection {
                            time: bi.time,
                            normal: bi.normal,
                            point: bi.point,
                            emitted: bi.emitted,
                            object: Choice::OptB(bi.object)
                        })
                    },
                    None => Some(Intersection {
                        time: ai.time,
                        normal: ai.normal,
                        point: ai.point,
                        emitted: ai.emitted,
                        object: Choice::OptA(ai.object)
                    })
                }
            },
            None => match self.1.intersect(ray, bid) {
                Some(bi) => Some(Intersection {
                    time: bi.time,
                    normal: bi.normal,
                    point: bi.point,
                    emitted: bi.emitted,
                    object: Choice::OptB(bi.object)
                }),
                None => None
            }
        }
    }
}

impl<T: Scene> Scene for [T] {
    type ObjectId = (usize, T::ObjectId);
    fn intersect(&self, ray: Ray3, previous: Option<(usize, T::ObjectId)>) -> Option<Intersection<(usize, T::ObjectId)>> {
        let mut best: Option<Intersection<(usize, T::ObjectId)>> = None;

        for (id, obj) in self.iter().enumerate() {
            let prev = match previous {
                Some((prev_index, prev_obj)) => if prev_index == id {
                    Some(prev_obj)
                } else {
                    None
                },
                None => None
            };

            if let Some(intersection) = obj.intersect(ray, prev) {
                let new_best = match best {
                    Some(ref cur_best) => intersection.time < cur_best.time,
                    None => true
                };

                if new_best {
                    best = Some(Intersection {
                        time: intersection.time,
                        normal: intersection.normal,
                        point: intersection.point,
                        emitted: intersection.emitted,
                        object: (id, intersection.object)
                    });
                }
            }
        }

        best
    }
}

impl<'a, T: ?Sized + Scene> Scene for &'a T {
    type ObjectId = T::ObjectId;
    fn intersect(&self, ray: Ray3, previous: Option<T::ObjectId>) -> Option<Intersection<T::ObjectId>> {
        (*self).intersect(ray, previous)
    }
}

fn clamp(val: f32) -> f32 {
    if val > 1. {
        1.
    } else if val < 0. {
        0.
    } else {
        val
    }
}

fn rand_sphere<R: rand::Rng>(rng: &mut R) -> Vec3 {
    let z = rand::distributions::Range::new(-1., 1.).ind_sample(rng);
    let r = (1. - z*z).sqrt();
    let angle = rand::distributions::Range::new(0., PI_2).ind_sample(rng);
    Vec3::new(r*angle.cos(), r*angle.sin(), z)
}

fn main() {
    let mut rng = rand::weak_rng();

    let rays_per_pixel = 100;
    let scene: (&[Sphere], &[Plane]) = (
        &[Sphere {
            center: Point3::new(1.2, 0.0, 5.0),
            radius: 0.3,
            material: Material { emitted_radiance: 0. }
        },
        Sphere {
            center: Point3::new(1.5, 0.0, 3.5),
            radius: 0.35,
            material: Material { emitted_radiance: 0. }
        },
        Sphere {
            center: Point3::new(1.0, 2.5, 0.5),
            radius: 1.0,
            material: Material { emitted_radiance: 20. }
        }],
        &[Plane {
            origin: Point3::new(0.0, 0.0, 8.0),
            normal: Vec3::new(2.0, 0.0, -1.0),
            material: Material { emitted_radiance: 0. }
        },
        Plane {
            origin: Point3::new(0.0, 0.0, 8.0),
            normal: Vec3::new(-1.0, 0.0, -2.0),
            material: Material { emitted_radiance: 0. }
        },
        Plane {
            origin: Point3::new(0.0, 2.0, 0.0),
            normal: Vec3::new(0.0, -1.0, 0.0),
            material: Material { emitted_radiance: 0. }
        },
        Plane {
            origin: Point3::new(0.0, -3.0, 0.0),
            normal: Vec3::new(0.0, 1.0, 0.0),
            material: Material { emitted_radiance: 0. }
        }]
    );

    let imgx = 800;
    let imgy = 800;

    let scalex = 4.0 / imgx as f32;
    let scaley = 4.0 / imgy as f32;

    // Create a new ImgBuf with width: imgx and height: imgy
    let mut imgbuf = image::ImageBuffer::new(imgx, imgy);

    // Iterate over the coordiantes and pixels of the image
    for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
        let cy = -(y as f32 * scaley - 2.0);
        let cx = x as f32 * scalex - 2.0;

        let mut total_light = 0.;
        for _ in 0..rays_per_pixel {
            let mut ray = Ray3 {
                start: Point3::new(0., 0., -8.0),
                dir: Vec3::new(cx, cy, 8.0)
            };
            let mut prev_object = None;
            let mut scale = 1.;
            loop {
                if let Some(intersection) = scene.intersect(ray, prev_object) {
                    prev_object = Some(intersection.object);

                    total_light += scale * intersection.emitted;

                    let cand_dir = rand_sphere(&mut rng);
                    let dir = if cand_dir.dot(intersection.normal) < 0. {
                        -cand_dir
                    } else {
                        cand_dir
                    };
                    ray = Ray3 {
                        start: intersection.point,
                        dir: dir
                    };

                    let p = dir.dot(intersection.normal) / intersection.normal.mag2().sqrt();
                    if scale > 0.2 {
                        scale *= p;
                    } else if rng.next_f32() > p {
                        break;
                    }
                } else {
                    break;
                }
            }
        }

        // Create an 8bit pixel of type Luma and value i
        // and assign in to the pixel at position (x, y)
        *pixel = image::Luma([(clamp(total_light / rays_per_pixel as f32)*255.) as u8]);
    }

    // Save the image as “out.png”
    let ref mut fout = File::create(&Path::new("out.png")).unwrap();

    // We must indicate the image’s color type and what format to save as
    let _ = image::ImageLuma8(imgbuf).save(fout, image::PNG);
}
<|endoftext|>


<commit_before>use flate2::bufread::GzDecoder;
use time::precise_time_ns;

use std::fs;
use std::io;
use std::io::Read;
use std::str;

use errors::*;

pub struct Streamer {
    buffer: Vec<u8>,
    bytes: io::Bytes<GzDecoder<io::BufReader<fs::File>>>,
}

// TODO: Is the fact that we are copying into "buffer" costing us a lot?
impl Streamer {
    pub fn new(input_file: &str) -> Result<Streamer, WikiError> {
        let f = fs::File::open(input_file)?;
        let bf = io::BufReader::new(f);
        let rdr = GzDecoder::new(bf)?;
        let bytes = rdr.bytes();
        Ok(Streamer { buffer: Vec::new(),
                      bytes: bytes })
    }

    fn advance_to_eol(&mut self) {
        let itr = (&mut self.bytes).take_while(|b| match b {
            &Ok(bb) => { bb != 0xA },
            _ => { false },
        });
        for b in itr {
            if let Ok(bb) = b {
                self.buffer.push(bb);
            }
        }
    }
}

// TODO: Can we make the iterator return string slices?
impl Iterator for Streamer {
    type Item = String;
    fn next(&mut self) -> Option<String> {
        let t0 = precise_time_ns();
        self.buffer.clear();
        self.advance_to_eol();
        let ret = if self.buffer.len() > 0 {
            if let Ok(s) = String::from_utf8(self.buffer.clone()) {
                Some(s)
            } else {
                None
            }
        } else {
            None
        };
        let t1 = precise_time_ns();
        println!("Streamer::next: {} us", (t1 - t0) / 1000 );
        ret
    }
}
<commit_msg>Removing comments<commit_after>use flate2::bufread::GzDecoder;
use time::precise_time_ns;

use std::fs;
use std::io;
use std::io::Read;
use std::str;

use errors::*;

pub struct Streamer {
    buffer: Vec<u8>,
    bytes: io::Bytes<GzDecoder<io::BufReader<fs::File>>>,
}

impl Streamer {
    pub fn new(input_file: &str) -> Result<Streamer, WikiError> {
        let f = fs::File::open(input_file)?;
        let bf = io::BufReader::new(f);
        let rdr = GzDecoder::new(bf)?;
        let bytes = rdr.bytes();
        Ok(Streamer { buffer: Vec::new(),
                      bytes: bytes })
    }

    fn advance_to_eol(&mut self) {
        let itr = (&mut self.bytes).take_while(|b| match b {
            &Ok(bb) => { bb != 0xA },
            _ => { false },
        });
        for b in itr {
            if let Ok(bb) = b {
                self.buffer.push(bb);
            }
        }
    }
}

impl Iterator for Streamer {
    type Item = String;
    fn next(&mut self) -> Option<String> {
        let t0 = precise_time_ns();
        self.buffer.clear();
        self.advance_to_eol();
        let ret = if self.buffer.len() > 0 {
            if let Ok(s) = String::from_utf8(self.buffer.clone()) {
                Some(s)
            } else {
                None
            }
        } else {
            None
        };
        let t1 = precise_time_ns();
        println!("Streamer::next: {} us", (t1 - t0) / 1000 );
        ret
    }
}
<|endoftext|>


<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

/*!

Bindings and wrappers for __GTK+__, __GLib__ and __Cairo__.

The various parts of __rgtk__ can be found in the submodules __gtk__, __gdk__, __glib__ and __cairo__.

Trait reexports
===============

For you're conveniance the various traits of `rgtk` are reexported in the `rgtk::*`
namespace as `{Gtk/Gdk/Glib/Cairo}{trait_name}Trait` so you can just use...

```Rust
extern mod rgtk;
use rgtk::*;
```

...to easily access all the traits methods:

```Rust
let button = gtk::Button:new(); // trait gtk::traits::Button reexported as GtkButtonTrait,
                                // it's trait methods can be accessed here.
```
*/

#![crate_name = "rgtk"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![feature(macro_rules)]
#![allow(dead_code)] // TODO: drop this
#![feature(unsafe_destructor)]

extern crate libc;

pub use GtkWidgetTrait          = gtk::traits::Widget;
pub use GtkContainerTrait       = gtk::traits::Container;
pub use GtkWindowTrait          = gtk::traits::Window;
pub use GtkMiscTrait            = gtk::traits::Misc;
pub use GtkButtonTrait          = gtk::traits::Button;
pub use GtkLabelTrait           = gtk::traits::Label;
pub use GtkBoxTrait             = gtk::traits::Box;
pub use GtkOrientableTrait      = gtk::traits::Orientable;
pub use GtkFrameTrait           = gtk::traits::Frame;
pub use GtkToggleButtonTrait    = gtk::traits::ToggleButton;
pub use GtkScaleButtonTrait     = gtk::traits::ScaleButton;
pub use GtkEntryTrait           = gtk::traits::Entry;
pub use GtkBinTrait             = gtk::traits::Bin;
pub use GtkToolShellTrait       = gtk::traits::ToolShell;
pub use GtkToolItemTrait        = gtk::traits::ToolItem;
pub use GtkToolButtonTrait      = gtk::traits::ToolButton;
pub use GtkToggleToolButtonTrait= gtk::traits::ToggleToolButton;
pub use GtkDialogTrait          = gtk::traits::Dialog;
pub use GtkColorChooserTrait    = gtk::traits::ColorChooser;
pub use GtkScrollableTrait      = gtk::traits::Scrollable;
pub use GtkFileChooser          = gtk::traits::FileChooser;
pub use GtkAppChooser           = gtk::traits::AppChooser;

#[doc(hidden)]
#[cfg(target_os="macos")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3.0")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="linux")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

pub mod gtk;
pub mod cairo;
pub mod gdk;
pub mod glib;
<commit_msg>Rename some trait reexports<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

/*!

Bindings and wrappers for __GTK+__, __GLib__ and __Cairo__.

The various parts of __rgtk__ can be found in the submodules __gtk__, __gdk__, __glib__ and __cairo__.

Trait reexports
===============

For you're conveniance the various traits of `rgtk` are reexported in the `rgtk::*`
namespace as `{Gtk/Gdk/Glib/Cairo}{trait_name}Trait` so you can just use...

```Rust
extern mod rgtk;
use rgtk::*;
```

...to easily access all the traits methods:

```Rust
let button = gtk::Button:new(); // trait gtk::traits::Button reexported as GtkButtonTrait,
                                // it's trait methods can be accessed here.
```
*/

#![crate_name = "rgtk"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![feature(macro_rules)]
#![allow(dead_code)] // TODO: drop this
#![feature(unsafe_destructor)]

extern crate libc;

pub use GtkWidgetTrait          = gtk::traits::Widget;
pub use GtkContainerTrait       = gtk::traits::Container;
pub use GtkWindowTrait          = gtk::traits::Window;
pub use GtkMiscTrait            = gtk::traits::Misc;
pub use GtkButtonTrait          = gtk::traits::Button;
pub use GtkLabelTrait           = gtk::traits::Label;
pub use GtkBoxTrait             = gtk::traits::Box;
pub use GtkOrientableTrait      = gtk::traits::Orientable;
pub use GtkFrameTrait           = gtk::traits::Frame;
pub use GtkToggleButtonTrait    = gtk::traits::ToggleButton;
pub use GtkScaleButtonTrait     = gtk::traits::ScaleButton;
pub use GtkEntryTrait           = gtk::traits::Entry;
pub use GtkBinTrait             = gtk::traits::Bin;
pub use GtkToolShellTrait       = gtk::traits::ToolShell;
pub use GtkToolItemTrait        = gtk::traits::ToolItem;
pub use GtkToolButtonTrait      = gtk::traits::ToolButton;
pub use GtkToggleToolButtonTrait= gtk::traits::ToggleToolButton;
pub use GtkDialogTrait          = gtk::traits::Dialog;
pub use GtkColorChooserTrait    = gtk::traits::ColorChooser;
pub use GtkScrollableTrait      = gtk::traits::Scrollable;
pub use GtkFileChooserTrait     = gtk::traits::FileChooser;
pub use GtkAppChooserTrait      = gtk::traits::AppChooser;

#[doc(hidden)]
#[cfg(target_os="macos")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3.0")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="linux")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

pub mod gtk;
pub mod cairo;
pub mod gdk;
pub mod glib;
<|endoftext|>


<commit_before>use std::io;

#[cfg(not(target_os = "redox"))]
use libc::c_ushort;

#[cfg(not(target_os = "redox"))]
#[repr(C)]
struct TermSize {
    row: c_ushort,
    col: c_ushort,
    _x: c_ushort,
    _y: c_ushort,
}

// Since attributes on non-item statements is not stable yet, we use a function.
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "redox"))]
#[cfg(target_pointer_width = "64")]
#[cfg(not(target_env = "musl"))]
fn tiocgwinsz() -> u64 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as u64
}
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "redox"))]
#[cfg(target_pointer_width = "32")]
#[cfg(not(target_env = "musl"))]
fn tiocgwinsz() -> u32 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as u32
}

#[cfg(any(target_env = "musl", target_os = "android"))]
#[cfg(target_pointer_width = "32")]
fn tiocgwinsz() -> i32 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as i32
}

#[cfg(target_os = "android")]
#[cfg(target_pointer_width = "64")]
fn tiocgwinsz() -> i64 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as i64
}

/// Get the size of the terminal.
#[cfg(not(target_os = "redox"))]
pub fn terminal_size() -> io::Result<(u16, u16)> {
    use libc::ioctl;
    use libc::STDOUT_FILENO;

    use std::mem;
    unsafe {
        let mut size: TermSize = mem::zeroed();

        if ioctl(STDOUT_FILENO, tiocgwinsz(), &mut size as *mut _) == 0 {
            Ok((size.col as u16, size.row as u16))
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "Unable to get the terminal size."))
        }
    }
}

/// Get the size of the terminal.
#[cfg(target_os = "redox")]
pub fn terminal_size() -> io::Result<(u16, u16)> {
    use std::env;

    let width = try!(env::var("COLUMNS").map_err(|x| io::Error::new(io::ErrorKind::NotFound, x)))
        .parse()
        .unwrap_or(0);
    let height = try!(env::var("LINES").map_err(|x| io::Error::new(io::ErrorKind::NotFound, x)))
        .parse()
        .unwrap_or(0);

    Ok((width, height))
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_size() {
        assert!(terminal_size().is_ok());
    }
}
<commit_msg>Fix 64 bit build for musl and android (#90)<commit_after>use std::io;

#[cfg(not(target_os = "redox"))]
use libc::c_ushort;

#[cfg(not(target_os = "redox"))]
#[repr(C)]
struct TermSize {
    row: c_ushort,
    col: c_ushort,
    _x: c_ushort,
    _y: c_ushort,
}

// Since attributes on non-item statements is not stable yet, we use a function.
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "redox"))]
#[cfg(target_pointer_width = "64")]
#[cfg(not(target_env = "musl"))]
fn tiocgwinsz() -> u64 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as u64
}
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "redox"))]
#[cfg(target_pointer_width = "32")]
#[cfg(not(target_env = "musl"))]
fn tiocgwinsz() -> u32 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as u32
}

#[cfg(any(target_env = "musl", target_os = "android"))]
fn tiocgwinsz() -> i32 {
    use termios::TIOCGWINSZ;
    TIOCGWINSZ as i32
}

/// Get the size of the terminal.
#[cfg(not(target_os = "redox"))]
pub fn terminal_size() -> io::Result<(u16, u16)> {
    use libc::ioctl;
    use libc::STDOUT_FILENO;

    use std::mem;
    unsafe {
        let mut size: TermSize = mem::zeroed();

        if ioctl(STDOUT_FILENO, tiocgwinsz(), &mut size as *mut _) == 0 {
            Ok((size.col as u16, size.row as u16))
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "Unable to get the terminal size."))
        }
    }
}

/// Get the size of the terminal.
#[cfg(target_os = "redox")]
pub fn terminal_size() -> io::Result<(u16, u16)> {
    use std::env;

    let width = try!(env::var("COLUMNS").map_err(|x| io::Error::new(io::ErrorKind::NotFound, x)))
        .parse()
        .unwrap_or(0);
    let height = try!(env::var("LINES").map_err(|x| io::Error::new(io::ErrorKind::NotFound, x)))
        .parse()
        .unwrap_or(0);

    Ok((width, height))
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_size() {
        assert!(terminal_size().is_ok());
    }
}
<|endoftext|>


<commit_before>//! Helpers to program the task state segment.
//! See Intel 3a, Chapter 7, Section 7

use segmentation;

pub type TaskStateDescriptorLow = segmentation::SegmentDescriptor;
pub type TaskStateDescriptorHigh = u64;

/// In 64-bit mode the TSS holds information that is not
/// directly related to the task-switch mechanism,
/// but is used for finding kernel level stack
/// if interrupts arrive while in kernel mode.
#[derive(Debug)]
#[repr(C, packed)]
pub struct TaskStateSegment {
    pub reserved: u32,
    /// The full 64-bit canonical forms of the stack pointers (RSP) for privilege levels 0-2.
    pub rsp: [u64; 3],
    pub reserved2: u64,
    /// The full 64-bit canonical forms of the interrupt stack table (IST) pointers.
    pub ist: [u64; 7],
    pub reserved3: u64,
    pub reserved4: u16,
    /// The 16-bit offset to the I/O permission bit map from the 64-bit TSS base.
    pub iomap_base: u16,
}

impl TaskStateSegment {
    pub const fn new() -> TaskStateSegment {
        TaskStateSegment {
            reserved: 0,
            rsp: [0; 3],
            reserved2: 0,
            ist: [0; 7],
            reserved3: 0,
            reserved4: 0,
            iomap_base: 0,
        }
    }
}

/// Load the task state register.
pub unsafe fn load_tr(sel: segmentation::SegmentSelector) {
    asm!("ltr $0" :: "r" (sel));
}
<commit_msg>The `SegmentDescriptor` type no longer exists<commit_after>//! Helpers to program the task state segment.
//! See Intel 3a, Chapter 7, Section 7

use segmentation;

/// In 64-bit mode the TSS holds information that is not
/// directly related to the task-switch mechanism,
/// but is used for finding kernel level stack
/// if interrupts arrive while in kernel mode.
#[derive(Debug)]
#[repr(C, packed)]
pub struct TaskStateSegment {
    pub reserved: u32,
    /// The full 64-bit canonical forms of the stack pointers (RSP) for privilege levels 0-2.
    pub rsp: [u64; 3],
    pub reserved2: u64,
    /// The full 64-bit canonical forms of the interrupt stack table (IST) pointers.
    pub ist: [u64; 7],
    pub reserved3: u64,
    pub reserved4: u16,
    /// The 16-bit offset to the I/O permission bit map from the 64-bit TSS base.
    pub iomap_base: u16,
}

impl TaskStateSegment {
    pub const fn new() -> TaskStateSegment {
        TaskStateSegment {
            reserved: 0,
            rsp: [0; 3],
            reserved2: 0,
            ist: [0; 7],
            reserved3: 0,
            reserved4: 0,
            iomap_base: 0,
        }
    }
}

/// Load the task state register.
pub unsafe fn load_tr(sel: segmentation::SegmentSelector) {
    asm!("ltr $0" :: "r" (sel));
}
<|endoftext|>


<commit_before>// run-pass
// aux-build:span-api-tests.rs
// aux-build:span-test-macros.rs

// ignore-pretty

#![feature(proc_macro_hygiene)]

#[macro_use]
extern crate span_test_macros;

extern crate span_api_tests;

use span_api_tests::{reemit, assert_fake_source_file, assert_source_file, macro_stringify};

macro_rules! say_hello {
    ($macname:ident) => ( $macname! { "Hello, world!" })
}

assert_source_file! { "Hello, world!" }

say_hello! { assert_source_file }

reemit_legacy! {
    assert_source_file! { "Hello, world!" }
}

say_hello_extern! { assert_fake_source_file }

reemit! {
    assert_source_file! { "Hello, world!" }
}

fn main() {
    let s = macro_stringify!(Hello, world!);
    assert_eq!(s, "Hello, world!");
    assert_eq!(macro_stringify!(Hello, world!), "Hello, world!");
    assert_eq!(reemit_legacy!(macro_stringify!(Hello, world!)), "Hello, world!");
    reemit_legacy!(assert_eq!(macro_stringify!(Hello, world!), "Hello, world!"));
    // reemit change the span to be that of the call site
    assert_eq!(
        reemit!(macro_stringify!(Hello, world!)),
        "reemit!(macro_stringify!(Hello, world!))"
    );
    let r = "reemit!(assert_eq!(macro_stringify!(Hello, world!), r));";
    reemit!(assert_eq!(macro_stringify!(Hello, world!), r));

    assert_eq!(macro_stringify!(
        Hello,
        world!
    ), "Hello,\n        world!");

    assert_eq!(macro_stringify!(Hello, /*world */ !), "Hello, /*world */ !");
        assert_eq!(macro_stringify!(
        Hello,
        // comment
        world!
    ), "Hello,\n        // comment\n        world!");

    assert_eq!(say_hello! { macro_stringify }, "\"Hello, world!\"");
    assert_eq!(say_hello_extern! { macro_stringify }, "\"Hello, world!\"");
}
<commit_msg>adjust span-api-tests.rs<commit_after>// run-pass
// aux-build:span-api-tests.rs
// aux-build:span-test-macros.rs

// ignore-pretty

#![feature(proc_macro_hygiene)]

#[macro_use]
extern crate span_test_macros;

extern crate span_api_tests;

use span_api_tests::{reemit, assert_source_file, macro_stringify};

macro_rules! say_hello {
    ($macname:ident) => ( $macname! { "Hello, world!" })
}

assert_source_file! { "Hello, world!" }

say_hello! { assert_source_file }

reemit_legacy! {
    assert_source_file! { "Hello, world!" }
}

say_hello_extern! { assert_source_file }

reemit! {
    assert_source_file! { "Hello, world!" }
}

fn main() {
    let s = macro_stringify!(Hello, world!);
    assert_eq!(s, "Hello, world!");
    assert_eq!(macro_stringify!(Hello, world!), "Hello, world!");
    assert_eq!(reemit_legacy!(macro_stringify!(Hello, world!)), "Hello, world!");
    reemit_legacy!(assert_eq!(macro_stringify!(Hello, world!), "Hello, world!"));
    // reemit change the span to be that of the call site
    assert_eq!(
        reemit!(macro_stringify!(Hello, world!)),
        "reemit!(macro_stringify!(Hello, world!))"
    );
    let r = "reemit!(assert_eq!(macro_stringify!(Hello, world!), r));";
    reemit!(assert_eq!(macro_stringify!(Hello, world!), r));

    assert_eq!(macro_stringify!(
        Hello,
        world!
    ), "Hello,\n        world!");

    assert_eq!(macro_stringify!(Hello, /*world */ !), "Hello, /*world */ !");
        assert_eq!(macro_stringify!(
        Hello,
        // comment
        world!
    ), "Hello,\n        // comment\n        world!");

    assert_eq!(say_hello! { macro_stringify }, "\"Hello, world!\"");
    assert_eq!(say_hello_extern! { macro_stringify }, "\"Hello, world!\"");
}
<|endoftext|>


<commit_before>//! [Lambda terms](https://en.wikipedia.org/wiki/Lambda_calculus#Lambda_terms)

use self::Term::*;
use self::Error::*;
use std::fmt;
use std::borrow::Cow;
use std::char::from_u32;

/// Set to `true` for λ or `false` for \ when displaying lambda terms. The default is `true`.
pub const DISPLAY_PRETTY: bool = true;

/// Set to `true` for classic lambda mode or `false` for the De Bruijn index display mode when
/// displaying lambda terms. The default is `false`.
pub const DISPLAY_CLASSIC: bool = false;

/// A lambda term that is either a variable with a De Bruijn index, an abstraction over a term or
/// an applicaction of one term to another.
#[derive(Debug, PartialEq, Clone)]
pub enum Term {
    /// a variable
    Var(usize),
    /// an abstraction
    Abs(Box<Term>),
    /// an application
    App(Box<Term>, Box<Term>)
}

/// An error that can be returned when an inapplicable function is applied to a term.
#[derive(Debug, PartialEq)]
pub enum Error {
    NotAVar,
    NotAnAbs,
    NotAnApp,
    NotANum,
    NotAPair,
    NotAList
}

impl Term {
    /// Applies `self` to another term without substitution or reduction.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::arithmetic::{zero, succ};
    ///
    /// assert_eq!(succ().app(zero()), App(Box::new(succ()), Box::new(zero())));
    /// ```
    pub fn app(self, argument: Term) -> Term { App(Box::new(self), Box::new(argument)) }

    /// Consumes a lambda variable and returns its De Bruijn index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar(), Ok(1));
    /// ```
    pub fn unvar(self) -> Result<usize, Error> {
        match self {
            Var(n) => Ok(n),
            _ => Err(NotAVar)
        }
    }

    /// Returns a reference to a variable's index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar_ref(), Ok(&1));
    /// ```
    pub fn unvar_ref(&self) -> Result<&usize, Error> {
        match *self {
            Var(ref n) => Ok(&n),
            _ => Err(NotAVar)
        }
    }

    /// Consumes an abstraction and returns its underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs(), Ok(Var(1)));
    /// ```
    pub fn unabs(self) -> Result<Term, Error> {
        match self {
            Abs(x) => Ok(*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref(), Ok(&Var(1)));
    /// ```
    pub fn unabs_ref(&self) -> Result<&Term, Error> {
        match *self {
            Abs(ref x) => Ok(&*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a mutable reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn unabs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        match *self {
            Abs(ref mut x) => Ok(&mut *x),
            _ => Err(NotAnAbs)
        }
    }

    /// Consumes an application and returns a pair containing its underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp(), Ok((Var(0), Var(1))));
    /// ```
    pub fn unapp(self) -> Result<(Term, Term), Error> {
        match self {
            App(lhs, rhs) => Ok((*lhs, *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp_ref(), Ok((&Var(0), &Var(1))));
    /// ```
    pub fn unapp_ref(&self) -> Result<(&Term, &Term), Error> {
        match *self {
            App(ref lhs, ref rhs) => Ok((&*lhs, &*rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing mutable references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp_ref_mut(), Ok((&mut Var(0), &mut Var(1))));
    /// ```
    pub fn unapp_ref_mut(&mut self) -> Result<(&mut Term, &mut Term), Error> {
        match *self {
            App(ref mut lhs, ref mut rhs) => Ok((&mut *lhs, &mut *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns the left-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs(), Ok(Var(0)));
    /// ```
    pub fn lhs(self) -> Result<Term, Error> {
        if let Ok((lhs, _)) = self.unapp() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs_ref(), Ok(&Var(0)));
    /// ```
    pub fn lhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs_ref_mut(), Ok(&mut Var(0)));
    /// ```
    pub fn lhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref_mut() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns the right-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs(), Ok(Var(1)));
    /// ```
    pub fn rhs(self) -> Result<Term, Error> {
        if let Ok((_, rhs)) = self.unapp() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs_ref(), Ok(&Var(1)));
    /// ```
    pub fn rhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn rhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref_mut() { Ok(rhs) } else { Err(NotAnApp) }
    }
}

/// Wraps a `Term` in an `Abs`traction. Consumes its argument.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::abs;
///
/// assert_eq!(abs(Var(1)), Abs(Box::new(Var(1))));
/// ```
pub fn abs(term: Term) -> Term { Abs(Box::new(term)) }

/// Produces an `App`lication of its `Term` arguments without any reduction, consuming them in the
/// process.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::app;
///
/// assert_eq!(app(Var(0), Var(1)), App(Box::new(Var(0)), Box::new(Var(1))));
/// ```
pub fn app(lhs: Term, rhs: Term) -> Term { App(Box::new(lhs), Box::new(rhs)) }

impl fmt::Display for Term {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", show_precedence(self, 0, 0))
    }
}

// TODO: make it safer (unwraps)
#[doc(hidden)]
pub fn show_precedence(term: &Term, context_precedence: usize, depth: u32) -> String {
    match *term {
        Var(i) => if DISPLAY_CLASSIC {
            if depth >= i as u32 {
                format!("{}", from_u32(depth + 97 - i as u32).unwrap())
            } else {
                format!("{}", from_u32(depth + 96 + i as u32).unwrap())
            }
        } else {
            format!("{:X}", i)
        },
        Abs(ref t) => {
            let ret = if DISPLAY_CLASSIC {
                format!("{}{}. {}", if DISPLAY_PRETTY { 'λ' } else { '\\' }, from_u32(depth + 97).unwrap(), show_precedence(t, 0, depth + 1))
            } else {
                format!("{}{}", if DISPLAY_PRETTY { 'λ' } else { '\\' }, t)
            };
            parenthesize_if(&ret, context_precedence > 1).into()
        },
        App(ref t1, ref t2) => {
            let ret = if DISPLAY_CLASSIC {
                format!("{} {}", show_precedence(t1, 2, depth), show_precedence(t2, 3, depth))
            } else {
                format!("{}{}", show_precedence(t1, 2, depth), show_precedence(t2, 3, depth))
            };
            parenthesize_if(&ret, context_precedence == 3).into()
        }
    }
}

fn parenthesize_if(input: &str, condition: bool) -> Cow<str> {
    if condition {
        format!("({})", input).into()
    } else {
        input.into()
    }
}

macro_rules! app {
    ($x:expr, $($y:expr),+) => {
        {
            let mut term = $x;
            $(term = term.app($y);)*
            term
        }
    };
}

#[cfg(test)]
mod test {
    use super::{Var, DISPLAY_CLASSIC};
    use arithmetic::{zero, succ, pred};

    #[test]
    fn app_macro() {
        assert_eq!(&format!("{}", app!(succ(), app!(Var(1), Var(2), Var(3)))), "(λλλ2(321))(123)");
    }

    #[test]
    fn display_modes() {
        if DISPLAY_CLASSIC {
            assert_eq!(&format!("{}", zero()), "λa. λb. b");
            assert_eq!(&format!("{}", succ()), "λa. λb. λc. b (a b c)");
            assert_eq!(&format!("{}", pred()), "λa. λb. λc. a (λd. λe. e (d b)) (λd. c) (λd. d)");
        } else {
            assert_eq!(&format!("{}", zero()), "λλ1");
            assert_eq!(&format!("{}", succ()), "λλλ2(321)");
            assert_eq!(&format!("{}", pred()), "λλλ3(λλ1(24))(λ2)(λ1)");
        }
    }
}
<commit_msg>change Var(0) to Var(1) in doc examples<commit_after>//! [Lambda terms](https://en.wikipedia.org/wiki/Lambda_calculus#Lambda_terms)

use self::Term::*;
use self::Error::*;
use std::fmt;
use std::borrow::Cow;
use std::char::from_u32;

/// Set to `true` for λ or `false` for \ when displaying lambda terms. The default is `true`.
pub const DISPLAY_PRETTY: bool = true;

/// Set to `true` for classic lambda mode or `false` for the De Bruijn index display mode when
/// displaying lambda terms. The default is `false`.
pub const DISPLAY_CLASSIC: bool = false;

/// A lambda term that is either a variable with a De Bruijn index, an abstraction over a term or
/// an applicaction of one term to another.
#[derive(Debug, PartialEq, Clone)]
pub enum Term {
    /// a variable
    Var(usize),
    /// an abstraction
    Abs(Box<Term>),
    /// an application
    App(Box<Term>, Box<Term>)
}

/// An error that can be returned when an inapplicable function is applied to a term.
#[derive(Debug, PartialEq)]
pub enum Error {
    NotAVar,
    NotAnAbs,
    NotAnApp,
    NotANum,
    NotAPair,
    NotAList
}

impl Term {
    /// Applies `self` to another term without substitution or reduction.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::arithmetic::{zero, succ};
    ///
    /// assert_eq!(succ().app(zero()), App(Box::new(succ()), Box::new(zero())));
    /// ```
    pub fn app(self, argument: Term) -> Term { App(Box::new(self), Box::new(argument)) }

    /// Consumes a lambda variable and returns its De Bruijn index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar(), Ok(1));
    /// ```
    pub fn unvar(self) -> Result<usize, Error> {
        match self {
            Var(n) => Ok(n),
            _ => Err(NotAVar)
        }
    }

    /// Returns a reference to a variable's index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar_ref(), Ok(&1));
    /// ```
    pub fn unvar_ref(&self) -> Result<&usize, Error> {
        match *self {
            Var(ref n) => Ok(&n),
            _ => Err(NotAVar)
        }
    }

    /// Consumes an abstraction and returns its underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs(), Ok(Var(1)));
    /// ```
    pub fn unabs(self) -> Result<Term, Error> {
        match self {
            Abs(x) => Ok(*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref(), Ok(&Var(1)));
    /// ```
    pub fn unabs_ref(&self) -> Result<&Term, Error> {
        match *self {
            Abs(ref x) => Ok(&*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a mutable reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn unabs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        match *self {
            Abs(ref mut x) => Ok(&mut *x),
            _ => Err(NotAnAbs)
        }
    }

    /// Consumes an application and returns a pair containing its underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).unapp(), Ok((Var(1), Var(2))));
    /// ```
    pub fn unapp(self) -> Result<(Term, Term), Error> {
        match self {
            App(lhs, rhs) => Ok((*lhs, *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).unapp_ref(), Ok((&Var(1), &Var(2))));
    /// ```
    pub fn unapp_ref(&self) -> Result<(&Term, &Term), Error> {
        match *self {
            App(ref lhs, ref rhs) => Ok((&*lhs, &*rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing mutable references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).unapp_ref_mut(), Ok((&mut Var(1), &mut Var(2))));
    /// ```
    pub fn unapp_ref_mut(&mut self) -> Result<(&mut Term, &mut Term), Error> {
        match *self {
            App(ref mut lhs, ref mut rhs) => Ok((&mut *lhs, &mut *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns the left-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).lhs(), Ok(Var(1)));
    /// ```
    pub fn lhs(self) -> Result<Term, Error> {
        if let Ok((lhs, _)) = self.unapp() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).lhs_ref(), Ok(&Var(1)));
    /// ```
    pub fn lhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).lhs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn lhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref_mut() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns the right-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).rhs(), Ok(Var(2)));
    /// ```
    pub fn rhs(self) -> Result<Term, Error> {
        if let Ok((_, rhs)) = self.unapp() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).rhs_ref(), Ok(&Var(2)));
    /// ```
    pub fn rhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).app(Var(2)).rhs_ref_mut(), Ok(&mut Var(2)));
    /// ```
    pub fn rhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref_mut() { Ok(rhs) } else { Err(NotAnApp) }
    }
}

/// Wraps a `Term` in an `Abs`traction. Consumes its argument.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::abs;
///
/// assert_eq!(abs(Var(1)), Abs(Box::new(Var(1))));
/// ```
pub fn abs(term: Term) -> Term { Abs(Box::new(term)) }

/// Produces an `App`lication of its `Term` arguments without any reduction, consuming them in the
/// process.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::app;
///
/// assert_eq!(app(Var(1), Var(2)), App(Box::new(Var(1)), Box::new(Var(2))));
/// ```
pub fn app(lhs: Term, rhs: Term) -> Term { App(Box::new(lhs), Box::new(rhs)) }

impl fmt::Display for Term {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", show_precedence(self, 0, 0))
    }
}

// TODO: make it safer (unwraps)
#[doc(hidden)]
pub fn show_precedence(term: &Term, context_precedence: usize, depth: u32) -> String {
    match *term {
        Var(i) => if DISPLAY_CLASSIC {
            if depth >= i as u32 {
                format!("{}", from_u32(depth + 97 - i as u32).unwrap())
            } else {
                format!("{}", from_u32(depth + 96 + i as u32).unwrap())
            }
        } else {
            format!("{:X}", i)
        },
        Abs(ref t) => {
            let ret = if DISPLAY_CLASSIC {
                format!("{}{}. {}", if DISPLAY_PRETTY { 'λ' } else { '\\' }, from_u32(depth + 97).unwrap(), show_precedence(t, 0, depth + 1))
            } else {
                format!("{}{}", if DISPLAY_PRETTY { 'λ' } else { '\\' }, t)
            };
            parenthesize_if(&ret, context_precedence > 1).into()
        },
        App(ref t1, ref t2) => {
            let ret = if DISPLAY_CLASSIC {
                format!("{} {}", show_precedence(t1, 2, depth), show_precedence(t2, 3, depth))
            } else {
                format!("{}{}", show_precedence(t1, 2, depth), show_precedence(t2, 3, depth))
            };
            parenthesize_if(&ret, context_precedence == 3).into()
        }
    }
}

fn parenthesize_if(input: &str, condition: bool) -> Cow<str> {
    if condition {
        format!("({})", input).into()
    } else {
        input.into()
    }
}

macro_rules! app {
    ($x:expr, $($y:expr),+) => {
        {
            let mut term = $x;
            $(term = term.app($y);)*
            term
        }
    };
}

#[cfg(test)]
mod test {
    use super::{Var, DISPLAY_CLASSIC};
    use arithmetic::{zero, succ, pred};

    #[test]
    fn app_macro() {
        assert_eq!(&format!("{}", app!(succ(), app!(Var(1), Var(2), Var(3)))), "(λλλ2(321))(123)");
    }

    #[test]
    fn display_modes() {
        if DISPLAY_CLASSIC {
            assert_eq!(&format!("{}", zero()), "λa. λb. b");
            assert_eq!(&format!("{}", succ()), "λa. λb. λc. b (a b c)");
            assert_eq!(&format!("{}", pred()), "λa. λb. λc. a (λd. λe. e (d b)) (λd. c) (λd. d)");
        } else {
            assert_eq!(&format!("{}", zero()), "λλ1");
            assert_eq!(&format!("{}", succ()), "λλλ2(321)");
            assert_eq!(&format!("{}", pred()), "λλλ3(λλ1(24))(λ2)(λ1)");
        }
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="sleep", vers="1.0.0", author="Arcterus")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::num;
use std::os;
use std::io::{print, timer};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "sleep";

#[allow(dead_code)]
fn main() { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).clone();

    let opts = [
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => {
            show_error!("{}", f.to_err_msg());
            return 1;
        }
    };

    if matches.opt_present("help") {
        println!("sleep 1.0.0");
        println!("");
        println!("Usage:");
        println!("  {0:s} NUMBER[SUFFIX]", program);
        println!("or");
        println!("  {0:s} OPTION", program);
        println!("");
        print(getopts::usage("Pause for NUMBER seconds.  SUFFIX may be 's' for seconds (the default),
'm' for minutes, 'h' for hours or 'd' for days.  Unlike most implementations
that require NUMBER be an integer, here NUMBER may be an arbitrary floating
point number.  Given two or more arguments, pause for the amount of time
specified by the sum of their values.", opts).as_slice());
    } else if matches.opt_present("version") {
        println!("sleep 1.0.0");
    } else if matches.free.is_empty() {
        show_error!("missing an argument");
        show_error!("for help, try '{0:s} --help'", program);
        return 1;
    } else {
        sleep(matches.free);
    }

    0
}

fn sleep(args: Vec<String>) {
    let sleep_time = args.iter().fold(0.0, |result, arg| {
        let (arg, suffix_time) = match match_suffix(arg.as_slice()) {
            Ok(m) => m,
            Err(f) => {
                crash!(1, "{}", f.to_string())
            }
        };
        let num =
            if suffix_time == 0 {
                0.0
            } else {
                match num::from_str_radix::<f64>((arg.as_slice()), 10) {
                    Some(m) => m,
                    None => {
                        crash!(1, "Invalid time interval '{}'", arg.to_string())
                    }
                }
            };
        result + num * suffix_time as f64
    });
    timer::sleep((sleep_time * 1000.0) as u64);
}

fn match_suffix(arg: &str) -> Result<(String, int), String> {
    let result = match (arg).char_at_reverse(0) {
        's' | 'S' => 1,
        'm' | 'M' => 60,
        'h' | 'H' => 60 * 60,
        'd' | 'D' => 60 * 60 * 24,
        val => {
            if !val.is_alphabetic() {
                return Ok((arg.to_string(), 1))
            } else {
                return Err(format!("Invalid time interval '{}'", arg))
            }
        }
    };
    Ok(((arg).slice_to((arg).len() - 1).to_string(), result))
}
<commit_msg>sleep: handle infinity<commit_after>#![crate_id(name="sleep", vers="1.0.0", author="Arcterus")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::f64;
use std::os;
use std::io::{print, timer};
use std::u64;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "sleep";

#[allow(dead_code)]
fn main() { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).clone();

    let opts = [
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => {
            show_error!("{}", f.to_err_msg());
            return 1;
        }
    };

    if matches.opt_present("help") {
        println!("sleep 1.0.0");
        println!("");
        println!("Usage:");
        println!("  {0:s} NUMBER[SUFFIX]", program);
        println!("or");
        println!("  {0:s} OPTION", program);
        println!("");
        print(getopts::usage("Pause for NUMBER seconds.  SUFFIX may be 's' for seconds (the default),
'm' for minutes, 'h' for hours or 'd' for days.  Unlike most implementations
that require NUMBER be an integer, here NUMBER may be an arbitrary floating
point number.  Given two or more arguments, pause for the amount of time
specified by the sum of their values.", opts).as_slice());
    } else if matches.opt_present("version") {
        println!("sleep 1.0.0");
    } else if matches.free.is_empty() {
        show_error!("missing an argument");
        show_error!("for help, try '{0:s} --help'", program);
        return 1;
    } else {
        sleep(matches.free);
    }

    0
}

fn sleep(args: Vec<String>) {
    let sleep_time = args.iter().fold(0.0, |result, arg| {
        let (arg, suffix_time) = match match_suffix(arg.as_slice()) {
            Ok(m) => m,
            Err(f) => {
                crash!(1, "{}", f.to_string())
            }
        };
        let num =
            if suffix_time == 0 {
                0.0
            } else {
                match from_str::<f64>(arg.as_slice()) {
                    Some(m) => m,
                    None => {
                        crash!(1, "Invalid time interval '{}'", arg.to_string())
                    }
                }
            };
        result + num * suffix_time as f64
    });
    timer::sleep(if sleep_time == f64::INFINITY { u64::MAX } else { (sleep_time * 1000.0) as u64 });
}

fn match_suffix(arg: &str) -> Result<(String, int), String> {
    let result = match (arg).char_at_reverse(0) {
        's' | 'S' => 1,
        'm' | 'M' => 60,
        'h' | 'H' => 60 * 60,
        'd' | 'D' => 60 * 60 * 24,
        val => {
            if !val.is_alphabetic() {
                return Ok((arg.to_string(), 1))
            } else if arg == "inf" || arg == "infinity" {
                return Ok(("inf".to_string(), 1))
            } else {
                return Err(format!("Invalid time interval '{}'", arg))
            }
        }
    };
    Ok(((arg).slice_to((arg).len() - 1).to_string(), result))
}
<|endoftext|>


<commit_before>#![cfg(test)]
use std::ops::Add;
use std::collections::HashMap;

use traits::Cell;
use traits::Coord;
use traits::Engine;
use traits::ReprConsumer;
use traits::Grid;
use engine::sequential::Sequential;
use grid::square::SquareGrid;
use grid::nhood::MooreNhood;
use grid::square::GridCoord;
use repr::CellRepr;
use repr::GridRepr;

/// Implementation of Conway's Game of Life.

#[derive(Clone, Debug)]
enum LifeState {
    Dead,
    Alive
}

#[derive(Clone, Debug)]
struct Life {
    state: LifeState
}

impl Life {

    fn alive_count<'a, I>(&self, neighbors: I) -> i32
        where I: Iterator<Item=Option<&'a Self>> {
        neighbors.map(
            |n| {
                match n {
                    Some(ref cell) => match cell.state {
                        LifeState::Alive => 1,
                        LifeState::Dead => 0
                    },
                    None => 0,
                }
            }
        ).fold(0, Add::add)
    }

    #[inline]
    fn dead_state(&self, alive: i32) -> LifeState {
        match alive {
            3 => LifeState::Alive,
            _ => LifeState::Dead
        }
    }

    #[inline]
    fn alive_state(&self, alive: i32) -> LifeState {
        match alive {
            2 | 3 => LifeState::Alive,
            _ => LifeState::Dead
        }
    }
}

impl Default for Life {

    fn default() -> Self {
        Life { state: LifeState::Dead }
    }
}

const ALIVE: &'static str = "a";
const DEAD: &'static str = "d";
const STATE: &'static str = "s";

impl Cell for Life {

    fn step<'a, I>(&self, neighbors: I) -> Self
        where I: Iterator<Item=Option<&'a Self>> {

        let alive_count = self.alive_count(neighbors);

        let new_state = match self.state {
            LifeState::Alive => self.alive_state(alive_count),
            LifeState::Dead => self.dead_state(alive_count)
        };

        println!("{:?} ====> {:?}", self.state, new_state);

        let mut new_cell = self.clone();
        new_cell.state = new_state;

        new_cell
    }

    fn repr(&self, meta: &mut HashMap<&str, &str>) {

        let state_str = match self.state {
            LifeState::Alive => ALIVE,
            LifeState::Dead  => DEAD
        };

        meta.insert(STATE, state_str);
    }

    fn from_repr(&mut self, meta: &HashMap<&str, &str>) {

        let new_state = match meta[STATE] {
            ALIVE => LifeState::Alive,
            DEAD => LifeState::Dead,
            _ => panic!("Unknown state: {}.", meta[STATE])
        };

        self.state = new_state;
    }
}

struct SpinnerTestConsumer {
    vertical: bool
}

impl ReprConsumer for SpinnerTestConsumer {

    fn consume<C: Coord>(&mut self, repr: &GridRepr<C>) {
        assert_eq!(repr.cells.len(), 9);

        println!("{:?}", repr);

        let alive_cells: Vec<&CellRepr<C>> =
            repr.cells.iter().filter(|c| c.state[STATE] == ALIVE).collect();
        assert_eq!(alive_cells.len(), 3);

        self.vertical = !self.vertical;

        println!("{:?}", alive_cells);

        // if spinner is in vertical state
        if alive_cells.iter().all(|c| c.coord.x() == 1) {
            assert!(self.vertical);
        }
        // if spinner is in horizontal state
        if alive_cells.iter().all(|c| c.coord.y() == 1) {
            assert!(!self.vertical);
        }
    }
}

#[test]
fn test_game_of_life() {

    let mut alive_cell = HashMap::new();
    alive_cell.insert(STATE, ALIVE);

    // Vertical spinner
    // D | A | D
    // D | A | D
    // D | A | D
    // Cells not specified below should be equal to default cell value
    let cells = vec![
        CellRepr::new(GridCoord::from_2d(1, 0), Some(&alive_cell)),
        CellRepr::new(GridCoord::from_2d(1, 1), Some(&alive_cell)),
        CellRepr::new(GridCoord::from_2d(1, 2), Some(&alive_cell)),
    ];

    {
        let alive_cells: Vec<&CellRepr<GridCoord>> =
            cells.iter().filter(|c| c.state[STATE] == ALIVE).collect();
        assert_eq!(alive_cells.len(), 3);
    }

    let grid_repr = GridRepr::new(3, 3, Some(cells));

    let nhood = MooreNhood::new();
    let mut grid: SquareGrid<Life, _> = SquareGrid::new(3, 3, nhood);
    grid.from_repr(&grid_repr);

    let consumer = SpinnerTestConsumer { vertical: true };
    let mut engine = Sequential::new(grid, consumer);
    engine.run_times(2);
}<commit_msg>Check for dead cells and removed prints.<commit_after>#![cfg(test)]
use std::ops::Add;
use std::collections::HashMap;

use traits::Cell;
use traits::Coord;
use traits::Engine;
use traits::ReprConsumer;
use traits::Grid;
use engine::sequential::Sequential;
use grid::square::SquareGrid;
use grid::nhood::MooreNhood;
use grid::square::GridCoord;
use repr::CellRepr;
use repr::GridRepr;

/// Implementation of Conway's Game of Life.

#[derive(Clone, Debug)]
enum LifeState {
    Dead,
    Alive
}

#[derive(Clone, Debug)]
struct Life {
    state: LifeState
}

impl Life {

    fn alive_count<'a, I>(&self, neighbors: I) -> i32
        where I: Iterator<Item=Option<&'a Self>> {
        neighbors.map(
            |n| {
                match n {
                    Some(ref cell) => match cell.state {
                        LifeState::Alive => 1,
                        LifeState::Dead => 0
                    },
                    None => 0,
                }
            }
        ).fold(0, Add::add)
    }

    #[inline]
    fn dead_state(&self, alive: i32) -> LifeState {
        match alive {
            3 => LifeState::Alive,
            _ => LifeState::Dead
        }
    }

    #[inline]
    fn alive_state(&self, alive: i32) -> LifeState {
        match alive {
            2 | 3 => LifeState::Alive,
            _ => LifeState::Dead
        }
    }
}

impl Default for Life {

    fn default() -> Self {
        Life { state: LifeState::Dead }
    }
}

const ALIVE: &'static str = "a";
const DEAD: &'static str = "d";
const STATE: &'static str = "s";

impl Cell for Life {

    fn step<'a, I>(&self, neighbors: I) -> Self
        where I: Iterator<Item=Option<&'a Self>> {

        let alive_count = self.alive_count(neighbors);

        let new_state = match self.state {
            LifeState::Alive => self.alive_state(alive_count),
            LifeState::Dead => self.dead_state(alive_count)
        };

        let mut new_cell = self.clone();
        new_cell.state = new_state;

        new_cell
    }

    fn repr(&self, meta: &mut HashMap<&str, &str>) {

        let state_str = match self.state {
            LifeState::Alive => ALIVE,
            LifeState::Dead  => DEAD
        };

        meta.insert(STATE, state_str);
    }

    fn from_repr(&mut self, meta: &HashMap<&str, &str>) {

        let new_state = match meta[STATE] {
            ALIVE => LifeState::Alive,
            DEAD => LifeState::Dead,
            _ => panic!("Unknown state: {}.", meta[STATE])
        };

        self.state = new_state;
    }
}

struct SpinnerTestConsumer {
    vertical: bool
}

impl ReprConsumer for SpinnerTestConsumer {

    fn consume<C: Coord>(&mut self, repr: &GridRepr<C>) {
        assert_eq!(repr.cells.len(), 9);

        let alive_cells: Vec<&CellRepr<C>> =
            repr.cells.iter().filter(|c| c.state[STATE] == ALIVE).collect();
        assert_eq!(alive_cells.len(), 3);

        let dead_cells: Vec<&CellRepr<C>> =
            repr.cells.iter().filter(|c| c.state[STATE] == DEAD).collect();
        assert_eq!(dead_cells.len(), 6);

        self.vertical = !self.vertical;

        // if spinner is in vertical state
        if alive_cells.iter().all(|c| c.coord.x() == 1) {
            assert!(self.vertical);
        }
        // if spinner is in horizontal state
        if alive_cells.iter().all(|c| c.coord.y() == 1) {
            assert!(!self.vertical);
        }
    }
}

#[test]
fn test_game_of_life() {

    let nhood = MooreNhood::new();
    let mut grid: SquareGrid<Life, _> = SquareGrid::new(3, 3, nhood);

    // Vertical spinner
    // D | A | D
    // D | A | D
    // D | A | D
    // Cells not specified below should be equal to default cell value
    let mut alive_cell = HashMap::new();
    alive_cell.insert(STATE, ALIVE);

    let cells = vec![
        CellRepr::new(GridCoord::from_2d(1, 0), Some(&alive_cell)),
        CellRepr::new(GridCoord::from_2d(1, 1), Some(&alive_cell)),
        CellRepr::new(GridCoord::from_2d(1, 2), Some(&alive_cell)),
    ];

    let grid_repr = GridRepr::new(3, 3, Some(cells));

    let life_default = Life::default();
    let mut default_state = HashMap::new();
    life_default.repr(&mut default_state);

    assert!(grid.repr().cells.iter().all(|c| c.state[STATE] == default_state[STATE]));

    grid.from_repr(&grid_repr);

    let consumer = SpinnerTestConsumer { vertical: true };
    let mut engine = Sequential::new(grid, consumer);
    engine.run_times(2);
}<|endoftext|>


<commit_before>use nalgebra::{Dim, BaseFloat};
use std::num::{Int, cast};
use std::iter::AdditiveIterator;

pub trait Positionable<P> {
    fn position(&self) -> P;
}

pub struct Entry<O, P> {
    pub object: O,
    pub position: P,
}

impl<O, P> Positionable<P> for Entry<O, P>
    where P: Copy
{
    fn position(&self) -> P {
        self.position
    }
}

pub enum NodeState<O, P, N> {
    Empty,
    Leaf(O),
    Branch(Vec<Node<O, P, N>>),
}

pub struct Node<O, P, N> {
    pub state: Option<NodeState<O, P, N>>,
    pub center: P,
    pub extent: N,
}

impl<O, P, N> Node<O, P, N> {
    pub fn new(state: NodeState<O, P, N>, center: P, extent: N) -> Node<O, P, N> {
        Node {
            state: Some(state),
            center: center,
            extent: extent,
        }
    }
}

/// Subdivision helper function
///
/// Given the center of a node and its extent, this function generates a vector
/// of empty nodes equally partitioning the given node geometry. This is generic
/// over the dimension of the point type.
///
/// # Params
/// - The `old_center` is the center point of the (old) node.
/// - The `old_extent` is its extent.
pub fn subdivide<P, N>(old_center: &P, old_extent: &N) -> Vec<(P, N)>
    where P: Dim + Index<uint, N> + IndexMut<uint, N> + Copy,
          N: BaseFloat,
{
    let dim = Dim::dim(None::<P>);
    let new_extent = *old_extent / cast(2.0f64).unwrap();
    range(0u, 2.pow(dim))
        .map(|n| {
            let mut new_center = *old_center;
            for i in range(0, dim) {
                new_center[i] = new_center[i] + match n / 2.pow(i) % 2 {
                    0 => -new_extent,
                    1 => new_extent,
                    _ => unreachable!(),
                };
            }
            (new_center, new_extent)
        })
        .collect()
}

pub fn branch_dispatch<P, N>(center: &P, point: &P) -> uint
    where P: Dim + Index<uint, N> + IndexMut<uint, N>,
          N: BaseFloat,
{
    let dim = Dim::dim(None::<P>);
    range(0, dim)
        .map(|k| if point[k] < center[k] {0} else {1 << k})
        .sum()
}

impl<O, P, N> Node<O, P, N>
    where O: Positionable<P>,
          P: Dim + Index<uint, N> + IndexMut<uint, N> + Copy,
          N: BaseFloat,
{
    pub fn insert(&mut self, entry: O) {
        let tmp = self.state.take().unwrap();
        self.state = Some(match tmp {
            NodeState::Empty => NodeState::Leaf(entry),
            NodeState::Leaf(other) => {
                let mut nodes: Vec<Node<O, P, N>> = subdivide(&self.center, &self.extent)
                    .into_iter()
                    .map(|(p, n)| Node::new(NodeState::Empty, p, n))
                    .collect();
                nodes[branch_dispatch(&self.center, &other.position())].insert(other);
                nodes[branch_dispatch(&self.center, &entry.position())].insert(entry);
                NodeState::Branch(nodes)
            },
            NodeState::Branch(mut nodes) => {
                nodes[branch_dispatch(&self.center, &entry.position())].insert(entry);
                NodeState::Branch(nodes)
            },
        });
    }
}

#[cfg(test)]
mod test {
    use super::{Node, Entry, NodeState, subdivide, branch_dispatch};
    use nalgebra::{ApproxEq, Pnt2, Pnt3, FloatPnt};
    use std::num::Float;
    use quickcheck::TestResult;

    #[test]
    fn subdivide_2d_4nodes() {
        let nodes = subdivide(&Pnt2::new(0.0f64, 0.0), &1.0f64);
        assert_eq!(nodes.len(), 4);
    }

    #[test]
    fn subdivide_3d_8nodes() {
        let nodes = subdivide(&Pnt3::new(0.0f64, 0.0, 0.0), &1.0f64);
        assert_eq!(nodes.len(), 8);
    }

    #[quickcheck]
    fn subdivide_new_extents_half_width((x, y, ext): (f64, f64, f64)) -> bool {
        let new_coords = subdivide(&Pnt2::new(x, y), &ext);
        new_coords.iter().all(|&(_, new_ext)|
            new_ext == ext / 2.0
        )
    }

    #[quickcheck]
    fn subdivide_new_centers_dist((x, y, ext): (f64, f64, f64)) -> TestResult {
        if ext > 0.0 {
            let center = Pnt2::new(x, y);
            let new_coords = subdivide(&center, &ext);
            TestResult::from_bool(new_coords.iter().all(|&(new_center, _)| {
                ApproxEq::approx_eq(
                    &FloatPnt::dist(&new_center, &center),
                    &(ext * 2.0.sqrt() / 2.0)
                )
            }))
        } else {
            TestResult::discard()
        }
    }

    #[quickcheck]
    fn branch_dispatch_index_range_2d((px, py): (f64, f64)) -> bool {
        // TODO: make the center variable
        branch_dispatch(&Pnt2::new(0.0, 0.0), &Pnt2::new(px, py)) < 4
    }

    #[quickcheck]
    fn branch_dispatch_index_range_3d((px, py, pz): (f64, f64, f64)) -> bool {
        // TODO: make the center variable
        branch_dispatch(&Pnt3::new(0.0, 0.0, 0.0), &Pnt3::new(px, py, pz)) < 8
    }

    #[test]
    fn branch_dispatch_cases_2d() {
        let center = Pnt2::new(0.0f64, 0.0);
        let ext = 10.0f64;
        let subs = subdivide(&center, &ext);
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt2::new(2.0, 2.0))].0,
            Pnt2::new(5.0, 5.0)
        );
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt2::new(-2.0, 2.0))].0,
            Pnt2::new(-5.0, 5.0)
        );
    }

    #[test]
    fn branch_dispatch_cases_3d() {
        let center = Pnt3::new(0.0f64, 0.0, 0.0);
        let ext = 8.0f64;
        let subs = subdivide(&center, &ext);
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt3::new(3.0, 1.0, -1.2))].0,
            Pnt3::new(4.0, 4.0, -4.0)
        );
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt3::new(-2.0, 2.0, -0.1))].0,
            Pnt3::new(-4.0, 4.0, -4.0)
        );
    }

    #[test]
    fn node_insert_into_empty() {
        let mut n = Node::new(
            NodeState::Empty,
            Pnt2::new(0.0f32, 0.0),
            10.0f32,
        );
        n.insert(Entry { position: Pnt2::new(1.0f32, 0.0), object: 1i });
        match n.state {
            Some(NodeState::Leaf(entry)) => assert_eq!(entry.object, 1),
            _ => panic!("node is no leaf")
        }
    }

    #[test]
    fn node_insert_into_leaf() {
        let mut n = Node::new(
            NodeState::Leaf(Entry {object: 1i, position: Pnt2::new(1.0f64, -2.0)}),
            Pnt2::new(0.0f64, 0.0),
            10.0f64,
        );
        n.insert(Entry { object: 2i, position: Pnt2::new(2.0, 1.0) });
        match n.state {
            Some(NodeState::Branch(nodes)) => {
                for &k in [1, 2].iter() {
                    assert!(nodes.iter().any(|node| match node.state {
                        Some(NodeState::Leaf(ref entry)) => entry.object == k,
                        _ => false,
                    }));
                }
            },
            _ => panic!("node is no branch"),
        }
    }

    #[test]
    fn node_branch_on_second_insert() {
        let mut n = Node::new(NodeState::Empty, Pnt2::new(0.0f64, 0.0), 8.0f64);
        n.insert(Entry { object: 1u, position: Pnt2::new(1.0, 2.0) });
        n.insert(Entry { object: 1u, position: Pnt2::new(2.0, -3.0) });
        match n.state.unwrap() {
            NodeState::Branch(_) => (),
            _ => panic!("node is no branch"),
        }
    }
}
<commit_msg>Clean up privacy of items<commit_after>use nalgebra::{Dim, BaseFloat};
use std::num::{Int, cast};
use std::iter::AdditiveIterator;

pub trait Positionable<P> {
    fn position(&self) -> P;
}

pub struct Entry<O, P> {
    pub object: O,
    pub position: P,
}

impl<O, P> Positionable<P> for Entry<O, P>
    where P: Copy
{
    fn position(&self) -> P {
        self.position
    }
}

/// Subdivision helper function
///
/// Given the center of a node and its extent, this function generates a vector
/// of empty nodes equally partitioning the given node geometry. This is generic
/// over the dimension of the point type.
///
/// # Params
/// - The `old_center` is the center point of the (old) node.
/// - The `old_extent` is its extent.
fn subdivide<P, N>(old_center: &P, old_extent: &N) -> Vec<(P, N)>
    where P: Dim + Index<uint, N> + IndexMut<uint, N> + Copy,
          N: BaseFloat,
{
    let dim = Dim::dim(None::<P>);
    let new_extent = *old_extent / cast(2.0f64).unwrap();
    range(0u, 2.pow(dim))
        .map(|n| {
            let mut new_center = *old_center;
            for i in range(0, dim) {
                new_center[i] = new_center[i] + match n / 2.pow(i) % 2 {
                    0 => -new_extent,
                    1 => new_extent,
                    _ => unreachable!(),
                };
            }
            (new_center, new_extent)
        })
        .collect()
}

fn branch_dispatch<P, N>(center: &P, point: &P) -> uint
    where P: Dim + Index<uint, N> + IndexMut<uint, N>,
          N: BaseFloat,
{
    let dim = Dim::dim(None::<P>);
    range(0, dim)
        .map(|k| if point[k] < center[k] {0} else {1 << k})
        .sum()
}

enum NodeState<O, P, N> {
    Empty,
    Leaf(O),
    Branch(Vec<Node<O, P, N>>),
}

pub struct Node<O, P, N> {
    state: Option<NodeState<O, P, N>>,
    center: P,
    extent: N,
}

impl<O, P, N> Node<O, P, N> {
    pub fn empty(center: P, extent: N) -> Node<O, P, N> {
        Node {
            state: Some(NodeState::Empty),
            center: center,
            extent: extent,
        }
    }
}

impl<O, P, N> Node<O, P, N>
    where O: Positionable<P>,
          P: Dim + Index<uint, N> + IndexMut<uint, N> + Copy,
          N: BaseFloat,
{
    pub fn insert(&mut self, entry: O) {
        let tmp = self.state.take().unwrap();
        self.state = Some(match tmp {
            NodeState::Empty => NodeState::Leaf(entry),
            NodeState::Leaf(other) => {
                let mut nodes: Vec<Node<O, P, N>> = subdivide(&self.center, &self.extent)
                    .into_iter()
                    .map(|(p, n)| Node::empty(p, n))
                    .collect();
                nodes[branch_dispatch(&self.center, &other.position())].insert(other);
                nodes[branch_dispatch(&self.center, &entry.position())].insert(entry);
                NodeState::Branch(nodes)
            },
            NodeState::Branch(mut nodes) => {
                nodes[branch_dispatch(&self.center, &entry.position())].insert(entry);
                NodeState::Branch(nodes)
            },
        });
    }
}

#[cfg(test)]
mod test {
    use super::{Node, Entry, NodeState, subdivide, branch_dispatch};
    use nalgebra::{ApproxEq, Pnt2, Pnt3, FloatPnt};
    use std::num::Float;
    use quickcheck::TestResult;

    #[test]
    fn subdivide_2d_4nodes() {
        let nodes = subdivide(&Pnt2::new(0.0f64, 0.0), &1.0f64);
        assert_eq!(nodes.len(), 4);
    }

    #[test]
    fn subdivide_3d_8nodes() {
        let nodes = subdivide(&Pnt3::new(0.0f64, 0.0, 0.0), &1.0f64);
        assert_eq!(nodes.len(), 8);
    }

    #[quickcheck]
    fn subdivide_new_extents_half_width((x, y, ext): (f64, f64, f64)) -> bool {
        let new_coords = subdivide(&Pnt2::new(x, y), &ext);
        new_coords.iter().all(|&(_, new_ext)|
            new_ext == ext / 2.0
        )
    }

    #[quickcheck]
    fn subdivide_new_centers_dist((x, y, ext): (f64, f64, f64)) -> TestResult {
        if ext > 0.0 {
            let center = Pnt2::new(x, y);
            let new_coords = subdivide(&center, &ext);
            TestResult::from_bool(new_coords.iter().all(|&(new_center, _)| {
                ApproxEq::approx_eq(
                    &FloatPnt::dist(&new_center, &center),
                    &(ext * 2.0.sqrt() / 2.0)
                )
            }))
        } else {
            TestResult::discard()
        }
    }

    #[quickcheck]
    fn branch_dispatch_index_range_2d((px, py): (f64, f64)) -> bool {
        // TODO: make the center variable
        branch_dispatch(&Pnt2::new(0.0, 0.0), &Pnt2::new(px, py)) < 4
    }

    #[quickcheck]
    fn branch_dispatch_index_range_3d((px, py, pz): (f64, f64, f64)) -> bool {
        // TODO: make the center variable
        branch_dispatch(&Pnt3::new(0.0, 0.0, 0.0), &Pnt3::new(px, py, pz)) < 8
    }

    #[test]
    fn branch_dispatch_cases_2d() {
        let center = Pnt2::new(0.0f64, 0.0);
        let ext = 10.0f64;
        let subs = subdivide(&center, &ext);
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt2::new(2.0, 2.0))].0,
            Pnt2::new(5.0, 5.0)
        );
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt2::new(-2.0, 2.0))].0,
            Pnt2::new(-5.0, 5.0)
        );
    }

    #[test]
    fn branch_dispatch_cases_3d() {
        let center = Pnt3::new(0.0f64, 0.0, 0.0);
        let ext = 8.0f64;
        let subs = subdivide(&center, &ext);
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt3::new(3.0, 1.0, -1.2))].0,
            Pnt3::new(4.0, 4.0, -4.0)
        );
        assert_eq!(
            subs[branch_dispatch(&center, &Pnt3::new(-2.0, 2.0, -0.1))].0,
            Pnt3::new(-4.0, 4.0, -4.0)
        );
    }

    #[test]
    fn node_insert_into_empty() {
        let mut n = Node::empty(Pnt2::new(0.0f32, 0.0), 10.0f32);
        n.insert(Entry { position: Pnt2::new(1.0f32, 0.0), object: 1i });
        match n.state {
            Some(NodeState::Leaf(entry)) => assert_eq!(entry.object, 1),
            _ => panic!("node is no leaf")
        }
    }

    #[test]
    fn node_insert_into_leaf() {
        let mut n = Node::empty(Pnt2::new(0.0f64, 0.0), 10.0f64);
        n.insert(Entry { object: 1i, position: Pnt2::new(1.0f64, -2.0) });
        n.insert(Entry { object: 2i, position: Pnt2::new(2.0, 1.0) });
        match n.state {
            Some(NodeState::Branch(nodes)) => {
                for &k in [1, 2].iter() {
                    assert!(nodes.iter().any(|node| match node.state {
                        Some(NodeState::Leaf(ref entry)) => entry.object == k,
                        _ => false,
                    }));
                }
            },
            _ => panic!("node is no branch"),
        }
    }

    #[test]
    fn node_branch_on_second_insert() {
        let mut n = Node::empty(Pnt2::new(0.0f64, 0.0), 8.0f64);
        n.insert(Entry { object: 1u, position: Pnt2::new(1.0, 2.0) });
        n.insert(Entry { object: 1u, position: Pnt2::new(2.0, -3.0) });
        match n.state.unwrap() {
            NodeState::Branch(_) => (),
            _ => panic!("node is no branch"),
        }
    }
}
<|endoftext|>


<commit_before>use std::ffi::OsString;
use ::rand;
use ::rand::Rng;
use std::ffi::CString;
use std::path::Path;
use std::io;

pub fn tmpname() -> OsString {
    let mut bytes = vec!['.' as u8; 7];
    rand::thread_rng().fill_bytes(&mut bytes[1..]);

    for byte in bytes[1..].iter_mut() {
        *byte = match *byte % 62 {
            v @ 0...9 => (v + '0' as u8),
            v @ 10...35 => (v - 10 + 'a' as u8),
            v @ 36...61 => (v - 36 + 'A' as u8),
            _ => unreachable!(),
        }
    }
    OsString::from_bytes(bytes).unwrap()
}

// Stolen from std.
pub fn cstr(path: &Path) -> io::Result<CString> {
    path.as_os_str().to_cstring().ok_or(
        io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
}

<commit_msg>annotate cstr.<commit_after>use std::ffi::OsString;
use ::rand;
use ::rand::Rng;
use std::ffi::CString;
use std::path::Path;
use std::io;

pub fn tmpname() -> OsString {
    let mut bytes = vec!['.' as u8; 7];
    rand::thread_rng().fill_bytes(&mut bytes[1..]);

    for byte in bytes[1..].iter_mut() {
        *byte = match *byte % 62 {
            v @ 0...9 => (v + '0' as u8),
            v @ 10...35 => (v - 10 + 'a' as u8),
            v @ 36...61 => (v - 36 + 'A' as u8),
            _ => unreachable!(),
        }
    }
    OsString::from_bytes(bytes).unwrap()
}

// Stolen from std.
#[allow(dead_code)] // Not used on windows.
#[inline(always)]
pub fn cstr(path: &Path) -> io::Result<CString> {
    path.as_os_str().to_cstring().ok_or(
        io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
}

<|endoftext|>