<commit_before>pub type c_char = i8;
pub type c_long = i64;
pub type c_ulong = u64;

pub type wchar_t = i16;

pub type off_t = usize;
pub type mode_t = u16;
pub type time_t = i64;
pub type pid_t = usize;
pub type gid_t = usize;
pub type uid_t = usize;

pub type in_addr_t = u32;
pub type in_port_t = u16;

pub type socklen_t = u32;
pub type sa_family_t = u16;

s! {
    pub struct in_addr {
        pub s_addr: in_addr_t,
    }

    pub struct in6_addr {
        pub s6_addr: [u8; 16],
        __align: [u32; 0],
    }

    pub struct sockaddr {
        pub sa_family: sa_family_t,
        pub sa_data: [::c_char; 14],
    }

    pub struct sockaddr_in {
        pub sin_family: sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
        pub sin_zero: [u8; 8],
    }

    pub struct sockaddr_in6 {
        pub sin6_family: sa_family_t,
        pub sin6_port: in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }
}

extern {
    pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void;
}

#[link(name = "c", kind = "static")]
#[link(name = "m", kind = "static")]
extern {}
<commit_msg>Remove kind='static'<commit_after>pub type c_char = i8;
pub type c_long = i64;
pub type c_ulong = u64;

pub type wchar_t = i16;

pub type off_t = usize;
pub type mode_t = u16;
pub type time_t = i64;
pub type pid_t = usize;
pub type gid_t = usize;
pub type uid_t = usize;

pub type in_addr_t = u32;
pub type in_port_t = u16;

pub type socklen_t = u32;
pub type sa_family_t = u16;

s! {
    pub struct in_addr {
        pub s_addr: in_addr_t,
    }

    pub struct in6_addr {
        pub s6_addr: [u8; 16],
        __align: [u32; 0],
    }

    pub struct sockaddr {
        pub sa_family: sa_family_t,
        pub sa_data: [::c_char; 14],
    }

    pub struct sockaddr_in {
        pub sin_family: sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
        pub sin_zero: [u8; 8],
    }

    pub struct sockaddr_in6 {
        pub sin6_family: sa_family_t,
        pub sin6_port: in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }
}

extern {
    pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void;
}

#[link(name = "c")]
#[link(name = "m")]
extern {}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Rot-13

fn rot13 (string: &str) -> String {
    fn rot13u8 (c: char) -> char {
        let d = c as u8;
        match c {
            'a' .. 'm'
            | 'A' .. 'M' => (d + 13) as char,
            'n' .. 'z'
            | 'N' .. 'Z' => (d - 13) as char,
            _ => c
        }
    }

    string.chars().map(rot13u8).collect::<String>()
}

#[cfg(not(test))]
fn main () {
    let string = "Do you love apples?";

    println!("Original: {}", string);
    println!("Encoded: {}", rot13(string));
}

#[test]
fn test_basic() {
    assert_eq!(rot13("abc").as_slice(), "nop");
}

#[test]
fn test_coherence() {
    assert!(range(50000, 50050).map(|x| format!("{}", x)).all(|s| {
        let encoded = rot13(s.as_slice());
        let decoded = rot13(encoded.as_slice());
        decoded == s
    }));
}
<commit_msg>Remove unnecessary type annotation. `rustc` can figure it out itself.<commit_after>// Implements http://rosettacode.org/wiki/Rot-13

fn rot13 (string: &str) -> String {
    fn rot13u8 (c: char) -> char {
        let d = c as u8;
        match c {
            'a' .. 'm'
            | 'A' .. 'M' => (d + 13) as char,
            'n' .. 'z'
            | 'N' .. 'Z' => (d - 13) as char,
            _ => c
        }
    }

    string.chars().map(rot13u8).collect()
}

#[cfg(not(test))]
fn main () {
    let string = "Do you love apples?";

    println!("Original: {}", string);
    println!("Encoded: {}", rot13(string));
}

#[test]
fn test_basic() {
    assert_eq!(rot13("abc").as_slice(), "nop");
}

