<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! A library for interacting with Twitter.
//!
//! [Repository](https://github.com/QuietMisdreavus/twitter-rs)
//!
//! egg-mode is a Twitter library that aims to make as few assumptions about the user's codebase as
//! possible. Endpoints are exposed as bare functions where authentication details are passed in as
//! arguments, rather than as builder functions of a root "service" manager. The only exceptions to
//! this guideline are endpoints with many optional parameters, like posting a status update or
//! updating the metadata of a list.
//!
//! To use the Twitter API, there are some extra steps you need to do, both inside and outside of
//! your app code. Find the Authentication Overview and quick start guide in the [Token][]
//! documentation. The following examples already have a `token` on hand.
//!
//! [Token]: enum.Token.html
//!
//! To load the profile information of a single user:
//!
//! ```rust,no_run
//! # let token = egg_mode::Token::Access {
//! #     consumer: egg_mode::KeyPair::new("", ""),
//! #     access: egg_mode::KeyPair::new("", ""),
//! # };
//! let rustlang = egg_mode::user::show("rustlang", &token).unwrap();
//!
//! println!("{} (@{})", rustlang.name, rustlang.screen_name);
//! ```
//!
//! To post a new tweet:
//!
//! ```rust,no_run
//! # let token = egg_mode::Token::Access {
//! #     consumer: egg_mode::KeyPair::new("", ""),
//! #     access: egg_mode::KeyPair::new("", ""),
//! # };
//! use egg_mode::tweet::DraftTweet;
//!
//! let post = DraftTweet::new("Hey Twitter!").send(&token).unwrap();
//! ```
//!
//! # Types and Functions
//!
//! All of the main content of egg-mode is in submodules, but there are a few things here in the
//! crate root. To wit, it contains items related to authentication and a couple items that all the
//! submodules use.
//!
//! ## `Response<T>`
//!
//! Every method that calls Twitter and carries rate-limit information wraps its return value in a
//! [`Response`][] struct, that transmits this information to your app. From there, you can handle
//! the rate-limit information to hold off on that kind of request, or simply grab its `response`
//! field to get the output of whatever method you called. `Response` also implements `Deref`, so
//! for the most part you can access fields of the final result without having to grab the
//! `response` field directly.
//!
//! `Response` also has IntoIterator implementations and iterator creation methods that echo those
//! on `Vec<T>`, for methods that return Vecs. These methods and iterator types distribute the
//! rate-limit information across each iteration.
//!
//! There's also a type alias, [`WebResponse`], which is an alias to `Result<Response<T>, Error>`,
//! indicating a shorthand for network calls that return rate-limit metadata.
//!
//! [`Response`]: struct.Response.html
//! [`WebResponse`]: type.WebResponse.html
//!
//! ## Authentication Types/Functions
//!
//! The remaining types and methods are explained as part of the [authentication overview][Token],
//! with the exception of `verify_tokens`, which is a simple method to ensure a given token is
//! still valid.
//!
//! # Modules
//!
//! As there are many actions available in the Twitter API, egg-mode divides them roughly into
//! several modules by their shared purpose. Here's a sort of high-level overview, in rough order
//! from "most important" to "less directly used":
//!
//! ## Primary actions
//!
//! These could be considered the "core" actions within the Twitter API that egg-mode has made
//! available.
//!
//! * `tweet`: This module lets you act on tweets. Here you can find actions to load a user's
//!   timeline, post a new tweet, or like and retweet individual posts.
//! * `user`: This module lets you act on users, be it by following or unfollowing them, loading
//!   their profile information, blocking or muting them, or showing the relationship between two
//!   users.
//! * `search`: Due to the complexity of searching for tweets, it gets its own module.
//! * `direct`: Here you can work with a user's Direct Messages, either by loading DMs they've sent
//!   or received, or by sending new ones.
//! * `list`: This module lets you act on lists, from creating and deleting them, adding and
//!   removing users, or loading the posts made by their members.
//! * `text`: Text processing functions to count characters in new tweets and extract links and
//!   hashtags for highlighting and linking.
//!
//! ## Secondary actions
//!
//! These modules still contain direct actions for Twitter, but they can be considered as having
//! more of a helper role than something you might use directly.
//!
//! * `place`: Here are actions that look up physical locations that can be attached to tweets, as
//!   well at the `Place` struct that appears on tweets with locations attached.
//! * `service`: These are some miscellaneous methods that show information about the Twitter
//!   service as a whole, like loading the maximum length of t.co URLs or loading the current Terms
//!   of Service or Privacy Policy.
//!
//! ## Helper structs
//!
//! These modules contain some implementations that wrap some pattern seen in multiple "action"
//! modules.
//!
//! * `cursor`: This contains a helper trait and some helper structs that allow effective cursoring
//!   through certain collections of results from Twitter.
//! * `entities`: Whenever some text can be returned that may contain links, hashtags, media, or
//!   user mentions, its metadata is parsed into something that lives in this module.
//! * `error`: Any interaction with Twitter may result in an error condition, be it from finding a
//!   tweet or user that doesn't exist or the network connection being unavailable. All the error
//!   types are aggregated into an enum in this module.

#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_qualifications)]

#[macro_use] extern crate hyper;
#[macro_use] extern crate lazy_static;
extern crate futures;
extern crate tokio_core;
extern crate hyper_tls;
extern crate native_tls;
extern crate url;
extern crate rand;
extern crate hmac;
extern crate sha_1;
extern crate rustc_serialize;
extern crate mime;
extern crate chrono;
extern crate regex;
extern crate unicode_normalization;

#[macro_use] mod common;
mod auth;
pub mod error;
pub mod user;
pub mod entities;
pub mod cursor;
pub mod tweet;
pub mod search;
pub mod place;
pub mod direct;
pub mod service;
pub mod text;
pub mod list;
mod links;

pub use auth::{KeyPair, Token, AuthFuture, request_token, authorize_url, authenticate_url,
               access_token, verify_tokens, bearer_token, invalidate_bearer};
pub use common::{Response, ResponseIter, ResponseIterRef,
                 ResponseIterMut, WebResponse, TwitterFuture};
<commit_msg>swap exporting WebResponse for FutureResponse<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! A library for interacting with Twitter.
//!
//! [Repository](https://github.com/QuietMisdreavus/twitter-rs)
//!
//! egg-mode is a Twitter library that aims to make as few assumptions about the user's codebase as
//! possible. Endpoints are exposed as bare functions where authentication details are passed in as
//! arguments, rather than as builder functions of a root "service" manager. The only exceptions to
//! this guideline are endpoints with many optional parameters, like posting a status update or
//! updating the metadata of a list.
//!
//! To use the Twitter API, there are some extra steps you need to do, both inside and outside of
//! your app code. Find the Authentication Overview and quick start guide in the [Token][]
//! documentation. The following examples already have a `token` on hand.
//!
//! [Token]: enum.Token.html
//!
//! To load the profile information of a single user:
//!
//! ```rust,no_run
//! # let token = egg_mode::Token::Access {
//! #     consumer: egg_mode::KeyPair::new("", ""),
//! #     access: egg_mode::KeyPair::new("", ""),
//! # };
//! let rustlang = egg_mode::user::show("rustlang", &token).unwrap();
//!
//! println!("{} (@{})", rustlang.name, rustlang.screen_name);
//! ```
//!
//! To post a new tweet:
//!
//! ```rust,no_run
//! # let token = egg_mode::Token::Access {
//! #     consumer: egg_mode::KeyPair::new("", ""),
//! #     access: egg_mode::KeyPair::new("", ""),
//! # };
//! use egg_mode::tweet::DraftTweet;
//!
//! let post = DraftTweet::new("Hey Twitter!").send(&token).unwrap();
//! ```
//!
//! # Types and Functions
//!
//! All of the main content of egg-mode is in submodules, but there are a few things here in the
//! crate root. To wit, it contains items related to authentication and a couple items that all the
//! submodules use.
//!
//! ## `Response<T>`
//!
//! Every method that calls Twitter and carries rate-limit information wraps its return value in a
//! [`Response`][] struct, that transmits this information to your app. From there, you can handle
//! the rate-limit information to hold off on that kind of request, or simply grab its `response`
//! field to get the output of whatever method you called. `Response` also implements `Deref`, so
//! for the most part you can access fields of the final result without having to grab the
//! `response` field directly.
//!
//! `Response` also has IntoIterator implementations and iterator creation methods that echo those
//! on `Vec<T>`, for methods that return Vecs. These methods and iterator types distribute the
//! rate-limit information across each iteration.
//!
//! There's also a type alias, [`WebResponse`], which is an alias to `Result<Response<T>, Error>`,
//! indicating a shorthand for network calls that return rate-limit metadata.
//!
//! [`Response`]: struct.Response.html
//! [`WebResponse`]: type.WebResponse.html
//!
//! ## Authentication Types/Functions
//!
//! The remaining types and methods are explained as part of the [authentication overview][Token],
//! with the exception of `verify_tokens`, which is a simple method to ensure a given token is
//! still valid.
//!
//! # Modules
//!
//! As there are many actions available in the Twitter API, egg-mode divides them roughly into
//! several modules by their shared purpose. Here's a sort of high-level overview, in rough order
//! from "most important" to "less directly used":
//!
//! ## Primary actions
//!
//! These could be considered the "core" actions within the Twitter API that egg-mode has made
//! available.
//!
//! * `tweet`: This module lets you act on tweets. Here you can find actions to load a user's
//!   timeline, post a new tweet, or like and retweet individual posts.
//! * `user`: This module lets you act on users, be it by following or unfollowing them, loading
//!   their profile information, blocking or muting them, or showing the relationship between two
//!   users.
//! * `search`: Due to the complexity of searching for tweets, it gets its own module.
//! * `direct`: Here you can work with a user's Direct Messages, either by loading DMs they've sent
//!   or received, or by sending new ones.
//! * `list`: This module lets you act on lists, from creating and deleting them, adding and
//!   removing users, or loading the posts made by their members.
//! * `text`: Text processing functions to count characters in new tweets and extract links and
//!   hashtags for highlighting and linking.
//!
//! ## Secondary actions
//!
//! These modules still contain direct actions for Twitter, but they can be considered as having
//! more of a helper role than something you might use directly.
//!
//! * `place`: Here are actions that look up physical locations that can be attached to tweets, as
//!   well at the `Place` struct that appears on tweets with locations attached.
//! * `service`: These are some miscellaneous methods that show information about the Twitter
//!   service as a whole, like loading the maximum length of t.co URLs or loading the current Terms
//!   of Service or Privacy Policy.
//!
//! ## Helper structs
//!
//! These modules contain some implementations that wrap some pattern seen in multiple "action"
//! modules.
//!
//! * `cursor`: This contains a helper trait and some helper structs that allow effective cursoring
//!   through certain collections of results from Twitter.
//! * `entities`: Whenever some text can be returned that may contain links, hashtags, media, or
//!   user mentions, its metadata is parsed into something that lives in this module.
//! * `error`: Any interaction with Twitter may result in an error condition, be it from finding a
//!   tweet or user that doesn't exist or the network connection being unavailable. All the error
//!   types are aggregated into an enum in this module.

#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_qualifications)]

#[macro_use] extern crate hyper;
#[macro_use] extern crate lazy_static;
extern crate futures;
extern crate tokio_core;
extern crate hyper_tls;
extern crate native_tls;
extern crate url;
extern crate rand;
extern crate hmac;
extern crate sha_1;
extern crate rustc_serialize;
extern crate mime;
extern crate chrono;
extern crate regex;
extern crate unicode_normalization;

#[macro_use] mod common;
mod auth;
pub mod error;
pub mod user;
pub mod entities;
pub mod cursor;
pub mod tweet;
pub mod search;
pub mod place;
pub mod direct;
pub mod service;
pub mod text;
pub mod list;
mod links;

