<commit_before>#[cfg_attr(test, macro_use)]
extern crate assert_float_eq;
extern crate crossbeam;

use csv::WriterBuilder;
use image::RgbImage;
use ndarray::prelude::*;
use ndarray_csv::Array2Writer;
use std::convert::TryFrom;
use std::env;
use std::fs::File;

/// A count that represents how many times a point is transformed
type Count = i32;

/// A coordinate in screens
type Coordinate = f32;

/// A number of pixels
type PixelSize = isize;

/// A point as two coordinates in screens
type Point = num::complex::Complex<Coordinate>;

/// A set of coordinates and its view
type CoordinateSet = ndarray::Array1<Coordinate>;
type CoordinateSetView<'a> = ndarray::ArrayView1<'a, Coordinate>;

/// RGB colors at pixels in a screen
type Bitmap = ndarray::Array3<u8>;

/// All counts in a screen
type CountSet = ndarray::Array2<Count>;

/// Returns a transformed point under the rule of Julia sets
///
/// # Arguments
///
/// * `from` An original point
/// * `offset` An offset to be added
fn transform_point(from: Point, offset: Point) -> Point {
    from * from + offset
}

/// Returns how many times a point is transformed
///
/// # Arguments
///
/// * `point_x` The x coordinate of a point
/// * `point_y` The y coordinate of a point
/// * `point_offset` An offset to be added to points
/// * `max_iter` The maximum number of iterations
/// * `eps` Tolerance to check if transformations are converged
fn converge_point(
    point_x: Coordinate,
    point_y: Coordinate,
    point_offset: Point,
    max_iter: Count,
    eps: Coordinate,
) -> Count {
    let mut z = Point::new(point_x, point_y);
    let mut count: Count = 0;
    let mut previous_modulus: Coordinate = 10.0;

    for _ in 0..max_iter {
        z = transform_point(z, point_offset);
        let z_modulus = z.norm_sqr();
        if z_modulus > 4.0 {
            break;
        }
        if (previous_modulus - z_modulus).abs() < eps {
            break;
        }
        count += 1;
        previous_modulus = z_modulus;
    }

    count
}

/// Returns how many times each point in a screen is transformed
///
/// # Arguments
///
/// * `xs` A X-coordinates view of points in a screen
/// * `ys` A Y-coordinates view of points in a screen
/// * `point_offset` An offset to be added to points
/// * `max_iter` The maximum number of iterations
/// * `eps` Tolerance to check if transformations are converged
fn converge_point_set(
    xs: CoordinateSetView,
    ys: CoordinateSetView,
    point_offset: Point,
    max_iter: Count,
    eps: Coordinate,
) -> CountSet {
    let mut mat_counts = CountSet::zeros([ys.shape()[0], xs.shape()[0]]);

    for (y_index, point_y) in ys.iter().enumerate() {
        for (x_index, point_x) in xs.iter().enumerate() {
            mat_counts[[y_index, x_index]] =
                converge_point(*point_x, *point_y, point_offset, max_iter, eps);
        }
    }

    mat_counts
}

/// Returns pixel coordinates on an axis in a screen
///
/// # Arguments
///
/// * `half_length` Maximum x and y coordinates relative to (0,0)
/// * `n_pixels` Numbers of pixels in X and Y axes
fn map_coordinates(half_length: Coordinate, n_pixels: PixelSize) -> CoordinateSet {
    let n = n_pixels as Coordinate;
    (0..n_pixels)
        .map(|i| ((i as Coordinate) * 2.0 * half_length / n) - half_length)
        .collect()
}

/// Returns how many times each point in a screen is transformed
///
/// # Arguments
///
/// * `x_offset` An x offset to be added
/// * `y_offset` A y offset to be added
/// * `max_iter` The maximum number of iterations
/// * `n_pixels` Numbers of pixels in X and Y axes
fn scan_points(
    x_offset: Coordinate,
    y_offset: Coordinate,
    max_iter: Count,
    n_pixels: PixelSize,
) -> CountSet {
    let half_length = (2.0 as Coordinate).sqrt() + 0.1;
    let xs = map_coordinates(half_length, n_pixels);
    let ys = map_coordinates(half_length, n_pixels);
    let point_offset = Point::new(x_offset, y_offset);
    let eps = 1e-5;

    let n_ys = ys.shape()[0];
    crossbeam::scope(|scope| {
        let mut mat_counts = CountSet::zeros([n_ys, xs.shape()[0]]);
        let mut children = vec![];
        let mut y_base: usize = 0;
        let n_cpus = 1; // num_cpus::get();
        let x_view = xs.view();
        for ys_sub in ys.axis_chunks_iter(Axis(0), n_ys / n_cpus) {
            children.push(
                scope.spawn(move |_| {
                    converge_point_set(x_view, ys_sub, point_offset, max_iter, eps)
                }),
            );
            y_base += ys_sub.len();
        }
        assert!(y_base == n_ys);

        let mut y_total: usize = 0;
        for child in children {
            let sub_counts = child.join().unwrap();
            let height = sub_counts.shape()[0];
            mat_counts
                .slice_mut(s![y_total..(y_total + height), ..])
                .assign(&sub_counts);
            y_total += height;
        }
        assert!(y_total == n_ys);

        mat_counts
    })
    .unwrap()
}

/// Draws a PNG image from an input screen
///
/// # Arguments
///
/// * `count_set` Counts of a Julia set in a screen
/// * `png_filename` An output PNG filename
fn draw_image(count_set: CountSet, png_filename: &str) {
    type BitmapCoord = usize;

    let (height, width) = count_set.dim();
    let shape = [height, width, 3];
    let mut bitmap = Bitmap::zeros(shape);
    let max_count_raw = match count_set.iter().max() {
        Some(x) => *x,
        None => 0,
    };
    let max_count = BitmapCoord::try_from(max_count_raw).unwrap();

    let gradient = colorous::CIVIDIS;
    let color_map: Vec<colorous::Color> = (0..=(max_count))
        .map(|i| gradient.eval_rational(i, max_count))
        .collect();

    let mut count_bitmap_r = count_set.mapv(|i| color_map[BitmapCoord::try_from(i).unwrap()].r);
    let count_slice_r = count_bitmap_r.slice_mut(s![.., ..]);
    bitmap.slice_mut(s![.., .., 0]).assign(&count_slice_r);

    let mut count_bitmap_g = count_set.mapv(|i| color_map[BitmapCoord::try_from(i).unwrap()].g);
    let count_slice_g = count_bitmap_g.slice_mut(s![.., ..]);
    bitmap.slice_mut(s![.., .., 1]).assign(&count_slice_g);

    let mut count_bitmap_b = count_set.mapv(|i| color_map[BitmapCoord::try_from(i).unwrap()].b);
    let count_slice_b = count_bitmap_b.slice_mut(s![.., ..]);
    bitmap.slice_mut(s![.., .., 2]).assign(&count_slice_b);

    let raw = bitmap.into_raw_vec();
    let image = RgbImage::from_raw(
        u32::try_from(width).unwrap(),
        u32::try_from(height).unwrap(),
        raw,
    )
    .expect("Creating an image failed");
    image.save(png_filename).expect("Saving an image failed");
}

// Takes the first command line argument as a pixel size if available
fn main() {
    let n_pixels = match env::args().nth(1) {
        Some(arg) => arg.parse::<PixelSize>().unwrap(),
        None => 1024,
    };
    let count_set = scan_points(0.382, 0.382, 75, n_pixels);

    let file = File::create("rust_juliaset.csv").expect("creating file failed");
    let mut writer = WriterBuilder::new().has_headers(false).from_writer(file);
    writer.serialize_array2(&count_set).expect("write failed");
    draw_image(count_set, "rust_juliaset.png");
}

#[test]
fn test_transform_point() {
    let from = Point::new(2.0, 4.0);
    let offset = Point::new(3.0, 5.0);
    let actual = transform_point(from, offset);
    let expected = Point::new(-9.0, 21.0);
    assert_float_eq::assert_float_absolute_eq!(actual.re, expected.re, Coordinate::EPSILON);
    assert_float_eq::assert_float_absolute_eq!(actual.im, expected.im, Coordinate::EPSILON);
}
<commit_msg>Use a macro<commit_after>#[cfg_attr(test, macro_use)]
extern crate assert_float_eq;
extern crate crossbeam;

use csv::WriterBuilder;
use image::RgbImage;
use ndarray::prelude::*;
use ndarray_csv::Array2Writer;
use std::convert::TryFrom;
use std::env;
use std::fs::File;

/// A count that represents how many times a point is transformed
type Count = i32;

/// A coordinate in screens
type Coordinate = f32;

/// A number of pixels
type PixelSize = isize;

/// A point as two coordinates in screens
type Point = num::complex::Complex<Coordinate>;

/// A set of coordinates and its view
type CoordinateSet = ndarray::Array1<Coordinate>;
type CoordinateSetView<'a> = ndarray::ArrayView1<'a, Coordinate>;

/// RGB colors at pixels in a screen
type Bitmap = ndarray::Array3<u8>;

/// All counts in a screen
type CountSet = ndarray::Array2<Count>;

/// Returns a transformed point under the rule of Julia sets
///
/// # Arguments
///
/// * `from` An original point
/// * `offset` An offset to be added
fn transform_point(from: Point, offset: Point) -> Point {
    from * from + offset
}

/// Returns how many times a point is transformed
///
/// # Arguments
///
/// * `point_x` The x coordinate of a point
/// * `point_y` The y coordinate of a point
/// * `point_offset` An offset to be added to points
/// * `max_iter` The maximum number of iterations
/// * `eps` Tolerance to check if transformations are converged
fn converge_point(
    point_x: Coordinate,
    point_y: Coordinate,
    point_offset: Point,
    max_iter: Count,
    eps: Coordinate,
) -> Count {
    let mut z = Point::new(point_x, point_y);
    let mut count: Count = 0;
    let mut previous_modulus: Coordinate = 10.0;

    for _ in 0..max_iter {
        z = transform_point(z, point_offset);
        let z_modulus = z.norm_sqr();
        if z_modulus > 4.0 {
            break;
        }
        if (previous_modulus - z_modulus).abs() < eps {
            break;
        }
        count += 1;
        previous_modulus = z_modulus;
    }

    count
}

/// Returns how many times each point in a screen is transformed
///
/// # Arguments
///
/// * `xs` A X-coordinates view of points in a screen
/// * `ys` A Y-coordinates view of points in a screen
/// * `point_offset` An offset to be added to points
/// * `max_iter` The maximum number of iterations
/// * `eps` Tolerance to check if transformations are converged
fn converge_point_set(
    xs: CoordinateSetView,
    ys: CoordinateSetView,
    point_offset: Point,
    max_iter: Count,
    eps: Coordinate,
) -> CountSet {
    let mut mat_counts = CountSet::zeros([ys.shape()[0], xs.shape()[0]]);

    for (y_index, point_y) in ys.iter().enumerate() {
        for (x_index, point_x) in xs.iter().enumerate() {
            mat_counts[[y_index, x_index]] =
                converge_point(*point_x, *point_y, point_offset, max_iter, eps);
        }
    }

    mat_counts
}