#[test]
fn test_coherence() {
    assert!(range(50000, 50050).map(|x| format!("{}", x)).all(|s| {
        let encoded = rot13(s.as_slice());
        let decoded = rot13(encoded.as_slice());
        decoded == s
    }));
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016
 * Jeff Nettleton
 *
 * Licensed under the MIT license (http://opensource.org/licenses/MIT). This
 * file may not be copied, modified, or distributed except according to those
 * terms
 */

extern crate regex;

use std::collections::HashMap;
use regex::Regex;

use request::*;
use response::*;

// The various types of parameters that can be contained in a URI.
#[derive(PartialEq, Eq, Hash, Debug)]
enum ParamType {
    Integer,
    Unsigned,
    String,
    Float,
    Path,
}

/// This struct represents a route definition. It is only necessary for
/// use internally.
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub struct RouteDef {
    pub pathdef: String,
    pub method:  Method,
}

/// This struct defines a route or endpoint.
pub struct Route {
    matcher:     Regex,
    method:      Method,
    params:      HashMap<String, ParamType>,
    pub handler: fn(&Request) -> Response,
}

impl Route {
    /// Create a new Route. This function is called by the Canteen struct.
    pub fn new(path: &str, method: Method, handler: fn(&Request) -> Response) -> Route {
        let re = Regex::new(r"^<(?:(int|uint|str|float|path):)?([\w_][a-zA-Z0-9_]*)>$").unwrap();
        let parts: Vec<&str> = path.split('/').filter(|&s| s != "").collect();
        let mut matcher: String = String::from(r"^");
        let mut params: HashMap<String, ParamType> = HashMap::new();

        for part in parts {
            let chunk: String = match re.is_match(part) {
                true  => {
                    let caps = re.captures(part).unwrap();
                    let param = caps.get(2).unwrap().as_str();
                    let ptype: ParamType = match caps.get(1) {
                        Some(x)     => {
                            match x.as_str() {
                                "int"   => ParamType::Integer,
                                "uint"  => ParamType::Unsigned,
                                "float" => ParamType::Float,
                                "path"  => ParamType::Path,
                                "str"   => ParamType::String,
                                _       => ParamType::String,

                            }
                        }
                        None        => ParamType::String,
                    };

                    let mstr: String = match ptype {
                        ParamType::String   => String::from(r"(?:[^/])+"),
                        ParamType::Integer  => String::from(r"-*[0-9]+"),
                        ParamType::Unsigned => String::from(r"[0-9]+"),
                        ParamType::Float    => String::from(r"-*[0-9]*[.]?[0-9]+"),
                        ParamType::Path     => String::from(r".+"),
                    };

                    params.insert(String::from(param), ptype);

                    format!("/(?P<{}>{})", &param, &mstr)
                },
                false => String::from("/") + part,
            };

            matcher.push_str(&chunk);
        }

        /* end the regex with an optional final slash and a string terminator */
        matcher.push_str("/?$");

        Route {
            matcher: Regex::new(&matcher).unwrap(),
            params:  params,
            method:  method,
            handler: handler,
        }
    }

    /// Check if this Route matches a given URI.
    pub fn is_match(&self, req: &Request) -> bool {
        self.matcher.is_match(&req.path) && self.method == req.method
    }

    /// Parse and extract the variables from a URI based on this Route's definition.
    pub fn parse(&self, path: &str) -> HashMap<String, String> {
        let mut params: HashMap<String, String> = HashMap::new();

        if self.matcher.is_match(&path) {
            let caps = self.matcher.captures(path).unwrap();
            for (param, _) in &self.params {
                params.insert(param.clone(), String::from(caps.name(&param).unwrap().as_str()));
            }
        }

        params
    }
}

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

    #[test]
    fn test_route_match_fail() {
        let rt = Route::new("/api/v1/foo/<int:foo_id>", Method::Get, utils::err_404);
        let mut req = Request::new();

        req.path = String::from("/api/v1/bar");
        req.method = Method::Get;

        assert_eq!(false, rt.is_match(&req));

        req.path = String::from("/api/v1/foo");
        req.method = Method::Post;

        assert_eq!(false, rt.is_match(&req));

        req.path = String::from("/api/v1/foo/asdf");
        req.method = Method::Get;

        assert_eq!(false, rt.is_match(&req));

        req.path = String::from("/api/v1/foo/123");
        req.method = Method::Get;

        assert_eq!(true, rt.is_match(&req));
    }

    #[test]
    fn test_route_match_simple() {
        let route = Route::new("/api/v1/foo/<foo_stuff>", Method::Get, utils::err_404);
        let parsed = route.parse("/api/v1/foo/blahblahblah");

        assert_eq!("blahblahblah", parsed.get("foo_stuff").unwrap());
    }

    #[test]
    fn test_route_match_single_int() {
        let route = Route::new("/api/v1/foo/<int:foo_id>", Method::Get, utils::err_404);
        let parsed = route.parse("/api/v1/foo/123");

        assert_eq!("123", parsed.get("foo_id").unwrap());
    }

    #[test]
    fn test_route_match_single_uint() {
        let route = Route::new("/api/v1/foo/<uint:foo_id>", Method::Get, utils::err_404);
        let parsed = route.parse("/api/v1/foo/123");
        let mut badreq = Request::new();

        badreq.method = Method::Get;
        badreq.path = String::from("/api/v1/foo/-123");

        assert_eq!("123", parsed.get("foo_id").unwrap());
        assert_eq!(false, route.is_match(&badreq));
    }

    #[test]
    fn test_route_match_single_str() {
        let rt = Route::new("/api/v1/foo/<str:foo_stuff>", Method::Get, utils::err_404);
        assert_eq!("blahblahblah", rt.parse("/api/v1/foo/blahblahblah").get("foo_stuff").unwrap());
    }

    #[test]
    fn test_route_match_many() {
        let rt = Route::new("/api/v1/foo/<int:foo_id>/bar/<str:bar>/baz/<int:baz_id>", Method::Get, utils::err_404);
        let rm = rt.parse("/api/v1/foo/123/bar/bar/baz/456");

        assert_eq!("123", rm.get("foo_id").unwrap());
        assert_eq!("bar", rm.get("bar").unwrap());
        assert_eq!("456", rm.get("baz_id").unwrap());
    }

    #[test]
    fn test_find_route_native_types() {
        let mut request = Request::new();
        let routes = vec![Route::new("/api/v1/foo/<int:foo_id>", Method::Get, utils::err_404),
                          Route::new("/api/v1/foo/<int:foo_id>/bar/<int:bar_id>", Method::Get, utils::err_404)];

        request.method = Method::Get;
        request.path = String::from("/api/v1/foo/42/bar/1234");

        for route in routes {
            match route.is_match(&request) {
                false => continue,
                true  => {
                    request.params = route.parse(&request.path);
                    break;
                },
            }
        }

        let foo_id: i32 = request.get("foo_id");
        let bar_id: i32 = request.get("bar_id");

        assert_eq!(42, foo_id);
        assert_eq!(1234, bar_id);
    }
}
<commit_msg>simple test cleanup<commit_after>/* Copyright (c) 2016
 * Jeff Nettleton
 *
 * Licensed under the MIT license (http://opensource.org/licenses/MIT). This
 * file may not be copied, modified, or distributed except according to those
 * terms
 */

extern crate regex;

use std::collections::HashMap;
use regex::Regex;

use request::*;
use response::*;

// The various types of parameters that can be contained in a URI.
#[derive(PartialEq, Eq, Hash, Debug)]
enum ParamType {
    Integer,
    Unsigned,
    String,
    Float,
    Path,
}

/// This struct represents a route definition. It is only necessary for
/// use internally.
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub struct RouteDef {
    pub pathdef: String,
    pub method:  Method,
}

/// This struct defines a route or endpoint.
pub struct Route {
    matcher:     Regex,
    method:      Method,
    params:      HashMap<String, ParamType>,
    pub handler: fn(&Request) -> Response,
}

impl Route {
    /// Create a new Route. This function is called by the Canteen struct.
    pub fn new(path: &str, method: Method, handler: fn(&Request) -> Response) -> Route {
        let re = Regex::new(r"^<(?:(int|uint|str|float|path):)?([\w_][a-zA-Z0-9_]*)>$").unwrap();
        let parts: Vec<&str> = path.split('/').filter(|&s| s != "").collect();
        let mut matcher: String = String::from(r"^");
        let mut params: HashMap<String, ParamType> = HashMap::new();

        for part in parts {
            let chunk: String = match re.is_match(part) {
                true  => {
                    let caps = re.captures(part).unwrap();
                    let param = caps.get(2).unwrap().as_str();
                    let ptype: ParamType = match caps.get(1) {
                        Some(x)     => {
                            match x.as_str() {
                                "int"   => ParamType::Integer,
                                "uint"  => ParamType::Unsigned,
                                "float" => ParamType::Float,
                                "path"  => ParamType::Path,
                                "str"   => ParamType::String,
                                _       => ParamType::String,

                            }
                        }
                        None        => ParamType::String,
                    };

                    let mstr: String = match ptype {
                        ParamType::String   => String::from(r"(?:[^/])+"),
                        ParamType::Integer  => String::from(r"-*[0-9]+"),
                        ParamType::Unsigned => String::from(r"[0-9]+"),
                        ParamType::Float    => String::from(r"-*[0-9]*[.]?[0-9]+"),
                        ParamType::Path     => String::from(r".+"),
                    };

                    params.insert(String::from(param), ptype);

                    format!("/(?P<{}>{})", &param, &mstr)
                },
                false => String::from("/") + part,
            };

            matcher.push_str(&chunk);
        }

        /* end the regex with an optional final slash and a string terminator */
        matcher.push_str("/?$");

        Route {
            matcher: Regex::new(&matcher).unwrap(),
            params:  params,
            method:  method,
            handler: handler,
        }
    }

    /// Check if this Route matches a given URI.
    pub fn is_match(&self, req: &Request) -> bool {
        self.matcher.is_match(&req.path) && self.method == req.method
    }

    /// Parse and extract the variables from a URI based on this Route's definition.
    pub fn parse(&self, path: &str) -> HashMap<String, String> {
        let mut params: HashMap<String, String> = HashMap::new();

        if self.matcher.is_match(&path) {
            let caps = self.matcher.captures(path).unwrap();
            for (param, _) in &self.params {
                params.insert(param.clone(), String::from(caps.name(&param).unwrap().as_str()));
            }
        }

        params
    }
}

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

    #[test]
    fn test_route_match() {
        let rt = Route::new("/api/v1/foo/<int:foo_id>", Method::Get, utils::err_404);
        let mut req = Request::new();
        let cases = vec![
            (String::from("/api/v1/bar"),      Method::Get,  false),
            (String::from("/api/v1/foo"),      Method::Post, false),
            (String::from("/api/v1/foo/asdf"), Method::Get,  false),
            (String::from("/api/va/foo/1.23"), Method::Get,  false),
            (String::from("/api/v1/foo/123"),  Method::Post, false),
            (String::from("/api/v1/foo/123"),  Method::Get,  true),
        ];

        for (path, method, success) in cases.into_iter() {
            req.path = path;
            req.method = method;

            assert_eq!(success, rt.is_match(&req));
        }
    }

    #[test]
    fn test_route_match_simple() {
        let route = Route::new("/api/v1/foo/<foo_stuff>", Method::Get, utils::err_404);
        let parsed = route.parse("/api/v1/foo/blahblahblah");

        assert_eq!("blahblahblah", parsed.get("foo_stuff").unwrap());
    }

    #[test]
    fn test_route_match_single_int() {
        let route = Route::new("/api/v1/foo/<int:foo_id>", Method::Get, utils::err_404);
        let parsed = route.parse("/api/v1/foo/123");

        assert_eq!("123", parsed.get("foo_id").unwrap());
    }

    #[test]
    fn test_route_match_single_uint() {
        let route = Route::new("/api/v1/foo/<uint:foo_id>", Method::Get, utils::err_404);
        let parsed = route.parse("/api/v1/foo/123");
        let mut badreq = Request::new();

        badreq.method = Method::Get;
        badreq.path = String::from("/api/v1/foo/-123");

        assert_eq!("123", parsed.get("foo_id").unwrap());
        assert_eq!(false, route.is_match(&badreq));
    }

    #[test]
    fn test_route_match_single_str() {
        let rt = Route::new("/api/v1/foo/<str:foo_stuff>", Method::Get, utils::err_404);
        assert_eq!("blahblahblah", rt.parse("/api/v1/foo/blahblahblah").get("foo_stuff").unwrap());
    }

    #[test]
    fn test_route_match_many() {
        let rt = Route::new("/api/v1/foo/<int:foo_id>/bar/<str:bar>/baz/<int:baz_id>", Method::Get, utils::err_404);
        let rm = rt.parse("/api/v1/foo/123/bar/bar/baz/456");

        assert_eq!("123", rm.get("foo_id").unwrap());
        assert_eq!("bar", rm.get("bar").unwrap());
        assert_eq!("456", rm.get("baz_id").unwrap());
    }

    #[test]
    fn test_find_route_native_types() {
        let mut request = Request::new();
        let routes = vec![Route::new("/api/v1/foo/<int:foo_id>", Method::Get, utils::err_404),
                          Route::new("/api/v1/foo/<int:foo_id>/bar/<int:bar_id>", Method::Get, utils::err_404)];

        request.method = Method::Get;
        request.path = String::from("/api/v1/foo/42/bar/1234");

        for route in routes {
            match route.is_match(&request) {
                false => continue,
                true  => {
                    request.params = route.parse(&request.path);
                    break;
                },
            }
        }

        let foo_id: i32 = request.get("foo_id");
        let bar_id: i32 = request.get("bar_id");

        assert_eq!(42, foo_id);
        assert_eq!(1234, bar_id);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A type-checked scaling factor between units.

use num::One;

use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde;
use core::fmt;
use core::ops::{Add, Div, Mul, Neg, Sub};
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::cmp::Ordering;
use {Point2D, Rect, Size2D, Vector2D};

/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums.  For example:
///
/// ```rust
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::Deserialize<'de>")))]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);

impl<T, Src, Dst> Scale<T, Src, Dst> {
    #[inline]
    pub const fn new(x: T) -> Self {
        Scale(x, PhantomData)
    }

    /// Returns the given point transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, point2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));
    /// ```
    #[inline]
    pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>
        where T: Clone + Mul
    {
        Point2D::new(point.x * self.get(), point.y * self.get())
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, vec2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));
    /// ```
    #[inline]
    pub fn transform_vector(&self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>
        where T: Clone + Mul
    {
        Vector2D::new(vec.x * self.get(), vec.y * self.get())
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, size2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));
    /// ```
    #[inline]
    pub fn transform_size(&self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>
        where T: Clone + Mul
    {
        Size2D::new(size.width * self.get(), size.height * self.get())
    }

    /// Returns the given rect transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, rect};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));
    /// ```
    #[inline]
    pub fn transform_rect(&self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>
        where T: Copy + Mul
    {
        Rect::new(
            self.transform_point(rect.origin),
            self.transform_size(rect.size),
        )
    }

    /// Returns the inverse of this scale.
    #[inline]
    pub fn inverse(&self) -> Scale<T::Output, Dst, Src>
        where T: Clone + Neg
    {
        Scale::new(-self.get())
    }

    /// Returns `true` if this scale has no effect.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// use euclid::num::One;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
    /// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);
    ///
    /// assert_eq!(cm_per_mm.is_identity(), false);
    /// assert_eq!(mm_per_mm.is_identity(), true);
    /// assert_eq!(mm_per_mm, Scale::one());
    /// ```
    #[inline]
    pub fn is_identity(&self) -> bool
        where T: PartialEq + One
    {
        self.0 == T::one()
    }
}

impl<T: Clone, Src, Dst> Scale<T, Src, Dst> {
    #[inline]
    pub fn get(&self) -> T {
        self.0.clone()
    }

    /// The inverse Scale (1.0 / self).
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);
    ///
    /// assert_eq!(cm_per_mm.inv(), Scale::new(10.0));
    /// ```
    pub fn inv(&self) -> Scale<T::Output, Dst, Src>
    where
        T: One + Div
    {
        let one: T = One::one();
        Scale::new(one / self.0.clone())
    }
}

impl<T: NumCast + Clone, Src, Dst> Scale<T, Src, Dst> {
    /// Cast from one numeric representation to another, preserving the units.
    ///
    /// # Panics
    ///
    /// If the source value cannot be represented by the target type `NewT`, then
    /// method panics. Use `try_cast` if that must be case.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.cast::<f32>(), Scale::new(10.0));
    /// ```
    /// That conversion will panic, because `i32` not enough to store such big numbers:
    /// ```rust,should_panic
    /// use euclid::Scale;
    /// enum Mm {};// millimeter = 10^-2 meters
    /// enum Em {};// exameter   = 10^18 meters
    ///
    /// // Panics
    /// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();
    /// ```
    #[inline]
    pub fn cast<NewT: NumCast>(&self) -> Scale<NewT, Src, Dst> {
        self.try_cast().unwrap()
    }

    /// Fallible cast from one numeric representation to another, preserving the units.
    /// If the source value cannot be represented by the target type `NewT`, then `None`
    /// is returned.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    /// enum Em {};// Exameter = 10^18 meters
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    /// let to_em: Scale<f32, Mm, Em> = Scale::new(10e20);
    ///
    /// assert_eq!(to_mm.try_cast::<f32>(), Some(Scale::new(10.0)));
    /// // Integer to small to store that number
    /// assert_eq!(to_em.try_cast::<i32>(), None);
    /// ```
    pub fn try_cast<NewT: NumCast>(&self) -> Option<Scale<NewT, Src, Dst>> {
        NumCast::from(self.get()).map(Scale::new)
    }
}

impl<Src, Dst> Scale<f32, Src, Dst> {
    /// Identity scaling, could be used to safely transit from one space to another.
    pub const ONE: Self = Scale(1.0, PhantomData);
}

// scale0 * scale1
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {
    type Output = Scale<T::Output, A, C>;

    #[inline]
    fn mul(self, other: Scale<T, B, C>) -> Self::Output {
        Scale::new(self.0 * other.0)
    }
}

// scale0 + scale1
impl<T: Add, Src, Dst> Add for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn add(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 + other.0)
    }
}