pub use auth::{KeyPair, Token, AuthFuture, request_token, authorize_url, authenticate_url,
               access_token, verify_tokens, bearer_token, invalidate_bearer};
pub use common::{Response, ResponseIter, ResponseIterRef,
                 ResponseIterMut, FutureResponse, TwitterFuture};
<|endoftext|>


<commit_before>//! A library to parse and load configuration files.
//!
//! This library parses and loads configuration files in much the same way as C/C++'s
//! [libconfig](http://www.hyperrealm.com/libconfig/). At this time, it can only read and load
//! configurations, but future plans include a much richer user API to allow other forms of
//! interaction, such as manipulating values, writing the current configuration to a file, etc.
//!
//!# Getting started
//!
//! A configuration file consists of a group of settings. A setting is a key/value pair, where the
//! key is a string of the form `[a-zA-Z][-a-zA-Z0-9_]*`, and the value is anything represented by
//! `types::Value`. In a configuration file, setting/value pairs are written as
//! `setting_name = value;`. Possible values include primitive integer and floating point types,
//! strings, arrays, lists, etc.
//!
//! The library provides a bunch of methods to read the configuration data in the `reader` module.
//! The possibilities include reading from a string, from a file, or from anything that implements
//! the `Read` trait.
//!
//! As of now, every reader will first attempt to read the whole configuration into memory,
//! and only begins parsing once everything was read.
//!
//! In case of error, the parser returns a `config::error`.
//! On success, the parser returns a `Config`, which can then be used to browse the loaded data.
//!
//! Browsing is typically done with the `lookup_*` methods implemented by `Config`. The `lookup`
//! methods work with *paths*. Essentially, a path unambiguously describes the location of
//! a setting.
//!
//! For example, consider this input configuration file:
//!
//!```ignore
//! title = "My HTTP server";
//! listen_ports = [ 80, 443 ];
//! misc = {
//!     owner = "Chuck Norris";
//!     location = "CA";
//!     contact = {
//!         phone = "415-256-9999";
//!         // This is an array. Arrays start with `[` and end with `]`
//!         // Arrays are homogeneous and can only hold scalar data types.
//!         // See types::ScalarValue for further information
//!         emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
//!     };
//! };
//!```
//!
//! At the top level, we have 3 settings: `title`, `listen_ports` and `misc`. `misc` is itself a
//! group of settings. Each value in this configuration is reachable by a unique path of settings
//! to follow. Each setting in a path is separated by `.`
//!
//! **Example**: The path `misc.contact.phone` identifies the setting with value `415-256-9999`.
//!
//! Array and list types are indexed using `[i]` in a path.
//!
//! **Example**: The path `listen_ports.[1]` identifies the setting with value `443`.
//!
//! **Example**: The path `misc.contact.emails.[0]` identifies the setting with value
//! `chuck@norris.com`
//!
//! Lists, as opposed to arrays, are heterogeneous and can store any data type, including other
//! lists. Here's a setting consisting of a heterogeneous list:
//!
//!```ignore
//! // This is a list. Lists start with `(` and end with `)`
//! // Lists are heterogeneous and can store any data type, including other lists
//! a_setting = ("a string", // The first element is a string
//!              ((1, 2, 3)), // The 2nd element is a list storing a list of 3 integers
//!              misc = { x = 4; y = 3; } // 3rd element: a group
//!             );
//!```
//!
//! Here are some valid paths for this example:
//!
//! `a_setting.[0]` - returns the string `a string`
//!
//! `a_setting.[1].[0].[2]` - returns the integer `3`
//!
//! `a_setting.[2].misc.x` - returns the integer `4`
//!
//! Adjacent string literals separated by whitespace, newlines and / or comments are automatically
//! concatenated.
//!
//! **Example**:
//!
//! ```ignore
//! "a"/* a comment */" string"    " liter"
//!
//! // This is a commment
//!
//!    "al"
//! ```
//!
//! is equivalent to:
//!
//! ```ignore
//! "a string literal"
//! ```
//!
//! See the integration tests (in the `tests/` directory) for sample use cases and more complex
//! examples.
//!
//!# Environment variables
//!
//! The crate has an ability to inject environment variables into the configuration file. That
//! becomes possible using special symtax:
//!
//!  * $"SOME_ENV_VAR_NAME"::bool for `ScalarValue::Boolean`
//!  * $"SOME_ENV_VAR_NAME"::str for `ScalarValue::Str`
//!  * $"SOME_ENV_VAR_NAME"::i32 for `ScalarValue::Integer32`
//!  * $"SOME_ENV_VAR_NAME"::i64 for `ScalarValue::Integer64`
//!  * $"SOME_ENV_VAR_NAME"::f32 for `ScalarValue::Floating32`
//!  * $"SOME_ENV_VAR_NAME"::f64 for `ScalarValue::Floating64`
//!
//!
//! **Example**:
//!
//! ```ignore
//! log = {
//!       // Inject (use) the value of the environment variable LOG_LEVEL
//!       level = $"LOG_LEVEL"::str;
//! }
//! ```
//!
//!# Grammar
//!
//! This section describes the configuration input format. The starting rule is `conf`.
//!
//! ```text
//! conf -> __ settings_list __
//!
//! settings_list -> // empty
//!                | setting settings_list
//! setting -> __ name __ (":"|"=") __ value __ ";" __
//!
//! name -> [a-zA-Z][-a-zA-Z0-9_]*
//!
//! value -> scalar_value
//!        | array_value
//!        | list_value
//!        | group_value
//!
//! scalar_value -> boolean_scalar_value
//!               | floating64_scalar_value
//!               | floating32_scalar_value
//!               | integer64_scalar_value
//!               | integer32_scalar_value
//!               | str_scalar_value
//!
//! boolean_scalar_value -> [Tt][Rr][Uu][Ee]
//!                       | [Yy][Ee][Ss]
//!                       | [Ff][Aa][Ll][Ss][Ee]
//!                       | [Nn][Oo]
//!
//! floating64_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?"L"
//!
//! floating32_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?
//!
//! integer32_scalar_value -> [+-]?[0-9]+
//!
//! integer64_scalar_value -> [+-]?[0-9]+"L"
//!
//! str_scalar_value -> __ str_literal __
//!                   | __ str_literal __ str_scalar_value
//!
//! str_literal -> "\"" ([^\"\\]|(("\\r"|"\\n"|"\\t"|"\\\""|"\\\\")))* "\""
//!
//! array_value -> "["
//!                (bool_array |
//!                 flt64_array | flt32_array |
//!                 int64_array | int32_array |
//!                 str_array)
//!                "]"
//!              | "[" __ "]"
//!
//! bool_array -> __ boolean_scalar_value __
//!             | __ boolean_scalar_value __ "," __ bool_array
//!
//! flt64_array -> __ floating64_scalar_value __
//!              | __ floating64_scalar_value __ "," __ flt64_array
//!
//! flt32_array -> __ floating32_scalar_value __
//!              | __ floating32_scalar_value __ "," __ flt32_array
//
//! int64_array -> __ integer64_scalar_value __
//!              | __ integer64_scalar_value __ "," __ int64_array
//!
//! int32_array -> __ integer32_scalar_value __
//!              | __ integer32_scalar_value __ "," __ int32_array
//!
//! str_array -> __ str_scalar_value __
//!            | __ str_scalar_value __ "," __ str_array
//!
//! list_value -> "(" __ ")"
//!             | "(" list_elements ")"
//!
//! list_elements -> __ value __
//!                | __ value __ "," __ list_elements
//!
//! group_value -> "{" settings_list "}"
//!
//! __ -> // empty
//!     | whitespace __
//!     | eol __
//!     | comment __
//!
//! whitespace -> [\s\t]
//!
//! eol -> "\r\n"
//!      | "\n"
//!
//! comment -> single_line_comment
//!          | multi_line_comment
//!
//! single_line_comment -> ("//"|"#")[^\n]*"\n"?
//!
//! multi_line_comment -> "/*"([^*]|"*"[^/])*"*/"
//!
//! ```
//!

#![crate_name = "config"]
#![crate_type = "lib"]
#![warn(missing_docs)]

#[macro_use]
extern crate nom;

mod parser;

