<commit_before>//! Replaces the deprecated functionality of std::os::num_cpus.
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]

extern crate libc;

/// Returns the number of CPUs of the current machine.
#[inline]
pub fn get() -> usize {
    get_num_cpus()
}

#[cfg(windows)]
fn get_num_cpus() -> usize {
    unsafe {
        let mut sysinfo: libc::SYSTEM_INFO = ::std::mem::uninitialized();
        libc::GetSystemInfo(&mut sysinfo);
        sysinfo.dwNumberOfProcessors as usize
    }
}

#[cfg(
    all(
        any(
            target_os = "macos",
            target_os = "ios",
            target_os = "freebsd",
            target_os = "dragonfly",
            target_os = "bitrig",
            target_os = "openbsd"
        ),
        not(unix)
    )
)]
fn get_num_cpus() -> usize {
    use libc::{c_int, c_uint};
    use libc::funcs::bsd44::sysctl;

    //XXX: uplift to libc?
    const CTL_HW: c_int = 6;
    const HW_AVAILCPU: c_int = 25;
    const HW_NCPU: c_int = 3;

    let mut cpus: c_uint = 0;
    let mut CPUS_SIZE = ::std::mem::size_of::<c_uint>();
    let mut mib: [c_int; 4] = [CTL_HW, HW_AVAILCPU, 0, 0];

    unsafe {
        sysctl(mib.as_mut_ptr(), 2, &mut cpus, &mut CPUS_SIZE, &mut (), 0);
    }

    if cpus < 1 {
        mib[1] = HW_NCPU;
        unsafe {
            sysctl(mib.as_mut_ptr(), 2, &mut cpus, &mut CPUS_SIZE, &mut (), 0);
        }
        if cpus < 1 {
            cpus = 1;
        }
    }

    cpus as usize
}

#[cfg(target_os= "linux")]
fn get_num_cpus() -> usize {
    //to-do: replace with libc::_SC_NPROCESSORS_ONLN once available
    unsafe {
        libc::sysconf(84) as usize
    }
}

#[cfg(target_os="macos")]
fn get_num_cpus() -> usize {
    //to-do: replace with libc::_SC_NPROCESSORS_ONLN once available
    unsafe {
        libc::sysconf(58) as usize
    }
}

#[test]
fn lower_bound() {
    assert!(get() > 0);
}

#[test]
fn upper_bound() {
    assert!(get() < 236_451);
}
<commit_msg>Impl for NativeClient<commit_after>//! Replaces the deprecated functionality of std::os::num_cpus.
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]

extern crate libc;

/// Returns the number of CPUs of the current machine.
#[inline]
pub fn get() -> usize {
    get_num_cpus()
}

#[cfg(windows)]
fn get_num_cpus() -> usize {
    unsafe {
        let mut sysinfo: libc::SYSTEM_INFO = ::std::mem::uninitialized();
        libc::GetSystemInfo(&mut sysinfo);
        sysinfo.dwNumberOfProcessors as usize
    }
}

#[cfg(
    all(
        any(
            target_os = "macos",
            target_os = "ios",
            target_os = "freebsd",
            target_os = "dragonfly",
            target_os = "bitrig",
            target_os = "openbsd"
        ),
        not(unix)
    )
)]
fn get_num_cpus() -> usize {
    use libc::{c_int, c_uint};
    use libc::funcs::bsd44::sysctl;

    //XXX: uplift to libc?
    const CTL_HW: c_int = 6;
    const HW_AVAILCPU: c_int = 25;
    const HW_NCPU: c_int = 3;

    let mut cpus: c_uint = 0;
    let mut CPUS_SIZE = ::std::mem::size_of::<c_uint>();
    let mut mib: [c_int; 4] = [CTL_HW, HW_AVAILCPU, 0, 0];

    unsafe {
        sysctl(mib.as_mut_ptr(), 2, &mut cpus, &mut CPUS_SIZE, &mut (), 0);
    }

    if cpus < 1 {
        mib[1] = HW_NCPU;
        unsafe {
            sysctl(mib.as_mut_ptr(), 2, &mut cpus, &mut CPUS_SIZE, &mut (), 0);
        }
        if cpus < 1 {
            cpus = 1;
        }
    }

    cpus as usize
}

#[cfg(target_os= "linux")]
fn get_num_cpus() -> usize {
    //to-do: replace with libc::_SC_NPROCESSORS_ONLN once available
    unsafe {
        libc::sysconf(84) as usize
    }
}
#[cfg(target_os = "nacl")]
fn get_num_cpus() -> usize {
    //to-do: replace with libc::_SC_NPROCESSORS_ONLN once available
    unsafe {
        libc::sysconf(1) as usize
    }
}

#[cfg(target_os="macos")]
fn get_num_cpus() -> usize {
    //to-do: replace with libc::_SC_NPROCESSORS_ONLN once available
    unsafe {
        libc::sysconf(58) as usize
    }
}

#[test]
fn lower_bound() {
    assert!(get() > 0);
}

#[test]
fn upper_bound() {
    assert!(get() < 236_451);
}
<|endoftext|>


<commit_before>extern crate json_schema;
extern crate serde_json;

#[macro_use]
extern crate quote;

use std::borrow::Cow;

use json_schema::{Schema, Type};

use quote::{Tokens, ToTokens};

struct Ident<S>(S);

impl<S: AsRef<str>> ToTokens for Ident<S> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        tokens.append(self.0.as_ref())
    }
}

fn field(s: &str) -> Ident<Cow<str>> {
    Ident(if ["type", "struct", "enum"].iter().any(|&keyword| keyword == s) {
        format!("{}_", s).into()
    } else {
        s.into()
    })
}

fn merge(result: &mut Schema, r: &Schema) {
    use std::collections::hash_map::Entry;

    for (k, v) in &r.properties {
        match result.properties.entry(k.clone()) {
            Entry::Vacant(entry) => {
                entry.insert(v.clone());
            }
            Entry::Occupied(mut entry) => merge(entry.get_mut(), v),
        }
    }
}

struct Expander<'r> {
    root: &'r Schema,
}

impl<'r> Expander<'r> {
    fn type_ref(&self, s: &str) -> String {
        s.split('/').last().expect("Component").into()
    }

    fn schema(&self, s: &'r Schema) -> &'r Schema {
        if let Some(ref ref_) = s.ref_ {
            self.schema_ref(ref_)
        } else {
            s
        }
    }

    fn schema_ref(&self, s: &str) -> &'r Schema {
        s.split('/').fold(self.root, |schema, comp| {
            if comp == "#" {
                self.root
            } else if comp == "definitions" {
                schema
            } else {
                schema.definitions
                    .get(comp)
                    .unwrap_or_else(|| panic!("Expected definition: `{}` {}", s, comp))
            }
        })
    }

    fn expand_type(&mut self, typ: &Schema) -> String {
        if let Some(ref ref_) = typ.ref_ {
            self.type_ref(ref_)
        } else if typ.type_.len() == 1 {
            match typ.type_[0] {
                Type::String => {
                    if !typ.enum_.is_empty() {
                        "serde_json::Value".into()
                    } else {
                        "String".into()
                    }
                }
                Type::Integer => "i64".into(),
                Type::Boolean => "bool".into(),
                Type::Number => "f64".into(),
                Type::Object => "obj".into(),
                Type::Array => {
                    let item_schema =
                        typ.items.as_ref().expect("Array type must have items schema");
                    format!("Vec<{}>", self.expand_type(item_schema))
                }
                _ => panic!("Type"),
            }
        } else {
            "serde_json::Value".into()
        }
    }

    fn expand_fields(&mut self, schema: &Schema) -> Vec<Tokens> {
        if let Some(ref ref_) = schema.ref_ {
            let schema = self.schema_ref(ref_);
            self.expand_fields(schema)
        } else if !schema.allOf.is_empty() {
            let first = schema.allOf.first().unwrap().clone();
            let result = schema.allOf
                .iter()
                .skip(1)
                .fold(first, |mut result, def| {
                    merge(&mut result, self.schema(def));
                    result
                });
            self.expand_fields(&result)
        } else {
            schema.properties
                .iter()
                .map(|(key, value)| {
                    let key = field(key);
                    let typ = Ident(self.expand_type(value));
                    quote!( #key : #typ )
                })
                .collect()
        }
    }

    pub fn expand_schema(&mut self, schema: &Schema) -> Tokens {
        let mut types = Vec::new();
        for (name, def) in &schema.definitions {
            let fields = self.expand_fields(def);
            let name = Ident(name);
            let tokens = quote! {
                pub struct #name {
                    #(#fields),*
                }
            };
            types.push(tokens);
        }
        quote! { #(
            #types
            )*
        }
    }
}

pub fn generate(s: &str) -> Tokens {
    let schema = serde_json::from_str(s).unwrap();
    let mut expander = Expander { root: &schema };
    expander.expand_schema(&schema)
}

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

    #[test]
    fn attempt() {
        let s = include_str!("../../json-schema/tests/debugserver-schema.json");

        let s = generate(s).to_string();
        println!("`{}`", s);
        assert!(false);
    }
}
<commit_msg>fix: object -> serde_json::Value<commit_after>extern crate json_schema;
extern crate serde_json;

#[macro_use]
extern crate quote;

use std::borrow::Cow;

use json_schema::{Schema, Type};

use quote::{Tokens, ToTokens};

struct Ident<S>(S);

impl<S: AsRef<str>> ToTokens for Ident<S> {
    fn to_tokens(&self, tokens: &mut Tokens) {
        tokens.append(self.0.as_ref())
    }
}

fn field(s: &str) -> Ident<Cow<str>> {
    Ident(if ["type", "struct", "enum"].iter().any(|&keyword| keyword == s) {
        format!("{}_", s).into()
    } else {
        s.into()
    })
}

fn merge(result: &mut Schema, r: &Schema) {
    use std::collections::hash_map::Entry;

    for (k, v) in &r.properties {
        match result.properties.entry(k.clone()) {
            Entry::Vacant(entry) => {
                entry.insert(v.clone());
            }
            Entry::Occupied(mut entry) => merge(entry.get_mut(), v),
        }
    }
}

struct Expander<'r> {
    root: &'r Schema,
}

impl<'r> Expander<'r> {
    fn type_ref(&self, s: &str) -> String {
        s.split('/').last().expect("Component").into()
    }

    fn schema(&self, s: &'r Schema) -> &'r Schema {
        if let Some(ref ref_) = s.ref_ {
            self.schema_ref(ref_)
        } else {
            s
        }
    }

    fn schema_ref(&self, s: &str) -> &'r Schema {
        s.split('/').fold(self.root, |schema, comp| {
            if comp == "#" {
                self.root
            } else if comp == "definitions" {
                schema
            } else {
                schema.definitions
                    .get(comp)
                    .unwrap_or_else(|| panic!("Expected definition: `{}` {}", s, comp))
            }
        })
    }

    fn expand_type(&mut self, typ: &Schema) -> String {
        if let Some(ref ref_) = typ.ref_ {
            self.type_ref(ref_)
        } else if typ.type_.len() == 1 {
            match typ.type_[0] {
                Type::String => {
                    if !typ.enum_.is_empty() {
                        "serde_json::Value".into()
                    } else {
                        "String".into()
                    }
                }
                Type::Integer => "i64".into(),
                Type::Boolean => "bool".into(),
                Type::Number => "f64".into(),
                Type::Object => "serde_json::Value".into(),
                Type::Array => {
                    let item_schema =
                        typ.items.as_ref().expect("Array type must have items schema");
                    format!("Vec<{}>", self.expand_type(item_schema))
                }
                _ => panic!("Type"),
            }
        } else {
            "serde_json::Value".into()
        }
    }