// scale0 - scale1
impl<T: Sub, Src, Dst> Sub for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn sub(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 - other.0)
    }
}

// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/rust-lang/rust/issues/26925

impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {
    fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {
        self.0 == other.0
    }
}

impl<T: Eq, Src, Dst> Eq for Scale<T, Src, Dst> {}

impl<T: PartialOrd, Src, Dst> PartialOrd for Scale<T, Src, Dst> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {
    fn clone(&self) -> Scale<T, Src, Dst> {
        Scale::new(self.get())
    }
}

impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}

impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: fmt::Display, Src, Dst> fmt::Display for Scale<T, Src, Dst> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T: Hash, Src, Dst> Hash for Scale<T, Src, Dst> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state)
    }
}

impl<T: One, Src, Dst> One for Scale<T, Src, Dst> {
    #[inline]
    fn one() -> Self {
        Scale::new(T::one())
    }
}

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

    enum Inch {}
    enum Cm {}
    enum Mm {}

    #[test]
    fn test_scale() {
        let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
        let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);

        let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inv();
        assert_eq!(mm_per_cm.get(), 10.0);

        let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
        assert_eq!(cm_per_inch, Scale::new(2.54));

        let a: Scale<isize, Inch, Inch> = Scale::new(2);
        let b: Scale<isize, Inch, Inch> = Scale::new(3);
        assert_ne!(a, b);
        assert_eq!(a, a.clone());
        assert_eq!(a.clone() + b.clone(), Scale::new(5));
        assert_eq!(a - b, Scale::new(-1));
    }
}
<commit_msg>Scale: add tests for `scale * (scale^-1) == 1`<commit_after>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A type-checked scaling factor between units.