/// Returns pixel coordinates on an axis in a screen
///
/// # Arguments
///
/// * `half_length` Maximum x and y coordinates relative to (0,0)
/// * `n_pixels` Numbers of pixels in X and Y axes
fn map_coordinates(half_length: Coordinate, n_pixels: PixelSize) -> CoordinateSet {
    let n = n_pixels as Coordinate;
    (0..n_pixels)
        .map(|i| ((i as Coordinate) * 2.0 * half_length / n) - half_length)
        .collect()
}

/// Returns how many times each point in a screen is transformed
///
/// # Arguments
///
/// * `x_offset` An x offset to be added
/// * `y_offset` A y offset to be added
/// * `max_iter` The maximum number of iterations
/// * `n_pixels` Numbers of pixels in X and Y axes
fn scan_points(
    x_offset: Coordinate,
    y_offset: Coordinate,
    max_iter: Count,
    n_pixels: PixelSize,
) -> CountSet {
    let half_length = (2.0 as Coordinate).sqrt() + 0.1;
    let xs = map_coordinates(half_length, n_pixels);
    let ys = map_coordinates(half_length, n_pixels);
    let point_offset = Point::new(x_offset, y_offset);
    let eps = 1e-5;

    let n_ys = ys.shape()[0];
    crossbeam::scope(|scope| {
        let mut mat_counts = CountSet::zeros([n_ys, xs.shape()[0]]);
        let mut children = vec![];
        let mut y_base: usize = 0;
        let n_cpus = num_cpus::get();
        let x_view = xs.view();
        for ys_sub in ys.axis_chunks_iter(Axis(0), n_ys / n_cpus) {
            children.push(
                scope.spawn(move |_| {
                    converge_point_set(x_view, ys_sub, point_offset, max_iter, eps)
                }),
            );
            y_base += ys_sub.len();
        }
        assert!(y_base == n_ys);

        let mut y_total: usize = 0;
        for child in children {
            let sub_counts = child.join().unwrap();
            let height = sub_counts.shape()[0];
            mat_counts
                .slice_mut(s![y_total..(y_total + height), ..])
                .assign(&sub_counts);
            y_total += height;
        }
        assert!(y_total == n_ys);

        mat_counts
    })
    .unwrap()
}

/// Draws a PNG image from an input screen
///
/// # Arguments
///
/// * `count_set` Counts of a Julia set in a screen
/// * `png_filename` An output PNG filename
fn draw_image(count_set: CountSet, png_filename: &str) {
    macro_rules! set_color {
        (  $bitmap:expr, $count_set:expr, $color_map:expr, $rgb:tt, $index_t:ty ) => {
            let count_bitmap =
                ($count_set).mapv(|i| $color_map[<$index_t>::try_from(i).unwrap()].$rgb);
            let count_slice = count_bitmap.slice(s![.., ..]);
            $bitmap.assign(&count_slice);
        };
    }

    println!("Drawing an image");

    type BitmapCoord = usize;
    let (height, width) = count_set.dim();
    let shape = [height, width, 3];
    let mut bitmap = Bitmap::zeros(shape);
    let max_count_raw = match count_set.iter().max() {
        Some(x) => *x,
        None => 0,
    };
    let max_count = BitmapCoord::try_from(max_count_raw).unwrap();

    let gradient = colorous::CIVIDIS;
    let color_map: Vec<colorous::Color> = (0..=(max_count))
        .map(|i| gradient.eval_rational(i, max_count))
        .collect();

    crossbeam::scope(|scope| {
        let mut children = vec![];

        for (index, mut bitmap_slice) in bitmap.axis_iter_mut(Axis(2)).enumerate() {
            let count_set_view = count_set.view();
            let color_map_view = &color_map[..];
            if index == 0 {
                children.push(scope.spawn(move |_| {
                    set_color!(
                        bitmap_slice,
                        &count_set_view,
                        color_map_view,
                        r,
                        BitmapCoord
                    );
                }));
            } else if index == 1 {
                children.push(scope.spawn(move |_| {
                    set_color!(
                        bitmap_slice,
                        &count_set_view,
                        color_map_view,
                        g,
                        BitmapCoord
                    );
                }));
            } else if index == 2 {
                children.push(scope.spawn(move |_| {
                    set_color!(
                        bitmap_slice,
                        &count_set_view,
                        color_map_view,
                        b,
                        BitmapCoord
                    );
                }));
            } else {
                panic!("Unknown color index")
            }
        }

        for child in children {
            child.join().unwrap();
        }
    })
    .unwrap();

    println!("Writing a PNG image");
    let raw = bitmap.into_raw_vec();
    let image = RgbImage::from_raw(
        u32::try_from(width).unwrap(),
        u32::try_from(height).unwrap(),
        raw,
    )
    .expect("Creating an image failed");
    image.save(png_filename).expect("Saving an image failed");
}

// Takes the first command line argument as a pixel size if available
fn main() {
    let n_pixels = match env::args().nth(1) {
        Some(arg) => arg.parse::<PixelSize>().unwrap(),
        None => 1024,
    };
    println!("Scanning points");
    let count_set = scan_points(0.382, 0.382, 75, n_pixels);

    let file = File::create("rust_juliaset.csv").expect("creating file failed");
    let mut writer = WriterBuilder::new().has_headers(false).from_writer(file);
    writer.serialize_array2(&count_set).expect("write failed");
    draw_image(count_set, "rust_juliaset.png");
}

#[test]
fn test_transform_point() {
    let from = Point::new(2.0, 4.0);
    let offset = Point::new(3.0, 5.0);
    let actual = transform_point(from, offset);
    let expected = Point::new(-9.0, 21.0);
    assert_float_eq::assert_float_absolute_eq!(actual.re, expected.re, Coordinate::EPSILON);
    assert_float_eq::assert_float_absolute_eq!(actual.im, expected.im, Coordinate::EPSILON);
}
<|endoftext|>


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

use core::{
    Dependency,
    PackageId,
    Summary,
    Registry
};

use util::{CargoResult, human, internal};

/* TODO:
 * - The correct input here is not a registry. Resolves should be performable
 * on package summaries vs. the packages themselves.
 */
pub fn resolve<R: Registry>(deps: &[Dependency],
                            registry: &mut R) -> CargoResult<Vec<PackageId>> {
    log!(5, "resolve; deps={}", deps);

    let mut remaining = Vec::from_slice(deps);
    let mut resolve = HashMap::<String, Summary>::new();

    loop {
        let curr = match remaining.pop() {
            Some(curr) => curr,
            None => {
                let ret = resolve.values().map(|summary| {
                    summary.get_package_id().clone()
                }).collect();
                log!(5, "resolve complete; ret={}", ret);
                return Ok(ret);
            }
        };

        let opts = try!(registry.query(&curr));

        if opts.len() == 0 {
            return Err(human(format!("No package named {} found", curr.get_name())));
        }

        if opts.len() > 1 {
            return Err(internal(format!("At the moment, Cargo only supports a\
                single source for a particular package name ({}).", curr.get_name())));
        }

        let pkg = opts.get(0).clone();
        resolve.insert(pkg.get_name().to_str(), pkg.clone());

        for dep in pkg.get_dependencies().iter() {
            if !dep.is_transitive() { continue; }

            if !resolve.contains_key_equiv(&dep.get_name()) {
                remaining.push(dep.clone());
            }
        }
    }
}

#[cfg(test)]
mod test {
    use url;
    use hamcrest::{assert_that, equal_to, contains};

    use core::source::{SourceId, RegistryKind, Location, Remote};
    use core::{Dependency, PackageId, Summary};
    use super::resolve;

    trait ToDep {
        fn to_dep(self) -> Dependency;
    }

    impl ToDep for &'static str {
        fn to_dep(self) -> Dependency {
            let url = url::from_str("http://example.com").unwrap();
            let source_id = SourceId::new(RegistryKind, Remote(url));
            Dependency::parse(self, Some("1.0.0"), &source_id).unwrap()
        }
    }

    impl ToDep for Dependency {
        fn to_dep(self) -> Dependency {
            self
        }
    }

    macro_rules! pkg(
        ($name:expr => $($deps:expr),+) => ({
            let d: Vec<Dependency> = vec!($($deps.to_dep()),+);

            Summary::new(&PackageId::new($name, "1.0.0", &registry_loc()).unwrap(),
                         d.as_slice())
        });

        ($name:expr) => (
            Summary::new(&PackageId::new($name, "1.0.0", &registry_loc()).unwrap(),
                         [])
        )
    )

    fn registry_loc() -> Location {
        Location::parse("http://www.example.com/").unwrap()
    }

    fn pkg(name: &str) -> Summary {
        Summary::new(&PackageId::new(name, "1.0.0", &registry_loc()).unwrap(),
                     &[])
    }

    fn dep(name: &str) -> Dependency {
        let url = url::from_str("http://example.com").unwrap();
        let source_id = SourceId::new(RegistryKind, Remote(url));
        Dependency::parse(name, Some("1.0.0"), &source_id).unwrap()
    }

    fn registry(pkgs: Vec<Summary>) -> Vec<Summary> {
        pkgs
    }

    fn names(names: &[&'static str]) -> Vec<PackageId> {
        names.iter()
            .map(|name| PackageId::new(*name, "1.0.0", &registry_loc()).unwrap())
            .collect()
    }

    #[test]
    pub fn test_resolving_empty_dependency_list() {
        let res = resolve([], &mut registry(vec!())).unwrap();

        assert_that(&res, equal_to(&names([])));
    }

    #[test]
    pub fn test_resolving_only_package() {
        let mut reg = registry(vec!(pkg("foo")));
        let res = resolve([dep("foo")], &mut reg);

        assert_that(&res.unwrap(), equal_to(&names(["foo"])));
    }

    #[test]
    pub fn test_resolving_one_dep() {
        let mut reg = registry(vec!(pkg("foo"), pkg("bar")));
        let res = resolve([dep("foo")], &mut reg);

        assert_that(&res.unwrap(), equal_to(&names(["foo"])));
    }

    #[test]
    pub fn test_resolving_multiple_deps() {
        let mut reg = registry(vec!(pkg!("foo"), pkg!("bar"), pkg!("baz")));
        let res = resolve([dep("foo"), dep("baz")], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "baz"])).exactly());
    }

    #[test]
    pub fn test_resolving_transitive_deps() {
        let mut reg = registry(vec!(pkg!("foo"), pkg!("bar" => "foo")));
        let res = resolve([dep("bar")], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "bar"])));
    }

    #[test]
    pub fn test_resolving_common_transitive_deps() {
        let mut reg = registry(vec!(pkg!("foo" => "bar"), pkg!("bar")));
        let res = resolve([dep("foo"), dep("bar")], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "bar"])));
    }

    #[test]
    pub fn test_resolving_with_dev_deps() {
        let mut reg = registry(vec!(
            pkg!("foo" => "bar", dep("baz").as_dev()),
            pkg!("baz" => "bat", dep("bam").as_dev()),
            pkg!("bar"),
            pkg!("bat")
        ));

        let res = resolve([dep("foo"), dep("baz").as_dev()], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "bar", "baz"])));
    }
}
<commit_msg>Fix missing space typo in single source error<commit_after>use std::collections::HashMap;