    fn expand_fields(&mut self, schema: &Schema) -> Vec<Tokens> {
        if let Some(ref ref_) = schema.ref_ {
            let schema = self.schema_ref(ref_);
            self.expand_fields(schema)
        } else if !schema.allOf.is_empty() {
            let first = schema.allOf.first().unwrap().clone();
            let result = schema.allOf
                .iter()
                .skip(1)
                .fold(first, |mut result, def| {
                    merge(&mut result, self.schema(def));
                    result
                });
            self.expand_fields(&result)
        } else {
            schema.properties
                .iter()
                .map(|(key, value)| {
                    let key = field(key);
                    let typ = Ident(self.expand_type(value));
                    quote!( #key : #typ )
                })
                .collect()
        }
    }

    pub fn expand_schema(&mut self, schema: &Schema) -> Tokens {
        let mut types = Vec::new();
        for (name, def) in &schema.definitions {
            let fields = self.expand_fields(def);
            let name = Ident(name);
            let tokens = quote! {
                pub struct #name {
                    #(#fields),*
                }
            };
            types.push(tokens);
        }
        quote! { #(
            #types
            )*
        }
    }
}

pub fn generate(s: &str) -> Tokens {
    let schema = serde_json::from_str(s).unwrap();
    let mut expander = Expander { root: &schema };
    expander.expand_schema(&schema)
}

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

    #[test]
    fn attempt() {
        let s = include_str!("../../json-schema/tests/debugserver-schema.json");

        let s = generate(s).to_string();
        println!("`{}`", s);
        assert!(false);
    }
}
<|endoftext|>


<commit_before>//! # rustfm-scrobble
//!
//! Client for the Last.fm Scrobble API v2.0.

extern crate reqwest;
extern crate crypto;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde;

mod scrobbler;
mod client;
mod auth;
mod dto;

pub use scrobbler::Scrobbler;
<commit_msg>Expose API Response types plus ScrobblerErro (Issue #3)<commit_after>//! # rustfm-scrobble
//!
//! Client for the Last.fm Scrobble API v2.0.

extern crate reqwest;
extern crate crypto;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde;

mod scrobbler;
mod client;
mod auth;
mod dto;

pub use scrobbler::{Scrobbler, ScrobblerError};
pub use dto::{
    SessionResponse,
    NowPlayingResponse,
    ScrobbleResponse,
    CorrectableString
};
<|endoftext|>


<commit_before>#![crate_id = "graphics"]
#![deny(missing_doc)]

//! A library for 2D graphics that works with multiple back-ends.
//!
//! To implement your own back-end, use the BackEnd trait.
//!
//! ## Usage
//!
//! If you are using [Rust-Empty](https://github.com/bvssvni/rust-empty)
//! or Cargo, put the compiled library in
//! the "target/cpu-vendor-platform/lib/" directory,
//! then add the following to your source:
//!
//! ```Rust
//! #![feature(globs)] // Allow global imports
//!
//! extern crate graphics; // Link to 'graphics' library
//!
//! use graphics::*; // Use the graphics types in the module
//! ```
//!
//! To draw to the back-end, you need a context.
//! The context contains the information necessary to perform the drawing.
//! Unlike other graphics libraries, this library is not bound to the back-end.
//! You do not have to specify which back-end to use
//! before doing the actual drawing.
//!
//! For example, assuming we have a back-end called `back_end`:
//!
//! ```
//! Context::new().rect(x, y, w, h).rgba(r, g, b, a).fill(&mut back_end);
//! ```
//!
//! ## Important!
//!
//! Because the context is built using borrowed pointers,
//! it is not possible to do two or more steps at a time and
//! assign it to a variable:
//!
//! ```
//! // ERROR: Borrowed value does not live long enough
//! let rect = Context::new().rect(x, y, w, h);
//! ```
//!
//! This is because the lifetime of the first step only
//! lives inside the expression.
//! To solve this problem, break the statement into two parts,
//! one for each step:
//!
//! ```
//! let c = Context::new();
//! let rect = c.rect(x, y, w, h);
//! ```
//!
//! This is only the case when you are assigning the context to a variable.

extern crate core;
extern crate std;

pub use AddBevel
    = add_bevel::AddBevel;
pub use AddBevelBorder
    = add_bevel_border::AddBevelBorder;
pub use AddBorder
    = add_border::AddBorder;
pub use AddColor
    = add_color::AddColor;
pub use AddEllipse
    = add_ellipse::AddEllipse;
pub use AddImage
    = add_image::AddImage;
pub use AddLine
    = add_line::AddLine;
pub use AddPolygon
    = add_polygon::AddPolygon;
pub use AddPolygons
    = add_polygons::AddPolygons;
pub use AddRectangle
    = add_rectangle::AddRectangle;
pub use AddRound
    = add_round::AddRound;
pub use AddRoundBorder
    = add_round_border::AddRoundBorder;
pub use AddSquareBorder
    = add_square_border::AddSquareBorder;
pub use AddTween
    = add_tween::AddTween;
pub use BackEnd
    = back_end::BackEnd;
pub use BevelBorderLineColorContext
    = bevel_border_line_color_context::BevelBorderLineColorContext;
pub use BevelBorderLineContext
    = bevel_border_line_context::BevelBorderLineContext;
pub use BevelRectangleBorderColorContext
    = bevel_rectangle_border_color_context::BevelRectangleBorderColorContext;
pub use BevelRectangleBorderContext
    = bevel_rectangle_border_context::BevelRectangleBorderContext;
pub use BevelRectangleColorContext
    = bevel_rectangle_color_context::BevelRectangleColorContext;
pub use BevelRectangleContext
    = bevel_rectangle_context::BevelRectangleContext;
pub use ColorContext
    = color_context::ColorContext;
pub use Context
    = context::Context;
pub use Draw
    = draw::Draw;
pub use EllipseContext
    = ellipse_context::EllipseContext;
pub use EllipseBorderContext
    = ellipse_border_context::EllipseBorderContext;
pub use EllipseColorContext
    = ellipse_color_context::EllipseColorContext;
pub use EllipseBorderColorContext
    = ellipse_border_color_context::EllipseBorderColorContext;
pub use ImageSize
    = image_size::ImageSize;
pub use ImageContext
    = image_context::ImageContext;
pub use ImageColorContext
    = image_color_context::ImageColorContext;
pub use ImageRectangleContext
    = image_rectangle_context::ImageRectangleContext;
pub use ImageRectangleColorContext
    = image_rectangle_color_context::ImageRectangleColorContext;
pub use LerpTweenContext
    = lerp_tween_context::LerpTweenContext;
pub use LerpTweenColorContext
    = lerp_tween_color_context::LerpTweenColorContext;
pub use LerpTweenPolygonsContext
    = lerp_tween_polygons_context::LerpTweenPolygonsContext;
pub use LerpTweenPolygonsColorContext
    = lerp_tween_polygons_color_context::LerpTweenPolygonsColorContext;
pub use LineContext
    = line_context::LineContext;
pub use LineColorContext
    = line_color_context::LineColorContext;
pub use PolygonContext
    = polygon_context::PolygonContext;
pub use PolygonColorContext
    = polygon_color_context::PolygonColorContext;
pub use RectangleBorderContext
    = rectangle_border_context::RectangleBorderContext;
pub use RectangleBorderColorContext
    = rectangle_border_color_context::RectangleBorderColorContext;
pub use RectangleContext
    = rectangle_context::RectangleContext;
pub use RectangleColorContext
    = rectangle_color_context::RectangleColorContext;
pub use RelativeColor
    = relative_color::RelativeColor;
pub use RelativeRectangle
    = relative_rectangle::RelativeRectangle;
pub use RelativeSourceRectangle
    = relative_source_rectangle::RelativeSourceRectangle;
pub use RelativeTransform2d
    = relative_transform2d::RelativeTransform2d;
pub use RoundBorderLineContext
    = round_border_line_context::RoundBorderLineContext;
pub use RoundBorderLineColorContext
    = round_border_line_color_context::RoundBorderLineColorContext;
pub use RoundRectangleBorderColorContext
    = round_rectangle_border_color_context::RoundRectangleBorderColorContext;
pub use RoundRectangleBorderContext
    = round_rectangle_border_context::RoundRectangleBorderContext;
pub use RoundRectangleColorContext
    = round_rectangle_color_context::RoundRectangleColorContext;
pub use RoundRectangleContext
    = round_rectangle_context::RoundRectangleContext;
pub use SquareBorderLineColorContext
    = square_border_line_color_context::SquareBorderLineColorContext;
pub use SquareBorderLineContext
    = square_border_line_context::SquareBorderLineContext;
pub use View
    = view::View;

mod add_bevel;
mod add_bevel_border;
mod add_border;
mod add_color;
mod add_ellipse;
mod add_image;
mod add_line;
mod add_polygon;
mod add_polygons;
mod add_rectangle;
mod add_round;
mod add_round_border;
mod add_square_border;
mod add_tween;
mod back_end;
mod bevel_border_line_color_context;
mod bevel_border_line_context;
mod bevel_rectangle_border_color_context;
mod bevel_rectangle_border_context;
mod bevel_rectangle_color_context;
mod bevel_rectangle_context;
mod color_context;
mod context;
mod draw;
mod ellipse_border_context;
mod ellipse_border_color_context;
mod ellipse_color_context;
mod ellipse_context;
mod image_size;
mod image_context;
mod image_color_context;
mod image_rectangle_color_context;
mod image_rectangle_context;
mod line_color_context;
mod line_context;
mod polygon_color_context;
mod polygon_context;
mod rectangle_border_context;
mod rectangle_border_color_context;
mod rectangle_color_context;
mod rectangle_context;
mod relative_color;
mod relative_rectangle;
mod relative_source_rectangle;
mod relative_transform2d;
mod round_border_line_color_context;
mod round_border_line_context;
mod round_rectangle_border_color_context;
mod round_rectangle_border_context;
mod round_rectangle_color_context;
mod round_rectangle_context;
mod square_border_line_color_context;
mod square_border_line_context;
mod lerp_tween_color_context;
mod lerp_tween_context;
mod lerp_tween_polygons_color_context;
mod lerp_tween_polygons_context;
mod view;

pub mod internal;
pub mod interpolation;
pub mod modular_index;
pub mod triangulation;
pub mod vecmath;

/// A structure that might contain a value or a borrowed value.
/// This is to used as building block to create data structure
/// that is partially based on an existing structure.
pub enum Field<T> {
    /// Contains a value.
    Value(T),
}

impl<T: Copy> Field<T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&self) -> T {
        match *self {
            Value(val) => val,
        }
    }
}

/* Uncomment when lifetime traits problem is solved.
pub enum Field<'a, T> {
    /// Contains a value.
    Value(T),
    /// Contains a borrowed pointer.
    Borrowed(&'a T),
}

impl<'a, T> Field<'a, T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&'a self) -> &'a T {
        match *self {
            Value(val) => val,
        }
    }
}
*/

<commit_msg>Removed outdated comment<commit_after>#![crate_id = "graphics"]
#![deny(missing_doc)]

//! A library for 2D graphics that works with multiple back-ends.

extern crate core;
extern crate std;