use num::One;

use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde;
use core::fmt;
use core::ops::{Add, Div, Mul, Neg, Sub};
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::cmp::Ordering;
use {Point2D, Rect, Size2D, Vector2D};

/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums.  For example:
///
/// ```rust
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::Deserialize<'de>")))]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);

impl<T, Src, Dst> Scale<T, Src, Dst> {
    #[inline]
    pub const fn new(x: T) -> Self {
        Scale(x, PhantomData)
    }

    /// Returns the given point transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, point2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));
    /// ```
    #[inline]
    pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>
        where T: Clone + Mul
    {
        Point2D::new(point.x * self.get(), point.y * self.get())
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, vec2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));
    /// ```
    #[inline]
    pub fn transform_vector(&self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>
        where T: Clone + Mul
    {
        Vector2D::new(vec.x * self.get(), vec.y * self.get())
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, size2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));
    /// ```
    #[inline]
    pub fn transform_size(&self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>
        where T: Clone + Mul
    {
        Size2D::new(size.width * self.get(), size.height * self.get())
    }

    /// Returns the given rect transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, rect};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));
    /// ```
    #[inline]
    pub fn transform_rect(&self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>
        where T: Copy + Mul
    {
        Rect::new(
            self.transform_point(rect.origin),
            self.transform_size(rect.size),
        )
    }

    /// Returns the inverse of this scale.
    #[inline]
    pub fn inverse(&self) -> Scale<T::Output, Dst, Src>
        where T: Clone + Neg
    {
        Scale::new(-self.get())
    }

    /// Returns `true` if this scale has no effect.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// use euclid::num::One;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
    /// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);
    ///
    /// assert_eq!(cm_per_mm.is_identity(), false);
    /// assert_eq!(mm_per_mm.is_identity(), true);
    /// assert_eq!(mm_per_mm, Scale::one());
    /// ```
    #[inline]
    pub fn is_identity(&self) -> bool
        where T: PartialEq + One
    {
        self.0 == T::one()
    }
}

impl<T: Clone, Src, Dst> Scale<T, Src, Dst> {
    #[inline]
    pub fn get(&self) -> T {
        self.0.clone()
    }

    /// The inverse Scale (1.0 / self).
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);
    ///
    /// assert_eq!(cm_per_mm.inv(), Scale::new(10.0));
    /// ```
    pub fn inv(&self) -> Scale<T::Output, Dst, Src>
    where
        T: One + Div
    {
        let one: T = One::one();
        Scale::new(one / self.0.clone())
    }
}

impl<T: NumCast + Clone, Src, Dst> Scale<T, Src, Dst> {
    /// Cast from one numeric representation to another, preserving the units.
    ///
    /// # Panics
    ///
    /// If the source value cannot be represented by the target type `NewT`, then
    /// method panics. Use `try_cast` if that must be case.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.cast::<f32>(), Scale::new(10.0));
    /// ```
    /// That conversion will panic, because `i32` not enough to store such big numbers:
    /// ```rust,should_panic
    /// use euclid::Scale;
    /// enum Mm {};// millimeter = 10^-2 meters
    /// enum Em {};// exameter   = 10^18 meters
    ///
    /// // Panics
    /// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();
    /// ```
    #[inline]
    pub fn cast<NewT: NumCast>(&self) -> Scale<NewT, Src, Dst> {
        self.try_cast().unwrap()
    }

    /// Fallible cast from one numeric representation to another, preserving the units.
    /// If the source value cannot be represented by the target type `NewT`, then `None`
    /// is returned.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    /// enum Em {};// Exameter = 10^18 meters
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    /// let to_em: Scale<f32, Mm, Em> = Scale::new(10e20);
    ///
    /// assert_eq!(to_mm.try_cast::<f32>(), Some(Scale::new(10.0)));
    /// // Integer to small to store that number
    /// assert_eq!(to_em.try_cast::<i32>(), None);
    /// ```
    pub fn try_cast<NewT: NumCast>(&self) -> Option<Scale<NewT, Src, Dst>> {
        NumCast::from(self.get()).map(Scale::new)
    }
}

impl<Src, Dst> Scale<f32, Src, Dst> {
    /// Identity scaling, could be used to safely transit from one space to another.
    pub const ONE: Self = Scale(1.0, PhantomData);
}