pub mod types;
pub mod error;
pub mod reader;
<commit_msg>Fix type in the lib documentation<commit_after>//! A library to parse and load configuration files.
//!
//! This library parses and loads configuration files in much the same way as C/C++'s
//! [libconfig](http://www.hyperrealm.com/libconfig/). At this time, it can only read and load
//! configurations, but future plans include a much richer user API to allow other forms of
//! interaction, such as manipulating values, writing the current configuration to a file, etc.
//!
//!# Getting started
//!
//! A configuration file consists of a group of settings. A setting is a key/value pair, where the
//! key is a string of the form `[a-zA-Z][-a-zA-Z0-9_]*`, and the value is anything represented by
//! `types::Value`. In a configuration file, setting/value pairs are written as
//! `setting_name = value;`. Possible values include primitive integer and floating point types,
//! strings, arrays, lists, etc.
//!
//! The library provides a bunch of methods to read the configuration data in the `reader` module.
//! The possibilities include reading from a string, from a file, or from anything that implements
//! the `Read` trait.
//!
//! As of now, every reader will first attempt to read the whole configuration into memory,
//! and only begins parsing once everything was read.
//!
//! In case of error, the parser returns a `config::error`.
//! On success, the parser returns a `Config`, which can then be used to browse the loaded data.
//!
//! Browsing is typically done with the `lookup_*` methods implemented by `Config`. The `lookup`
//! methods work with *paths*. Essentially, a path unambiguously describes the location of
//! a setting.
//!
//! For example, consider this input configuration file:
//!
//!```ignore
//! title = "My HTTP server";
//! listen_ports = [ 80, 443 ];
//! misc = {
//!     owner = "Chuck Norris";
//!     location = "CA";
//!     contact = {
//!         phone = "415-256-9999";
//!         // This is an array. Arrays start with `[` and end with `]`
//!         // Arrays are homogeneous and can only hold scalar data types.
//!         // See types::ScalarValue for further information
//!         emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
//!     };
//! };
//!```
//!
//! At the top level, we have 3 settings: `title`, `listen_ports` and `misc`. `misc` is itself a
//! group of settings. Each value in this configuration is reachable by a unique path of settings
//! to follow. Each setting in a path is separated by `.`
//!
//! **Example**: The path `misc.contact.phone` identifies the setting with value `415-256-9999`.
//!
//! Array and list types are indexed using `[i]` in a path.
//!
//! **Example**: The path `listen_ports.[1]` identifies the setting with value `443`.
//!
//! **Example**: The path `misc.contact.emails.[0]` identifies the setting with value
//! `chuck@norris.com`
//!
//! Lists, as opposed to arrays, are heterogeneous and can store any data type, including other
//! lists. Here's a setting consisting of a heterogeneous list:
//!
//!```ignore
//! // This is a list. Lists start with `(` and end with `)`
//! // Lists are heterogeneous and can store any data type, including other lists
//! a_setting = ("a string", // The first element is a string
//!              ((1, 2, 3)), // The 2nd element is a list storing a list of 3 integers
//!              misc = { x = 4; y = 3; } // 3rd element: a group
//!             );
//!```
//!
//! Here are some valid paths for this example:
//!
//! `a_setting.[0]` - returns the string `a string`
//!
//! `a_setting.[1].[0].[2]` - returns the integer `3`
//!
//! `a_setting.[2].misc.x` - returns the integer `4`
//!
//! Adjacent string literals separated by whitespace, newlines and / or comments are automatically
//! concatenated.
//!
//! **Example**:
//!
//! ```ignore
//! "a"/* a comment */" string"    " liter"
//!
//! // This is a commment
//!
//!    "al"
//! ```
//!
//! is equivalent to:
//!
//! ```ignore
//! "a string literal"
//! ```
//!
//! See the integration tests (in the `tests/` directory) for sample use cases and more complex
//! examples.
//!
//!# Environment variables
//!
//! The crate has an ability to inject environment variables into the configuration file. That
//! becomes possible using special syntax:
//!
//!  * $"SOME_ENV_VAR_NAME"::bool for `ScalarValue::Boolean`
//!  * $"SOME_ENV_VAR_NAME"::str for `ScalarValue::Str`
//!  * $"SOME_ENV_VAR_NAME"::i32 for `ScalarValue::Integer32`
//!  * $"SOME_ENV_VAR_NAME"::i64 for `ScalarValue::Integer64`
//!  * $"SOME_ENV_VAR_NAME"::f32 for `ScalarValue::Floating32`
//!  * $"SOME_ENV_VAR_NAME"::f64 for `ScalarValue::Floating64`
//!
//!
//! **Example**:
//!
//! ```ignore
//! log = {
//!       // Inject (use) the value of the environment variable LOG_LEVEL
//!       level = $"LOG_LEVEL"::str;
//! }
//! ```
//!
//!# Grammar
//!
//! This section describes the configuration input format. The starting rule is `conf`.
//!
//! ```text
//! conf -> __ settings_list __
//!
//! settings_list -> // empty
//!                | setting settings_list
//! setting -> __ name __ (":"|"=") __ value __ ";" __
//!
//! name -> [a-zA-Z][-a-zA-Z0-9_]*
//!
//! value -> scalar_value
//!        | array_value
//!        | list_value
//!        | group_value
//!
//! scalar_value -> boolean_scalar_value
//!               | floating64_scalar_value
//!               | floating32_scalar_value
//!               | integer64_scalar_value
//!               | integer32_scalar_value
//!               | str_scalar_value
//!
//! boolean_scalar_value -> [Tt][Rr][Uu][Ee]
//!                       | [Yy][Ee][Ss]
//!                       | [Ff][Aa][Ll][Ss][Ee]
//!                       | [Nn][Oo]
//!
//! floating64_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?"L"
//!
//! floating32_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?
//!
//! integer32_scalar_value -> [+-]?[0-9]+
//!
//! integer64_scalar_value -> [+-]?[0-9]+"L"
//!
//! str_scalar_value -> __ str_literal __
//!                   | __ str_literal __ str_scalar_value
//!
//! str_literal -> "\"" ([^\"\\]|(("\\r"|"\\n"|"\\t"|"\\\""|"\\\\")))* "\""
//!
//! array_value -> "["
//!                (bool_array |
//!                 flt64_array | flt32_array |
//!                 int64_array | int32_array |
//!                 str_array)
//!                "]"
//!              | "[" __ "]"
//!
//! bool_array -> __ boolean_scalar_value __
//!             | __ boolean_scalar_value __ "," __ bool_array
//!
//! flt64_array -> __ floating64_scalar_value __
//!              | __ floating64_scalar_value __ "," __ flt64_array
//!
//! flt32_array -> __ floating32_scalar_value __
//!              | __ floating32_scalar_value __ "," __ flt32_array
//
//! int64_array -> __ integer64_scalar_value __
//!              | __ integer64_scalar_value __ "," __ int64_array
//!
//! int32_array -> __ integer32_scalar_value __
//!              | __ integer32_scalar_value __ "," __ int32_array
//!
//! str_array -> __ str_scalar_value __
//!            | __ str_scalar_value __ "," __ str_array
//!
//! list_value -> "(" __ ")"
//!             | "(" list_elements ")"
//!
//! list_elements -> __ value __
//!                | __ value __ "," __ list_elements
//!
//! group_value -> "{" settings_list "}"
//!
//! __ -> // empty
//!     | whitespace __
//!     | eol __
//!     | comment __
//!
//! whitespace -> [\s\t]
//!
//! eol -> "\r\n"
//!      | "\n"
//!
//! comment -> single_line_comment
//!          | multi_line_comment
//!
//! single_line_comment -> ("//"|"#")[^\n]*"\n"?
//!
//! multi_line_comment -> "/*"([^*]|"*"[^/])*"*/"
//!
//! ```
//!

#![crate_name = "config"]
#![crate_type = "lib"]
#![warn(missing_docs)]

#[macro_use]
extern crate nom;

mod parser;

pub mod types;
pub mod error;
pub mod reader;
<|endoftext|>


<commit_before>#![crate_id = "rust-hl-lua"]
#![crate_type = "lib"]
#![comment = "Lua bindings for Rust"]
#![license = "MIT"]
#![allow(visible_private_types)]
#![feature(macro_rules)]

extern crate libc;
extern crate std;

mod liblua;
mod functions;
mod tables;
mod userdata;
mod values;

/**
 * Main object of the library
 */
pub struct Lua {
    lua: *mut liblua::lua_State
}

/**
 * Object which allows access to a Lua variable
 */
pub struct LoadedVariable<'a> {
    lua: &'a mut Lua,
    size: int       // number of elements at the top of the stack
}

/**
 * Should be implemented by whatever type is pushable on the Lua stack
 */
pub trait Pushable {
    fn push_to_lua(&self, &Lua);
}

/**
 * Should be implemented by whatever type can be read from the Lua stack
 */
pub trait Readable {
    /**
     * # Arguments
     *  * `lua` - The Lua object to read from
     *  * `index` - The index on the stack to read from
     */
    fn read_from_lua(lua: &Lua, index: i32) -> Option<Self>;
}

/**
 * Types that can be indices in Lua tables
 */
pub trait Index: Pushable + Readable {
}

/**
 * Object which can store variables
 */
pub trait Table<I, LV> {
    /// Loads the given index at the top of the stack
    fn get<V: Readable>(&mut self, &I) -> Option<V>;
    /// Stores the value in the table
    fn set<V: Pushable>(&mut self, &I, V) -> Result<(), &'static str>;
    ///
    fn access(self, index: &I) -> LV;
}

/**
 * Represents the global variables
 */
struct Globals<'a> {
    lua: &'a mut Lua
}

/**
 * Error that can happen when executing Lua code
 */
#[deriving(Show)]
pub enum ExecutionError {
    SyntaxError(String),
    ExecError(String)
}

extern "C" fn alloc(_ud: *mut libc::c_void, ptr: *mut libc::c_void, _osize: libc::size_t, nsize: libc::size_t) -> *mut libc::c_void {
    unsafe {
        if nsize == 0 {
            libc::free(ptr as *mut libc::c_void);
            std::ptr::mut_null()
        } else {
            libc::realloc(ptr, nsize)
        }
    }
}

extern "C" fn panic(lua: *mut liblua::lua_State) -> libc::c_int {
    let err = unsafe { liblua::lua_tostring(lua, -1) };
    println!("PANIC: unprotected error in call to Lua API ({})\n", err);
    0
}

extern {
    pub fn luaL_loadstring(L: *mut liblua::lua_State, s: *libc::c_char) -> libc::c_int;
}

impl Lua {
    /**
     * Builds a new Lua context
     * # Failure
     * The function fails if lua_newstate fails (which indicates lack of memory)
     */
    pub fn new() -> Lua {
        let lua = unsafe { liblua::lua_newstate(alloc, std::ptr::mut_null()) };
        if lua.is_null() {
            fail!("lua_newstate failed");
        }

        unsafe { liblua::lua_atpanic(lua, panic) };

        Lua { lua: lua }
    }

    /**
     * Executes some Lua code on the context
     */
    pub fn execute<T: Readable>(&mut self, code: &str) -> Result<T, ExecutionError> {
        try!(self.load(code));
        self.callStackTop()
    }

    pub fn access<'a, I: Str>(&'a mut self, index: I) -> LoadedVariable<'a> {
        let g = Globals{lua: self};
        g.access(&index)
    }

    pub fn get<I: Str, V: Readable>(&mut self, index: I) -> Option<V> {
        let mut g = Globals{lua: self};
        g.get(&index)
    }

    pub fn set<I: Str, V: Pushable>(&mut self, index: I, value: V) -> Result<(), &'static str> {
        let mut g = Globals{lua: self};
        g.set(&index, value)
    }

    fn load(&mut self, code: &str) -> Result<(), ExecutionError> {
        let loadReturnValue = unsafe { luaL_loadstring(self.lua, code.to_c_str().unwrap()) };

        if loadReturnValue == 0 {
            return Ok(());
        }

        let errorMsg: String = Readable::read_from_lua(self, -1).unwrap();
        unsafe { liblua::lua_pop(self.lua, 1) };

        if loadReturnValue == liblua::LUA_ERRMEM {
            fail!("LUA_ERRMEM");
        }
        if loadReturnValue == liblua::LUA_ERRSYNTAX {
            return Err(SyntaxError(errorMsg));
        }

        fail!("Unknown error while calling lua_load");
    }

    fn callStackTop<T: Readable>(&mut self) -> Result<T, ExecutionError> {
        // calling pcall pops the parameters and pushes output
        let pcallReturnValue = unsafe { liblua::lua_pcall(self.lua, 0, 1, 0) };     // TODO:

        // if pcall succeeded, returning
        if pcallReturnValue == 0 {
            return match Readable::read_from_lua(self, -1) {
                None => fail!("Wrong type"),       // TODO: add to executionerror
                Some(x) => Ok(x)
            };
        }

        // an error occured during execution
        if pcallReturnValue == liblua::LUA_ERRMEM {
            fail!("LUA_ERRMEM");
        }

        if pcallReturnValue == liblua::LUA_ERRRUN {
            let errorMsg: String = Readable::read_from_lua(self, -1).unwrap();
            unsafe { liblua::lua_pop(self.lua, 1) };
            return Err(ExecError(errorMsg));
        }

        fail!("Unknown error code returned by lua_pcall")
    }
}

// TODO: this destructor crash the compiler
// https://github.com/mozilla/rust/issues/13853
// https://github.com/mozilla/rust/issues/14377
/*impl<'a> Drop for LoadedVariable<'a> {
    fn drop(&mut self) {
        unsafe { liblua::lua_pop(self.lua.lua, self.size as i32) }
    }
}*/

impl<'a, I: Str> Table<I, LoadedVariable<'a>> for Globals<'a> {
    fn get<V: Readable>(&mut self, index: &I) -> Option<V> {
        unsafe { liblua::lua_getglobal(self.lua.lua, index.as_slice().to_c_str().unwrap()); }
        let val = Readable::read_from_lua(self.lua, -1);
        unsafe { liblua::lua_pop(self.lua.lua, 1); }
        val
    }

    fn set<V: Pushable>(&mut self, index: &I, value: V) -> Result<(), &'static str> {
        value.push_to_lua(self.lua);
        unsafe { liblua::lua_setglobal(self.lua.lua, index.as_slice().to_c_str().unwrap()); }
        Ok(())
    }

    fn access(self, index: &I) -> LoadedVariable<'a> {
        unsafe {
            liblua::lua_getglobal(self.lua.lua, index.as_slice().to_c_str().unwrap());
        }

        // TODO: check if not null

        LoadedVariable {
            lua: self.lua,
            size: 1
        }
    }
}

impl<'a, I: Index> Table<I, LoadedVariable<'a>> for LoadedVariable<'a> {
    fn get<V: Readable>(&mut self, index: &I) -> Option<V> {
        index.push_to_lua(self.lua);
        unsafe { liblua::lua_gettable(self.lua.lua, -2); }
        let val = Readable::read_from_lua(self.lua, -1);
        unsafe { liblua::lua_pop(self.lua.lua, 1); }
        val
    }

    fn set<V: Pushable>(&mut self, index: &I, value: V) -> Result<(), &'static str> {
        value.push_to_lua(self.lua);
        index.push_to_lua(self.lua);
        unsafe { liblua::lua_settable(self.lua.lua, -3); }
        unsafe { liblua::lua_pop(self.lua.lua, 1); }
        Ok(())
    }

    fn access(self, index: &I) -> LoadedVariable<'a> {
        index.push_to_lua(self.lua);
        unsafe { liblua::lua_gettable(self.lua.lua, -2); }

        LoadedVariable {
            lua: self.lua,
            size: self.size + 1
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn globals_readwrite() {
        let mut lua = super::Lua::new();

        lua.set("a", 2).unwrap();
        let x: int = lua.get("a").unwrap();
        assert_eq!(x, 2)
    }

    // TODO: doesn't compile, have absolutely NO IDEA why
    /*#[test]
    fn table_readwrite() {
        let mut lua = super::Lua::new();

        lua.execute("a = { foo = 5 }");

        assert_eq!(lua.access("a").get(&"foo").unwrap(), 2);

        {   let access = lua.access("a");
            access.set(5, 3);
            assert_eq!(access.get(5), 3);
        }
    }*/
}
<commit_msg>Add some comments<commit_after>#![crate_id = "rust-hl-lua"]
#![crate_type = "lib"]
#![comment = "Lua bindings for Rust"]
#![license = "MIT"]
#![allow(visible_private_types)]
#![feature(macro_rules)]