pub use AddBevel
    = add_bevel::AddBevel;
pub use AddBevelBorder
    = add_bevel_border::AddBevelBorder;
pub use AddBorder
    = add_border::AddBorder;
pub use AddColor
    = add_color::AddColor;
pub use AddEllipse
    = add_ellipse::AddEllipse;
pub use AddImage
    = add_image::AddImage;
pub use AddLine
    = add_line::AddLine;
pub use AddPolygon
    = add_polygon::AddPolygon;
pub use AddPolygons
    = add_polygons::AddPolygons;
pub use AddRectangle
    = add_rectangle::AddRectangle;
pub use AddRound
    = add_round::AddRound;
pub use AddRoundBorder
    = add_round_border::AddRoundBorder;
pub use AddSquareBorder
    = add_square_border::AddSquareBorder;
pub use AddTween
    = add_tween::AddTween;
pub use BackEnd
    = back_end::BackEnd;
pub use BevelBorderLineColorContext
    = bevel_border_line_color_context::BevelBorderLineColorContext;
pub use BevelBorderLineContext
    = bevel_border_line_context::BevelBorderLineContext;
pub use BevelRectangleBorderColorContext
    = bevel_rectangle_border_color_context::BevelRectangleBorderColorContext;
pub use BevelRectangleBorderContext
    = bevel_rectangle_border_context::BevelRectangleBorderContext;
pub use BevelRectangleColorContext
    = bevel_rectangle_color_context::BevelRectangleColorContext;
pub use BevelRectangleContext
    = bevel_rectangle_context::BevelRectangleContext;
pub use ColorContext
    = color_context::ColorContext;
pub use Context
    = context::Context;
pub use Draw
    = draw::Draw;
pub use EllipseContext
    = ellipse_context::EllipseContext;
pub use EllipseBorderContext
    = ellipse_border_context::EllipseBorderContext;
pub use EllipseColorContext
    = ellipse_color_context::EllipseColorContext;
pub use EllipseBorderColorContext
    = ellipse_border_color_context::EllipseBorderColorContext;
pub use ImageSize
    = image_size::ImageSize;
pub use ImageContext
    = image_context::ImageContext;
pub use ImageColorContext
    = image_color_context::ImageColorContext;
pub use ImageRectangleContext
    = image_rectangle_context::ImageRectangleContext;
pub use ImageRectangleColorContext
    = image_rectangle_color_context::ImageRectangleColorContext;
pub use LerpTweenContext
    = lerp_tween_context::LerpTweenContext;
pub use LerpTweenColorContext
    = lerp_tween_color_context::LerpTweenColorContext;
pub use LerpTweenPolygonsContext
    = lerp_tween_polygons_context::LerpTweenPolygonsContext;
pub use LerpTweenPolygonsColorContext
    = lerp_tween_polygons_color_context::LerpTweenPolygonsColorContext;
pub use LineContext
    = line_context::LineContext;
pub use LineColorContext
    = line_color_context::LineColorContext;
pub use PolygonContext
    = polygon_context::PolygonContext;
pub use PolygonColorContext
    = polygon_color_context::PolygonColorContext;
pub use RectangleBorderContext
    = rectangle_border_context::RectangleBorderContext;
pub use RectangleBorderColorContext
    = rectangle_border_color_context::RectangleBorderColorContext;
pub use RectangleContext
    = rectangle_context::RectangleContext;
pub use RectangleColorContext
    = rectangle_color_context::RectangleColorContext;
pub use RelativeColor
    = relative_color::RelativeColor;
pub use RelativeRectangle
    = relative_rectangle::RelativeRectangle;
pub use RelativeSourceRectangle
    = relative_source_rectangle::RelativeSourceRectangle;
pub use RelativeTransform2d
    = relative_transform2d::RelativeTransform2d;
pub use RoundBorderLineContext
    = round_border_line_context::RoundBorderLineContext;
pub use RoundBorderLineColorContext
    = round_border_line_color_context::RoundBorderLineColorContext;
pub use RoundRectangleBorderColorContext
    = round_rectangle_border_color_context::RoundRectangleBorderColorContext;
pub use RoundRectangleBorderContext
    = round_rectangle_border_context::RoundRectangleBorderContext;
pub use RoundRectangleColorContext
    = round_rectangle_color_context::RoundRectangleColorContext;
pub use RoundRectangleContext
    = round_rectangle_context::RoundRectangleContext;
pub use SquareBorderLineColorContext
    = square_border_line_color_context::SquareBorderLineColorContext;
pub use SquareBorderLineContext
    = square_border_line_context::SquareBorderLineContext;
pub use View
    = view::View;

mod add_bevel;
mod add_bevel_border;
mod add_border;
mod add_color;
mod add_ellipse;
mod add_image;
mod add_line;
mod add_polygon;
mod add_polygons;
mod add_rectangle;
mod add_round;
mod add_round_border;
mod add_square_border;
mod add_tween;
mod back_end;
mod bevel_border_line_color_context;
mod bevel_border_line_context;
mod bevel_rectangle_border_color_context;
mod bevel_rectangle_border_context;
mod bevel_rectangle_color_context;
mod bevel_rectangle_context;
mod color_context;
mod context;
mod draw;
mod ellipse_border_context;
mod ellipse_border_color_context;
mod ellipse_color_context;
mod ellipse_context;
mod image_size;
mod image_context;
mod image_color_context;
mod image_rectangle_color_context;
mod image_rectangle_context;
mod line_color_context;
mod line_context;
mod polygon_color_context;
mod polygon_context;
mod rectangle_border_context;
mod rectangle_border_color_context;
mod rectangle_color_context;
mod rectangle_context;
mod relative_color;
mod relative_rectangle;
mod relative_source_rectangle;
mod relative_transform2d;
mod round_border_line_color_context;
mod round_border_line_context;
mod round_rectangle_border_color_context;
mod round_rectangle_border_context;
mod round_rectangle_color_context;
mod round_rectangle_context;
mod square_border_line_color_context;
mod square_border_line_context;
mod lerp_tween_color_context;
mod lerp_tween_context;
mod lerp_tween_polygons_color_context;
mod lerp_tween_polygons_context;
mod view;

pub mod internal;
pub mod interpolation;
pub mod modular_index;
pub mod triangulation;
pub mod vecmath;

/// A structure that might contain a value or a borrowed value.
/// This is to used as building block to create data structure
/// that is partially based on an existing structure.
pub enum Field<T> {
    /// Contains a value.
    Value(T),
}

impl<T: Copy> Field<T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&self) -> T {
        match *self {
            Value(val) => val,
        }
    }
}

/* Uncomment when lifetime traits problem is solved.
pub enum Field<'a, T> {
    /// Contains a value.
    Value(T),
    /// Contains a borrowed pointer.
    Borrowed(&'a T),
}

impl<'a, T> Field<'a, T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&'a self) -> &'a T {
        match *self {
            Value(val) => val,
        }
    }
}
*/

<|endoftext|>


<commit_before>// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the Cargo.toml file at the top-level directory of this distribution.
//
// 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.

//! A low-dimensional linear algebra library, targeted at computer graphics.
//!
//! # Trait overview
//!
//! In order to make a clean, composable API, we divide operations into traits
//! that are roughly based on mathematical properties. The main ones that we
//! concern ourselves with are listed below:
//!
//! - `VectorSpace`: Specifies the main operators for vectors, quaternions, and
//!   matrices.
//! - `MetricSpace`: For types that have a distance function implemented.
//! - `InnerSpace`: For types that have a dot (or inner) product - ie. vectors or
//!   quaternions. This also allows for the definition of operations that are
//!   based on the dot product, like finding the magnitude or normalizing.
//! - `EuclideanSpace`: Points in euclidean space, with an associated space of
//!   displacement vectors.
//! - `Matrix`: Common operations for matrices of arbitrary dimensions.
//! - `SquareMatrix`: A special trait for matrices where the number of columns
//!   equal the number of rows.
//!
//! Other traits are included for practical convenience, for example:
//!
//! - `Array`: For contiguous, indexable arrays of elements, specifically
//!   vectors.
//! - `ElementWise`: For element-wise addition, subtraction, multiplication,
//!   division, and remainder operations.
//!
//! # The prelude
//!
//! Importing each trait individually can become a chore, so we provide a
//! `prelude` module to allow you to import the main trait all at once. For
//! example:
//!
//! ```rust
//! use cgmath::prelude::*;
//! ```

#![cfg_attr(feature = "simd", feature(specialization))]

#[macro_use]
extern crate approx;

#[cfg(feature = "mint")]
pub extern crate mint;

extern crate rand;
pub extern crate num_traits;

#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;

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

// Re-exports

pub use approx::*;
pub use num::*;
pub use structure::*;

pub use matrix::{Matrix2, Matrix3, Matrix4};
pub use quaternion::Quaternion;
pub use vector::{dot, Vector1, Vector2, Vector3, Vector4, vec1, vec2, vec3, vec4};

pub use angle::{Deg, Rad};
pub use euler::Euler;
pub use point::{Point1, Point2, Point3, point1, point2, point3};
pub use rotation::*;
pub use transform::*;

pub use projection::*;

// Modules

pub mod conv;
pub mod prelude;

mod macros;

mod num;
mod structure;

mod matrix;
mod quaternion;
mod vector;

mod angle;
mod euler;
mod point;
mod rotation;
mod transform;

mod projection;
<commit_msg>fixed dropped 's' in trait.<commit_after>// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the Cargo.toml file at the top-level directory of this distribution.
//
// 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.

//! A low-dimensional linear algebra library, targeted at computer graphics.
//!
//! # Trait overview
//!
//! In order to make a clean, composable API, we divide operations into traits
//! that are roughly based on mathematical properties. The main ones that we
//! concern ourselves with are listed below:
//!
//! - `VectorSpace`: Specifies the main operators for vectors, quaternions, and
//!   matrices.
//! - `MetricSpace`: For types that have a distance function implemented.
//! - `InnerSpace`: For types that have a dot (or inner) product - ie. vectors or
//!   quaternions. This also allows for the definition of operations that are
//!   based on the dot product, like finding the magnitude or normalizing.
//! - `EuclideanSpace`: Points in euclidean space, with an associated space of
//!   displacement vectors.
//! - `Matrix`: Common operations for matrices of arbitrary dimensions.
//! - `SquareMatrix`: A special trait for matrices where the number of columns
//!   equal the number of rows.
//!
//! Other traits are included for practical convenience, for example:
//!
//! - `Array`: For contiguous, indexable arrays of elements, specifically
//!   vectors.
//! - `ElementWise`: For element-wise addition, subtraction, multiplication,
//!   division, and remainder operations.
//!
//! # The prelude
//!
//! Importing each trait individually can become a chore, so we provide a
//! `prelude` module to allow you to import the main traits all at once. For
//! example:
//!
//! ```rust
//! use cgmath::prelude::*;
//! ```

#![cfg_attr(feature = "simd", feature(specialization))]

#[macro_use]
extern crate approx;

#[cfg(feature = "mint")]
pub extern crate mint;

extern crate rand;
pub extern crate num_traits;

#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;

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

// Re-exports

pub use approx::*;
pub use num::*;
pub use structure::*;

pub use matrix::{Matrix2, Matrix3, Matrix4};
pub use quaternion::Quaternion;
pub use vector::{dot, Vector1, Vector2, Vector3, Vector4, vec1, vec2, vec3, vec4};