// scale0 * scale1
// (A,B) * (B,C) = (A,C)
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {
    type Output = Scale<T::Output, A, C>;

    #[inline]
    fn mul(self, other: Scale<T, B, C>) -> Self::Output {
        Scale::new(self.0 * other.0)
    }
}

// scale0 + scale1
impl<T: Add, Src, Dst> Add for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn add(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 + other.0)
    }
}

// scale0 - scale1
impl<T: Sub, Src, Dst> Sub for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn sub(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 - other.0)
    }
}

// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/rust-lang/rust/issues/26925

impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {
    fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {
        self.0 == other.0
    }
}

impl<T: Eq, Src, Dst> Eq for Scale<T, Src, Dst> {}

impl<T: PartialOrd, Src, Dst> PartialOrd for Scale<T, Src, Dst> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {
    fn clone(&self) -> Scale<T, Src, Dst> {
        Scale::new(self.get())
    }
}

impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}

impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: fmt::Display, Src, Dst> fmt::Display for Scale<T, Src, Dst> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T: Hash, Src, Dst> Hash for Scale<T, Src, Dst> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state)
    }
}

impl<T: One, Src, Dst> One for Scale<T, Src, Dst> {
    #[inline]
    fn one() -> Self {
        Scale::new(T::one())
    }
}

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

    enum Inch {}
    enum Cm {}
    enum Mm {}

    #[test]
    fn test_scale() {
        let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
        let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);

        let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inv();
        assert_eq!(mm_per_cm.get(), 10.0);

        let one: Scale<f32, Mm, Mm> = cm_per_mm * mm_per_cm;
        assert_eq!(one.get(), 1.0);

        let one: Scale<f32, Cm, Cm> = mm_per_cm * cm_per_mm;
        assert_eq!(one.get(), 1.0);

        let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
        //  mm     cm     cm
        // ---- x ---- = ----
        // inch    mm    inch
        assert_eq!(cm_per_inch, Scale::new(2.54));

        let a: Scale<isize, Inch, Inch> = Scale::new(2);
        let b: Scale<isize, Inch, Inch> = Scale::new(3);
        assert_ne!(a, b);
        assert_eq!(a, a.clone());
        assert_eq!(a.clone() + b.clone(), Scale::new(5));
        assert_eq!(a - b, Scale::new(-1));
    }
}
<|endoftext|>


<commit_before>//! The idea here is basically we provide a Game type,
//! which can swap between several different Scene types.
//! Ideally Scenes can be nested and we can build a stack
//! of them?  Or something.
//! We also need hooks: Load, unload... more finely grained?
//! Kinda tricky to separate create/destroy vs. load and unload,
//! KISS for now.
<commit_msg>Starting to work on scene manager.<commit_after>//! The idea here is basically we provide a Game type,
//! which can swap between several different Scene types.
//! Ideally Scenes can be nested and we can build a stack
//! of them?  Or something.
//! We also need hooks: Load, unload... more finely grained?
//! Kinda tricky to separate create/destroy vs. load and unload,
//! KISS for now.

use ggez;
use ggez::GameResult;
use ggez::conf;
use ggez::game::GameState;

use std::time::Duration;

pub trait Scene: GameState {}

pub struct SceneManager {
    current_scene: Option<Box<Scene>>,
    scene_stack: Vec<Box<Scene>>,
}

impl Default for SceneManager {
    fn default() -> Self {
        SceneManager {
            current_scene: None,
            scene_stack: Vec::default(),
        }
    }
}

impl GameState for SceneManager {
    fn load(ctx: &mut ggez::Context, conf: &conf::Conf) -> GameResult<Self> {
        Ok(SceneManager::default())
    }

    fn update(&mut self, ctx: &mut ggez::Context, dt: Duration) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut ggez::Context) -> GameResult<()> {
        Ok(())
    }
}
<|endoftext|>


<commit_before>//! Serialization/Deserialization for the Game Maker Studio GEN8 format.
//!
//! Game Maker Studio uses a pseudo IFF-like format.
//!
//! It doesn't actually conform to the IFF spec, so it doesn't make sense
//! to use a generic IFF library.
//!
//! A couple assumptions are made about the format.
//!
//! - The root chunk is always a FORM chunk
//!
//! - The chunks are the following in the following order
//!   (optional chunks are marked with parentheses):
//!
//!    1. GEN8
//!    2. OPTN
//!    3. EXTN
//!    4. SOND
//!    5. (AGRP)
//!    6. SPRT
//!    7. BGND
//!    8. PATH
//!    9. SCPT
//!   10. SHDR
//!   11. FONT
//!   12. TMLN
//!   13. OBJT
//!   14. ROOM
//!   15. DAFL
//!   16. TPAG
//!   17. CODE
//!   18. VARI
//!   19. FUNC
//!   20. STRG
//!   21. TXTR
//!   22. AUDO
//!   23. (LANG)
//!   24. (GLOB)
//!
//! - Chunks are aligned on even byte offsets. Padding bytes are always zero.
//!
//! - You can rely on the fact that chunks always have sizes (indicated by their
//!   IFF chunk size property) that land you on even alignment when reading,
//!   so you don't have to manually adjust alignment.
//!
//! - You can't rely on any of the chunks (other than the root FORM) having a constant size,
//!   that is, having the same size in every game. Therefore, unknown trailing data should be
//!   read, and collected into a buffer that can be written back when serializing.

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::error::Error;
use std::io::{self, SeekFrom, Read};
use {GameData, GameDataWrite};

pub fn read_from<R: Read>(reader: &mut R) -> Result<GameData, Box<Error>> {
    read_form_chunk(reader)?;
    Ok(GameData {
        gen8: read_opt_chunk(reader, b"GEN8")?.ok_or("missing GEN8 chunk")?,
        optn: read_opt_chunk(reader, b"OPTN")?.ok_or("missing OPTN chunk")?,
        extn: read_opt_chunk(reader, b"EXTN")?.ok_or("missing EXTN chunk")?,
        sond: read_opt_chunk(reader, b"SOND")?.ok_or("missing SOND chunk")?,
        agrp: read_opt_chunk(reader, b"AGRP")?,
        sprt: read_opt_chunk(reader, b"SPRT")?.ok_or("missing SPRT chunk")?,
        bgnd: read_opt_chunk(reader, b"BGND")?.ok_or("missing BGND chunk")?,
        path: read_opt_chunk(reader, b"PATH")?.ok_or("missing PATH chunk")?,
        scpt: read_opt_chunk(reader, b"SCPT")?.ok_or("missing SCPT chunk")?,
        shdr: read_opt_chunk(reader, b"SHDR")?.ok_or("missing SHDR chunk")?,
        font: read_opt_chunk(reader, b"FONT")?.ok_or("missing FONT chunk")?,
        tmln: read_opt_chunk(reader, b"TMLN")?.ok_or("missing TMLN chunk")?,
        objt: read_opt_chunk(reader, b"OBJT")?.ok_or("missing OBJT chunk")?,
        room: read_opt_chunk(reader, b"ROOM")?.ok_or("missing ROOM chunk")?,
        dafl: read_opt_chunk(reader, b"DAFL")?.ok_or("missing DAFL chunk")?,
        tpag: read_opt_chunk(reader, b"TPAG")?.ok_or("missing TPAG chunk")?,
        code: read_opt_chunk(reader, b"CODE")?.ok_or("missing CODE chunk")?,
        vari: read_opt_chunk(reader, b"VARI")?.ok_or("missing VARI chunk")?,
        func: read_opt_chunk(reader, b"FUNC")?.ok_or("missing FUNC chunk")?,
        strg: read_opt_chunk(reader, b"STRG")?.ok_or("missing STRG chunk")?,
        txtr: read_opt_chunk(reader, b"TXTR")?.ok_or("missing TXTR chunk")?,
        audo: read_opt_chunk(reader, b"AUDO")?.ok_or("missing AUDO chunk")?,
        lang: read_opt_chunk(reader, b"LANG")?,
        glob: read_opt_chunk(reader, b"GLOB")?,
    })
}