use core::{
    Dependency,
    PackageId,
    Summary,
    Registry
};

use util::{CargoResult, human, internal};

/* TODO:
 * - The correct input here is not a registry. Resolves should be performable
 * on package summaries vs. the packages themselves.
 */
pub fn resolve<R: Registry>(deps: &[Dependency],
                            registry: &mut R) -> CargoResult<Vec<PackageId>> {
    log!(5, "resolve; deps={}", deps);

    let mut remaining = Vec::from_slice(deps);
    let mut resolve = HashMap::<String, Summary>::new();

    loop {
        let curr = match remaining.pop() {
            Some(curr) => curr,
            None => {
                let ret = resolve.values().map(|summary| {
                    summary.get_package_id().clone()
                }).collect();
                log!(5, "resolve complete; ret={}", ret);
                return Ok(ret);
            }
        };

        let opts = try!(registry.query(&curr));

        if opts.len() == 0 {
            return Err(human(format!("No package named {} found", curr.get_name())));
        }

        if opts.len() > 1 {
            return Err(internal(format!("At the moment, Cargo only supports a \
                single source for a particular package name ({}).", curr.get_name())));
        }

        let pkg = opts.get(0).clone();
        resolve.insert(pkg.get_name().to_str(), pkg.clone());

        for dep in pkg.get_dependencies().iter() {
            if !dep.is_transitive() { continue; }

            if !resolve.contains_key_equiv(&dep.get_name()) {
                remaining.push(dep.clone());
            }
        }
    }
}

#[cfg(test)]
mod test {
    use url;
    use hamcrest::{assert_that, equal_to, contains};

    use core::source::{SourceId, RegistryKind, Location, Remote};
    use core::{Dependency, PackageId, Summary};
    use super::resolve;

    trait ToDep {
        fn to_dep(self) -> Dependency;
    }

    impl ToDep for &'static str {
        fn to_dep(self) -> Dependency {
            let url = url::from_str("http://example.com").unwrap();
            let source_id = SourceId::new(RegistryKind, Remote(url));
            Dependency::parse(self, Some("1.0.0"), &source_id).unwrap()
        }
    }

    impl ToDep for Dependency {
        fn to_dep(self) -> Dependency {
            self
        }
    }

    macro_rules! pkg(
        ($name:expr => $($deps:expr),+) => ({
            let d: Vec<Dependency> = vec!($($deps.to_dep()),+);

            Summary::new(&PackageId::new($name, "1.0.0", &registry_loc()).unwrap(),
                         d.as_slice())
        });

        ($name:expr) => (
            Summary::new(&PackageId::new($name, "1.0.0", &registry_loc()).unwrap(),
                         [])
        )
    )

    fn registry_loc() -> Location {
        Location::parse("http://www.example.com/").unwrap()
    }

    fn pkg(name: &str) -> Summary {
        Summary::new(&PackageId::new(name, "1.0.0", &registry_loc()).unwrap(),
                     &[])
    }

    fn dep(name: &str) -> Dependency {
        let url = url::from_str("http://example.com").unwrap();
        let source_id = SourceId::new(RegistryKind, Remote(url));
        Dependency::parse(name, Some("1.0.0"), &source_id).unwrap()
    }

    fn registry(pkgs: Vec<Summary>) -> Vec<Summary> {
        pkgs
    }

    fn names(names: &[&'static str]) -> Vec<PackageId> {
        names.iter()
            .map(|name| PackageId::new(*name, "1.0.0", &registry_loc()).unwrap())
            .collect()
    }

    #[test]
    pub fn test_resolving_empty_dependency_list() {
        let res = resolve([], &mut registry(vec!())).unwrap();

        assert_that(&res, equal_to(&names([])));
    }

    #[test]
    pub fn test_resolving_only_package() {
        let mut reg = registry(vec!(pkg("foo")));
        let res = resolve([dep("foo")], &mut reg);

        assert_that(&res.unwrap(), equal_to(&names(["foo"])));
    }

    #[test]
    pub fn test_resolving_one_dep() {
        let mut reg = registry(vec!(pkg("foo"), pkg("bar")));
        let res = resolve([dep("foo")], &mut reg);

        assert_that(&res.unwrap(), equal_to(&names(["foo"])));
    }

    #[test]
    pub fn test_resolving_multiple_deps() {
        let mut reg = registry(vec!(pkg!("foo"), pkg!("bar"), pkg!("baz")));
        let res = resolve([dep("foo"), dep("baz")], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "baz"])).exactly());
    }

    #[test]
    pub fn test_resolving_transitive_deps() {
        let mut reg = registry(vec!(pkg!("foo"), pkg!("bar" => "foo")));
        let res = resolve([dep("bar")], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "bar"])));
    }

    #[test]
    pub fn test_resolving_common_transitive_deps() {
        let mut reg = registry(vec!(pkg!("foo" => "bar"), pkg!("bar")));
        let res = resolve([dep("foo"), dep("bar")], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "bar"])));
    }

    #[test]
    pub fn test_resolving_with_dev_deps() {
        let mut reg = registry(vec!(
            pkg!("foo" => "bar", dep("baz").as_dev()),
            pkg!("baz" => "bat", dep("bam").as_dev()),
            pkg!("bar"),
            pkg!("bat")
        ));

        let res = resolve([dep("foo"), dep("baz").as_dev()], &mut reg).unwrap();

        assert_that(&res, contains(names(["foo", "bar", "baz"])));
    }
}
<|endoftext|>


<commit_before>use bit_twiddles::*;
use board::*;
use templates::*;
use std::ptr;

struct MagicHelper {
    square_BB: [u64; 64], // Maps index to square
    magic_bishop_table: [[u64; 4096]; 64],
    magic_rook_table: [[u64; 1024]; 64],
    knight_table: [u64; 64],
    king_table: [u64; 64]
}

//impl MagicHelper {
//    pub fn new() -> MagicHelper {
//        MagicHelper {
//            magic_bishop_moves: MagicHelper::gen_magic_bishop(),
//            magic_rook_moves: MagicHelper::gen_magic_rook()
//        }
//    }
//
//    pub fn default() -> MagicHelper { MagicHelper::new() }
//
//    fn gen_magic_bishop() -> [[u64; 4096]; 64] {
//        let mut arr: [[u64; 4096]; 64] = [[0; 4096]; 64];
//        let mut mask: u64 = 0;
//        for bitRef in 0..64 {
//            mask = BISHOP_MASK[bitRef];
//
//        }
//
//    }
//
//    fn gen_magic_rook() -> [[u64; 1024]; 64] {
//        let mut arr: [[u64; 1024]; 64] = [[0; 1024]; 64];
//
//    }
//}

fn gen_king_moves() -> [u64; 64] {
    let mut moves: [u64;64] = [0; 64];

    for index in 0..64 {
        let mut mask: u64 = 0;
        let file = index % 8;
        // LEFT
        if file != 0 {
            mask |= 1 << (index - 1);
        }
        // RIGHT
        if file != 7 {
            mask |= 1 << (index + 1);
        }
        // UP
        if index < 56  {
            mask |= 1 << (index + 8);
        }
        // DOWN
        if index > 7  {
            mask |= 1 << (index - 8);
        }
        // LEFT UP
        if file != 0 && index < 56 {
            mask |= 1 << (index + 7);
        }
        // LEFT DOWN
        if file != 0 && index > 7 {
            mask |= 1 << (index - 9);
        }
        // RIGHT DOWN
        if file!= 7 && index > 7 {
            mask |= 1 << (index - 7);
        }
        // RIGHT UP
        if file != 7 && index < 56 {
            mask |= 1 << (index + 0);
        }
        moves[index] = mask;
    }
    moves
}

fn gen_knight_moves() -> [u64; 64] {
    let mut moves: [u64;64] = [0; 64];
    for index in 0..64 {
        let mut mask: u64 = 0;
        let file = index % 8;

        // 1 UP   + 2 LEFT
        if file > 1 && index < 56 {
            mask |= 1 << (index + 6);
        }
        // 2 UP   + 1 LEFT
        if file != 0 && index < 48 {
            mask |= 1 << (index + 15);
        }
        // 2 UP   + 1 RIGHT
        if file != 7 && index < 48 {
            mask |= 1 << (index + 17);
        }
        // 1 UP   + 2 RIGHT
        if file < 6 && index < 56 {
            mask |= 1 << (index + 10);
        }
        // 1 DOWN   + 2 RIGHT
        if file < 6 && index > 7 {
            mask |= 1 << (index - 6);
        }
        // 2 DOWN   + 1 RIGHT
        if file != 7 && index > 15 {
            mask |= 1 << (index - 15 );
        }
        // 2 DOWN   + 1 LEFT
        if file != 0 && index > 15 {
            mask |= 1 << (index - 17 );
        }
        // 1 DOWN   + 2 LEFT
        if file > 1 && index > 7 {
            mask |= 1 << (index - 10 );
        }
        moves[index] = mask;
    }
    moves
}

//Bitboard  RookMasks  [SQUARE_NB];
//Bitboard  RookMagics [SQUARE_NB];
//Bitboard* RookAttacks[SQUARE_NB];
//unsigned  RookShifts [SQUARE_NB];
//
//Bitboard  BishopMasks  [SQUARE_NB];
//Bitboard  BishopMagics [SQUARE_NB];
//Bitboard* BishopAttacks[SQUARE_NB];
//unsigned  BishopShifts [SQUARE_NB];
//Bitboard RookTable[0x19000];  // To store rook attacks
//Bitboard BishopTable[0x1480]; // To store bishop attacks

// RookTable
fn get_magics() {
    let rook_table: [u64; 0x19000] = [0; 0x19000];
    let bishop_table: [u64; 0x1480] = [0; 0x1480];

    let rook_masks: [u64; 64] = [0; 64];
    let rook_magics: [u64; 64] = [0; 64];
    let rook_attacks: [u64; 64] = [0; 64];
    let rook_shifts: [u64; 64] = [0; 64];

    let bishop_masks: [u64; 64] = [0; 64];
    let bishop_magics: [u64; 64] = [0; 64];
    let bishop_attacks: [u64; 64] = [0; 64];
    let bishop_shifts: [u64; 64] = [0; 64];

}