pub use angle::{Deg, Rad};
pub use euler::Euler;
pub use point::{Point1, Point2, Point3, point1, point2, point3};
pub use rotation::*;
pub use transform::*;

pub use projection::*;

// Modules

pub mod conv;
pub mod prelude;

mod macros;

mod num;
mod structure;

mod matrix;
mod quaternion;
mod vector;

mod angle;
mod euler;
mod point;
mod rotation;
mod transform;

mod projection;
<|endoftext|>


<commit_before>//! Use this library to open a path or URL using the program configured on the system.
//!
//! # Usage
//!
//! The following should open the given URL in a web browser
//!
//! ```test_harness,no_run
//! extern crate open;
//!
//! # #[test]
//! # fn doit() {
//! open::that("http://rust-lang.org").unwrap();
//! # }
//! ```
//!
//! # Notes
//!
//! As an operating system program is used, chances are that the open operation fails.
//! Therefore, you are advised to at least check the result with `.is_err()` and
//! behave accordingly, e.g. by letting the user know what you tried to open, and failed.
//!
//! ```
//! # fn doit() {
//! match open::that("http://rust-lang.org") {
//!     Ok(exit_status) => {
//!         if exit_status.success() {
//!             println!("Look at your browser!");
//!         } else {
//!             if let Some(code) = exit_status.code() {
//!                 println!("Command returned non-zero exit status {}!", code);
//!             } else {
//!                 println!("Command returned with unknown exit status!");
//!             }
//!         }
//!     }
//!     Err(why) => println!("Failure to execute command: {}", why),
//! }
//! # }
//! ```
#[cfg(windows)]
extern crate winapi;

#[cfg(not(windows))]
use std::process::Stdio;

use std::{
    ffi::OsStr,
    io,
    process::ExitStatus,
    thread
};

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
pub fn that<T: AsRef<OsStr> + Sized>(path: T) -> io::Result<ExitStatus> {
    let path_ref = path.as_ref();
    let mut last_err: io::Error = io::Error::from_raw_os_error(0);
    for program in &["xdg-open", "gnome-open", "kde-open", "wslview"] {
        match Command::new(program)
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .arg(path_ref)
            .spawn()
        {
            Ok(mut child) => return child.wait(),
            Err(err) => {
                last_err = err;
                continue;
            }
        }
    }
    Err(last_err)
}

#[cfg(target_os = "windows")]
pub fn that<T: AsRef<OsStr> + Sized>(path: T) -> io::Result<ExitStatus> {
    use std::os::windows::ffi::OsStrExt;
    use std::os::windows::process::ExitStatusExt;
    use std::ptr;
    use winapi::ctypes::c_int;
    use winapi::um::shellapi::ShellExecuteW;

    const SW_SHOW: c_int = 5;

    let path = windows::convert_path(path.as_ref())?;
    let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
    let result = unsafe {
        ShellExecuteW(
            ptr::null_mut(),
            operation.as_ptr(),
            path.as_ptr(),
            ptr::null(),
            ptr::null(),
            SW_SHOW,
        )
    };
    if result as c_int > 32 {
        Ok(ExitStatus::from_raw(0))
    } else {
        Err(io::Error::last_os_error())
    }
}

#[cfg(target_os = "macos")]
pub fn that<T: AsRef<OsStr> + Sized>(path: T) -> io::Result<ExitStatus> {
    Command::new("open")
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .arg(path.as_ref())
        .spawn()?
        .wait()
}

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
pub fn with<T:AsRef<OsStr>+Sized>(path: T, app: impl Into<String>) -> io::Result<ExitStatus> {
    Command::new(app.into())
        .arg(path.as_ref())
        .spawn()?
        .wait()
}

#[cfg(target_os = "windows")]
pub fn with<T:AsRef<OsStr>+Sized>(path: T, app: impl Into<String>) -> io::Result<ExitStatus> {
    use std::os::windows::ffi::OsStrExt;
    use std::os::windows::process::ExitStatusExt;
    use std::ptr;
    use winapi::ctypes::c_int;
    use winapi::um::shellapi::ShellExecuteW;

    const SW_SHOW: c_int = 5;

    let path = windows::convert_path(path.as_ref())?;
    let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
    let app_name: Vec<u16> = OsStr::new(&format!("{}\0", app.into())).encode_wide().collect();
    let result = unsafe {
        ShellExecuteW(
            ptr::null_mut(),
            operation.as_ptr(),
            app_name.as_ptr(),
            path.as_ptr(),
            ptr::null(),
            SW_SHOW,
        )
    };
    if result as c_int > 32 {
        Ok(ExitStatus::from_raw(0))
    } else {
        Err(io::Error::last_os_error())
    }
}

#[cfg(target_os = "macos")]
pub fn with<T:AsRef<OsStr>+Sized>(path: T, app: impl Into<String>) -> io::Result<ExitStatus> {
    Command::new("open")
        .arg(path.as_ref())
        .arg("-a")
        .arg(app.into())
        .spawn()?
        .wait()
}

/// Convenience function for opening the passed path in a new thread.
/// See documentation of `that(...)` for more details.
pub fn that_in_background<T: AsRef<OsStr> + Sized>(
    path: T,
) -> thread::JoinHandle<io::Result<ExitStatus>> {
    let path = path.as_ref().to_os_string();
    thread::spawn(|| that(path))
}

pub fn with_in_background<T: AsRef<OsStr> + Sized>(
    path: T,
    app: impl Into<String>
) -> thread::JoinHandle<io::Result<ExitStatus>> {
    let path = path.as_ref().to_os_string();
    let app = app.into();
    thread::spawn(|| with(path, app))
}

#[cfg(windows)]
mod windows {
    use std::ffi::OsStr;
    use std::io;
    use std::os::windows::ffi::OsStrExt;

    pub fn convert_path(path: &OsStr) -> io::Result<Vec<u16>> {
        let mut maybe_result: Vec<_> = path.encode_wide().collect();
        if maybe_result.iter().any(|&u| u == 0) {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                "path contains NUL byte(s)",
            ));
        }
        maybe_result.push(0);
        Ok(maybe_result)
    }
}
<commit_msg>fixed import bug<commit_after>//! Use this library to open a path or URL using the program configured on the system.
//!
//! # Usage
//!
//! The following should open the given URL in a web browser
//!
//! ```test_harness,no_run
//! extern crate open;
//!
//! # #[test]
//! # fn doit() {
//! open::that("http://rust-lang.org").unwrap();
//! # }
//! ```
//!
//! # Notes
//!
//! As an operating system program is used, chances are that the open operation fails.
//! Therefore, you are advised to at least check the result with `.is_err()` and
//! behave accordingly, e.g. by letting the user know what you tried to open, and failed.
//!
//! ```
//! # fn doit() {
//! match open::that("http://rust-lang.org") {
//!     Ok(exit_status) => {
//!         if exit_status.success() {
//!             println!("Look at your browser!");
//!         } else {
//!             if let Some(code) = exit_status.code() {
//!                 println!("Command returned non-zero exit status {}!", code);
//!             } else {
//!                 println!("Command returned with unknown exit status!");
//!             }
//!         }
//!     }
//!     Err(why) => println!("Failure to execute command: {}", why),
//! }
//! # }
//! ```
#[cfg(windows)]
extern crate winapi;

#[cfg(not(windows))]
use std::process::{Command, Stdio};

use std::{
    ffi::OsStr,
    io,
    process::ExitStatus,
    thread
};

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
pub fn that<T: AsRef<OsStr> + Sized>(path: T) -> io::Result<ExitStatus> {
    let path_ref = path.as_ref();
    let mut last_err: io::Error = io::Error::from_raw_os_error(0);
    for program in &["xdg-open", "gnome-open", "kde-open", "wslview"] {
        match Command::new(program)
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .arg(path_ref)
            .spawn()
        {
            Ok(mut child) => return child.wait(),
            Err(err) => {
                last_err = err;
                continue;
            }
        }
    }
    Err(last_err)
}

#[cfg(target_os = "windows")]
pub fn that<T: AsRef<OsStr> + Sized>(path: T) -> io::Result<ExitStatus> {
    use std::os::windows::ffi::OsStrExt;
    use std::os::windows::process::ExitStatusExt;
    use std::ptr;
    use winapi::ctypes::c_int;
    use winapi::um::shellapi::ShellExecuteW;

    const SW_SHOW: c_int = 5;

    let path = windows::convert_path(path.as_ref())?;
    let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
    let result = unsafe {
        ShellExecuteW(
            ptr::null_mut(),
            operation.as_ptr(),
            path.as_ptr(),
            ptr::null(),
            ptr::null(),
            SW_SHOW,
        )
    };
    if result as c_int > 32 {
        Ok(ExitStatus::from_raw(0))
    } else {
        Err(io::Error::last_os_error())
    }
}

#[cfg(target_os = "macos")]
pub fn that<T: AsRef<OsStr> + Sized>(path: T) -> io::Result<ExitStatus> {
    Command::new("open")
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .arg(path.as_ref())
        .spawn()?
        .wait()
}

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
pub fn with<T:AsRef<OsStr>+Sized>(path: T, app: impl Into<String>) -> io::Result<ExitStatus> {
    Command::new(app.into())
        .arg(path.as_ref())
        .spawn()?
        .wait()
}

#[cfg(target_os = "windows")]
pub fn with<T:AsRef<OsStr>+Sized>(path: T, app: impl Into<String>) -> io::Result<ExitStatus> {
    use std::os::windows::ffi::OsStrExt;
    use std::os::windows::process::ExitStatusExt;
    use std::ptr;
    use winapi::ctypes::c_int;
    use winapi::um::shellapi::ShellExecuteW;

    const SW_SHOW: c_int = 5;

    let path = windows::convert_path(path.as_ref())?;
    let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
    let app_name: Vec<u16> = OsStr::new(&format!("{}\0", app.into())).encode_wide().collect();
    let result = unsafe {
        ShellExecuteW(
            ptr::null_mut(),
            operation.as_ptr(),
            app_name.as_ptr(),
            path.as_ptr(),
            ptr::null(),
            SW_SHOW,
        )
    };
    if result as c_int > 32 {
        Ok(ExitStatus::from_raw(0))
    } else {
        Err(io::Error::last_os_error())
    }
}

#[cfg(target_os = "macos")]
pub fn with<T:AsRef<OsStr>+Sized>(path: T, app: impl Into<String>) -> io::Result<ExitStatus> {
    Command::new("open")
        .arg(path.as_ref())
        .arg("-a")
        .arg(app.into())
        .spawn()?
        .wait()
}

/// Convenience function for opening the passed path in a new thread.
/// See documentation of `that(...)` for more details.
pub fn that_in_background<T: AsRef<OsStr> + Sized>(
    path: T,
) -> thread::JoinHandle<io::Result<ExitStatus>> {
    let path = path.as_ref().to_os_string();
    thread::spawn(|| that(path))
}

pub fn with_in_background<T: AsRef<OsStr> + Sized>(
    path: T,
    app: impl Into<String>
) -> thread::JoinHandle<io::Result<ExitStatus>> {
    let path = path.as_ref().to_os_string();
    let app = app.into();
    thread::spawn(|| with(path, app))
}

#[cfg(windows)]
mod windows {
    use std::ffi::OsStr;
    use std::io;
    use std::os::windows::ffi::OsStrExt;