pub fn write_to<W: GameDataWrite>(gdat: &GameData, writer: &mut W) -> io::Result<()> {
    writer.write_all(b"FORM")?;
    // Skip writing the FORM length, because we don't know it yet.
    let after_form_len = writer.seek(SeekFrom::Current(4))?;
    macro_rules! write {
        ($field:expr, $id:expr) => {
            writer.write_all($id)?;
            writer.write_i32::<LittleEndian>($field.len() as i32)?;
            writer.write_all(&$field)?;
        }
    }
    write!(gdat.gen8, b"GEN8");
    write!(gdat.optn, b"OPTN");
    write!(gdat.extn, b"EXTN");
    write!(gdat.sond, b"SOND");
    if let Some(ref data) = gdat.agrp {
        write!(data, b"AGRP");
    }
    write!(gdat.sprt, b"SPRT");
    write!(gdat.bgnd, b"BGND");
    write!(gdat.path, b"PATH");
    write!(gdat.scpt, b"SCPT");
    write!(gdat.shdr, b"SHDR");
    write!(gdat.font, b"FONT");
    write!(gdat.tmln, b"TMLN");
    write!(gdat.objt, b"OBJT");
    write!(gdat.room, b"ROOM");
    write!(gdat.dafl, b"DAFL");
    write!(gdat.tpag, b"TPAG");
    write!(gdat.code, b"CODE");
    write!(gdat.vari, b"VARI");
    write!(gdat.func, b"FUNC");
    write!(gdat.strg, b"STRG");
    write!(gdat.txtr, b"TXTR");
    write!(gdat.audo, b"AUDO");
    if let Some(ref data) = gdat.lang {
        write!(data, b"LANG");
    }
    if let Some(ref data) = gdat.glob {
        write!(data, b"GLOB");
    }
    let end = writer.seek(SeekFrom::Current(0))?;
    let form_len = end - after_form_len;
    // Finally write the form length
    writer.seek(SeekFrom::Start(after_form_len - 4))?;
    writer.write_i32::<LittleEndian>(form_len as i32)?;
    Ok(())
}

fn read_form_chunk<R: Read>(reader: &mut R) -> Result<(), Box<Error>> {
    let mut type_id = [0; 4];
    reader.read_exact(&mut type_id)?;
    let _len = reader.read_i32::<LittleEndian>();

    if &type_id[..] != b"FORM" {
        return Err(
            "Invalid data.win file. Must start with a FORM chunk.".into(),
        );
    }
    Ok(())
}

fn read_opt_chunk<R: Read>(
    reader: &mut R,
    expected_type: &'static [u8; 4],
) -> Result<Option<Box<[u8]>>, Box<Error>> {
    use std::io::ErrorKind;

    let mut type_id = [0; 4];
    if let Err(e) = reader.read_exact(&mut type_id) {
        match e.kind() {
            ErrorKind::UnexpectedEof => return Ok(None),
            _ => return Err(Box::new(e)),
        }
    }

    if type_id != *expected_type {
        // TODO: You can't just return None here, you already read the type id,
        // Which consumed the type id of the next item you're about to read.
        panic!("Optional chunks are not properly implemented.");
    }

    let size = reader.read_i32::<LittleEndian>()?;
    let mut data = vec![0; size as usize];
    reader.read_exact(&mut data[..])?;

    Ok(Some(data.into_boxed_slice()))
}
<commit_msg>Number assumptions, rewrite assumption about alignment and padding<commit_after>//! Serialization/Deserialization for the Game Maker Studio GEN8 format.
//!
//! Game Maker Studio uses a pseudo IFF-like format.
//!
//! It doesn't actually conform to the IFF spec, so it doesn't make sense
//! to use a generic IFF library.
//!
//! A couple assumptions are made about the format.
//!
//! 1. The root chunk is always a FORM chunk
//!
//! 2. The chunks are the following in the following order
//!    (optional chunks are marked with parentheses):
//!
//!     1. GEN8
//!     2. OPTN
//!     3. EXTN
//!     4. SOND
//!     5. (AGRP)
//!     6. SPRT
//!     7. BGND
//!     8. PATH
//!     9. SCPT
//!    10. SHDR
//!    11. FONT
//!    12. TMLN
//!    13. OBJT
//!    14. ROOM
//!    15. DAFL
//!    16. TPAG
//!    17. CODE
//!    18. VARI
//!    19. FUNC
//!    20. STRG
//!    21. TXTR
//!    22. AUDO
//!    23. (LANG)
//!    24. (GLOB)
//!
//! 3. Chunks are aligned on even byte offsets. Practically, we don't have to care about this,
//!    due to (4.) and due to (5.) saving any alignment padding as trailing data.
//!
//! 4. You can rely on the fact that chunks always have sizes (indicated by their
//!    IFF chunk size property) that land you on even alignment when reading,
//!    so you don't have to manually adjust alignment.
//!
//! 5. You can't rely on any of the chunks (other than the root FORM) having a constant size,
//!    that is, having the same size in every game. Therefore, unknown trailing data should be
//!    read, and collected into a buffer that can be written back when serializing.

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::error::Error;
use std::io::{self, SeekFrom, Read};
use {GameData, GameDataWrite};