// std::mem::transmute::<f32, u32>(1.0)
fn init_rook_magics(mut table: [u64; 0x19000], mut attacks: [*mut u64; 64], magics: [u64; 64],
                    mut masks: [u64; 64], shifts: [u64; 64], deltas: [u64; 4], index: [u64; 64]) {

    let seeds: [[u64;8]; 2] = [ [ 8977, 44560, 54343, 38998,  5731, 95205, 104912, 17020 ],
                                [  728, 10316, 55013, 32803, 12281, 15100,  16645,   255 ] ];

    let bishop_deltas: [i8; 4] = [7,9,9,7];
    let rook_deltas: [i8; 4] = [8,1,-8,1];

    let mut occupancy: [u64; 4096] = [0; 4096];
    let mut reference: [u64; 4096] = [0; 4096];
    let mut edges: u64 = 0;
    let mut age: [i32; 4096] =  [0; 4096];
    let mut current: i32 = 0;
    let mut size: usize = 0;

    for s in 0..64 {
        // ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s));
        edges = ((RANK_1 | RANK_8) & !rank_bb(s)) | ((FILE_A | FILE_B) & !file_bb(s));

        masks[s as usize] = sliding_attack(deltas, s, 0) & !edges;
        shifts[s as usize] = (64 - popcount64(masks[s as usize])) as u64;
        let mut b = 0;
        size = 0;

        loop {
            occupancy[size] = b;
            reference[size] = sliding_attack(deltas, s, b);
            size += 1;
            b = (b - masks[s as usize]) * masks[s as usize];
            if b == 0 {
                break;
            }
        }

        if s < 63 {
            unsafe {
                attacks[s as usize + 1] = std::mem::transmute::<*u64, u64>(1.0);
                    attacks[s as usize] + size as u64;

            }
//            attacks[s as usize + 1] = attacks[s as usize] + size as u64;

        }

        let mut rng = PRNG::init(seeds[1][rank_of(s) as usize]);

        'outer: loop {
            'first_in: loop {
                magics[s as usize] = rng.sparse_rand();
                if popcount64((magics[s as usize] * masks[s as usize]) >> 56) < 6 {
                    break 'first_in;
                }
            }
            // magic_index return unsigned(((occupied & Masks[s]) * Magics[s]) >> Shifts[s]);
            current += 1;
            let mut i: usize = 0;
            'secon_in: while i < size {
                let index: usize = (((occupancy[i as usize] & masks[s as usize]) * magics[s as usize]) >> shifts[s as usize]) as usize;
                if age[index] < current {
                    age[index] = current;
                    attacks[s as usize][index] = reference[i];
                } else if attacks[s as usize][index as usize] != reference[i] {
                    break 'secon_in;
                }
            }
            if i < size {
                break 'outer;
            }
        }
    }
}

// https://bluss.github.io/rust-ndarray/master/ndarray/struct.ArrayBase.html

struct PRNG {
    seed: u64
}

impl PRNG {
    pub fn init(s: u64) -> PRNG {
        assert_ne!(s,0);
        PRNG {seed: s}
    }

    pub fn rand(&mut self) -> u64 {
        self.rand_change()
    }

    pub fn sparse_rand(&mut self) -> u64 {
        let mut s = self.rand_change();
        s ^= self.rand_change();
        s ^= self.rand_change();
        s
    }

    fn rand_change(&mut self) -> u64 {
        self.seed ^= self.seed >> 12;
        self.seed ^= self.seed << 25;
        self.seed ^= self.seed >> 27;

        self.seed * 2685821657736338717
    }
}

fn sliding_attack(deltas: [u64; 4], square: u64, occupied: u64) -> u64 {
    let mut attack: u64 = 0;

    for i in 0..4 {
        let mut s: u64 = square + deltas[i];
        while is_ok(s) &&  distance(s, s - deltas[i]) == 1 {

            if occupied & s == 0 { break;}
            s += deltas[i];
        }
    }
    attack
}

pub fn gen_rook_masks() {
    let mut arr_masks: [u64; 64] = [0; 64];
    let mut shifts: [u8; 64] = [0; 64];

    let mut bit_ref: usize = 0;
    while bit_ref < 64 {
        let mut mask: u64 = 0;
        let mut i = bit_ref + 8;
        while i < 56 {
            mask |= (1 as u64) << (i as u8);
            i += 8;
        }
        if bit_ref > 7 {
            let mut i = bit_ref - 8;
            while i > 7 {
                mask |= (1 as u64) << (i as u8);
                i -= 8;
            }
        }
        let mut i = bit_ref + 1;
        while i % 8 != 0 && i <= 63 {
            mask |= (1 as u64) << (i as u8);
            i += 1;
        }
        if bit_ref > 0  {
            let mut i = bit_ref - 1;
            while i % 8 != 0 && i >= 0 {
                mask |= (1 as u64) << (i as u8);
                i -= 1;
            }
        }
        arr_masks[bit_ref] = mask;
        format_bits(format!("{:b}",mask));
        bit_ref += 1;
    }
}

pub fn gen_bishop_masks() {
    let mut arr_masks: [u64; 64] = [0; 64];
    let mut shifts: [u8; 64] = [0; 64];

    let mut bitRef: i32 = 0;
    while bitRef < 64 {
        let mut mask: u64 = 0;

        let mut i = bitRef + 9;
        while i < 56 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i += 9;
        }
        let mut i = bitRef - 9;
        while i > 7 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i -= 9;
        }
        let mut i = bitRef + 7;
        while i < 56 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i += 7;
        }

        let mut i = bitRef - 7;
        while i > 7 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i -= 7;
        }
        format_bits(format!("{:b}",mask));
        arr_masks[bitRef as usize] = mask;
        bitRef += 1;
    }
}

pub fn format_bits(bits: String) {
    let x = 64 - bits.len();
    let mut i = 0;
    while i < x {
        print!("0");
        i += 1;
    }
    println!("{}",bits);
}

#[test]
fn test_king_mask_gen() {
    let arr = gen_king_moves().to_vec();
    let sum = arr.iter().fold(0 as  u64,|a, &b| a + (bit_twiddles::popcount64(b) as u64));
    assert_eq!(sum, (3*4) + (5 * 6 * 4) + (8 * 6 * 6));
}

#[test]
fn test_knight_mask_gen() {
    let arr = gen_knight_moves().to_vec();
    let sum = arr.iter().fold(0 as  u64,|a, &b| a + (bit_twiddles::popcount64(b) as u64));
    assert_eq!(sum, (2 * 4) + (4 * 4) + (3 * 2 * 4) + (4 * 4 * 4) + (6 * 4 * 4) + (8 * 4 * 4));
}
<commit_msg>Committing Sins with unsafe rust<commit_after>use bit_twiddles::*;
use board::*;
use templates::*;
use std::ptr;
use std::mem;
use std::slice;
use std;

struct MagicHelper {
    square_BB: [u64; 64], // Maps index to square
    magic_bishop_table: [[u64; 4096]; 64],
    magic_rook_table: [[u64; 1024]; 64],
    knight_table: [u64; 64],
    king_table: [u64; 64]
}

//impl MagicHelper {
//    pub fn new() -> MagicHelper {
//        MagicHelper {
//            magic_bishop_moves: MagicHelper::gen_magic_bishop(),
//            magic_rook_moves: MagicHelper::gen_magic_rook()
//        }
//    }
//
//    pub fn default() -> MagicHelper { MagicHelper::new() }
//
//    fn gen_magic_bishop() -> [[u64; 4096]; 64] {
//        let mut arr: [[u64; 4096]; 64] = [[0; 4096]; 64];
//        let mut mask: u64 = 0;
//        for bitRef in 0..64 {
//            mask = BISHOP_MASK[bitRef];
//
//        }
//
//    }
//
//    fn gen_magic_rook() -> [[u64; 1024]; 64] {
//        let mut arr: [[u64; 1024]; 64] = [[0; 1024]; 64];
//
//    }
//}

fn gen_king_moves() -> [u64; 64] {
    let mut moves: [u64;64] = [0; 64];

    for index in 0..64 {
        let mut mask: u64 = 0;
        let file = index % 8;
        // LEFT
        if file != 0 {
            mask |= 1 << (index - 1);
        }
        // RIGHT
        if file != 7 {
            mask |= 1 << (index + 1);
        }
        // UP
        if index < 56  {
            mask |= 1 << (index + 8);
        }
        // DOWN
        if index > 7  {
            mask |= 1 << (index - 8);
        }
        // LEFT UP
        if file != 0 && index < 56 {
            mask |= 1 << (index + 7);
        }
        // LEFT DOWN
        if file != 0 && index > 7 {
            mask |= 1 << (index - 9);
        }
        // RIGHT DOWN
        if file!= 7 && index > 7 {
            mask |= 1 << (index - 7);
        }
        // RIGHT UP
        if file != 7 && index < 56 {
            mask |= 1 << (index + 0);
        }
        moves[index] = mask;
    }
    moves
}

fn gen_knight_moves() -> [u64; 64] {
    let mut moves: [u64;64] = [0; 64];
    for index in 0..64 {
        let mut mask: u64 = 0;
        let file = index % 8;

        // 1 UP   + 2 LEFT
        if file > 1 && index < 56 {
            mask |= 1 << (index + 6);
        }
        // 2 UP   + 1 LEFT
        if file != 0 && index < 48 {
            mask |= 1 << (index + 15);
        }
        // 2 UP   + 1 RIGHT
        if file != 7 && index < 48 {
            mask |= 1 << (index + 17);
        }
        // 1 UP   + 2 RIGHT
        if file < 6 && index < 56 {
            mask |= 1 << (index + 10);
        }
        // 1 DOWN   + 2 RIGHT
        if file < 6 && index > 7 {
            mask |= 1 << (index - 6);
        }
        // 2 DOWN   + 1 RIGHT
        if file != 7 && index > 15 {
            mask |= 1 << (index - 15 );
        }
        // 2 DOWN   + 1 LEFT
        if file != 0 && index > 15 {
            mask |= 1 << (index - 17 );
        }
        // 1 DOWN   + 2 LEFT
        if file > 1 && index > 7 {
            mask |= 1 << (index - 10 );
        }
        moves[index] = mask;
    }
    moves
}