    pub fn convert_path(path: &OsStr) -> io::Result<Vec<u16>> {
        let mut maybe_result: Vec<_> = path.encode_wide().collect();
        if maybe_result.iter().any(|&u| u == 0) {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                "path contains NUL byte(s)",
            ));
        }
        maybe_result.push(0);
        Ok(maybe_result)
    }
}
<|endoftext|>


<commit_before>//! Compile-time assertions to ensure that invariants are met.
//!
//! _All_ assertions within this crate are performed at **compile-time**. This
//! allows for finding errors quickly and early when it comes to ensuring
//! certain features or aspects of a codebase.
//!
//! # Usage
//!
//! This crate is available [on crates.io][crate] and can be used by adding the
//! following to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! static_assertions = "0.2.4"
//! ```
//!
//! and this to your crate root:
//!
//! ```
//! #[macro_use]
//! extern crate static_assertions;
//! # fn main() {}
//! ```
//!
//! # Examples
//!
//! Very thorough examples are provided in the docs for each individual macro.
//! Failure case examples are also documented.
//!
//! # Limitations
//!
//! Due to implementation details, some macros can only be used normally from
//! within the context of a function. To use these macros in other contexts, a
//! unique label must be provided.
//!
//! ```compile_fail
//! # #[macro_use] extern crate static_assertions;
//! # fn main() {}
//! // error: expected item after attributes
//! const_assert!(true == true);
//! ```
//!
//! This can be fixed via:
//!
//! ```
//! # #[macro_use] extern crate static_assertions;
//! # fn main() {}
//! const_assert!(label; true == true);
//! ```
//!
//! This issue can be followed [here][issue1]. Feedback and potential solutions
//! are welcome!
//!
//! [issue1]: https://github.com/nvzqz/static-assertions-rs/issues/1
//! [crate]: https://crates.io/crates/static_assertions

#![no_std]

#![deny(unused_macros)]

#[doc(hidden)]
pub extern crate core as _core;

/// Asserts that a given configuration is set.
///
/// # Examples
///
/// A project may not support a set of configurations and thus you may want to
/// report why:
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// // We should only be compiling for Unix or Linux
/// # #[cfg(any(unix, linux))]
/// assert_cfg!(any(unix, linux));
/// # fn main() {}
/// ```
///
/// If users need to specify a database back-end:
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # #[cfg(target_pointer_width = "0")] // Impossible
/// assert_cfg!("Must exclusively use MySQL or MongoDB as database back-end",
///             all(not(all(feature = "mysql", feature = "mongodb")),
///                 any(    feature = "mysql", feature = "mongodb")));
/// # fn main() {}
/// ```
///
/// We can't be compiling for both Unix _and_ Windows simultaneously:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_cfg!("No, that's not how it works! ಠ_ಠ", all(unix, windows));
/// # }
/// ```
#[macro_export]
macro_rules! assert_cfg {
    () => {};
    ($msg:expr, $($cfg:tt)*) => {
        #[cfg(not($($cfg)*))]
        compile_error!($msg);
    };
    ($($cfg:tt)*) => {
        #[cfg(not($($cfg)*))]
        compile_error!(concat!("Cfg does not pass: ", stringify!($($cfg)*)));
    };
}

/// Asserts that types are equal in size.
///
/// When performing operations such as pointer casts or dealing with [`usize`]
/// versus [`u64`] versus [`u32`], the size of your types matter. This is where
/// this macro comes into play.
///
/// # Alternatives
///
/// There are also [`assert_eq_size_val`](macro.assert_eq_size_val.html) and
/// [`assert_eq_size_ptr`](macro.assert_eq_size_ptr.html). Instead of specifying
/// types to compare, values' sizes can be directly compared against each other.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// // Can be declared outside of a function if labeled
/// assert_eq_size!(bytes; (u8, u8), u16);
///
/// fn main() {
///     // Supports unlimited arguments:
///     assert_eq_size!([u8; 4], (u16, u16), u32);
/// }
/// ```
///
/// The following produces a compilation failure because `u32` has 4 times the
/// size of `u8`:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_eq_size!(u32, u8);
/// # }
/// ```
///
/// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
/// [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html
/// [`u32`]: https://doc.rust-lang.org/std/primitive.u32.html
#[macro_export]
macro_rules! assert_eq_size {
    ($x:ty, $($xs:ty),+ $(,)*) => {
        $(let _ = $crate::_core::mem::transmute::<$x, $xs>;)+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_eq_size!($($xs)+); }
    };
}

/// Asserts that values pointed to are equal in size.
///
/// This especially is useful for when coercing pointers between different types
/// and ensuring the underlying values are the same size.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// fn operation(x: &(u32, u32), y: &[u16; 4]) {
///     assert_eq_size_ptr!(x, y);
/// }
/// # fn main() {}
/// ```
///
/// Byte arrays of different lengths have different sizes:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// static BYTES: &[u8; 4] = &[
///     /* ... */
///     # 0; 4
/// ];
///
/// static TABLE: &[u8; 16] = &[
///     /* ... */
///     # 0; 16
/// ];
///
/// assert_eq_size_ptr!(BYTES, TABLE);
/// # }
/// ```
#[macro_export]
macro_rules! assert_eq_size_ptr {
    ($x:expr, $($xs:expr),+ $(,)*) => {
        #[allow(unknown_lints, forget_copy, unused_unsafe, useless_transmute)]
        unsafe {
            use $crate::_core::{mem, ptr};
            let mut copy = ptr::read($x);
            $(ptr::write(&mut copy, mem::transmute(ptr::read($xs)));)+
            mem::forget(copy);
        }
    }
}

/// Asserts that values are equal in size.
///
/// This macro doesn't consume its arguments and thus works for
/// non-[`Clone`]able values.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # fn main() {
/// struct Byte(u8);
///
/// let x = 10u8;
/// let y = Byte(42); // Works for non-cloneable types
///
/// assert_eq_size_val!(x, y);
/// assert_eq_size_val!(x, y, 0u8);
/// # }
/// ```
///
/// Even though both values are 0, they are of types with different sizes:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_eq_size_val!(0u8, 0u32);
/// # }
/// ```
///
/// [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html
#[macro_export]
macro_rules! assert_eq_size_val {
    ($x:expr, $($xs:expr),+ $(,)*) => {
        assert_eq_size_ptr!(&$x, $(&$xs),+);
    }
}

/// Asserts that constant expressions evaluate to `true`.
///
/// There also exists [`const_assert_eq`](macro.const_assert_eq.html) for
/// validating whether a sequence of expressions are equal to one another.
///
/// # Examples
///
/// Constant expressions can be ensured to have certain properties via this
/// macro If the expression evaluates to `false`, the file will fail to compile.
/// This is synonymous to [`static_assert` in C++][static_assert].
///
/// As a [limitation](index.html#limitations), a unique label is required if
/// the macro is used outside of a function.
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// const FIVE: usize = 5;
///
/// const_assert!(twenty_five; FIVE * FIVE == 25);
///
/// fn main() {
///     const_assert!(2 + 2 == 4);
///     const_assert!(FIVE - FIVE == 0);
/// }
/// ```
///
/// Some expressions are blatantly false:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// const_assert!(1 >= 2);
/// # }
/// ```
///
/// [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
#[macro_export]
macro_rules! const_assert {
    ($($xs:expr),+ $(,)*) => {
        #[allow(unknown_lints, eq_op)]
        let _: [(); 0 - !($($xs)&&+) as usize];
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { const_assert!($($xs)+); }
    };
}

/// Asserts that constants are equal in value.
///
/// # Examples
///
/// Works as a shorthand for `const_assert!(a == b)`:
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// const TWO: usize = 2;
/// const_assert_eq!(two; TWO * TWO, TWO + TWO, 4);
///
/// fn main() {
///     const NUM: usize = 32;
///     const_assert_eq!(NUM + NUM, 64);
/// }
/// ```
///
/// Just because 2 × 2 = 2 + 2 doesn't mean it holds true for other numbers:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// const_assert_eq!(4 + 4, 4 * 4);
/// # }
/// ```
#[macro_export]
macro_rules! const_assert_eq {
    ($x:expr, $($xs:expr),+ $(,)*) => {
        const_assert!($($x == $xs),+);
    };
    ($label:ident; $x:expr, $($xs:expr),+ $(,)*) => {
        const_assert!($label; $($x == $xs),+);
    };
}

/// Asserts that the traits are object-safe.
///
/// This is useful for when changes are made to a trait that accidentally
/// prevent it from being used as an object. Such a case would be adding a
/// generic method and forgetting to add `where Self: Sized` after it. If left
/// unnoticed, that mistake will affect crate users and break both forward and
/// backward compatibility.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// assert_obj_safe!(basic; Send, Sync, AsRef<str>);
///
/// mod inner {
///     // Works with traits that are not in the calling module
///     pub trait BasicTrait {
///         fn foo(&self);
///     }
/// }
///
/// trait MySafeTrait {
///     fn bar(&self) -> u32;
/// }
///
/// fn main() {
///     assert_obj_safe!(MySafeTrait);
///     assert_obj_safe!(inner::BasicTrait);
/// }
/// ```
///
/// Generics without `where Self: Sized` are not allowed in object-safe traits:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// trait MyUnsafeTrait {
///     fn baz<T>(&self) -> T;
/// }
///
/// # fn main() {
/// assert_obj_safe!(MyUnsafeTrait);
/// # }
/// ```
#[macro_export]
macro_rules! assert_obj_safe {
    ($($xs:ty),+ $(,)*) => {
        $(let _: &$xs;)+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_obj_safe!($($xs)+); }
    };
}

/// Asserts that the type has the given fields.
///
/// # Examples
///
/// This may be used when types have odd fields as a result of `#[cfg]`.
///
/// ```
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// struct Ty {
///     #[cfg(windows)]
///     value: u8,
///     #[cfg(not(windows))]
///     value: usize,
/// }
///
/// /* ... */
///
/// // Always have `value` regardless of OS
/// assert_fields!(Ty, value);
/// # }
/// ```
///
/// Range does not have a field named `middle`:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// use std::ops::Range;
///
/// assert_fields!(Range<u32>, middle);
/// # }
/// ```
#[macro_export]
macro_rules! assert_fields {
    ($t:path, $($f:ident),+) => {
        $(let $t { $f: _, .. };)+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_fields!($($xs)+); }
    };
}

/// Asserts that the type implements the given traits.
///
/// # Examples
///
/// Can be used to ensure types implement [`Send`], [`Sync`], and other traits:
///
/// ```
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {}
/// assert_impl!(str; String, Send, Sync, From<&'static str>);
/// assert_impl!(vec; &'static [u8], Into<Vec<u8>>);
/// ```
///
/// Raw pointers cannot be sent between threads safely:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_impl!(*const u8, Send);
/// # }
/// ```
///
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
#[macro_export]
macro_rules! assert_impl {
    ($x:ty, $($t:path),+ $(,)*) => {
        $({
            fn assert_impl<T: ?Sized + $t>() {}
            assert_impl::<$x>();
        })+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_impl!($($xs)+); }
    };
}
<commit_msg>Combine trait bounds in assert_impl fn<commit_after>//! Compile-time assertions to ensure that invariants are met.
//!
//! _All_ assertions within this crate are performed at **compile-time**. This
//! allows for finding errors quickly and early when it comes to ensuring
//! certain features or aspects of a codebase.
//!
//! # Usage
//!
//! This crate is available [on crates.io][crate] and can be used by adding the
//! following to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! static_assertions = "0.2.4"
//! ```
//!
//! and this to your crate root:
//!
//! ```
//! #[macro_use]
//! extern crate static_assertions;
//! # fn main() {}
//! ```
//!
//! # Examples
//!
//! Very thorough examples are provided in the docs for each individual macro.
//! Failure case examples are also documented.
//!
//! # Limitations
//!
//! Due to implementation details, some macros can only be used normally from
//! within the context of a function. To use these macros in other contexts, a
//! unique label must be provided.
//!
//! ```compile_fail
//! # #[macro_use] extern crate static_assertions;
//! # fn main() {}
//! // error: expected item after attributes
//! const_assert!(true == true);
//! ```
//!
//! This can be fixed via:
//!
//! ```
//! # #[macro_use] extern crate static_assertions;
//! # fn main() {}
//! const_assert!(label; true == true);
//! ```
//!
//! This issue can be followed [here][issue1]. Feedback and potential solutions
//! are welcome!
//!
//! [issue1]: https://github.com/nvzqz/static-assertions-rs/issues/1
//! [crate]: https://crates.io/crates/static_assertions