pub fn read_from<R: Read>(reader: &mut R) -> Result<GameData, Box<Error>> {
    read_form_chunk(reader)?;
    Ok(GameData {
        gen8: read_opt_chunk(reader, b"GEN8")?.ok_or("missing GEN8 chunk")?,
        optn: read_opt_chunk(reader, b"OPTN")?.ok_or("missing OPTN chunk")?,
        extn: read_opt_chunk(reader, b"EXTN")?.ok_or("missing EXTN chunk")?,
        sond: read_opt_chunk(reader, b"SOND")?.ok_or("missing SOND chunk")?,
        agrp: read_opt_chunk(reader, b"AGRP")?,
        sprt: read_opt_chunk(reader, b"SPRT")?.ok_or("missing SPRT chunk")?,
        bgnd: read_opt_chunk(reader, b"BGND")?.ok_or("missing BGND chunk")?,
        path: read_opt_chunk(reader, b"PATH")?.ok_or("missing PATH chunk")?,
        scpt: read_opt_chunk(reader, b"SCPT")?.ok_or("missing SCPT chunk")?,
        shdr: read_opt_chunk(reader, b"SHDR")?.ok_or("missing SHDR chunk")?,
        font: read_opt_chunk(reader, b"FONT")?.ok_or("missing FONT chunk")?,
        tmln: read_opt_chunk(reader, b"TMLN")?.ok_or("missing TMLN chunk")?,
        objt: read_opt_chunk(reader, b"OBJT")?.ok_or("missing OBJT chunk")?,
        room: read_opt_chunk(reader, b"ROOM")?.ok_or("missing ROOM chunk")?,
        dafl: read_opt_chunk(reader, b"DAFL")?.ok_or("missing DAFL chunk")?,
        tpag: read_opt_chunk(reader, b"TPAG")?.ok_or("missing TPAG chunk")?,
        code: read_opt_chunk(reader, b"CODE")?.ok_or("missing CODE chunk")?,
        vari: read_opt_chunk(reader, b"VARI")?.ok_or("missing VARI chunk")?,
        func: read_opt_chunk(reader, b"FUNC")?.ok_or("missing FUNC chunk")?,
        strg: read_opt_chunk(reader, b"STRG")?.ok_or("missing STRG chunk")?,
        txtr: read_opt_chunk(reader, b"TXTR")?.ok_or("missing TXTR chunk")?,
        audo: read_opt_chunk(reader, b"AUDO")?.ok_or("missing AUDO chunk")?,
        lang: read_opt_chunk(reader, b"LANG")?,
        glob: read_opt_chunk(reader, b"GLOB")?,
    })
}

pub fn write_to<W: GameDataWrite>(gdat: &GameData, writer: &mut W) -> io::Result<()> {
    writer.write_all(b"FORM")?;
    // Skip writing the FORM length, because we don't know it yet.
    let after_form_len = writer.seek(SeekFrom::Current(4))?;
    macro_rules! write {
        ($field:expr, $id:expr) => {
            writer.write_all($id)?;
            writer.write_i32::<LittleEndian>($field.len() as i32)?;
            writer.write_all(&$field)?;
        }
    }
    write!(gdat.gen8, b"GEN8");
    write!(gdat.optn, b"OPTN");
    write!(gdat.extn, b"EXTN");
    write!(gdat.sond, b"SOND");
    if let Some(ref data) = gdat.agrp {
        write!(data, b"AGRP");
    }
    write!(gdat.sprt, b"SPRT");
    write!(gdat.bgnd, b"BGND");
    write!(gdat.path, b"PATH");
    write!(gdat.scpt, b"SCPT");
    write!(gdat.shdr, b"SHDR");
    write!(gdat.font, b"FONT");
    write!(gdat.tmln, b"TMLN");
    write!(gdat.objt, b"OBJT");
    write!(gdat.room, b"ROOM");
    write!(gdat.dafl, b"DAFL");
    write!(gdat.tpag, b"TPAG");
    write!(gdat.code, b"CODE");
    write!(gdat.vari, b"VARI");
    write!(gdat.func, b"FUNC");
    write!(gdat.strg, b"STRG");
    write!(gdat.txtr, b"TXTR");
    write!(gdat.audo, b"AUDO");
    if let Some(ref data) = gdat.lang {
        write!(data, b"LANG");
    }
    if let Some(ref data) = gdat.glob {
        write!(data, b"GLOB");
    }
    let end = writer.seek(SeekFrom::Current(0))?;
    let form_len = end - after_form_len;
    // Finally write the form length
    writer.seek(SeekFrom::Start(after_form_len - 4))?;
    writer.write_i32::<LittleEndian>(form_len as i32)?;
    Ok(())
}

fn read_form_chunk<R: Read>(reader: &mut R) -> Result<(), Box<Error>> {
    let mut type_id = [0; 4];
    reader.read_exact(&mut type_id)?;
    let _len = reader.read_i32::<LittleEndian>();

    if &type_id[..] != b"FORM" {
        return Err(
            "Invalid data.win file. Must start with a FORM chunk.".into(),
        );
    }
    Ok(())
}