//Bitboard  RookMasks  [SQUARE_NB];
//Bitboard  RookMagics [SQUARE_NB];
//Bitboard* RookAttacks[SQUARE_NB];
//unsigned  RookShifts [SQUARE_NB];
//
//Bitboard  BishopMasks  [SQUARE_NB];
//Bitboard  BishopMagics [SQUARE_NB];
//Bitboard* BishopAttacks[SQUARE_NB];
//unsigned  BishopShifts [SQUARE_NB];
//Bitboard RookTable[0x19000];  // To store rook attacks
//Bitboard BishopTable[0x1480]; // To store bishop attacks

// RookTable
fn get_magics() {
    let rook_table: [u64; 0x19000] = [0; 0x19000];
    let bishop_table: [u64; 0x1480] = [0; 0x1480];

    let rook_masks: [u64; 64] = [0; 64];
    let rook_magics: [u64; 64] = [0; 64];
    let rook_attacks: [u64; 64] = [0; 64];
    let rook_shifts: [u64; 64] = [0; 64];

    let bishop_masks: [u64; 64] = [0; 64];
    let bishop_magics: [u64; 64] = [0; 64];
    let bishop_attacks: [u64; 64] = [0; 64];
    let bishop_shifts: [u64; 64] = [0; 64];

}

// std::mem::transmute::<f32, u32>(1.0)
fn init_rook_magics<T>(mut table: Vec<u64>, mut attacks: [&mut [u64]; 64], mut magics: [u64; 64],
                    mut masks: [u64; 64], mut shifts: [u64; 64], deltas: [u64; 4], mut index: [u64; 64]) {

    let seeds: [[u64;8]; 2] = [ [ 8977, 44560, 54343, 38998,  5731, 95205, 104912, 17020 ],
                                [  728, 10316, 55013, 32803, 12281, 15100,  16645,   255 ] ];

    let bishop_deltas: [i8; 4] = [7,9,9,7];
    let rook_deltas: [i8; 4] = [8,1,-8,1];

    let mut occupancy: [u64; 4096] = [0; 4096];
    let mut reference: [u64; 4096] = [0; 4096];
    let mut edges: u64 = 0;
    let mut age: [i32; 4096] =  [0; 4096];

    let mut current: i32 = 0;
    let mut size: usize = 0;

    attacks[0] = unsafe{std::slice::from_raw_parts_mut(table.as_mut_ptr(),8000)};

    // s = index for the square
    for s in 0..64 {
        // ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s));
        edges = ((RANK_1 | RANK_8) & !rank_bb(s)) | ((FILE_A | FILE_B) & !file_bb(s));

        masks[s as usize] = sliding_attack(deltas, s, 0) & !edges;
        shifts[s as usize] = (64 - popcount64(masks[s as usize])) as u64;

        let mut b = 0;
        size = 0;

        loop {
            occupancy[size] = b;
            reference[size] = sliding_attack(deltas, s, b);
            size += 1;
            b = (b - masks[s as usize]) * masks[s as usize];
            if b == 0 {
                break;
            }
        }

        if s < 63 {
            unsafe {
                attacks[s as usize + 1] = std::slice::from_raw_parts_mut(
                    attacks[s as usize].as_mut_ptr().offset(size as isize),4000);
//                attacks[s as usize] = slice::from_raw_parts(attacks[s as usize], size);
            }

//            attacks[s as usize + 1] = attacks[s as usize] + size as u64;
//            https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html
        }

        let mut rng = PRNG::init(seeds[1][rank_of(s) as usize]);

        'outer: loop {
            'first_in: loop {
                magics[s as usize] = rng.sparse_rand();
                if popcount64((magics[s as usize] * masks[s as usize]) >> 56) < 6 {
                    break 'first_in;
                }
            }
            // magic_index return unsigned(((occupied & Masks[s]) * Magics[s]) >> Shifts[s]);
            current += 1;
            let mut i: usize = 0;
            'secon_in: while i < size {
                let index: usize = (((occupancy[i as usize] & masks[s as usize]) * magics[s as usize]) >> shifts[s as usize]) as usize;
                if age[index] < current {
                    age[index] = current;
                    attacks[s as usize][index] = reference[i];
                } else if attacks[s as usize][index as usize] != reference[i] {
                    break 'secon_in;
                }
            }
            if i < size {
                break 'outer;
            }
        }
    }
}
// https://bluss.github.io/rust-ndarray/master/ndarray/struct.ArrayBase.html

//struct TableAttacks {
//    table: [u64],
//    attacks:
//}

struct PRNG {
    seed: u64
}

impl PRNG {
    pub fn init(s: u64) -> PRNG {
        assert_ne!(s,0);
        PRNG {seed: s}
    }

    pub fn rand(&mut self) -> u64 {
        self.rand_change()
    }

    pub fn sparse_rand(&mut self) -> u64 {
        let mut s = self.rand_change();
        s ^= self.rand_change();
        s ^= self.rand_change();
        s
    }

    fn rand_change(&mut self) -> u64 {
        self.seed ^= self.seed >> 12;
        self.seed ^= self.seed << 25;
        self.seed ^= self.seed >> 27;

        self.seed * 2685821657736338717
    }
}

fn sliding_attack(deltas: [u64; 4], square: u64, occupied: u64) -> u64 {
    let mut attack: u64 = 0;

    for i in 0..4 {
        let mut s: u64 = square + deltas[i];
        while is_ok(s) &&  distance(s, s - deltas[i]) == 1 {

            if occupied & s == 0 { break;}
            s += deltas[i];
        }
    }
    attack
}

pub fn gen_rook_masks() {
    let mut arr_masks: [u64; 64] = [0; 64];
    let mut shifts: [u8; 64] = [0; 64];

    let mut bit_ref: usize = 0;
    while bit_ref < 64 {
        let mut mask: u64 = 0;
        let mut i = bit_ref + 8;
        while i < 56 {
            mask |= (1 as u64) << (i as u8);
            i += 8;
        }
        if bit_ref > 7 {
            let mut i = bit_ref - 8;
            while i > 7 {
                mask |= (1 as u64) << (i as u8);
                i -= 8;
            }
        }
        let mut i = bit_ref + 1;
        while i % 8 != 0 && i <= 63 {
            mask |= (1 as u64) << (i as u8);
            i += 1;
        }
        if bit_ref > 0  {
            let mut i = bit_ref - 1;
            while i % 8 != 0 && i >= 0 {
                mask |= (1 as u64) << (i as u8);
                i -= 1;
            }
        }
        arr_masks[bit_ref] = mask;
        format_bits(format!("{:b}",mask));
        bit_ref += 1;
    }
}

pub fn gen_bishop_masks() {
    let mut arr_masks: [u64; 64] = [0; 64];
    let mut shifts: [u8; 64] = [0; 64];

    let mut bitRef: i32 = 0;
    while bitRef < 64 {
        let mut mask: u64 = 0;

        let mut i = bitRef + 9;
        while i < 56 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i += 9;
        }
        let mut i = bitRef - 9;
        while i > 7 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i -= 9;
        }
        let mut i = bitRef + 7;
        while i < 56 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i += 7;
        }

        let mut i = bitRef - 7;
        while i > 7 && i % 8 != 0 && i % 8 != 7 {
            mask |= (1 as u64) << (i as u8);
            i -= 7;
        }
        format_bits(format!("{:b}",mask));
        arr_masks[bitRef as usize] = mask;
        bitRef += 1;
    }
}

pub fn format_bits(bits: String) {
    let x = 64 - bits.len();
    let mut i = 0;
    while i < x {
        print!("0");
        i += 1;
    }
    println!("{}",bits);
}

#[test]
fn test_king_mask_gen() {
    let arr = gen_king_moves().to_vec();
    let sum = arr.iter().fold(0 as  u64,|a, &b| a + (popcount64(b) as u64));
    assert_eq!(sum, (3*4) + (5 * 6 * 4) + (8 * 6 * 6));
}

#[test]
fn test_knight_mask_gen() {
    let arr = gen_knight_moves().to_vec();
    let sum = arr.iter().fold(0 as  u64,|a, &b| a + (popcount64(b) as u64));
    assert_eq!(sum, (2 * 4) + (4 * 4) + (3 * 2 * 4) + (4 * 4 * 4) + (6 * 4 * 4) + (8 * 4 * 4));
}
<|endoftext|>


<commit_before>//! `signal()` is special on Linux and macOS that it's only supported within libstd.
// ignore-windows: No libc on Windows
#![feature(rustc_private)]

extern crate libc;

fn main() {
    unsafe {
        libc::signal(libc::SIGPIPE, libc::SIG_IGN);
        //~^ ERROR unsupported operation: can't call foreign function: signal
    }
}
<commit_msg>expand comment<commit_after>//! `signal()` is special on Linux and macOS that it's only supported within libstd.
//! The implementation is not complete enough to permit user code to call it.
// ignore-windows: No libc on Windows
#![feature(rustc_private)]

extern crate libc;

fn main() {
    unsafe {
        libc::signal(libc::SIGPIPE, libc::SIG_IGN);
        //~^ ERROR unsupported operation: can't call foreign function: signal
    }
}
<|endoftext|>


<commit_before>use serde_json;
use sputnikvm;

use sputnikvm::{read_hex, Gas, M256, Address};
use sputnikvm::vm::{VM, Machine, Stack, PC};

use super::json::{create_machine, create_block, test_machine, apply_to_block, fire_with_block};

use serde_json::{Value, Error};
use std::fs::File;
use std::path::Path;
use std::io::{BufReader, Write, stdout};
use std::str::FromStr;

use rustyline::error::ReadlineError;
use rustyline::Editor;

pub fn test_transaction(name: &str, v: &Value, debug: bool) -> bool {
    print!("Testing {} ... ", name);
    if debug {
        print!("\n");
    }
    stdout().flush();

    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let result = fire_with_block(&mut machine, &block);
    apply_to_block(&machine, &mut block);

    let out = v["out"].as_str();

    if out.is_some() {
        if result.is_ok() {
            if test_machine(v, &machine, &block, debug) {
                println!("OK");
                return true;
            } else {
                println!("Failed (result not match)");
                return false;
            }
        } else {
            println!("Failed {:?}", result.err().unwrap());
            return false;
        }
    } else {
        if result.is_err() {
            println!("OK");
            return true;
        } else {
            println!("Failed");
            return false;
        }
    }
}