extern crate libc;
extern crate std;

mod liblua;
mod functions;
mod tables;
mod userdata;
mod values;

/**
 * Main object of the library
 */
pub struct Lua {
    lua: *mut liblua::lua_State
}

/**
 * Object which allows access to a Lua variable
 */
pub struct LoadedVariable<'a> {
    lua: &'a mut Lua,
    size: int       // number of elements at the top of the stack
}

/**
 * Should be implemented by whatever type is pushable on the Lua stack
 */
pub trait Pushable {
    fn push_to_lua(&self, &Lua);
}

/**
 * Should be implemented by whatever type can be read from the Lua stack
 */
pub trait Readable {
    /**
     * # Arguments
     *  * `lua` - The Lua object to read from
     *  * `index` - The index on the stack to read from
     */
    fn read_from_lua(lua: &Lua, index: i32) -> Option<Self>;
}

/**
 * Types that can be indices in Lua tables
 */
pub trait Index: Pushable + Readable {
}

/**
 * Object which can store variables
 */
pub trait Table<I, LV> {
    /// Loads the given index at the top of the stack
    fn get<V: Readable>(&mut self, &I) -> Option<V>;
    /// Stores the value in the table
    fn set<V: Pushable>(&mut self, &I, V) -> Result<(), &'static str>;
    ///
    fn access(self, index: &I) -> LV;
}

/**
 * Represents the global variables
 */
struct Globals<'a> {
    lua: &'a mut Lua
}

/**
 * Error that can happen when executing Lua code
 */
#[deriving(Show)]
pub enum ExecutionError {
    SyntaxError(String),
    ExecError(String)
}

// this alloc function is required to create a lua state
extern "C" fn alloc(_ud: *mut libc::c_void, ptr: *mut libc::c_void, _osize: libc::size_t, nsize: libc::size_t) -> *mut libc::c_void {
    unsafe {
        if nsize == 0 {
            libc::free(ptr as *mut libc::c_void);
            std::ptr::mut_null()
        } else {
            libc::realloc(ptr, nsize)
        }
    }
}

// called whenever lua encounters an unexpected error
extern "C" fn panic(lua: *mut liblua::lua_State) -> libc::c_int {
    let err = unsafe { liblua::lua_tostring(lua, -1) };
    fail!("PANIC: unprotected error in call to Lua API ({})\n", err);
}

// TODO: don't put this here
extern {
    pub fn luaL_loadstring(L: *mut liblua::lua_State, s: *libc::c_char) -> libc::c_int;
}

impl Lua {
    /**
     * Builds a new Lua context
     * # Failure
     * The function fails if lua_newstate fails (which indicates lack of memory)
     */
    pub fn new() -> Lua {
        let lua = unsafe { liblua::lua_newstate(alloc, std::ptr::mut_null()) };
        if lua.is_null() {
            fail!("lua_newstate failed");
        }

        unsafe { liblua::lua_atpanic(lua, panic) };

        Lua { lua: lua }
    }

    /**
     * Executes some Lua code on the context
     */
    pub fn execute<T: Readable>(&mut self, code: &str) -> Result<T, ExecutionError> {
        try!(self.load(code));
        self.call_stack_top()
    }

    pub fn access<'a, I: Str>(&'a mut self, index: I) -> LoadedVariable<'a> {
        let g = Globals{lua: self};
        g.access(&index)
    }

    /**
     * Reads the value of a global variable
     */
    pub fn get<I: Str, V: Readable>(&mut self, index: I) -> Option<V> {
        let mut g = Globals{lua: self};
        g.get(&index)
    }

    /**
     * Modifies the value of a global variable
     */
    pub fn set<I: Str, V: Pushable>(&mut self, index: I, value: V) -> Result<(), &'static str> {
        let mut g = Globals{lua: self};
        g.set(&index, value)
    }

    fn load(&mut self, code: &str) -> Result<(), ExecutionError> {
        let loadReturnValue = unsafe { luaL_loadstring(self.lua, code.to_c_str().unwrap()) };

        if loadReturnValue == 0 {
            return Ok(());
        }

        let errorMsg: String = Readable::read_from_lua(self, -1).unwrap();
        unsafe { liblua::lua_pop(self.lua, 1) };

        if loadReturnValue == liblua::LUA_ERRMEM {
            fail!("LUA_ERRMEM");
        }
        if loadReturnValue == liblua::LUA_ERRSYNTAX {
            return Err(SyntaxError(errorMsg));
        }

        fail!("Unknown error while calling lua_load");
    }

    fn call_stack_top<T: Readable>(&mut self) -> Result<T, ExecutionError> {
        // calling pcall pops the parameters and pushes output
        let pcallReturnValue = unsafe { liblua::lua_pcall(self.lua, 0, 1, 0) };     // TODO:

        // if pcall succeeded, returning
        if pcallReturnValue == 0 {
            return match Readable::read_from_lua(self, -1) {
                None => fail!("Wrong type"),       // TODO: add to executionerror
                Some(x) => Ok(x)
            };
        }

        // an error occured during execution
        if pcallReturnValue == liblua::LUA_ERRMEM {
            fail!("LUA_ERRMEM");
        }

        if pcallReturnValue == liblua::LUA_ERRRUN {
            let errorMsg: String = Readable::read_from_lua(self, -1).unwrap();
            unsafe { liblua::lua_pop(self.lua, 1) };
            return Err(ExecError(errorMsg));
        }

        fail!("Unknown error code returned by lua_pcall")
    }
}

// TODO: this destructor crash the compiler
// https://github.com/mozilla/rust/issues/13853
// https://github.com/mozilla/rust/issues/14377
/*impl<'a> Drop for LoadedVariable<'a> {
    fn drop(&mut self) {
        unsafe { liblua::lua_pop(self.lua.lua, self.size as i32) }
    }
}*/

impl<'a, I: Str> Table<I, LoadedVariable<'a>> for Globals<'a> {
    fn get<V: Readable>(&mut self, index: &I) -> Option<V> {
        unsafe { liblua::lua_getglobal(self.lua.lua, index.as_slice().to_c_str().unwrap()); }
        let val = Readable::read_from_lua(self.lua, -1);
        unsafe { liblua::lua_pop(self.lua.lua, 1); }
        val
    }

    fn set<V: Pushable>(&mut self, index: &I, value: V) -> Result<(), &'static str> {
        value.push_to_lua(self.lua);
        unsafe { liblua::lua_setglobal(self.lua.lua, index.as_slice().to_c_str().unwrap()); }
        Ok(())
    }

    fn access(self, index: &I) -> LoadedVariable<'a> {
        unsafe {
            liblua::lua_getglobal(self.lua.lua, index.as_slice().to_c_str().unwrap());
        }

        // TODO: check if not null

        LoadedVariable {
            lua: self.lua,
            size: 1
        }
    }
}

impl<'a, I: Index> Table<I, LoadedVariable<'a>> for LoadedVariable<'a> {
    fn get<V: Readable>(&mut self, index: &I) -> Option<V> {
        index.push_to_lua(self.lua);
        unsafe { liblua::lua_gettable(self.lua.lua, -2); }
        let val = Readable::read_from_lua(self.lua, -1);
        unsafe { liblua::lua_pop(self.lua.lua, 1); }
        val
    }

    fn set<V: Pushable>(&mut self, index: &I, value: V) -> Result<(), &'static str> {
        value.push_to_lua(self.lua);
        index.push_to_lua(self.lua);
        unsafe { liblua::lua_settable(self.lua.lua, -3); }
        unsafe { liblua::lua_pop(self.lua.lua, 1); }
        Ok(())
    }

    fn access(self, index: &I) -> LoadedVariable<'a> {
        index.push_to_lua(self.lua);
        unsafe { liblua::lua_gettable(self.lua.lua, -2); }

        LoadedVariable {
            lua: self.lua,
            size: self.size + 1
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn globals_readwrite() {
        let mut lua = super::Lua::new();

        lua.set("a", 2).unwrap();
        let x: int = lua.get("a").unwrap();
        assert_eq!(x, 2)
    }

    // TODO: doesn't compile, have absolutely NO IDEA why
    /*#[test]
    fn table_readwrite() {
        let mut lua = super::Lua::new();

        lua.execute("a = { foo = 5 }");

        assert_eq!(lua.access("a").get(&"foo").unwrap(), 2);

        {   let access = lua.access("a");
            access.set(5, 3);
            assert_eq!(access.get(5), 3);
        }
    }*/
}
<|endoftext|>


<commit_before>
//! A semi-safe, semi-stateless wrapper around OpenGL 3.3 Core. This library provides various
//! utilities to make using OpenGL 3.3 safer. It uses rust's type system to encode some information
//! which helps prevent common errors. This library is primarily intended to be used for games,
//! but you can also use it to create other graphics applications.

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

extern crate gl;
extern crate png;
extern crate rusttype;

extern crate cable_math;

mod color;
mod input;
mod window;

pub mod texture;
#[macro_use]
pub mod shader;
pub mod buffer;
pub mod graphics;
pub mod framebuffer;
pub mod font;
pub mod draw_group;
//pub mod ui; // Temporarily disabled. Broken due to changes in font code. Should be rewritten to use draw_group

pub use color::*;
pub use input::*;
pub use window::*;

use std::time::{Instant, Duration};
use std::ops::{Add, Sub, AddAssign, SubAssign};

use cable_math::Vec2;

pub use draw_group::DrawGroup;

/// Utility to track time in a program
#[derive(Clone)]
pub struct Timer {
    start: Instant,
    last: Instant,
}

impl Timer {
    pub fn new() -> Timer {
        let now = Instant::now();

        Timer {
            start: now,
            last: now,
        }
    }

    /// Returns `(time_since_start, time_since_last_tick)`
    pub fn tick(&mut self) -> (Timing, Timing) {
        let now = Instant::now();

        let age = (now - self.start).into();
        let delta = (now - self.last).into();

        self.last = now;

        (age, delta)
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timing(pub u64);

impl Timing {
    pub fn zero() -> Timing { Timing(0) }

    pub fn from_ms(ms: u64) -> Timing { Timing(ms * 1_000_000) }
    pub fn from_secs(s: u64) -> Timing { Timing(s * 1_000_000_000) }
    pub fn from_secs_float(s: f32) -> Timing { Timing((s * 1_000_000_000.0) as u64) }

    /// Converts this timing to seconds, truncating any overflow. 1.999 ms will be converted to 1 ms.
    pub fn as_ms(self) -> u64 { self.0 / 1_000_000 }

    /// Converts this timing to seconds, truncating any overflow. 1.999 seconds will be converted to 1.
    pub fn as_secs(self) -> u64 { self.0 / 1_000_000_000 }

    pub fn as_secs_float(self) -> f32 { self.0 as f32 / 1_000_000_000.0 }

    pub fn max(self, other: Timing) -> Timing {
        ::std::cmp::max(self, other)
    }

    pub fn min(self, other: Timing) -> Timing {
        ::std::cmp::min(self, other)
    }
}

impl Add for Timing {
    type Output = Timing;
    fn add(self, rhs: Timing) -> Timing {
        Timing(self.0 + rhs.0)
    }
}

impl Sub for Timing {
    type Output = Timing;
    fn sub(self, rhs: Timing) -> Timing {
        Timing(self.0 - rhs.0)
    }
}

impl AddAssign for Timing {
    fn add_assign(&mut self, rhs: Timing) {
        self.0 += rhs.0;
    }
}

impl SubAssign for Timing {
    fn sub_assign(&mut self, rhs: Timing) {
        self.0 -= rhs.0;
    }
}

impl From<Duration> for Timing {
    fn from(d: Duration) -> Timing {
        Timing(d.as_secs()*1_000_000_000 + (d.subsec_nanos() as u64))
    }
}

impl From<Timing> for Duration {
    fn from(t: Timing) -> Duration {
        let nanos = t.0 % 1_000_000_000;
        let secs = t.0 / 1_000_000_000;
        Duration::new(secs, nanos as u32)
    }
}

#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub struct Region {
    pub min: Vec2<f32>,
    pub max: Vec2<f32>,
}

impl Region {
    pub fn center(&self) -> Vec2<f32> { (self.min + self.max) / 2.0 }