fn read_opt_chunk<R: Read>(
    reader: &mut R,
    expected_type: &'static [u8; 4],
) -> Result<Option<Box<[u8]>>, Box<Error>> {
    use std::io::ErrorKind;

    let mut type_id = [0; 4];
    if let Err(e) = reader.read_exact(&mut type_id) {
        match e.kind() {
            ErrorKind::UnexpectedEof => return Ok(None),
            _ => return Err(Box::new(e)),
        }
    }

    if type_id != *expected_type {
        // TODO: You can't just return None here, you already read the type id,
        // Which consumed the type id of the next item you're about to read.
        panic!("Optional chunks are not properly implemented.");
    }

    let size = reader.read_i32::<LittleEndian>()?;
    let mut data = vec![0; size as usize];
    reader.read_exact(&mut data[..])?;

    Ok(Some(data.into_boxed_slice()))
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod rasterization {
    use cgmath::Point2;
    use rasterization::triangle;

    fn triangle_test(a: Point2<f32>, b: Point2<f32>, c: Point2<f32>, buffer_except: Vec<u32>) {
        let x_size: usize = 7;
        let y_size: usize = 5;
        let mut buffer: Vec<u32> = vec![0; x_size * y_size];
        triangle(&mut buffer, x_size, y_size, a, b, c, 1);

        println!("");
        println!("real: ");
        for y in (0..y_size) {
            print!("   ");
            for x in (0..x_size) {
                print!("{}",if buffer[(y_size - y - 1) * x_size + x]==0 {0} else {1});
            }
            println!("");
        }
        println!("except: ");
        for y in (0..y_size) {
            print!("   ");
            for x in (0..x_size) {
                print!("{}",if buffer_except[y * x_size + x]==0 {0} else {1});
            }
            println!("");
        }
        for y in 0..y_size {
            for x in 0..x_size {
                let val_real = buffer[y * x_size + x];
                let val_except = buffer_except[(y_size - y - 1) * x_size + x];
                debug_assert!((val_real==0) == (val_except==0),
                              "real = {}, except = {}, x = {} y = {}",
                              val_real, val_except, x, y);
            }
        }
    }

    #[test]
    fn triangle_00() {
        triangle_test(Point2::new(1.0,4.0), Point2::new(2.0,1.0), Point2::new(6.0,3.0),
                      vec![0,0,0,0,0,0,0,
                           0,1,1,0,0,0,0,
                           0,1,1,1,1,0,0,
                           0,0,1,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_01() {
        triangle_test(Point2::new(1.4,1.6), Point2::new(2.4,1.6), Point2::new(2.4,2.6),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_02() {
        triangle_test(Point2::new(3.5,1.5), Point2::new(4.5,1.5), Point2::new(4.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_03() {
        triangle_test(Point2::new(2.5,2.5), Point2::new(2.5,2.5), Point2::new(2.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_04() {
        triangle_test(Point2::new(0.0,0.0), Point2::new(4.0,0.0), Point2::new(6.0,2.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,1,0,0,
                           0,1,1,1,0,0,0]);
    }

    #[test]
    fn triangle_05() {
        triangle_test(Point2::new(1.0,2.0), Point2::new(4.0,1.0), Point2::new(3.0,4.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,1,0,0,0,0,
                           0,1,1,0,0,0,0,
                           0,0,1,1,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_06() {
        triangle_test(Point2::new(5.5,2.5), Point2::new(4.0,1.0), Point2::new(3.0,4.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,1,0,0,0,
                           0,0,0,1,1,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_07() {
        triangle_test(Point2::new(1.5,0.5), Point2::new(2.5,0.5), Point2::new(1.5,-2.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,1,0,0,0,0,0]);
    }

    #[test]
    fn triangle_08() {
        triangle_test(Point2::new(0.7,3.5), Point2::new(2.5,0.7), Point2::new(4.6,3.5),
                      vec![0,0,0,0,0,0,0,
                           0,1,1,1,1,0,0,
                           0,1,1,1,0,0,0,
                           0,0,1,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_09() {
        triangle_test(Point2::new(0.7,1.5), Point2::new(2.7,3.2), Point2::new(4.7,1.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,1,1,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_10() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(0.5,2.5), Point2::new(1.5,1.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_11() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(0.5,2.5), Point2::new(2.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,1,0,0,0,0,0,
                           1,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_12() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(2.5,2.5), Point2::new(2.5,0.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,1,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_13() {
        triangle_test(Point2::new(0.5,3.5), Point2::new(1.5,2.5), Point2::new(1.5,0.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_14() {
        triangle_test(Point2::new(0.5,3.5), Point2::new(1.5,2.5), Point2::new(2.0,5.0),
                      vec![0,1,0,0,0,0,0,
                           1,1,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_15() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(2.5,0.5), Point2::new(0.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_16() {
        triangle_test(Point2::new(2.5,2.5), Point2::new(2.5,0.5), Point2::new(0.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,1,0,0,0,0,0,
                           0,1,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_17() {
        triangle_test(Point2::new(5.0,2.0), Point2::new(5.0,-2.0), Point2::new(10.0,2.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,1,1,
                           0,0,0,0,0,1,1]);
    }

    #[test]
    fn triangle_18() {
        triangle_test(Point2::new(5.0,3.0), Point2::new(5.0,10.0), Point2::new(10.0,3.0),
                      vec![0,0,0,0,0,1,1,
                           0,0,0,0,0,1,1,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }
}
<commit_msg>invalid test<commit_after>#[cfg(test)]
mod rasterization {
    use cgmath::Point2;
    use rasterization::triangle;

    fn triangle_test(a: Point2<f32>, b: Point2<f32>, c: Point2<f32>, buffer_except: Vec<u32>) {
        let x_size: usize = 7;
        let y_size: usize = 5;
        let mut buffer: Vec<u32> = vec![0; x_size * y_size];
        triangle(&mut buffer, x_size, y_size, a, b, c, 1);

        println!("");
        println!("real: ");
        for y in (0..y_size) {
            print!("   ");
            for x in (0..x_size) {
                print!("{}",if buffer[(y_size - y - 1) * x_size + x]==0 {0} else {1});
            }
            println!("");
        }
        println!("except: ");
        for y in (0..y_size) {
            print!("   ");
            for x in (0..x_size) {
                print!("{}",if buffer_except[y * x_size + x]==0 {0} else {1});
            }
            println!("");
        }
        for y in 0..y_size {
            for x in 0..x_size {
                let val_real = buffer[y * x_size + x];
                let val_except = buffer_except[(y_size - y - 1) * x_size + x];
                debug_assert!((val_real==0) == (val_except==0),
                              "real = {}, except = {}, x = {} y = {}",
                              val_real, val_except, x, y);
            }
        }
    }

    #[test]
    fn triangle_00() {
        triangle_test(Point2::new(1.0,4.0), Point2::new(2.0,1.0), Point2::new(6.0,3.0),
                      vec![0,0,0,0,0,0,0,
                           0,1,1,0,0,0,0,
                           0,1,1,1,1,0,0,
                           0,0,1,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_01() {
        triangle_test(Point2::new(1.4,1.6), Point2::new(2.4,1.6), Point2::new(2.4,2.6),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_02() {
        triangle_test(Point2::new(3.5,1.5), Point2::new(4.5,1.5), Point2::new(4.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_03() {
        triangle_test(Point2::new(2.5,2.5), Point2::new(2.5,2.5), Point2::new(2.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_04() {
        triangle_test(Point2::new(0.0,0.0), Point2::new(4.0,0.0), Point2::new(6.0,2.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,1,0,0,
                           0,1,1,1,0,0,0]);
    }

    #[test]
    fn triangle_05() {
        triangle_test(Point2::new(1.0,2.0), Point2::new(4.0,1.0), Point2::new(3.0,4.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,1,0,0,0,0,
                           0,1,1,0,0,0,0,
                           0,0,1,1,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_06() {
        triangle_test(Point2::new(5.5,2.5), Point2::new(4.0,1.0), Point2::new(3.0,4.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,1,0,0,0,
                           0,0,0,1,1,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_07() {
        triangle_test(Point2::new(1.5,0.5), Point2::new(2.5,0.5), Point2::new(1.5,-2.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,1,0,0,0,0,0]);
    }

    #[test]
    fn triangle_08() {
        triangle_test(Point2::new(0.7,3.5), Point2::new(2.5,0.7), Point2::new(4.6,3.5),
                      vec![0,0,0,0,0,0,0,
                           0,1,1,1,1,0,0,
                           0,1,1,1,0,0,0,
                           0,0,1,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_09() {
        triangle_test(Point2::new(0.7,1.5), Point2::new(2.7,3.2), Point2::new(4.7,1.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,1,1,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_10() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(0.5,2.5), Point2::new(1.5,1.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_11() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(0.5,2.5), Point2::new(2.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,1,0,0,0,0,0,
                           1,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_12() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(2.5,2.5), Point2::new(2.5,0.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,1,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_13() {
        triangle_test(Point2::new(0.5,3.5), Point2::new(1.5,2.5), Point2::new(1.5,0.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_14() {
        triangle_test(Point2::new(0.5,3.5), Point2::new(1.5,2.5), Point2::new(2.0,5.0),
                      vec![0,1,0,0,0,0,0,
                           1,1,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_15() {
        triangle_test(Point2::new(0.5,0.5), Point2::new(2.5,0.5), Point2::new(0.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,0,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_16() {
        triangle_test(Point2::new(2.5,2.5), Point2::new(2.5,0.5), Point2::new(0.5,2.5),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           1,1,0,0,0,0,0,
                           0,1,0,0,0,0,0,
                           0,0,0,0,0,0,0]);
    }

    #[test]
    fn triangle_17() {
        triangle_test(Point2::new(5.0,2.0), Point2::new(5.0,-2.0), Point2::new(10.0,2.0),
                      vec![0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,1,1,
                           0,0,0,0,0,1,1]);
    }

    #[test]
    fn triangle_18() {
        triangle_test(Point2::new(5.0,3.0), Point2::new(5.0,10.0), Point2::new(10.0,3.0),
                      vec![0,0,0,0,0,1,1,
                           0,0,0,0,0,1,1,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,
                           0,0,0,0,0,0,1]);
    }
}
<|endoftext|>