pub fn debug_transaction(v: &Value) {
    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let owner = machine.context().address;
    machine.commit_account(block.request_account(owner));
    let mut rl = Editor::<()>::new();

    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                match line.as_ref() {
                    "step" => {
                        if machine.pc().stopped() {
                            println!("Stopped");
                        } else {
                            println!("Running {:?} ... {:?}.", machine.pc().peek_opcode(),
                                     machine.step());
                        }
                    },
                    "fire" => {
                        let result = machine.fire();
                        println!("{:?}", result);
                    },
                    "fire debug" => {
                        while !machine.pc().stopped() {
                            println!("Running {:?} ...", machine.pc().peek_opcode());
                            let gas = machine.peek_cost().unwrap();
                            if gas < Gas::from(u64::max_value()) {
                                let gas: u64 = gas.into();
                                println!("Cost: {}", gas);
                            } else {
                                println!("Cost: 0x{:x}", gas);
                            }
                            for i in 0..machine.stack().len() {
                                println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                            }
                            println!("Result: {:?}", machine.step());
                            print!("\n");
                        }
                    },
                    "gas" => {
                        let gas = machine.peek_cost();
                        if gas.is_ok() {
                            println!("0x{:x}", gas.unwrap());
                        } else {
                            println!("{:?}", gas);
                        }
                    }
                    "out" => {
                        let ret = machine.return_values();
                        println!("{:?}", ret);
                    }
                    "print stack" => {
                        for i in 0..machine.stack().len() {
                            println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                        }
                    },
                    _ => {
                        println!("Unknown command.");
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
    }
}
<commit_msg>Problem: fire debug does not handle multiple accounts Solution: a partial implementation for RequireAccount<commit_after>use serde_json;
use sputnikvm;

use sputnikvm::{read_hex, Gas, M256, Address};
use sputnikvm::vm::{VM, Machine, Stack, PC, ExecutionError};

use super::json::{create_machine, create_block, test_machine, apply_to_block, fire_with_block};

use serde_json::{Value, Error};
use std::fs::File;
use std::path::Path;
use std::io::{BufReader, Write, stdout};
use std::str::FromStr;

use rustyline::error::ReadlineError;
use rustyline::Editor;

pub fn test_transaction(name: &str, v: &Value, debug: bool) -> bool {
    print!("Testing {} ... ", name);
    if debug {
        print!("\n");
    }
    stdout().flush();

    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let result = fire_with_block(&mut machine, &block);
    apply_to_block(&machine, &mut block);

    let out = v["out"].as_str();

    if out.is_some() {
        if result.is_ok() {
            if test_machine(v, &machine, &block, debug) {
                println!("OK");
                return true;
            } else {
                println!("Failed (result not match)");
                return false;
            }
        } else {
            println!("Failed {:?}", result.err().unwrap());
            return false;
        }
    } else {
        if result.is_err() {
            println!("OK");
            return true;
        } else {
            println!("Failed");
            return false;
        }
    }
}

pub fn debug_transaction(v: &Value) {
    let mut block = create_block(v);
    let mut machine = create_machine(v, &block);
    let owner = machine.context().address;
    machine.commit_account(block.request_account(owner));
    let mut rl = Editor::<()>::new();

    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                match line.as_ref() {
                    "step" => {
                        if machine.pc().stopped() {
                            println!("Stopped");
                        } else {
                            println!("Running {:?} ... {:?}.", machine.pc().peek_opcode(),
                                     machine.step());
                        }
                    },
                    "fire" => {
                        let result = machine.fire();
                        println!("{:?}", result);
                    },
                    "fire debug" => {
                        while !machine.pc().stopped() {
                            println!("Running {:?} ...", machine.pc().peek_opcode());
                            let gas = match machine.peek_cost() {
                                Ok(gas) => gas,
                                Err(ExecutionError::RequireAccount(address)) => {
                                    machine.commit_account(block.request_account(owner));
                                    machine.peek_cost().unwrap()
                                },
                                _ => unimplemented!(),
                            };
                            if gas < Gas::from(u64::max_value()) {
                                let gas: u64 = gas.into();
                                println!("Cost: {}", gas);
                            } else {
                                println!("Cost: 0x{:x}", gas);
                            }
                            for i in 0..machine.stack().len() {
                                println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                            }
                            println!("Result: {:?}", machine.step());
                            print!("\n");
                        }
                    },
                    "gas" => {
                        let gas = machine.peek_cost();
                        if gas.is_ok() {
                            println!("0x{:x}", gas.unwrap());
                        } else {
                            println!("{:?}", gas);
                        }
                    }
                    "out" => {
                        let ret = machine.return_values();
                        println!("{:?}", ret);
                    }
                    "print stack" => {
                        for i in 0..machine.stack().len() {
                            println!("{}: {:x}", i, machine.stack().peek(i).unwrap());
                        }
                    },
                    _ => {
                        println!("Unknown command.");
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::io::Write;
use hyper::header::{ContentLength, ContentType};
use hyper::server::Response;
use hyper::status::StatusCode;
// use hyper::uri::RequestUri;

pub trait MakeResponse {
    fn status(&self) -> StatusCode {
        StatusCode::Ok
    }

    fn content_type(&self) -> ContentType {
        ContentType::plaintext()
    }

    fn content_length(&self) -> ContentLength {
        ContentLength(0)
    }

    fn content(&self) -> &[u8] {
        &[]
    }

    fn make_response(&self, mut response: Response) {
        *response.status_mut() = self.status();
        response.headers_mut().set(self.content_type());
        response.headers_mut().set(self.content_length());
        response.start().unwrap().write(self.content()).unwrap();
    }
}

impl MakeResponse for StatusCode {
    fn status(&self) -> StatusCode {
        *self
    }
}

pub struct Html(pub String);

impl MakeResponse for Html {
    fn content_type(&self) -> ContentType {
        ContentType::html()
    }

    fn content_length(&self) -> ContentLength {
        ContentLength(self.0.as_bytes().len() as u64)
    }

    fn content(&self) -> &[u8] {
        self.0.as_bytes()
    }
}

impl MakeResponse for String {
    fn content_type(&self) -> ContentType {
        ContentType::plaintext()
    }

    fn content_length(&self) -> ContentLength {
        ContentLength(self.as_bytes().len() as u64)
    }

    fn content(&self) -> &[u8] {
        self.as_bytes()
    }
}
<commit_msg>Use Response::send()<commit_after>use std::io::Write;
use hyper::header::{ContentLength, ContentType};
use hyper::server::Response;
use hyper::status::StatusCode;
// use hyper::uri::RequestUri;

pub trait MakeResponse {
    fn status(&self) -> StatusCode {
        StatusCode::Ok
    }

    fn content_type(&self) -> ContentType {
        ContentType::plaintext()
    }

    fn content_length(&self) -> ContentLength {
        ContentLength(0)
    }

    fn content(&self) -> &[u8] {
        &[]
    }

    fn make_response(&self, mut response: Response) {
        *response.status_mut() = self.status();
        response.headers_mut().set(self.content_type());
        response.send(self.content()).unwrap();
        // response.headers_mut().set(self.content_length());
        // response.start().unwrap().write(self.content()).unwrap();
    }
}

impl MakeResponse for StatusCode {
    fn status(&self) -> StatusCode {
        *self
    }
}

pub struct Html(pub String);

impl MakeResponse for Html {
    fn content_type(&self) -> ContentType {
        ContentType::html()
    }

    fn content_length(&self) -> ContentLength {
        ContentLength(self.0.as_bytes().len() as u64)
    }

    fn content(&self) -> &[u8] {
        self.0.as_bytes()
    }
}

impl MakeResponse for String {
    fn content_type(&self) -> ContentType {
        ContentType::plaintext()
    }

    fn content_length(&self) -> ContentLength {
        ContentLength(self.as_bytes().len() as u64)
    }

    fn content(&self) -> &[u8] {
        self.as_bytes()
    }
}
<|endoftext|>


<commit_before>use std::collections::{ HashSet, HashMap };
use std::sync::RwLock;
use super::blake2::blake2b::blake2b;
use super::{
    ClientDB,
    DBValue,
    DBError
};

type DBHashMap = HashMap<Vec<u8>, Vec<u8>>;
type ColumnHashSet = HashSet<String>;

/// An in-memory database implementing the ClientDB trait.
///
/// It is not particularily optimized, it exists for ease and speed of testing. It's not expected
/// this DB would be used outside of tests.
pub struct MemoryDB {
    db: RwLock<DBHashMap>,
    known_columns: RwLock<ColumnHashSet>
}

impl MemoryDB {
    /// Open the in-memory database.
    ///
    /// All columns must be supplied initially, you will get an error if you try to access a column
    /// that was not declared here. This condition is enforced artificially to simulate RocksDB.
    pub fn open(columns: Option<&[&str]>) -> Self {
        let db: DBHashMap = HashMap::new();
        let mut known_columns: ColumnHashSet = HashSet::new();
        if let Some(columns) = columns {
            for col in columns {
                known_columns.insert(col.to_string());
            }
        }
        Self {
            db: RwLock::new(db),
            known_columns: RwLock::new(known_columns),
        }
    }

    /// Hashes a key and a column name in order to get a unique key for the supplied column.
    fn get_key_for_col(col: &str, key: &[u8]) -> Vec<u8> {
        blake2b(32, col.as_bytes(), key).as_bytes().to_vec()
    }
}

impl ClientDB for MemoryDB {
    /// Get the value of some key from the database. Returns `None` if the key does not exist.
    fn get(&self, col: &str, key: &[u8])
        -> Result<Option<DBValue>, DBError>
    {
        // Panic if the DB locks are poisoned.
        let db = self.db.read().unwrap();
        let known_columns = self.known_columns.read().unwrap();

        match known_columns.contains(&col.to_string()) {
            false => Err(DBError{ message: "Unknown column".to_string() }),
            true => {
                let column_key = MemoryDB::get_key_for_col(col, key);
                Ok(db.get(&column_key).and_then(|val| Some(val.clone())))
            }
        }
    }

    /// Puts a key in the database.
    fn put(&self, col: &str, key: &[u8], val: &[u8])
        -> Result<(), DBError>
    {
        // Panic if the DB locks are poisoned.
        let mut db = self.db.write().unwrap();
        let known_columns = self.known_columns.read().unwrap();

        match known_columns.contains(&col.to_string()) {
            false => Err(DBError{ message: "Unknown column".to_string() }),
            true => {
                let column_key = MemoryDB::get_key_for_col(col, key);
                db.insert(column_key, val.to_vec());
                Ok(())
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::ClientDB;
    use std::thread;
    use std::sync::Arc;

    #[test]
    fn test_memorydb_column_access() {
        let col_a: &str = "ColumnA";
        let col_b: &str = "ColumnB";

        let column_families = vec![
            col_a,
            col_b,
        ];

        let db = MemoryDB::open(Some(&column_families));

        /*
         * Testing that if we write to the same key in different columns that
         * there is not an overlap.
         */
        db.put(col_a, "same".as_bytes(), "cat".as_bytes()).unwrap();
        db.put(col_b, "same".as_bytes(), "dog".as_bytes()).unwrap();

        assert_eq!(db.get(col_a, "same".as_bytes()).unwrap().unwrap(), "cat".as_bytes());
        assert_eq!(db.get(col_b, "same".as_bytes()).unwrap().unwrap(), "dog".as_bytes());

    }

    #[test]
    fn test_memorydb_unknown_column_access() {
        let col_a: &str = "ColumnA";
        let col_x: &str = "ColumnX";

        let column_families = vec![
            col_a,
            // col_x is excluded on purpose
        ];

        let db = MemoryDB::open(Some(&column_families));

        /*
         * Test that we get errors when using undeclared columns
         */
        assert!(db.put(col_a, "cats".as_bytes(), "lol".as_bytes()).is_ok());
        assert!(db.put(col_x, "cats".as_bytes(), "lol".as_bytes()).is_err());

        assert!(db.get(col_a, "cats".as_bytes()).is_ok());
        assert!(db.get(col_x, "cats".as_bytes()).is_err());
    }

    #[test]
    fn test_memorydb_threading() {
        let col_name: &str = "TestColumn";
        let column_families = vec![col_name];

        let db = Arc::new(MemoryDB::open(Some(&column_families)));

        let thread_count = 10;
        let write_count = 10;

        // We're execting the product of these numbers to fit in one byte.
        assert!(thread_count * write_count <= 255);

        let mut handles = vec![];
        for t in 0..thread_count {
            let wc = write_count;
            let db = db.clone();
            let col = col_name.clone();
            let handle = thread::spawn(move || {
                for w in 0..wc {
                    let key = (t * w) as u8;
                    let val = 42;
                    db.put(&col, &vec![key], &vec![val]).unwrap();
                }
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.join().unwrap();
        }

        for t in 0..thread_count {
            for w in 0..write_count {
                let key = (t * w) as u8;
                let val = db.get(&col_name, &vec![key]).unwrap().unwrap();
                assert_eq!(vec![42], val);
            }
        }
    }
}
<commit_msg>Add `exists()` function for MemoryDB<commit_after>use std::collections::{ HashSet, HashMap };
use std::sync::RwLock;
use super::blake2::blake2b::blake2b;
use super::{
    ClientDB,
    DBValue,
    DBError
};

type DBHashMap = HashMap<Vec<u8>, Vec<u8>>;
type ColumnHashSet = HashSet<String>;

/// An in-memory database implementing the ClientDB trait.
///
/// It is not particularily optimized, it exists for ease and speed of testing. It's not expected
/// this DB would be used outside of tests.
pub struct MemoryDB {
    db: RwLock<DBHashMap>,
    known_columns: RwLock<ColumnHashSet>
}

impl MemoryDB {
    /// Open the in-memory database.
    ///
    /// All columns must be supplied initially, you will get an error if you try to access a column
    /// that was not declared here. This condition is enforced artificially to simulate RocksDB.
    pub fn open(columns: Option<&[&str]>) -> Self {
        let db: DBHashMap = HashMap::new();
        let mut known_columns: ColumnHashSet = HashSet::new();
        if let Some(columns) = columns {
            for col in columns {
                known_columns.insert(col.to_string());
            }
        }
        Self {
            db: RwLock::new(db),
            known_columns: RwLock::new(known_columns),
        }
    }

    /// Hashes a key and a column name in order to get a unique key for the supplied column.
    fn get_key_for_col(col: &str, key: &[u8]) -> Vec<u8> {
        blake2b(32, col.as_bytes(), key).as_bytes().to_vec()
    }
}

impl ClientDB for MemoryDB {
    /// Get the value of some key from the database. Returns `None` if the key does not exist.
    fn get(&self, col: &str, key: &[u8])
        -> Result<Option<DBValue>, DBError>
    {
        // Panic if the DB locks are poisoned.
        let db = self.db.read().unwrap();
        let known_columns = self.known_columns.read().unwrap();

        match known_columns.contains(&col.to_string()) {
            false => Err(DBError{ message: "Unknown column".to_string() }),
            true => {
                let column_key = MemoryDB::get_key_for_col(col, key);
                Ok(db.get(&column_key).and_then(|val| Some(val.clone())))
            }
        }
    }

    /// Puts a key in the database.
    fn put(&self, col: &str, key: &[u8], val: &[u8])
        -> Result<(), DBError>
    {
        // Panic if the DB locks are poisoned.
        let mut db = self.db.write().unwrap();
        let known_columns = self.known_columns.read().unwrap();

        match known_columns.contains(&col.to_string()) {
            false => Err(DBError{ message: "Unknown column".to_string() }),
            true => {
                let column_key = MemoryDB::get_key_for_col(col, key);
                db.insert(column_key, val.to_vec());
                Ok(())
            }
        }
    }

    /// Return true if some key exists in some column.
    fn exists(&self, col: &str, key: &[u8])
        -> Result<bool, DBError>
    {
        // Panic if the DB locks are poisoned.
        let db = self.db.read().unwrap();
        let known_columns = self.known_columns.read().unwrap();

        match known_columns.contains(&col.to_string()) {
            false => Err(DBError{ message: "Unknown column".to_string() }),
            true => {
                let column_key = MemoryDB::get_key_for_col(col, key);
                Ok(db.contains_key(&column_key))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::ClientDB;
    use std::thread;
    use std::sync::Arc;

    #[test]
    fn test_memorydb_column_access() {
        let col_a: &str = "ColumnA";
        let col_b: &str = "ColumnB";

        let column_families = vec![
            col_a,
            col_b,
        ];

        let db = MemoryDB::open(Some(&column_families));

        /*
         * Testing that if we write to the same key in different columns that
         * there is not an overlap.
         */
        db.put(col_a, "same".as_bytes(), "cat".as_bytes()).unwrap();
        db.put(col_b, "same".as_bytes(), "dog".as_bytes()).unwrap();

        assert_eq!(db.get(col_a, "same".as_bytes()).unwrap().unwrap(), "cat".as_bytes());
        assert_eq!(db.get(col_b, "same".as_bytes()).unwrap().unwrap(), "dog".as_bytes());

    }

    #[test]
    fn test_memorydb_unknown_column_access() {
        let col_a: &str = "ColumnA";
        let col_x: &str = "ColumnX";

        let column_families = vec![
            col_a,
            // col_x is excluded on purpose
        ];

        let db = MemoryDB::open(Some(&column_families));

        /*
         * Test that we get errors when using undeclared columns
         */
        assert!(db.put(col_a, "cats".as_bytes(), "lol".as_bytes()).is_ok());
        assert!(db.put(col_x, "cats".as_bytes(), "lol".as_bytes()).is_err());

        assert!(db.get(col_a, "cats".as_bytes()).is_ok());
        assert!(db.get(col_x, "cats".as_bytes()).is_err());
    }

    #[test]
    fn test_memorydb_exists() {
        let col_a: &str = "ColumnA";
        let col_b: &str = "ColumnB";

        let column_families = vec![
            col_a,
            col_b,
        ];

        let db = MemoryDB::open(Some(&column_families));

        /*
         * Testing that if we write to the same key in different columns that
         * there is not an overlap.
         */
        db.put(col_a, "cats".as_bytes(), "lol".as_bytes()).unwrap();

        assert_eq!(true, db.exists(col_a, "cats".as_bytes()).unwrap());
        assert_eq!(false, db.exists(col_b, "cats".as_bytes()).unwrap());

        assert_eq!(false, db.exists(col_a, "dogs".as_bytes()).unwrap());
        assert_eq!(false, db.exists(col_b, "dogs".as_bytes()).unwrap());
    }

    #[test]
    fn test_memorydb_threading() {
        let col_name: &str = "TestColumn";
        let column_families = vec![col_name];

        let db = Arc::new(MemoryDB::open(Some(&column_families)));

        let thread_count = 10;
        let write_count = 10;

        // We're execting the product of these numbers to fit in one byte.
        assert!(thread_count * write_count <= 255);

        let mut handles = vec![];
        for t in 0..thread_count {
            let wc = write_count;
            let db = db.clone();
            let col = col_name.clone();
            let handle = thread::spawn(move || {
                for w in 0..wc {
                    let key = (t * w) as u8;
                    let val = 42;
                    db.put(&col, &vec![key], &vec![val]).unwrap();
                }
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.join().unwrap();
        }

        for t in 0..thread_count {
            for w in 0..write_count {
                let key = (t * w) as u8;
                let val = db.get(&col_name, &vec![key]).unwrap().unwrap();
                assert_eq!(vec![42], val);
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate phf;

use glib_sys;
use glib::translate::*;
use libc;
use std::str::FromStr;

use util::utf8_cstr;

include!(concat!(env!("OUT_DIR"), "/attributes-codegen.rs"));

impl FromStr for Attribute {
    type Err = ();

    fn from_str(s: &str) -> Result<Attribute, ()> {
        ATTRIBUTES.get(s).cloned().ok_or(())
    }
}

#[no_mangle]
pub extern fn rsvg_attribute_from_name(raw_name: *const libc::c_char,
                                       out_attr: *mut Attribute) -> glib_sys::gboolean {
    let name = unsafe { utf8_cstr(raw_name) };

    match Attribute::from_str(name) {
        Ok(a) => {
            unsafe { *out_attr = a; }
            true.to_glib()
        },

        Err(_) => {
            false.to_glib()
        }
    }
}

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

    #[test]
    fn parses_attributes() {
        assert_eq!(Attribute::from_str("width"), Ok(Attribute::Width));
    }

    #[test]
    fn unknown_attribute_yields_error() {
        assert_eq!(Attribute::from_str("foobar"), Err(()));
    }

    #[test]
    fn c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("width".as_ptr() as *const libc::c_char,
                                                           &mut a as *mut Attribute));
        assert!(res);
        assert_eq!(a, Attribute::Width);
    }

    #[test]
    fn invalid_c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("foobar".as_ptr() as *const libc::c_char,
                                                           &mut a as *mut Attribute));
        assert!(!res);
    }
}
<commit_msg>Sigh, pass C strings properly<commit_after>extern crate phf;

use glib_sys;
use glib::translate::*;
use libc;
use std::str::FromStr;

use util::utf8_cstr;

include!(concat!(env!("OUT_DIR"), "/attributes-codegen.rs"));

impl FromStr for Attribute {
    type Err = ();

    fn from_str(s: &str) -> Result<Attribute, ()> {
        ATTRIBUTES.get(s).cloned().ok_or(())
    }
}

#[no_mangle]
pub extern fn rsvg_attribute_from_name(raw_name: *const libc::c_char,
                                       out_attr: *mut Attribute) -> glib_sys::gboolean {
    let name = unsafe { utf8_cstr(raw_name) };

    match Attribute::from_str(name) {
        Ok(a) => {
            unsafe { *out_attr = a; }
            true.to_glib()
        },

        Err(_) => {
            false.to_glib()
        }
    }
}

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

    #[test]
    fn parses_attributes() {
        assert_eq!(Attribute::from_str("width"), Ok(Attribute::Width));
    }

    #[test]
    fn unknown_attribute_yields_error() {
        assert_eq!(Attribute::from_str("foobar"), Err(()));
    }

    #[test]
    fn c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("width".to_glib_none().0,
                                                           &mut a as *mut Attribute));
        assert!(res);
        assert_eq!(a, Attribute::Width);
    }

    #[test]
    fn invalid_c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("foobar".to_glib_none().0,
                                                           &mut a as *mut Attribute));
        assert!(!res);
    }
}
<|endoftext|>


<commit_before>extern crate yoga_wrapper;

use yoga_wrapper as yoga;

fn main() {
    let mut root = yoga::Node::new();
    root.set_width(500.0);
    root.set_height(120.0);
    root.set_flex_direction(yoga::FlexDirection::Row);
    root.set_padding(yoga::Edge::All, 20.0);

    let mut image = yoga::Node::new();
    image.set_width(80.0);
    image.set_margin(yoga::Edge::End, 20.0);

    let mut text = yoga::Node::new();
    text.set_height(25.0);
    text.set_align_self(yoga::Align::Center);
    text.set_flex_grow(1.0);

    root.insert_child(&image, 0);
    root.insert_child(&text, 1);

    root.calculate_layout();

    println!("height: {:?}", root.get_layout_height());
    println!("width:  {:?}", root.get_layout_width());
    println!("left:   {:?}", root.get_layout_left());
    println!("top:    {:?}", root.get_layout_top());

    println!("-------------");

    println!("height: {:?}", image.get_layout_height());
    println!("width:  {:?}", image.get_layout_width());
    println!("left:   {:?}", image.get_layout_left());
    println!("top:    {:?}", image.get_layout_top());

    println!("-------------");

    println!("height: {:?}", text.get_layout_height());
    println!("width:  {:?}", text.get_layout_width());
    println!("left:   {:?}", text.get_layout_left());
    println!("top:    {:?}", text.get_layout_top());
}
<commit_msg>chore(example): update references<commit_after>extern crate yoga_wrapper;

use yoga_wrapper::{Node, FlexDirection, Edge, Align};

fn main() {
    let mut root = Node::new();
    root.set_width(500.0);
    root.set_height(120.0);
    root.set_flex_direction(FlexDirection::Row);
    root.set_padding(Edge::All, 20.0);

    let mut image = Node::new();
    image.set_width(80.0);
    image.set_margin(Edge::End, 20.0);

    let mut text = Node::new();
    text.set_height(25.0);
    text.set_align_self(Align::Center);
    text.set_flex_grow(1.0);

    root.insert_child(&image, 0);
    root.insert_child(&text, 1);

    root.calculate_layout();

    println!("height: {:?}", root.get_layout_height());
    println!("width:  {:?}", root.get_layout_width());
    println!("left:   {:?}", root.get_layout_left());
    println!("top:    {:?}", root.get_layout_top());

    println!("-------------");

    println!("height: {:?}", image.get_layout_height());
    println!("width:  {:?}", image.get_layout_width());
    println!("left:   {:?}", image.get_layout_left());
    println!("top:    {:?}", image.get_layout_top());

    println!("-------------");

    println!("height: {:?}", text.get_layout_height());
    println!("width:  {:?}", text.get_layout_width());
    println!("left:   {:?}", text.get_layout_left());
    println!("top:    {:?}", text.get_layout_top());
}
<|endoftext|>


<commit_before>// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Structured representation of a plugin's features and capabilities.

use std::env;
use std::path::PathBuf;

use syntax::SyntaxDefinition;

// optional environment variable for debug plugin executables
static PLUGIN_DIR: &'static str = "XI_PLUGIN_DIR";

// example plugins. Eventually these should be loaded from disk.
#[cfg(not(target_os = "fuchsia"))]
pub fn debug_plugins() -> Vec<PluginDescription> {
    use self::PluginActivation::*;
    use self::PluginScope::*;
    let plugin_dir = match env::var(PLUGIN_DIR).map(PathBuf::from) {
        Ok(p) => p,
        Err(_) => env::current_exe().unwrap().parent().unwrap().to_owned(),
    };
    print_err!("looking for debug plugins in {:?}", plugin_dir);

    let make_path = |p: &str| -> PathBuf {
        let mut pb = plugin_dir.clone();
        pb.push(p);
        pb
    };

    vec![
        PluginDescription::new("syntect", "0.0", BufferLocal, make_path("xi-syntect-plugin"),
        vec![Autorun]),
        PluginDescription::new("braces", "0.0", BufferLocal, make_path("bracket_example.py"),
        Vec::new()),
        PluginDescription::new("spellcheck", "0.0", BufferLocal, make_path("spellcheck.py"),
        Vec::new()),
        PluginDescription::new("shouty", "0.0", BufferLocal, make_path("shouty.py"),
        Vec::new()),
    ].iter()
        .filter(|desc|{
            if !desc.exec_path.exists() {
                print_err!("missing plugin {} at {:?}", desc.name, desc.exec_path);
                false
            } else {
                true
            }
        })
        .map(|desc| desc.to_owned())
        .collect::<Vec<_>>()
}

#[cfg(target_os = "fuchsia")]
pub fn debug_plugins() -> Vec<PluginDescription> {
    Vec::new()
}

/// Describes attributes and capabilities of a plugin.
///
/// Note: - these will eventually be loaded from manifest files.
#[derive(Debug, Clone)]
pub struct PluginDescription {
    pub name: String,
    pub version: String,
    pub scope: PluginScope,
    // more metadata ...
    /// path to plugin executable
    pub exec_path: PathBuf,
    /// Events that cause this plugin to run
    pub activations: Vec<PluginActivation>,
}

/// `PluginActivation`s represent events that trigger running a plugin.
#[derive(Debug, Clone)]
pub enum PluginActivation {
    /// Always run this plugin, when available.
    Autorun,
    /// Run this plugin if the provided SyntaxDefinition is active.
    #[allow(dead_code)]
    OnSyntax(SyntaxDefinition),
    /// Run this plugin in response to a given command.
    #[allow(dead_code)]
    OnCommand,
}

#[derive(Debug, Clone)]
/// Describes the scope of events a plugin receives.
pub enum PluginScope {
    /// The plugin receives events from multiple buffers.
    Global,
    /// The plugin receives events for a single buffer.
    BufferLocal,
    /// The plugin is launched in response to a command, and receives no
    /// further updates.
    SingleInvocation,
}

impl PluginDescription {
    fn new<S, P>(name: S, version: S, scope: PluginScope, exec_path: P,
                 activations: Vec<PluginActivation>) -> Self
        where S: Into<String>, P: Into<PathBuf>
    {
        PluginDescription {
            name: name.into(),
            scope: scope,
            version: version.into(),
            exec_path: exec_path.into(),
            activations: activations,
        }
    }

    /// Returns `true` if this plugin is globally scoped, else `false`.
    pub fn is_global(&self) -> bool {
        match self.scope {
            PluginScope::Global => true,
            _ => false,
        }
    }
}
<commit_msg>Avoid unused warnings when building on Fuchsia<commit_after>// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Structured representation of a plugin's features and capabilities.

use std::path::PathBuf;

use syntax::SyntaxDefinition;

// optional environment variable for debug plugin executables
#[cfg(not(target_os = "fuchsia"))]
static PLUGIN_DIR: &'static str = "XI_PLUGIN_DIR";

// example plugins. Eventually these should be loaded from disk.
#[cfg(not(target_os = "fuchsia"))]
pub fn debug_plugins() -> Vec<PluginDescription> {
    use std::env;
    use self::PluginActivation::*;
    use self::PluginScope::*;
    let plugin_dir = match env::var(PLUGIN_DIR).map(PathBuf::from) {
        Ok(p) => p,
        Err(_) => env::current_exe().unwrap().parent().unwrap().to_owned(),
    };
    print_err!("looking for debug plugins in {:?}", plugin_dir);

    let make_path = |p: &str| -> PathBuf {
        let mut pb = plugin_dir.clone();
        pb.push(p);
        pb
    };

    vec![
        PluginDescription::new("syntect", "0.0", BufferLocal, make_path("xi-syntect-plugin"),
        vec![Autorun]),
        PluginDescription::new("braces", "0.0", BufferLocal, make_path("bracket_example.py"),
        Vec::new()),
        PluginDescription::new("spellcheck", "0.0", BufferLocal, make_path("spellcheck.py"),
        Vec::new()),
        PluginDescription::new("shouty", "0.0", BufferLocal, make_path("shouty.py"),
        Vec::new()),
    ].iter()
        .filter(|desc|{
            if !desc.exec_path.exists() {
                print_err!("missing plugin {} at {:?}", desc.name, desc.exec_path);
                false
            } else {
                true
            }
        })
        .map(|desc| desc.to_owned())
        .collect::<Vec<_>>()
}

#[cfg(target_os = "fuchsia")]
pub fn debug_plugins() -> Vec<PluginDescription> {
    Vec::new()
}

/// Describes attributes and capabilities of a plugin.
///
/// Note: - these will eventually be loaded from manifest files.
#[derive(Debug, Clone)]
pub struct PluginDescription {
    pub name: String,
    pub version: String,
    pub scope: PluginScope,
    // more metadata ...
    /// path to plugin executable
    pub exec_path: PathBuf,
    /// Events that cause this plugin to run
    pub activations: Vec<PluginActivation>,
}

/// `PluginActivation`s represent events that trigger running a plugin.
#[derive(Debug, Clone)]
pub enum PluginActivation {
    /// Always run this plugin, when available.
    Autorun,
    /// Run this plugin if the provided SyntaxDefinition is active.
    #[allow(dead_code)]
    OnSyntax(SyntaxDefinition),
    /// Run this plugin in response to a given command.
    #[allow(dead_code)]
    OnCommand,
}

#[derive(Debug, Clone)]
/// Describes the scope of events a plugin receives.
pub enum PluginScope {
    /// The plugin receives events from multiple buffers.
    Global,
    /// The plugin receives events for a single buffer.
    BufferLocal,
    /// The plugin is launched in response to a command, and receives no
    /// further updates.
    SingleInvocation,
}

#[cfg(not(target_os = "fuchsia"))]
impl PluginDescription {
    fn new<S, P>(name: S, version: S, scope: PluginScope, exec_path: P,
                 activations: Vec<PluginActivation>) -> Self
        where S: Into<String>, P: Into<PathBuf>
    {
        PluginDescription {
            name: name.into(),
            scope: scope,
            version: version.into(),
            exec_path: exec_path.into(),
            activations: activations,
        }
    }

    /// Returns `true` if this plugin is globally scoped, else `false`.
    pub fn is_global(&self) -> bool {
        match self.scope {
            PluginScope::Global => true,
            _ => false,
        }
    }
}
<|endoftext|>