    pub fn width(&self) -> f32        { self.max.x - self.min.x }
    pub fn height(&self) -> f32       { self.max.y - self.min.y }

    pub fn size(&self) -> Vec2<f32>   { self.max - self.min }

    /// Checks if the given point is inside this region.
    pub fn contains(&self, p: Vec2<f32>) -> bool {
        p.x > self.min.x && p.x < self.max.x &&
        p.y > self.min.y && p.y < self.max.y
    }

    /// Width divided by height.
    pub fn aspect(&self) -> f32 {
        let size = self.size();
        size.x / size.y
    }

    /// Swaps `min` and `max` along the y axis
    pub fn flip_y(self) -> Region {
        Region {
            min: Vec2::new(self.min.x, self.max.y),
            max: Vec2::new(self.max.x, self.min.y),
        }
    }

    /// Swaps `min` and `max` along the x axis
    pub fn flip_x(self) -> Region {
        Region {
            min: Vec2::new(self.max.x, self.min.y),
            max: Vec2::new(self.min.x, self.max.y),
        }
    }

    /// Returns the region in which this region overlaps the given other region. This might produce
    /// a negative region.
    pub fn overlap(self, other: Region) -> Region {
        Region {
            min: Vec2 {
                x: f32::max(self.min.x, other.min.x),
                y: f32::max(self.min.y, other.min.y),
            },
            max: Vec2 {
                x: f32::min(self.max.x, other.max.x),
                y: f32::min(self.max.y, other.max.y),
            },
        }
    }

    /// Moves `min` to `(0, 0)` but preserves width and height.
    pub fn unpositioned(self) -> Region {
        Region {
            min: Vec2::zero(),
            max: self.max - self.min,
        }
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn top_right(self) -> Vec2<f32> {
        Vec2::new(self.min.y, self.max.x)
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn bottom_left(self) -> Vec2<f32> {
        Vec2::new(self.max.y, self.min.x)
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn top_left(self) -> Vec2<f32> {
        self.min
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn bottom_right(self) -> Vec2<f32> {
        self.max
    }
}
<commit_msg>Comitting without testing is a viable method of development<commit_after>
//! A semi-safe, semi-stateless wrapper around OpenGL 3.3 Core. This library provides various
//! utilities to make using OpenGL 3.3 safer. It uses rust's type system to encode some information
//! which helps prevent common errors. This library is primarily intended to be used for games,
//! but you can also use it to create other graphics applications.

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

extern crate gl;
extern crate png;
extern crate rusttype;

extern crate cable_math;

mod color;
mod input;
mod window;

pub mod texture;
#[macro_use]
pub mod shader;
pub mod buffer;
pub mod graphics;
pub mod framebuffer;
pub mod font;
pub mod draw_group;
//pub mod ui; // Temporarily disabled. Broken due to changes in font code. Should be rewritten to use draw_group

pub use color::*;
pub use input::*;
pub use window::*;

use std::time::{Instant, Duration};
use std::ops::{Add, Sub, AddAssign, SubAssign};

use cable_math::Vec2;

pub use draw_group::DrawGroup;

/// Utility to track time in a program
#[derive(Clone)]
pub struct Timer {
    start: Instant,
    last: Instant,
}

impl Timer {
    pub fn new() -> Timer {
        let now = Instant::now();

        Timer {
            start: now,
            last: now,
        }
    }

    /// Returns `(time_since_start, time_since_last_tick)`
    pub fn tick(&mut self) -> (Timing, Timing) {
        let now = Instant::now();

        let age = (now - self.start).into();
        let delta = (now - self.last).into();

        self.last = now;

        (age, delta)
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timing(pub u64);

impl Timing {
    pub fn zero() -> Timing { Timing(0) }

    pub fn from_ms(ms: u64) -> Timing { Timing(ms * 1_000_000) }
    pub fn from_secs(s: u64) -> Timing { Timing(s * 1_000_000_000) }
    pub fn from_secs_float(s: f32) -> Timing { Timing((s * 1_000_000_000.0) as u64) }

    /// Converts this timing to seconds, truncating any overflow. 1.999 ms will be converted to 1 ms.
    pub fn as_ms(self) -> u64 { self.0 / 1_000_000 }

    /// Converts this timing to seconds, truncating any overflow. 1.999 seconds will be converted to 1.
    pub fn as_secs(self) -> u64 { self.0 / 1_000_000_000 }

    pub fn as_secs_float(self) -> f32 { self.0 as f32 / 1_000_000_000.0 }

    pub fn max(self, other: Timing) -> Timing {
        ::std::cmp::max(self, other)
    }

    pub fn min(self, other: Timing) -> Timing {
        ::std::cmp::min(self, other)
    }
}

impl Add for Timing {
    type Output = Timing;
    fn add(self, rhs: Timing) -> Timing {
        Timing(self.0 + rhs.0)
    }
}

impl Sub for Timing {
    type Output = Timing;
    fn sub(self, rhs: Timing) -> Timing {
        Timing(self.0 - rhs.0)
    }
}

impl AddAssign for Timing {
    fn add_assign(&mut self, rhs: Timing) {
        self.0 += rhs.0;
    }
}

impl SubAssign for Timing {
    fn sub_assign(&mut self, rhs: Timing) {
        self.0 -= rhs.0;
    }
}

impl From<Duration> for Timing {
    fn from(d: Duration) -> Timing {
        Timing(d.as_secs()*1_000_000_000 + (d.subsec_nanos() as u64))
    }
}

impl From<Timing> for Duration {
    fn from(t: Timing) -> Duration {
        let nanos = t.0 % 1_000_000_000;
        let secs = t.0 / 1_000_000_000;
        Duration::new(secs, nanos as u32)
    }
}

#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub struct Region {
    pub min: Vec2<f32>,
    pub max: Vec2<f32>,
}

impl Region {
    pub fn center(&self) -> Vec2<f32> { (self.min + self.max) / 2.0 }

    pub fn width(&self) -> f32        { self.max.x - self.min.x }
    pub fn height(&self) -> f32       { self.max.y - self.min.y }

    pub fn size(&self) -> Vec2<f32>   { self.max - self.min }

    /// Checks if the given point is inside this region.
    pub fn contains(&self, p: Vec2<f32>) -> bool {
        p.x > self.min.x && p.x < self.max.x &&
        p.y > self.min.y && p.y < self.max.y
    }

    /// Width divided by height.
    pub fn aspect(&self) -> f32 {
        let size = self.size();
        size.x / size.y
    }

    /// Swaps `min` and `max` along the y axis
    pub fn flip_y(self) -> Region {
        Region {
            min: Vec2::new(self.min.x, self.max.y),
            max: Vec2::new(self.max.x, self.min.y),
        }
    }

    /// Swaps `min` and `max` along the x axis
    pub fn flip_x(self) -> Region {
        Region {
            min: Vec2::new(self.max.x, self.min.y),
            max: Vec2::new(self.min.x, self.max.y),
        }
    }

    /// Returns the region in which this region overlaps the given other region. This might produce
    /// a negative region.
    pub fn overlap(self, other: Region) -> Region {
        Region {
            min: Vec2 {
                x: f32::max(self.min.x, other.min.x),
                y: f32::max(self.min.y, other.min.y),
            },
            max: Vec2 {
                x: f32::min(self.max.x, other.max.x),
                y: f32::min(self.max.y, other.max.y),
            },
        }
    }

    /// Moves `min` to `(0, 0)` but preserves width and height.
    pub fn unpositioned(self) -> Region {
        Region {
            min: Vec2::zero(),
            max: self.max - self.min,
        }
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn top_right(self) -> Vec2<f32> {
        Vec2::new(self.max.x, self.min.y)
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn bottom_left(self) -> Vec2<f32> {
        Vec2::new(self.min.x, self.max.y)
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn top_left(self) -> Vec2<f32> {
        self.min
    }

    /// Assumes that `min` is top left and `max` bottom right
    pub fn bottom_right(self) -> Vec2<f32> {
        self.max
    }
}
<|endoftext|>


<commit_before>//! `Future`-powered I/O at the core of Tokio
//!
//! This crate uses the `futures` crate to provide an event loop ("reactor
//! core") which can be used to drive I/O like TCP and UDP, spawned future
//! tasks, and other events like channels/timeouts. All asynchronous I/O is
//! powered by the `mio` crate.
//!
//! The concrete types provided in this crate are relatively bare bones but are
//! intended to be the essential foundation for further projects needing an
//! event loop. In this crate you'll find:
//!
//! * TCP, both streams and listeners
//! * UDP sockets
//! * Timeouts
//! * An event loop to run futures
//!
//! More functionality is likely to be added over time, but otherwise the crate
//! is intended to be flexible, with the `PollEvented` type accepting any
//! type that implements `mio::Evented`. For example, the `tokio-uds` crate
//! uses `PollEvented` to provide support for Unix domain sockets.
//!
//! Some other important tasks covered by this crate are:
//!
//! * The ability to spawn futures into an event loop. The `Handle` and `Remote`
//!   types have a `spawn` method which allows executing a future on an event
//!   loop. The `Handle::spawn` method crucially does not require the future
//!   itself to be `Send`.
//!
//! * The `Io` trait serves as an abstraction for future crates to build on top
//!   of. This packages up `Read` and `Write` functionality as well as the
//!   ability to poll for readiness on both ends.
//!
//! * All I/O is futures-aware. If any action in this crate returns "not ready"
//!   or "would block", then the current future task is scheduled to receive a
//!   notification when it would otherwise make progress.
//!
//! You can find more extensive documentation in terms of tutorials at
//! [https://tokio.rs](https://tokio.rs).
//!
//! # Examples
//!
//! A simple TCP echo server:
//!
//! ```no_run
//! extern crate futures;
//! extern crate tokio_core;
//!
//! use futures::{Future, Stream};
//! use tokio_core::io::{copy, Io};
//! use tokio_core::net::TcpListener;
//! use tokio_core::reactor::Core;
//!
//! fn main() {
//!     // Create the event loop that will drive this server
//!     let mut core = Core::new().unwrap();
//!     let handle = core.handle();
//!
//!     // Bind the server's socket
//!     let addr = "127.0.0.1:12345".parse().unwrap();
//!     let sock = TcpListener::bind(&addr, &handle).unwrap();
//!
//!     // Pull out a stream of sockets for incoming connections
//!     let server = sock.incoming().for_each(|(sock, _)| {
//!         // Split up the reading and writing parts of the
//!         // socket
//!         let (reader, writer) = sock.split();
//!
//!         // A future that echos the data and returns how
//!         // many bytes were copied...
//!         let bytes_copied = copy(reader, writer);
//!
//!         // ... after which we'll print what happened
//!         let handle_conn = bytes_copied.map(|amt| {
//!             println!("wrote {} bytes", amt)
//!         }).map_err(|err| {
//!             println!("IO error {:?}", err)
//!         });
//!
//!         // Spawn the future as a concurrent task
//!         handle.spawn(handle_conn);
//!
//!         Ok(())
//!     });
//!
//!     // Spin up the server on the event loop
//!     core.run(server).unwrap();
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/tokio-core/0.1")]
#![deny(missing_docs)]

#[macro_use]
extern crate futures;
extern crate mio;
extern crate slab;

#[macro_use]
extern crate scoped_tls;

#[macro_use]
extern crate log;

#[macro_use]
pub mod io;

mod heap;
#[doc(hidden)]
pub mod channel;
pub mod net;
pub mod reactor;
<commit_msg>Remove unneeded macro_use<commit_after>//! `Future`-powered I/O at the core of Tokio
//!
//! This crate uses the `futures` crate to provide an event loop ("reactor
//! core") which can be used to drive I/O like TCP and UDP, spawned future
//! tasks, and other events like channels/timeouts. All asynchronous I/O is
//! powered by the `mio` crate.
//!
//! The concrete types provided in this crate are relatively bare bones but are
//! intended to be the essential foundation for further projects needing an
//! event loop. In this crate you'll find:
//!
//! * TCP, both streams and listeners
//! * UDP sockets
//! * Timeouts
//! * An event loop to run futures
//!
//! More functionality is likely to be added over time, but otherwise the crate
//! is intended to be flexible, with the `PollEvented` type accepting any
//! type that implements `mio::Evented`. For example, the `tokio-uds` crate
//! uses `PollEvented` to provide support for Unix domain sockets.
//!
//! Some other important tasks covered by this crate are:
//!
//! * The ability to spawn futures into an event loop. The `Handle` and `Remote`
//!   types have a `spawn` method which allows executing a future on an event
//!   loop. The `Handle::spawn` method crucially does not require the future
//!   itself to be `Send`.
//!
//! * The `Io` trait serves as an abstraction for future crates to build on top
//!   of. This packages up `Read` and `Write` functionality as well as the
//!   ability to poll for readiness on both ends.
//!
//! * All I/O is futures-aware. If any action in this crate returns "not ready"
//!   or "would block", then the current future task is scheduled to receive a
//!   notification when it would otherwise make progress.
//!
//! You can find more extensive documentation in terms of tutorials at
//! [https://tokio.rs](https://tokio.rs).
//!
//! # Examples
//!
//! A simple TCP echo server:
//!
//! ```no_run
//! extern crate futures;
//! extern crate tokio_core;
//!
//! use futures::{Future, Stream};
//! use tokio_core::io::{copy, Io};
//! use tokio_core::net::TcpListener;
//! use tokio_core::reactor::Core;
//!
//! fn main() {
//!     // Create the event loop that will drive this server
//!     let mut core = Core::new().unwrap();
//!     let handle = core.handle();
//!
//!     // Bind the server's socket
//!     let addr = "127.0.0.1:12345".parse().unwrap();
//!     let sock = TcpListener::bind(&addr, &handle).unwrap();
//!
//!     // Pull out a stream of sockets for incoming connections
//!     let server = sock.incoming().for_each(|(sock, _)| {
//!         // Split up the reading and writing parts of the
//!         // socket
//!         let (reader, writer) = sock.split();
//!
//!         // A future that echos the data and returns how
//!         // many bytes were copied...
//!         let bytes_copied = copy(reader, writer);
//!
//!         // ... after which we'll print what happened
//!         let handle_conn = bytes_copied.map(|amt| {
//!             println!("wrote {} bytes", amt)
//!         }).map_err(|err| {
//!             println!("IO error {:?}", err)
//!         });
//!
//!         // Spawn the future as a concurrent task
//!         handle.spawn(handle_conn);
//!
//!         Ok(())
//!     });
//!
//!     // Spin up the server on the event loop
//!     core.run(server).unwrap();
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/tokio-core/0.1")]
#![deny(missing_docs)]

extern crate futures;
extern crate mio;
extern crate slab;

#[macro_use]
extern crate scoped_tls;

#[macro_use]
extern crate log;

#[macro_use]
pub mod io;

mod heap;
#[doc(hidden)]
pub mod channel;
pub mod net;
pub mod reactor;
<|endoftext|>


<commit_before>#![feature(plugin_registrar)]
#![feature(rustc_private)]
#![feature(slice_patterns)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::abi::Abi;
use syntax::ast::Expr_::ExprTup;
use syntax::ast::Item_::ItemFn;
use syntax::ast::{Constness, Expr, FnDecl, FunctionRetTy, Generics, Ident, Item_, TokenTree, Unsafety};
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use syntax::ext::build::AstBuilder;
use syntax::parse::PResult;
use syntax::parse::common::seq_sep_trailing_allowed;
use syntax::parse::parser::Parser;
use syntax::parse::token::get_ident_interner;
use syntax::parse::token::keywords::Keyword;
use syntax::parse::token::{DelimToken, Token};
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

type ItemInfo = (Ident, Item_);

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("plague", plague_macro);
}

pub fn plague_macro<'cx>(cx: &'cx mut ExtCtxt, span: Span, tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    let mut parser = cx.new_parser_from_tts(tts);

    match parse_plague(&mut parser) {
        Ok((params, ident, item, should_panic, fn_span)) => {
            match make_plague(cx, &mut parser, params, ident, item, should_panic, fn_span) {
                Ok(r) => r,
                Err(mut err) => {
                    err.emit();
                    DummyResult::any(span)
                }
            }
        }
        Err(mut err) => {
            err.emit();
            DummyResult::any(span)
        }
    }
}

fn parse_plague<'a>(parser: &mut Parser<'a>) -> PResult<'a, (Spanned<Vec<P<Expr>>>, Ident, Item_, bool, Span)> {
    try!(parser.expect_keyword(Keyword::For));

    let params = try!(parser.parse_seq(
        &Token::OpenDelim(DelimToken::Bracket),
        &Token::CloseDelim(DelimToken::Bracket),
        seq_sep_trailing_allowed(Token::Comma),
        |parser| parser.parse_expr()
    ));

    try!(expect_keyword(parser, "test"));

    let should_panic = try!(parser.eat(&Token::Not));

    let mut span = parser.span;
    let (constness, unsafety, abi) = try!(parser.parse_fn_front_matter());

    // Yep, copy-pasted pieces from libsyntax
    let ident = try!(parser.parse_ident());
    let mut generics = try!(parser.parse_generics());
    let decl = try!(parser.parse_fn_decl(false));
    generics.where_clause = try!(parser.parse_where_clause());
    let body = try!(parser.parse_block());
    let fn_ = ItemFn(decl, unsafety, constness, abi, generics, body);

    span.hi = parser.last_span.hi;

    Ok((params, ident, fn_, should_panic, span))
}

fn expect_keyword<'a>(parser: &mut Parser<'a>, kw: &str) -> PResult<'a, ()> {
    match parser.parse_ident() {
        Ok(test_ident) if test_ident.name.as_str() == kw => Ok(()),
        Ok(ident) => {
            Err(parser.fatal(&format!("expected `test`, found `{}`", ident)))
        }
        Err(mut err) => {
            err.cancel();
            Err(parser.fatal(&format!("expected `test`, found `{}`", parser.this_token_to_string())))
        }
    }
}

fn make_plague<'cx, 'a>(
    cx: &'cx mut ExtCtxt,
    parser: &mut Parser<'a>,
    params: Spanned<Vec<P<Expr>>>,
    ident: Ident,
    fn_: Item_,
    should_panic: bool,
    fn_span: Span
) -> PResult<'a, Box<MacResult + 'cx>> {
    let unpack_tuple = if let &ItemFn(ref decl, _, _, _, _, _) = &fn_ {
        decl.inputs.len() > 1
    }
    else {
        panic!();
    };

    let interner = get_ident_interner();

    let mut fns = Vec::with_capacity(params.node.len());

    fns.push(cx.item( fn_span, ident, Vec::new(), fn_));

    let attributes = {
        let make_attr = |name| {
            cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, interner.intern(name).as_str()))
        };

        if should_panic {
            vec![make_attr("test"), make_attr("should_panic")]
        }
        else {
            vec![make_attr("test")]
        }
    };