#![no_std]

#![deny(unused_macros)]

#[doc(hidden)]
pub extern crate core as _core;

/// Asserts that a given configuration is set.
///
/// # Examples
///
/// A project may not support a set of configurations and thus you may want to
/// report why:
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// // We should only be compiling for Unix or Linux
/// # #[cfg(any(unix, linux))]
/// assert_cfg!(any(unix, linux));
/// # fn main() {}
/// ```
///
/// If users need to specify a database back-end:
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # #[cfg(target_pointer_width = "0")] // Impossible
/// assert_cfg!("Must exclusively use MySQL or MongoDB as database back-end",
///             all(not(all(feature = "mysql", feature = "mongodb")),
///                 any(    feature = "mysql", feature = "mongodb")));
/// # fn main() {}
/// ```
///
/// We can't be compiling for both Unix _and_ Windows simultaneously:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_cfg!("No, that's not how it works! ಠ_ಠ", all(unix, windows));
/// # }
/// ```
#[macro_export]
macro_rules! assert_cfg {
    () => {};
    ($msg:expr, $($cfg:tt)*) => {
        #[cfg(not($($cfg)*))]
        compile_error!($msg);
    };
    ($($cfg:tt)*) => {
        #[cfg(not($($cfg)*))]
        compile_error!(concat!("Cfg does not pass: ", stringify!($($cfg)*)));
    };
}

/// Asserts that types are equal in size.
///
/// When performing operations such as pointer casts or dealing with [`usize`]
/// versus [`u64`] versus [`u32`], the size of your types matter. This is where
/// this macro comes into play.
///
/// # Alternatives
///
/// There are also [`assert_eq_size_val`](macro.assert_eq_size_val.html) and
/// [`assert_eq_size_ptr`](macro.assert_eq_size_ptr.html). Instead of specifying
/// types to compare, values' sizes can be directly compared against each other.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// // Can be declared outside of a function if labeled
/// assert_eq_size!(bytes; (u8, u8), u16);
///
/// fn main() {
///     // Supports unlimited arguments:
///     assert_eq_size!([u8; 4], (u16, u16), u32);
/// }
/// ```
///
/// The following produces a compilation failure because `u32` has 4 times the
/// size of `u8`:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_eq_size!(u32, u8);
/// # }
/// ```
///
/// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
/// [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html
/// [`u32`]: https://doc.rust-lang.org/std/primitive.u32.html
#[macro_export]
macro_rules! assert_eq_size {
    ($x:ty, $($xs:ty),+ $(,)*) => {
        $(let _ = $crate::_core::mem::transmute::<$x, $xs>;)+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_eq_size!($($xs)+); }
    };
}

/// Asserts that values pointed to are equal in size.
///
/// This especially is useful for when coercing pointers between different types
/// and ensuring the underlying values are the same size.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// fn operation(x: &(u32, u32), y: &[u16; 4]) {
///     assert_eq_size_ptr!(x, y);
/// }
/// # fn main() {}
/// ```
///
/// Byte arrays of different lengths have different sizes:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// static BYTES: &[u8; 4] = &[
///     /* ... */
///     # 0; 4
/// ];
///
/// static TABLE: &[u8; 16] = &[
///     /* ... */
///     # 0; 16
/// ];
///
/// assert_eq_size_ptr!(BYTES, TABLE);
/// # }
/// ```
#[macro_export]
macro_rules! assert_eq_size_ptr {
    ($x:expr, $($xs:expr),+ $(,)*) => {
        #[allow(unknown_lints, forget_copy, unused_unsafe, useless_transmute)]
        unsafe {
            use $crate::_core::{mem, ptr};
            let mut copy = ptr::read($x);
            $(ptr::write(&mut copy, mem::transmute(ptr::read($xs)));)+
            mem::forget(copy);
        }
    }
}

/// Asserts that values are equal in size.
///
/// This macro doesn't consume its arguments and thus works for
/// non-[`Clone`]able values.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # fn main() {
/// struct Byte(u8);
///
/// let x = 10u8;
/// let y = Byte(42); // Works for non-cloneable types
///
/// assert_eq_size_val!(x, y);
/// assert_eq_size_val!(x, y, 0u8);
/// # }
/// ```
///
/// Even though both values are 0, they are of types with different sizes:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_eq_size_val!(0u8, 0u32);
/// # }
/// ```
///
/// [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html
#[macro_export]
macro_rules! assert_eq_size_val {
    ($x:expr, $($xs:expr),+ $(,)*) => {
        assert_eq_size_ptr!(&$x, $(&$xs),+);
    }
}

/// Asserts that constant expressions evaluate to `true`.
///
/// There also exists [`const_assert_eq`](macro.const_assert_eq.html) for
/// validating whether a sequence of expressions are equal to one another.
///
/// # Examples
///
/// Constant expressions can be ensured to have certain properties via this
/// macro If the expression evaluates to `false`, the file will fail to compile.
/// This is synonymous to [`static_assert` in C++][static_assert].
///
/// As a [limitation](index.html#limitations), a unique label is required if
/// the macro is used outside of a function.
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// const FIVE: usize = 5;
///
/// const_assert!(twenty_five; FIVE * FIVE == 25);
///
/// fn main() {
///     const_assert!(2 + 2 == 4);
///     const_assert!(FIVE - FIVE == 0);
/// }
/// ```
///
/// Some expressions are blatantly false:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// const_assert!(1 >= 2);
/// # }
/// ```
///
/// [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
#[macro_export]
macro_rules! const_assert {
    ($($xs:expr),+ $(,)*) => {
        #[allow(unknown_lints, eq_op)]
        let _: [(); 0 - !($($xs)&&+) as usize];
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { const_assert!($($xs)+); }
    };
}

/// Asserts that constants are equal in value.
///
/// # Examples
///
/// Works as a shorthand for `const_assert!(a == b)`:
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// const TWO: usize = 2;
/// const_assert_eq!(two; TWO * TWO, TWO + TWO, 4);
///
/// fn main() {
///     const NUM: usize = 32;
///     const_assert_eq!(NUM + NUM, 64);
/// }
/// ```
///
/// Just because 2 × 2 = 2 + 2 doesn't mean it holds true for other numbers:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// const_assert_eq!(4 + 4, 4 * 4);
/// # }
/// ```
#[macro_export]
macro_rules! const_assert_eq {
    ($x:expr, $($xs:expr),+ $(,)*) => {
        const_assert!($($x == $xs),+);
    };
    ($label:ident; $x:expr, $($xs:expr),+ $(,)*) => {
        const_assert!($label; $($x == $xs),+);
    };
}

/// Asserts that the traits are object-safe.
///
/// This is useful for when changes are made to a trait that accidentally
/// prevent it from being used as an object. Such a case would be adding a
/// generic method and forgetting to add `where Self: Sized` after it. If left
/// unnoticed, that mistake will affect crate users and break both forward and
/// backward compatibility.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// assert_obj_safe!(basic; Send, Sync, AsRef<str>);
///
/// mod inner {
///     // Works with traits that are not in the calling module
///     pub trait BasicTrait {
///         fn foo(&self);
///     }
/// }
///
/// trait MySafeTrait {
///     fn bar(&self) -> u32;
/// }
///
/// fn main() {
///     assert_obj_safe!(MySafeTrait);
///     assert_obj_safe!(inner::BasicTrait);
/// }
/// ```
///
/// Generics without `where Self: Sized` are not allowed in object-safe traits:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// trait MyUnsafeTrait {
///     fn baz<T>(&self) -> T;
/// }
///
/// # fn main() {
/// assert_obj_safe!(MyUnsafeTrait);
/// # }
/// ```
#[macro_export]
macro_rules! assert_obj_safe {
    ($($xs:ty),+ $(,)*) => {
        $(let _: &$xs;)+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_obj_safe!($($xs)+); }
    };
}

/// Asserts that the type has the given fields.
///
/// # Examples
///
/// This may be used when types have odd fields as a result of `#[cfg]`.
///
/// ```
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// struct Ty {
///     #[cfg(windows)]
///     value: u8,
///     #[cfg(not(windows))]
///     value: usize,
/// }
///
/// /* ... */
///
/// // Always have `value` regardless of OS
/// assert_fields!(Ty, value);
/// # }
/// ```
///
/// Range does not have a field named `middle`:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// use std::ops::Range;
///
/// assert_fields!(Range<u32>, middle);
/// # }
/// ```
#[macro_export]
macro_rules! assert_fields {
    ($t:path, $($f:ident),+) => {
        $(let $t { $f: _, .. };)+
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_fields!($($xs)+); }
    };
}

/// Asserts that the type implements the given traits.
///
/// # Examples
///
/// Can be used to ensure types implement [`Send`], [`Sync`], and other traits:
///
/// ```
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {}
/// assert_impl!(str; String, Send, Sync, From<&'static str>);
/// assert_impl!(vec; &'static [u8], Into<Vec<u8>>);
/// ```
///
/// Raw pointers cannot be sent between threads safely:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions;
/// # fn main() {
/// assert_impl!(*const u8, Send);
/// # }
/// ```
///
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
#[macro_export]
macro_rules! assert_impl {
    ($x:ty, $($t:path),+ $(,)*) => {
        {
            fn assert_impl<T: ?Sized $(+ $t)+>() {}
            assert_impl::<$x>();
        }
    };
    ($label:ident; $($xs:tt)+) => {
        #[allow(dead_code, non_snake_case)]
        fn $label() { assert_impl!($($xs)+); }
    };
}
<|endoftext|>


<commit_before>//!
//! # Conrod
//!
//! An easy-to-use, immediate-mode, 2D GUI library featuring a range of useful widgets.
//!

#![deny(missing_copy_implementations)]
#![warn(missing_docs)]

#[macro_use] extern crate bitflags;
extern crate clock_ticks;
extern crate elmesque;
extern crate graphics;
extern crate num;
#[macro_use] extern crate piston;
extern crate rand;
extern crate rustc_serialize;
extern crate vecmath;

pub use canvas::split::Split;
pub use canvas::floating::Floating;

pub use widget::button::Button;
pub use widget::drop_down_list::DropDownList;
pub use widget::envelope_editor::EnvelopeEditor;
pub use widget::envelope_editor::EnvelopePoint;
pub use widget::label::Label;
pub use widget::matrix::Matrix as WidgetMatrix;
pub use widget::number_dialer::NumberDialer;
pub use widget::slider::Slider;
pub use widget::text_box::TextBox;
pub use widget::toggle::Toggle;
pub use widget::xy_pad::XYPad;

pub use widget::button::Style as ButtonStyle;
pub use widget::drop_down_list::Style as DropDownListStyle;
pub use widget::envelope_editor::Style as EnvelopeEditorStyle;
pub use widget::label::Style as LabelStyle;
pub use widget::number_dialer::Style as NumberDialerStyle;
pub use widget::slider::Style as SliderStyle;
pub use widget::text_box::Style as TextBoxStyle;
pub use widget::toggle::Style as ToggleStyle;
pub use widget::xy_pad::Style as XYPadStyle;

pub use background::Background;
pub use canvas::{Canvas, CanvasId};
pub use elmesque::color;
pub use elmesque::color::{Color, Colorable};
pub use frame::{Framing, Frameable};
pub use graphics::character::CharacterCache;
pub use label::{FontSize, Labelable};
pub use mouse::Mouse;
pub use mouse::ButtonState as MouseButtonState;
pub use mouse::Scroll as MouseScroll;
pub use position::{align_left_of, align_right_of, align_bottom_of, align_top_of};
pub use position::{middle_of, top_left_of, top_right_of, bottom_left_of, bottom_right_of,
                   mid_top_of, mid_bottom_of, mid_left_of, mid_right_of};
pub use position::{Corner, Depth, Direction, Dimensions, HorizontalAlign, Margin, Padding,
                   Place, Point, Position, Positionable, Sizeable, VerticalAlign};
pub use theme::{Align, Theme};
pub use ui::{GlyphCache, Ui, UiId, UserInput};
pub use widget::{Widget, WidgetId};

mod background;
mod canvas;
mod frame;
mod label;
mod mouse;
mod position;
mod theme;
mod ui;
pub mod utils;
mod widget;

// #[macro_export]
// macro_rules! widget_ids {
//     ($($ids:ident),*) => {
//         $(
//             new_widget_id!(0, $($ids,)*);
//         )*
//     };
// }
//
// macro_rules! new_widget_id{
//     ($count:expr, ,) => {};
//     ($count:expr, $current_id:ident) => {
//         const $current_id: WidgetId = $count;
//     };
//     ($count:expr, $current_id:ident, $($rest:ident,)*) => {
//         new_widget_id!($count, $current_id);
//         new_widget_id!($count + 1, $($rest),*,);
//     };
// }

<commit_msg>Exposed widget::State as WidgetState from top level, closes #456<commit_after>//!
//! # Conrod
//!
//! An easy-to-use, immediate-mode, 2D GUI library featuring a range of useful widgets.
//!

#![deny(missing_copy_implementations)]
#![warn(missing_docs)]

#[macro_use] extern crate bitflags;
extern crate clock_ticks;
extern crate elmesque;
extern crate graphics;
extern crate num;
#[macro_use] extern crate piston;
extern crate rand;
extern crate rustc_serialize;
extern crate vecmath;

pub use canvas::split::Split;
pub use canvas::floating::Floating;

pub use widget::button::Button;
pub use widget::drop_down_list::DropDownList;
pub use widget::envelope_editor::EnvelopeEditor;
pub use widget::envelope_editor::EnvelopePoint;
pub use widget::label::Label;
pub use widget::matrix::Matrix as WidgetMatrix;
pub use widget::number_dialer::NumberDialer;
pub use widget::slider::Slider;
pub use widget::text_box::TextBox;
pub use widget::toggle::Toggle;
pub use widget::xy_pad::XYPad;

pub use widget::button::Style as ButtonStyle;
pub use widget::drop_down_list::Style as DropDownListStyle;
pub use widget::envelope_editor::Style as EnvelopeEditorStyle;
pub use widget::label::Style as LabelStyle;
pub use widget::number_dialer::Style as NumberDialerStyle;
pub use widget::slider::Style as SliderStyle;
pub use widget::text_box::Style as TextBoxStyle;
pub use widget::toggle::Style as ToggleStyle;
pub use widget::xy_pad::Style as XYPadStyle;

pub use background::Background;
pub use canvas::{Canvas, CanvasId};
pub use elmesque::color;
pub use elmesque::color::{Color, Colorable};
pub use frame::{Framing, Frameable};
pub use graphics::character::CharacterCache;
pub use label::{FontSize, Labelable};
pub use mouse::Mouse;
pub use mouse::ButtonState as MouseButtonState;
pub use mouse::Scroll as MouseScroll;
pub use position::{align_left_of, align_right_of, align_bottom_of, align_top_of};
pub use position::{middle_of, top_left_of, top_right_of, bottom_left_of, bottom_right_of,
                   mid_top_of, mid_bottom_of, mid_left_of, mid_right_of};
pub use position::{Corner, Depth, Direction, Dimensions, HorizontalAlign, Margin, Padding,
                   Place, Point, Position, Positionable, Sizeable, VerticalAlign};
pub use theme::{Align, Theme};
pub use ui::{GlyphCache, Ui, UiId, UserInput};
pub use widget::{Widget, WidgetId};
pub use widget::State as WidgetState;

mod background;
mod canvas;
mod frame;
mod label;
mod mouse;
mod position;
mod theme;
mod ui;
pub mod utils;
mod widget;

// #[macro_export]
// macro_rules! widget_ids {
//     ($($ids:ident),*) => {
//         $(
//             new_widget_id!(0, $($ids,)*);
//         )*
//     };
// }
//
// macro_rules! new_widget_id{
//     ($count:expr, ,) => {};
//     ($count:expr, $current_id:ident) => {
//         const $current_id: WidgetId = $count;
//     };
//     ($count:expr, $current_id:ident, $($rest:ident,)*) => {
//         new_widget_id!($count, $current_id);
//         new_widget_id!($count + 1, $($rest),*,);
//     };
// }

<|endoftext|>


<commit_before>// Based on: http://www.sci.fi/~benefon/rscalc.c
//
// C program calculating the sunrise and sunset for
// the current date and a fixed location(latitude,longitude)
// Note, twilight calculation gives insufficient accuracy of results
// Jarmo Lammi 1999 - 2001
//
// Kept the function names simular for future reference

#![feature(std_misc)]
#![feature(core)]

extern crate time;

use time::{Timespec, Tm};
use std::num::Float;
use std::f64::consts;

const SUNRADIUS: f64 = 0.53;
const AIRREFR: f64 = 34.0/60.0;
const Y2000: Tm = Tm {tm_sec: 0, tm_min: 0, tm_hour: 0, tm_mday: 1, tm_mon: 0, tm_year: 100,
                      tm_wday: 6, tm_yday: 0, tm_isdst: 0, tm_utcoff: 0, tm_nsec: 0};

/// Result of the daylight calculation (calculated times are UTC based)
#[derive(Clone, Copy, Debug)]
pub struct Daylight {
    pub twilight_morning: Timespec,
    pub sunrise: Timespec,
    pub sunset: Timespec,
    pub twilight_evening: Timespec
}

/// the function below returns an angle in the range 0 to 2*pi
fn fnrange(x: f64) -> f64 {
    let b = 0.5 * x / consts::PI;
    let a = consts::PI_2 * (b - b.floor());
    return if a.is_negative() {a + consts::PI_2} else {a}
}

// Commonality between original f0 and f1 function
fn calculate_angle(lat: f64, declin: f64, fraction: f64) -> f64 {
    // Correction: different sign as S HS
    let df = if lat.is_negative() {-fraction} else {fraction};
    let f = (declin + df).tan() * lat.to_radians().tan();
    f.min(1.0).asin() + consts::FRAC_PI_2
}

/// Calculating the hourangle
fn f0(lat: f64, declin: f64) -> f64 {
    let df0 = (0.5 * SUNRADIUS + AIRREFR).to_radians();
    calculate_angle(lat, declin, df0)
}

/// Calculating the hourangle for twilight times
fn f1(lat: f64, declin: f64) -> f64 {
    let df1 = 6.0.to_radians();
    calculate_angle(lat, declin, df1)
}

/// Find the ecliptic longitude of the sun
fn fnsun(d: f64) -> (f64, f64) {
    // mean longitude of the sun
    let mean_longitude = fnrange(280.461.to_radians() + 0.9856474.to_radians() * d);

    // mean anomaly of the sun
    let g = fnrange(357.528.to_radians() + 0.9856003.to_radians() * d);

    // Ecliptic longitude of the sun
    let ecliptic_longitude = fnrange(mean_longitude + 1.915.to_radians() * g.sin() +
                                     0.02.to_radians() * (2.0*g).sin());

    (ecliptic_longitude, mean_longitude)
}

/// Returns the number of days (including fraction) since midnight 2000-01-01
fn days_since_2000(date: Tm) -> f64 {
    let duration = date - Y2000;

    duration.num_seconds() as f64 / (24.0 * 3600.0)
}

/// Converts daylight hours to Timespec
fn daylight_hours_to_timespec(midnight: Timespec, hours: f64) -> Timespec {
    Timespec {
        sec: midnight.sec + (hours * 3600.0) as i64,
        nsec: 0
    }
}

/// Calculate civil twilight (am/pm) and sunrise and sunset at given date
pub fn calculate_daylight(date: Tm, latitude: f64, longitude: f64) -> Daylight {
    let utc = date.to_utc();
    let d2000 = days_since_2000(utc);

    // find the ecliptic longitude of the sun
    let (ecliptic_longitude, mean_longitude) = fnsun(d2000);

    // Obliquity of the ecliptic
    let obliq = 23.439.to_radians() - 0.0000004.to_radians() * d2000;

    // Find the RA and DEC of the sun
    let alpha = (obliq.cos() * ecliptic_longitude.sin()).atan2(ecliptic_longitude.cos());
    let delta = (obliq.sin() * ecliptic_longitude.sin()).asin();

    // Find the equation of time
    // in minutes
    // Correction suggested by David Smith
    let mean_longitude_corr = mean_longitude - alpha;
    let mean_longitude_corr2 = if mean_longitude_corr < consts::PI {
        mean_longitude_corr + consts::PI_2} else {
            mean_longitude_corr};
    let equation = 1440.0 * (1.0 - mean_longitude_corr2 / consts::PI/2.0);
    let ha = f0(latitude, delta);
    let hb = f1(latitude, delta);
    let twx_radians = hb - ha; // length of twilight in radions
    let twx = 12.0 * twx_radians / consts::PI; // lenth of twilight in hours

    // artic winter
    let riset = 12.0 - 12.0 * ha / consts::PI - longitude / 15.0 + equation / 60.0;
    let settm = 12.0 + 12.0 * ha / consts::PI - longitude / 15.0 + equation / 60.0;

    let twam = riset - twx;
    let twpm = settm + twx;

    // get midnight reference
    let utcmidnight = Tm {tm_mday: utc.tm_mday, tm_mon: utc.tm_mon, tm_year: utc.tm_year,
                          tm_wday: utc.tm_wday, tm_yday: utc.tm_yday, tm_utcoff: utc.tm_utcoff,
                          tm_isdst: utc.tm_isdst, tm_nsec: 0, tm_sec: 0, tm_min: 0, tm_hour: 0};
    let tsmidnight = utcmidnight.to_timespec();

    Daylight {twilight_morning: daylight_hours_to_timespec(tsmidnight, twam),
              sunrise: daylight_hours_to_timespec(tsmidnight, riset),
              sunset: daylight_hours_to_timespec(tsmidnight, settm),
              twilight_evening: daylight_hours_to_timespec(tsmidnight, twpm)}
}