    let span = params.span;
    for (i, param) in params.node.iter().enumerate() {
        let params = try!(make_params(parser, &param, unpack_tuple));
        let fn_ = make_test_fn(cx, span, ident, params);

        fns.push(cx.item(
            span,
            Ident::new(interner.intern(&format!("{}_{}", ident.name, i)), ident.ctxt),
            attributes.clone(),
            fn_
        ));
    }

    Ok(MacEager::items(SmallVector::many(fns)))
}

fn make_test_fn<'cx>(
    cx: &'cx mut ExtCtxt,
    span: Span,
    ident: Ident,
    params: Vec<P<Expr>>
) -> Item_ {
    let call = cx.expr_call_ident(span, ident, params);
    let block = cx.block_expr(call);

    Item_::ItemFn(
        P(FnDecl { inputs: vec![], output: FunctionRetTy::DefaultReturn(DUMMY_SP), variadic: false }),
        Unsafety::Normal,
        Constness::NotConst,
        Abi::Rust,
        Generics::default(),
        block
    )
}

fn make_params<'a>(
    parser: &mut Parser<'a>,
    params: &P<Expr>,
    unpack_tuple: bool
) -> PResult<'a, Vec<P<Expr>>> {
    if !unpack_tuple {
        Ok(vec![params.clone()])
    }
    else if let ExprTup(ref params) = params.node {
        Ok(params.clone())
    }
    else {
        Err(parser.span_fatal(params.span, "expected tuple, the test function has several arguments"))
    }
}
<commit_msg>Warn about empty parameter lists<commit_after>#![feature(plugin_registrar)]
#![feature(rustc_private)]
#![feature(slice_patterns)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::abi::Abi;
use syntax::ast::Expr_::ExprTup;
use syntax::ast::Item_::ItemFn;
use syntax::ast::{Constness, Expr, FnDecl, FunctionRetTy, Generics, Ident, Item_, TokenTree, Unsafety};
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use syntax::ext::build::AstBuilder;
use syntax::parse::PResult;
use syntax::parse::common::seq_sep_trailing_allowed;
use syntax::parse::parser::Parser;
use syntax::parse::token::get_ident_interner;
use syntax::parse::token::keywords::Keyword;
use syntax::parse::token::{DelimToken, Token};
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

type ItemInfo = (Ident, Item_);

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("plague", plague_macro);
}

pub fn plague_macro<'cx>(cx: &'cx mut ExtCtxt, span: Span, tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    let mut parser = cx.new_parser_from_tts(tts);

    match parse_plague(&mut parser) {
        Ok((params, ident, item, should_panic, fn_span)) => {
            match make_plague(cx, &mut parser, params, ident, item, should_panic, fn_span) {
                Ok(r) => r,
                Err(mut err) => {
                    err.emit();
                    DummyResult::any(span)
                }
            }
        }
        Err(mut err) => {
            err.emit();
            DummyResult::any(span)
        }
    }
}

fn parse_plague<'a>(parser: &mut Parser<'a>) -> PResult<'a, (Spanned<Vec<P<Expr>>>, Ident, Item_, bool, Span)> {
    try!(parser.expect_keyword(Keyword::For));

    let params = try!(parser.parse_seq(
        &Token::OpenDelim(DelimToken::Bracket),
        &Token::CloseDelim(DelimToken::Bracket),
        seq_sep_trailing_allowed(Token::Comma),
        |parser| parser.parse_expr()
    ));

    try!(expect_keyword(parser, "test"));

    let should_panic = try!(parser.eat(&Token::Not));

    let mut span = parser.span;
    let (constness, unsafety, abi) = try!(parser.parse_fn_front_matter());

    // Yep, copy-pasted pieces from libsyntax
    let ident = try!(parser.parse_ident());
    let mut generics = try!(parser.parse_generics());
    let decl = try!(parser.parse_fn_decl(false));
    generics.where_clause = try!(parser.parse_where_clause());
    let body = try!(parser.parse_block());
    let fn_ = ItemFn(decl, unsafety, constness, abi, generics, body);

    span.hi = parser.last_span.hi;

    Ok((params, ident, fn_, should_panic, span))
}