#[test]
fn days_since_20150327_1200_utc() {
    let tm20150327_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 27, tm_mon: 2, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};

    assert_eq!(days_since_2000(tm20150327_1200), 5564.5);
}

#[test]
fn daylight_apeldoorn_20150327_1200_utc() {
    let tm20150327_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 27, tm_mon: 2, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};
    let lat_apeldoorn = 52.0 + 13.0/60.0;
    let long_apeldoorn = 5.0 + 58.0/60.0;

    let daylight = calculate_daylight(tm20150327_1200, lat_apeldoorn, long_apeldoorn);

    assert_eq!(daylight.twilight_morning.sec, 1427432129); // 2015-03-27T05:55:29+01:00
    assert_eq!(daylight.sunrise.sec, 1427433766); // 2015-03-27T06:22:46+01:00
    assert_eq!(daylight.sunset.sec, 1427479207); // 2015-03-27T19:00:07+01:00
    assert_eq!(daylight.twilight_evening.sec, 1427480844); // 2015-03-27T19:27:24+01:00
}
<commit_msg>New test + bugfix<commit_after>// Based on: http://www.sci.fi/~benefon/rscalc.c
//
// C program calculating the sunrise and sunset for
// the current date and a fixed location(latitude,longitude)
// Note, twilight calculation gives insufficient accuracy of results
// Jarmo Lammi 1999 - 2001
//
// Kept the function names simular for future reference

#![feature(std_misc)]
#![feature(core)]

extern crate time;

use time::{Timespec, Tm};
use std::num::Float;
use std::f64::consts;

const SUNRADIUS: f64 = 0.53;
const AIRREFR: f64 = 34.0/60.0;
const Y2000: Tm = Tm {tm_sec: 0, tm_min: 0, tm_hour: 0, tm_mday: 1, tm_mon: 0, tm_year: 100,
                      tm_wday: 6, tm_yday: 0, tm_isdst: 0, tm_utcoff: 0, tm_nsec: 0};

/// Result of the daylight calculation (calculated times are UTC based)
#[derive(Clone, Copy, Debug)]
pub struct Daylight {
    pub twilight_morning: Timespec,
    pub sunrise: Timespec,
    pub sunset: Timespec,
    pub twilight_evening: Timespec
}

/// the function below returns an angle in the range 0 to 2*pi
fn fnrange(x: f64) -> f64 {
    let b = 0.5 * x / consts::PI;
    let a = consts::PI_2 * (b - b.floor());
    if a.is_negative() {a + consts::PI_2} else {a}
}

// Commonality between original f0 and f1 function
fn calculate_angle(lat: f64, declin: f64, fraction: f64) -> f64 {
    // Correction: different sign as S HS
    let df = if lat.is_negative() {-fraction} else {fraction};
    let f = (declin + df).tan() * lat.to_radians().tan();
    f.min(1.0).max(-1.0).asin() + consts::FRAC_PI_2
}

/// Calculating the hourangle
fn f0(lat: f64, declin: f64) -> f64 {
    let df0 = (0.5 * SUNRADIUS + AIRREFR).to_radians();
    calculate_angle(lat, declin, df0)
}

/// Calculating the hourangle for twilight times
fn f1(lat: f64, declin: f64) -> f64 {
    let df1 = 6.0.to_radians();
    calculate_angle(lat, declin, df1)
}

/// Find the ecliptic longitude of the sun
fn fnsun(d: f64) -> (f64, f64) {
    // mean longitude of the sun
    let mean_longitude = fnrange(280.461.to_radians() + 0.9856474.to_radians() * d);

    // mean anomaly of the sun
    let g = fnrange(357.528.to_radians() + 0.9856003.to_radians() * d);

    // Ecliptic longitude of the sun
    let ecliptic_longitude = fnrange(mean_longitude + 1.915.to_radians() * g.sin() +
                                     0.02.to_radians() * (2.0*g).sin());

    (ecliptic_longitude, mean_longitude)
}

/// Returns the number of days (including fraction) since midnight 2000-01-01
fn days_since_2000(date: Tm) -> f64 {
    let duration = date - Y2000;

    duration.num_seconds() as f64 / (24.0 * 3600.0)
}

/// Converts daylight hours to Timespec
fn daylight_hours_to_timespec(midnight: Timespec, hours: f64) -> Timespec {
    Timespec {
        sec: midnight.sec + (hours * 3600.0) as i64,
        nsec: 0
    }
}

/// Calculate civil twilight (am/pm) and sunrise and sunset at given date
pub fn calculate_daylight(date: Tm, latitude: f64, longitude: f64) -> Daylight {
    let utc = date.to_utc();
    let d2000 = days_since_2000(utc);

    // find the ecliptic longitude of the sun
    let (ecliptic_longitude, mean_longitude) = fnsun(d2000);

    // Obliquity of the ecliptic
    let obliq = 23.439.to_radians() - 0.0000004.to_radians() * d2000;

    // Find the RA and DEC of the sun
    let alpha = (obliq.cos() * ecliptic_longitude.sin()).atan2(ecliptic_longitude.cos());
    let delta = (obliq.sin() * ecliptic_longitude.sin()).asin();

    // Find the equation of time
    // in minutes
    // Correction suggested by David Smith
    let mean_longitude_corr = mean_longitude - alpha;
    let mean_longitude_corr2 = if mean_longitude_corr < consts::PI {
        mean_longitude_corr + consts::PI_2} else {
            mean_longitude_corr};
    let equation = 1440.0 * (1.0 - mean_longitude_corr2 / consts::PI/2.0);
    let ha = f0(latitude, delta);
    let hb = f1(latitude, delta);
    let twx_radians = hb - ha; // length of twilight in radions
    let twx = 12.0 * twx_radians / consts::PI; // lenth of twilight in hours

    // artic winter
    let riset = 12.0 - 12.0 * ha / consts::PI - longitude / 15.0 + equation / 60.0;
    let settm = 12.0 + 12.0 * ha / consts::PI - longitude / 15.0 + equation / 60.0;

    let twam = riset - twx;
    let twpm = settm + twx;

    // get midnight reference
    let utcmidnight = Tm {tm_mday: utc.tm_mday, tm_mon: utc.tm_mon, tm_year: utc.tm_year,
                          tm_wday: utc.tm_wday, tm_yday: utc.tm_yday, tm_utcoff: utc.tm_utcoff,
                          tm_isdst: utc.tm_isdst, tm_nsec: 0, tm_sec: 0, tm_min: 0, tm_hour: 0};
    let tsmidnight = utcmidnight.to_timespec();

    Daylight {twilight_morning: daylight_hours_to_timespec(tsmidnight, twam),
              sunrise: daylight_hours_to_timespec(tsmidnight, riset),
              sunset: daylight_hours_to_timespec(tsmidnight, settm),
              twilight_evening: daylight_hours_to_timespec(tsmidnight, twpm)}
}

#[test]
fn days_since_20150327_1200_utc() {
    let tm20150327_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 27, tm_mon: 2, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};

    assert_eq!(days_since_2000(tm20150327_1200), 5564.5);
}

#[test]
fn daylight_apeldoorn_20150327_1200_utc() {
    let tm20150327_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 27, tm_mon: 2, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};
    let lat_apeldoorn = 52.0 + 13.0/60.0;
    let long_apeldoorn = 5.0 + 58.0/60.0;

    let daylight = calculate_daylight(tm20150327_1200, lat_apeldoorn, long_apeldoorn);

    assert_eq!(daylight.twilight_morning.sec, 1427432129); // 2015-03-27T05:55:29+01:00
    assert_eq!(daylight.sunrise.sec, 1427433766); // 2015-03-27T06:22:46+01:00
    assert_eq!(daylight.sunset.sec, 1427479207); // 2015-03-27T19:00:07+01:00
    assert_eq!(daylight.twilight_evening.sec, 1427480844); // 2015-03-27T19:27:24+01:00
}

#[test]
fn daylight_tokyo_20150327_1200_utc() {
    let tm20150327_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 27, tm_mon: 2, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};
    let lat_tokyo = 35.41;
    let long_tokyo = 139.41;

    let daylight = calculate_daylight(tm20150327_1200, lat_tokyo, long_tokyo);

    assert_eq!(daylight.twilight_morning.sec, 1427401349);
    assert_eq!(daylight.sunrise.sec, 1427402244);
    assert_eq!(daylight.sunset.sec, 1427446677);
    assert_eq!(daylight.twilight_evening.sec, 1427447573);
}

#[test]
fn daylight_avarua_20150327_1200_utc() {
    let tm20150327_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 27, tm_mon: 2, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};
    let lat_tokyo = -21.12;
    let long_tokyo = -159.46;

    let daylight = calculate_daylight(tm20150327_1200, lat_tokyo, long_tokyo);

    assert_eq!(daylight.twilight_morning.sec, 1427474290);
    assert_eq!(daylight.sunrise.sec, 1427474769);
    assert_eq!(daylight.sunset.sec, 1427517608);
    assert_eq!(daylight.twilight_evening.sec, 1427518088);
}

#[test]
fn daylight_longyearbyen_20150621_1200_utc_midsummer() {
    let tm20150621_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 21, tm_mon: 5, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};
    let lat_tokyo = 78.22;
    let long_tokyo = 15.65;

    let daylight = calculate_daylight(tm20150621_1200, lat_tokyo, long_tokyo);

    assert_eq!((daylight.sunset - daylight.sunrise).num_minutes(), 23*60 + 59); // midsummer
    assert_eq!(daylight.twilight_morning.sec, 1434841155);
    assert_eq!(daylight.sunrise.sec, 1434841155);
    assert_eq!(daylight.sunset.sec, 1434927554);
    assert_eq!(daylight.twilight_evening.sec, 1434927554);
}

#[test]
fn daylight_longyearbyen_20151221_1200_utc_midwinter() {
    let tm20151221_1200 = Tm {tm_sec: 0, tm_min: 0, tm_hour: 12, tm_mday: 21, tm_mon: 11, tm_year: 115,
        tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0};
    let lat_tokyo = 78.22;
    let long_tokyo = 15.65;

    let daylight = calculate_daylight(tm20151221_1200, lat_tokyo, long_tokyo);

    assert_eq!((daylight.sunset - daylight.sunrise).num_minutes(), 0); // midwinter
    assert_eq!(daylight.twilight_morning.sec, 1450695334);
    assert_eq!(daylight.sunrise.sec, 1450695334);
    assert_eq!(daylight.sunset.sec, 1450695334);
    assert_eq!(daylight.twilight_evening.sec, 1450695334);
}

#[test]
fn range_check() {
    for long in -180..181 {
        for lat in -90..91 {
            for year in 70..138 { // 138 -> last supported year at 32-bit systems
                let tm = Tm {tm_sec: 0, tm_min: 0, tm_hour: 0, tm_mday: 2, tm_mon: 0, tm_year: year,
                    tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_utcoff:0, tm_nsec: 0
                    // 2 january; because 1 january may still result in 1969 timestamps
                };

                let daylight = calculate_daylight(tm, lat as f64, long as f64);

                assert!(daylight.twilight_morning.sec > 0, "daylight={:?} lat={} long={} year={}",
                    daylight, lat, long, year);
                assert!(daylight.twilight_morning <= daylight.sunrise);
                assert!(daylight.sunrise <= daylight.sunset);
                assert!(daylight.sunset <= daylight.twilight_evening);
            }
        }
    }
}
<|endoftext|>