fn expect_keyword<'a>(parser: &mut Parser<'a>, kw: &str) -> PResult<'a, ()> {
    match parser.parse_ident() {
        Ok(test_ident) if test_ident.name.as_str() == kw => Ok(()),
        Ok(ident) => {
            Err(parser.fatal(&format!("expected `test`, found `{}`", ident)))
        }
        Err(mut err) => {
            err.cancel();
            Err(parser.fatal(&format!("expected `test`, found `{}`", parser.this_token_to_string())))
        }
    }
}

fn make_plague<'cx, 'a>(
    cx: &'cx mut ExtCtxt,
    parser: &mut Parser<'a>,
    params: Spanned<Vec<P<Expr>>>,
    ident: Ident,
    fn_: Item_,
    should_panic: bool,
    fn_span: Span
) -> PResult<'a, Box<MacResult + 'cx>> {
    if params.node.is_empty() {
        cx.span_err(params.span, "empty parametrized tests are useless");
    }

    let unpack_tuple = if let &ItemFn(ref decl, _, _, _, _, _) = &fn_ {
        decl.inputs.len() > 1
    }
    else {
        panic!();
    };

    let interner = get_ident_interner();

    let mut fns = Vec::with_capacity(params.node.len());

    fns.push(cx.item( fn_span, ident, Vec::new(), fn_));

    let attributes = {
        let make_attr = |name| {
            cx.attribute(DUMMY_SP, cx.meta_word(DUMMY_SP, interner.intern(name).as_str()))
        };

        if should_panic {
            vec![make_attr("test"), make_attr("should_panic")]
        }
        else {
            vec![make_attr("test")]
        }
    };

    let span = params.span;
    for (i, param) in params.node.iter().enumerate() {
        let params = try!(make_params(parser, &param, unpack_tuple));
        let fn_ = make_test_fn(cx, span, ident, params);

        fns.push(cx.item(
            span,
            Ident::new(interner.intern(&format!("{}_{}", ident.name, i)), ident.ctxt),
            attributes.clone(),
            fn_
        ));
    }

    Ok(MacEager::items(SmallVector::many(fns)))
}

fn make_test_fn<'cx>(
    cx: &'cx mut ExtCtxt,
    span: Span,
    ident: Ident,
    params: Vec<P<Expr>>
) -> Item_ {
    let call = cx.expr_call_ident(span, ident, params);
    let block = cx.block_expr(call);

    Item_::ItemFn(
        P(FnDecl { inputs: vec![], output: FunctionRetTy::DefaultReturn(DUMMY_SP), variadic: false }),
        Unsafety::Normal,
        Constness::NotConst,
        Abi::Rust,
        Generics::default(),
        block
    )
}

fn make_params<'a>(
    parser: &mut Parser<'a>,
    params: &P<Expr>,
    unpack_tuple: bool
) -> PResult<'a, Vec<P<Expr>>> {
    if !unpack_tuple {
        Ok(vec![params.clone()])
    }
    else if let ExprTup(ref params) = params.node {
        Ok(params.clone())
    }
    else {
        Err(parser.span_fatal(params.span, "expected tuple, the test function has several arguments"))
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

//! Documentation is currently under construction.

// TODO: Make documentation not be "currently under construction." :P

#![feature(test)]
#![feature(step_by)]

#![allow(unused_imports)]
#![allow(non_snake_case)]
#![allow(unused_parens)]
#![deny(unused_must_use)]

extern crate num;
extern crate test;
extern crate rand;
extern crate bit_set;

pub use primes::PrimeTester;
pub use primes::PrimeSieve;
pub use primes::MillerRabinTester;
pub use factorizer::Factorizer;
pub use factorizer::TrialDivisionFactorizer;
pub use factorizer::StubbornFactorizer;
//pub use factorizer::FermatFactorizer;
pub use factorizer_dixon::DixonFactorizer;
pub use factorizer_pollard::PollardBrentFactorizer;
//pub use factorizer::GeneralFactorizer;
pub use factorizer::SafeFactorizer;
pub use factorizer::DefaultFactorizer;
pub use factorizer::ListFactorizer;
pub use factorization::Factorization;
pub use util::isqrt;
pub use util::gcd;

use std::collections::HashMap;
use std::hash::Hash;
use std::ops::Shr;

use num::{Zero,One,Integer};
use num::{FromPrimitive,ToPrimitive};

mod primes;
mod factorization;
mod factorizer;
mod factorizer_dixon;
mod factorizer_pollard;
mod util;

/// Factors a number using `DefaultFactorizer`.
pub fn factorize<T>(x: T) -> Factorization<T>
 where T: Eq + Clone + Zero + One + Integer + Shr<usize, Output=T> + Hash + ToPrimitive + FromPrimitive
{
	DefaultFactorizer.factorize(x)
}
<commit_msg>add `primes_upto`<commit_after>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

//! Documentation is currently under construction.

// TODO: Make documentation not be "currently under construction." :P

#![feature(test)]
#![feature(step_by)]

#![allow(unused_imports)]
#![allow(non_snake_case)]
#![allow(unused_parens)]
#![deny(unused_must_use)]

extern crate num;
extern crate test;
extern crate rand;
extern crate bit_set;

pub use primes::PrimeTester;
pub use primes::PrimeSieve;
pub use primes::MillerRabinTester;
pub use factorizer::Factorizer;
pub use factorizer::TrialDivisionFactorizer;
pub use factorizer::StubbornFactorizer;
//pub use factorizer::FermatFactorizer;
pub use factorizer_dixon::DixonFactorizer;
pub use factorizer_pollard::PollardBrentFactorizer;
//pub use factorizer::GeneralFactorizer;
pub use factorizer::SafeFactorizer;
pub use factorizer::DefaultFactorizer;
pub use factorizer::ListFactorizer;
pub use factorization::Factorization;
pub use util::isqrt;
pub use util::gcd;

use util::literal;

use std::iter::FromIterator;
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::Shr;

use num::{Zero,One,Integer};
use num::{FromPrimitive,ToPrimitive};

mod primes;
mod factorization;
mod factorizer;
mod factorizer_dixon;
mod factorizer_pollard;
mod util;

/// Factors a number using `DefaultFactorizer`.
pub fn factorize<T>(x: T) -> Factorization<T>
 where T: Eq + Clone + Zero + One + Integer + Shr<usize, Output=T> + Hash + ToPrimitive + FromPrimitive
{
	DefaultFactorizer.factorize(x)
}

/// Collects all primes up to a limit (inclusive)
///
/// # Example
///
/// ```
/// let v: Vec<u64> = primes_upto(17);
/// assert_eq!(v, vec![2, 3, 5, 7, 11, 13, 17]);
/// assert!(false);
/// ```
pub fn primes_upto<Out>(limit: usize) -> Out
 where Out: FromIterator<u64>
{
	let max = limit + 1;
	let sieve = primes::PrimeSieve::new(max);
	(2..max).step_by(2)
		.filter(|&i| sieve.is_prime(&i))
		.map(|i| i as u64)
		.collect()
}

<|endoftext|>


<commit_before>//! The main entry point for the Space API server.
//!
//! Running this code starts a HTTP server instance. The default port is 3000, but you can set your
//! own favorite port by exporting the `PORT` environment variable.

extern crate rustc_serialize;
extern crate iron;
extern crate spaceapi;

pub mod datastore;
pub mod redis_store;

use std::net::Ipv4Addr;
use std::sync::Mutex;
use std::sync::Arc;

use rustc_serialize::json::ToJson;
use iron::{Request, Response, IronResult, Iron, Set};
use iron::{status, headers, middleware};
use iron::modifiers::Header;

pub use datastore::DataStore;
use spaceapi::Optional::{Value, Absent};

fn build_response_json(status: &spaceapi::Status, people_present: Option<u32>, raspi_temperature: Option<f32>) -> String {
    let people_present_sensor = match people_present {
        Some(count) => Value(vec![
            spaceapi::PeopleNowPresentSensor {
                value: count,
                location: Value("Hackerspace".to_string()),
                name: Absent,
                description: Absent,
                names: Absent,
            }
        ]),
        None => Absent,
    };

    let temperature_sensor = match raspi_temperature {
        Some(degrees) => Value(vec![
            spaceapi::TemperatureSensor {
                value: degrees,
                unit: "°C".to_string(),
                location: "Hackerspace".to_string(),
                name: Value("Raspberry CPU".to_string()),
                description: Absent,
            }
        ]),
        None => Absent,
    };

    // Create a mutable copy of the status struct and add sensor data.
    let mut status_copy = (*status).clone();
    status_copy.sensors = Value(spaceapi::Sensors {
        people_now_present: people_present_sensor,
        temperature: temperature_sensor,
    });

    // Serialize to JSON string
    status_copy.to_json().to_string()
}

/// A Space API server instance.
///
/// You can create a new instance using the ``new`` constructor method by
/// passing it the host, the port, the ``Status`` object and a datastore.
///
/// The ``SpaceapiServer`` includes a web server through
/// [Hyper](http://hyper.rs/hyper/hyper/server/index.html). Simply call the ``serve`` method.
pub struct SpaceapiServer {
    host: Ipv4Addr,
    port: u16,
    status: spaceapi::Status,
    datastore: Arc<Mutex<Box<DataStore>>>,
}

impl SpaceapiServer {

    pub fn new(host: Ipv4Addr, port: u16, status: spaceapi::Status, datastore: Arc<Mutex<Box<DataStore>>>) -> SpaceapiServer{
        SpaceapiServer {
            host: host,
            port: port,
            status: status,
            datastore: datastore,
        }
    }

    pub fn serve(self) {
        let host = self.host;
        let port = self.port;
        println!("Starting HTTP server on {}:{}...", host, port);
        Iron::new(self).http((host, port)).unwrap();
    }

}

impl middleware::Handler for SpaceapiServer {

    fn handle(&self, _: &mut Request) -> IronResult<Response> {

        // Fetch data from datastore
        let datastore_clone = self.datastore.clone();
        let datastore_lock = datastore_clone.lock().unwrap();
        let people_present: Option<u32> = match datastore_lock.retrieve("people_present") {
            Ok(v) => match v.parse::<u32>() {
                Ok(i) => Some(i),
                Err(_) => None,
            },
            Err(_) => None,
        };
        let raspi_temperature: Option<f32> = match datastore_lock.retrieve("raspi_temperature") {
            Ok(v) => match v.parse::<f32>() {
                Ok(i) => Some(i),
                Err(_) => None,
            },
            Err(_) => None,
        };

        // Get response body
        let body = build_response_json(&self.status, people_present, raspi_temperature);

        // Create response
        let mut response = Response::with((status::Ok, body));

        // Set headers
        response.set_mut(Header(headers::ContentType("application/json; charset=utf-8".parse().unwrap())));
        response.set_mut(Header(headers::CacheControl(vec![headers::CacheDirective::NoCache])));
        response.set_mut(Header(headers::AccessControlAllowOrigin::Any));

        Ok(response)
    }
}

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

    #[test]
    /// Verify that the response JSON looks OK.
    fn verify_response_json() {
        let people_present = Some(23);
        let temperature = Some(42.5);
        let json = build_response_json(people_present, temperature);
        assert_eq!(json, "{\
            \"api\":\"0.13\",\
            \"cache\":{\"schedule\":\"m.02\"},\
            \"contact\":{\
                \"email\":\"danilo@coredump.ch\",\
                \"foursquare\":\"525c20e5498e875d8231b1e5\",\
                \"irc\":\"irc://freenode.net/#coredump\",\
                \"twitter\":\"@coredump_ch\"\
            },\
            \"feeds\":{\
                \"blog\":{\"type\":\"rss\",\"url\":\"https://www.coredump.ch/feed/\"}\
            },\
            \"issue_report_channels\":[\"email\",\"twitter\"],\
            \"location\":{\
                \"address\":\"Spinnereistrasse 2, 8640 Rapperswil, Switzerland\",\
                \"lat\":47.22936,\"lon\":8.82949\
            },\
            \"logo\":\"https://www.coredump.ch/logo.png\",\
            \"projects\":[\
                \"https://www.coredump.ch/projekte/\",\
                \"https://discourse.coredump.ch/c/projects\",\
                \"https://github.com/coredump-ch/\"\
            ],\
            \"sensors\":{\
                \"people_now_present\":[{\
                    \"location\":\"Hackerspace\",\"value\":23\
                }],\
                \"temperature\":[{\
                    \"location\":\"Hackerspace\",\"name\":\"Raspberry CPU\",\
                    \"unit\":\"°C\",\"value\":42.5\
                }]\
            },\
            \"space\":\"coredump\",\
            \"spacefed\":{\"spacenet\":false,\"spacephone\":false,\"spacesaml\":false},\
            \"state\":{\"message\":\"Open every Monday from 20:00\",\"open\":false},\
            \"url\":\"https://www.coredump.ch/\"\
        }");
    }
}
<commit_msg>Changed build_response_json return type from String to Json<commit_after>//! The main entry point for the Space API server.
//!
//! Running this code starts a HTTP server instance. The default port is 3000, but you can set your
//! own favorite port by exporting the `PORT` environment variable.

extern crate rustc_serialize;
extern crate iron;
extern crate spaceapi;

pub mod datastore;
pub mod redis_store;

use std::net::Ipv4Addr;
use std::sync::Mutex;
use std::sync::Arc;

use rustc_serialize::json::{Json, ToJson};
use iron::{Request, Response, IronResult, Iron, Set};
use iron::{status, headers, middleware};
use iron::modifiers::Header;

pub use datastore::DataStore;
use spaceapi::Optional::{Value, Absent};

fn build_response_json(status: &spaceapi::Status, people_present: Option<u32>, raspi_temperature: Option<f32>) -> Json {
    let people_present_sensor = match people_present {
        Some(count) => Value(vec![
            spaceapi::PeopleNowPresentSensor {
                value: count,
                location: Value("Hackerspace".to_string()),
                name: Absent,
                description: Absent,
                names: Absent,
            }
        ]),
        None => Absent,
    };

    let temperature_sensor = match raspi_temperature {
        Some(degrees) => Value(vec![
            spaceapi::TemperatureSensor {
                value: degrees,
                unit: "°C".to_string(),
                location: "Basement".to_string(),
                name: Value("Raspberry CPU".to_string()),
                description: Absent,
            }
        ]),
        None => Absent,
    };

    // Create a mutable copy of the status struct and add sensor data.
    let mut status_copy = (*status).clone();
    status_copy.sensors = Value(spaceapi::Sensors {
        people_now_present: people_present_sensor,
        temperature: temperature_sensor,
    });

    // Serialize to JSON
    status_copy.to_json()
}

/// A Space API server instance.
///
/// You can create a new instance using the ``new`` constructor method by
/// passing it the host, the port, the ``Status`` object and a datastore.
///
/// The ``SpaceapiServer`` includes a web server through
/// [Hyper](http://hyper.rs/hyper/hyper/server/index.html). Simply call the ``serve`` method.
pub struct SpaceapiServer {
    host: Ipv4Addr,
    port: u16,
    status: spaceapi::Status,
    datastore: Arc<Mutex<Box<DataStore>>>,
}

impl SpaceapiServer {

    pub fn new(host: Ipv4Addr, port: u16, status: spaceapi::Status, datastore: Arc<Mutex<Box<DataStore>>>) -> SpaceapiServer{
        SpaceapiServer {
            host: host,
            port: port,
            status: status,
            datastore: datastore,
        }
    }

    pub fn serve(self) {
        let host = self.host;
        let port = self.port;
        println!("Starting HTTP server on {}:{}...", host, port);
        Iron::new(self).http((host, port)).unwrap();
    }

}

impl middleware::Handler for SpaceapiServer {

    fn handle(&self, _: &mut Request) -> IronResult<Response> {

        // Fetch data from datastore
        let datastore_clone = self.datastore.clone();
        let datastore_lock = datastore_clone.lock().unwrap();
        let people_present: Option<u32> = match datastore_lock.retrieve("people_present") {
            Ok(v) => match v.parse::<u32>() {
                Ok(i) => Some(i),
                Err(_) => None,
            },
            Err(_) => None,
        };
        let raspi_temperature: Option<f32> = match datastore_lock.retrieve("raspi_temperature") {
            Ok(v) => match v.parse::<f32>() {
                Ok(i) => Some(i),
                Err(_) => None,
            },
            Err(_) => None,
        };

        // Get response body
        let body = build_response_json(&self.status, people_present, raspi_temperature).to_string();

        // Create response
        let mut response = Response::with((status::Ok, body));

        // Set headers
        response.set_mut(Header(headers::ContentType("application/json; charset=utf-8".parse().unwrap())));
        response.set_mut(Header(headers::CacheControl(vec![headers::CacheDirective::NoCache])));
        response.set_mut(Header(headers::AccessControlAllowOrigin::Any));

        Ok(response)
    }
}

#[cfg(test)]
mod test {
    extern crate spaceapi;
    extern crate rustc_serialize;

    use super::build_response_json;
    use spaceapi::Optional;
    use rustc_serialize::json::Json;

    fn get_test_data() -> Json {
        // Create minimal status object
        let ref status = spaceapi::Status::new(
            "ourspace".to_string(),
            "https://example.com/logo.png".to_string(),
            "https://example.com/".to_string(),
            spaceapi::Location {
                address: Optional::Value("Street 1, Zürich, Switzerland".to_string()),
                lat: 47.123,
                lon: 8.88,
            },
            spaceapi::Contact {
                irc: Optional::Absent,
                twitter: Optional::Absent,
                foursquare: Optional::Absent,
                email: Optional::Value("hi@example.com".to_string()),
            },
            vec![
                "email".to_string(),
                "twitter".to_string(),
            ],
        );

        // Add sensor data, build JSON
        let people_present = Some(23);
        let temperature = Some(42.5);
        build_response_json(status, people_present, temperature)
    }

    #[test]
    /// Verify that the result is a JSON object.
    fn verify_json_obj() {
        let json = get_test_data();
        assert!(json.is_object());
    }

    #[test]
    /// Verify that the result has the correct keys.
    fn verify_json_keys() {
        let json = get_test_data();
        let status = json.as_object().unwrap();  // We get back a BTreeMap<String, Json>
        let keys: Vec<String> = status.keys().cloned().collect();  // Collect the keys
        assert_eq!(keys, ["api", "contact", "issue_report_channels", "location",
                          "logo", "sensors", "space", "state", "url"]);
    }

    #[test]
    /// Verify static data
    fn verify_json_static_data() {
        let json = get_test_data();
        let status = json.as_object().unwrap();  // We get back a BTreeMap<String, Json>

        // Strings
        assert_eq!(status.get("api").unwrap().as_string().unwrap(), "0.13");
        assert_eq!(status.get("space").unwrap().as_string().unwrap(), "ourspace");
        assert_eq!(status.get("url").unwrap().as_string().unwrap(), "https://example.com/");
        assert_eq!(status.get("logo").unwrap().as_string().unwrap(), "https://example.com/logo.png");

        // Channels
        let channels: &Vec<Json> = status.get("issue_report_channels").unwrap().as_array().unwrap();
        let channel_values: Vec<String> = channels.iter()
                                                  .cloned()
                                                  .map(|c| c.as_string().unwrap().to_string())
                                                  .collect();
        assert_eq!(vec!["email", "twitter"], channel_values);
    }

    #[test]
    /// Verify location
    fn verify_json_location() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let location = status.get("location").unwrap().as_object().unwrap();

        // Verify data
        let address = location.get("address").unwrap().as_string().unwrap();
        assert_eq!("Street 1, Zürich, Switzerland".to_string(), address);
        assert_eq!(47.123, location.get("lat").unwrap().as_f64().unwrap());
        assert_eq!(8.88, location.get("lon").unwrap().as_f64().unwrap());
    }

    #[test]
    /// Verify contact
    fn verify_json_contact() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let contact = status.get("contact").unwrap().as_object().unwrap();

        // Verify data
        let email = contact.get("email").unwrap().as_string().unwrap();
        assert_eq!("hi@example.com".to_string(), email);
    }

    #[test]
    /// Verify sensor data
    fn verify_json_sensors() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let sensors = status.get("sensors").unwrap().as_object().unwrap();
        let temperature_sensor = sensors.get("temperature").unwrap()
                                        .as_array().unwrap()[0]  // List of sensors
                                        .as_object().unwrap();  // Sensor object
        let people_sensor = sensors.get("people_now_present").unwrap()  // List of sensors
                                        .as_array().unwrap()[0]  // Sensor object
                                        .as_object().unwrap();

        // Verify temperature sensor
        let temp_location = temperature_sensor.get("location").unwrap().as_string().unwrap();
        let temp_name = temperature_sensor.get("name").unwrap().as_string().unwrap();
        let temp_unit = temperature_sensor.get("unit").unwrap().as_string().unwrap();
        let temp_value = temperature_sensor.get("value").unwrap().as_f64().unwrap();
        assert_eq!("Basement".to_string(), temp_location);
        assert_eq!("Raspberry CPU".to_string(), temp_name);
        assert_eq!("°C".to_string(), temp_unit);
        assert_eq!(42.5, temp_value);

        // Verify peoplesensor
        let people_location = people_sensor.get("location").unwrap().as_string().unwrap();
        let people_value = people_sensor.get("value").unwrap().as_u64().unwrap();
        assert_eq!("Hackerspace".to_string(), people_location);
        assert_eq!(23, people_value);
    }

}
<|endoftext|>


<commit_before>#![feature(plugin_registrar, box_syntax)]

#![allow(unused_imports, unstable)]

#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;

// Only for the compile time checking of paths
extern crate collections;

use rustc::plugin::Registry;
use rustc::lint::LintPassObject;

pub mod types;
pub mod misc;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_lint_pass(box types::TypePass as LintPassObject);
    reg.register_lint_pass(box misc::MiscPass as LintPassObject);
    reg.register_lint_pass(box misc::StrToStringPass as LintPassObject);
    reg.register_lint_pass(box misc::TopLevelRefPass as LintPassObject);
    reg.register_lint_group("clippy", vec![types::BOX_VEC, types::DLIST,
                                           misc::SINGLE_MATCH, misc::STR_TO_STRING,
                                           misc::TOPLEVEL_REF_ARG]);
}
<commit_msg>-warnings<commit_after>#![feature(plugin_registrar, box_syntax)]
#![feature(rustc_private, core, collections)]

#![allow(unused_imports)]

#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;

// Only for the compile time checking of paths
extern crate collections;

use rustc::plugin::Registry;
use rustc::lint::LintPassObject;

pub mod types;
pub mod misc;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_lint_pass(box types::TypePass as LintPassObject);
    reg.register_lint_pass(box misc::MiscPass as LintPassObject);
    reg.register_lint_pass(box misc::StrToStringPass as LintPassObject);
    reg.register_lint_pass(box misc::TopLevelRefPass as LintPassObject);
    reg.register_lint_group("clippy", vec![types::BOX_VEC, types::DLIST,
                                           misc::SINGLE_MATCH, misc::STR_TO_STRING,
                                           misc::TOPLEVEL_REF_ARG]);
}
<|endoftext|>