<commit_before>//! redis-rs is a rust implementation of a Redis client library.  It exposes
//! a general purpose interface to Redis and also provides specific helpers for
//! commonly used functionality.
//!
//! The crate is called `redis` and you can depend on it via cargo:
//!
//! ```ini
//! [dependencies.redis]
//! git = "https://github.com/mitsuhiko/redis-rs.git"
//! ```
//!
//! # Basic Operation
//!
//! redis-rs exposes to API levels: a low- and a high-level part.  The high-level
//! part does not expose all the functionality of redis and might take some
//! liberties in how it speaks the protocol.  The low-level part of the API
//! allows you to express any request on the redis level.  You can fluently
//! switch between both API levels at any point.
//!
//! ## Connection Handling
//!
//! For connecting to redis you can use a client object which then can produce
//! actual connections.  Connections and clients as well as results of
//! connections and clients are considered `ConnectionLike` objects and
//! can be used anywhere a request is made.
//!
//! The full canonical way to get a connection is to create a client and
//! to ask for a connection from it:
//!
//! ```rust,no_run
//! extern crate redis;
//!
//! fn do_something() -> redis::RedisResult<()> {
//!     let client = try!(redis::Client::open("redis://127.0.0.1/"));
//!     let con = try!(client.get_connection());
//!
//!     /* do something here */
//!
//!     Ok(())
//! }
//! # fn main() {}
//! ```
//!
//! ## Connection Parameters
//!
//! redis-rs knows different ways to define where a connection should
//! go.  The parameter to `Client::open` needs to implement the
//! `IntoConnectionInfo` trait of which there are three implementations:
//!
//! * string slices in `redis://` URL format.
//! * URL objects from the redis-url crate.
//! * `ConnectionInfo` objects.
//!
//! The URL format is `redis://[:<passwd>@]<hostname>[:port][/<db>]`
//!
//! ## Executing Low-Level Commands
//!
//! To execute low-level commands you can use the `cmd` function which allows
//! you to build redis requests.  Once you have configured a command object
//! to your liking you can send a query into any `ConnectionLike` object:
//!
//! ```rust,no_run
//! fn do_something(con: &redis::Connection) -> redis::RedisResult<()> {
//!     let _ : () = try!(redis::cmd("SET").arg("my_key").arg(42i).query(con));
//!     Ok(())
//! }
//! ```
//!
//! Upon querying the return value is a result object.  If you do not care
//! about the actual return value (other than that it is not a failure)
//! you can always type annotate it to the unit type `()`.
//!
//! ## Executing High-Level Commands
//!
//! The high-level interface is similar.  For it to become available you
//! need to use the `Commands` trait in which case all `ConnectionLike`
//! objects the library provides will also have high-level methods which
//! make working with the protocol easier:
//!
//! ```rust,no_run
//! extern crate redis;
//! use redis::Commands;
//!
//! fn do_something(con: &redis::Connection) -> redis::RedisResult<()> {
//!     let _ : () = try!(con.set("my_key", 42i));
//!     Ok(())
//! }
//! # fn main() {}
//! ```
//!
//! Note that high-level commands are work in progress and many are still
//! missing!
//!
//! ## Type Conversions
//!
//! Because redis inherently is mostly type-less and the protocol is not
//! exactly friendly to developers, this library provides flexible support
//! for casting values to the intended results.  This is driven through the
//! `FromRedisValue` and `ToRedisArgs` traits.
//!
//! The `arg` method of the command will accept a wide range of types through
//! the `ToRedisArgs` trait and the `query` method of a command can convert the
//! value to what you expect the function to return through the `FromRedisValue`
//! trait.  This is quite flexible and allows vectors, tuples, hashsets, hashmaps
//! as well as optional values:
//!
//! ```rust,no_run
//! # use redis::Commands;
//! # use std::collections::{HashMap, HashSet};
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let count : i32 = try!(con.get("my_counter"));
//! let count = con.get("my_counter").unwrap_or(0i32);
//! let k : Option<String> = try!(con.get("missing_key"));
//! let name : String = try!(con.get("my_name"));
//! let bin : Vec<u8> = try!(con.get("my_binary"));
//! let map : HashMap<String, i32> = try!(con.hgetall("my_hash"));
//! let keys : Vec<String> = try!(con.hkeys("my_hash"));
//! let mems : HashSet<i32> = try!(con.smembers("my_set"));
//! let (k1, k2) : (String, String) = try!(con.get(["k1", "k2"].as_slice()));
//! # Ok(())
//! # }
//! ```
//!
//! # Iteration Protocol
//!
//! In addition to sending a single query you iterators are also supported.  When
//! used with regular bulk responses they don't give you much over querying and
//! converting into a vector (both use a vector internally) but they can also
//! be used with `SCAN` like commands in which case iteration will send more
//! queries until the cursor is exhausted:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let mut iter : redis::Iter<int> = try!(redis::cmd("SSCAN").arg("my_set")
//!     .cursor_arg(0).iter(&con));
//! for x in iter {
//!     // do something with the item
//! }
//! # Ok(()) }
//! ```
//!
//! As you can see the cursor argument needs to be defined with `cursor_arg`
//! instead of `arg` so that the library knows which argument needs updating
//! as the query is run for more items.
//!
//! # Pipelining
//!
//! In addition to simple queries you can also send command pipelines.  This
//! is provided through the `pipe` function.  It works very similar to sending
//! individual commands but you can send more than one in one go.  This also
//! allows you to ignore individual results so that matching on the end result
//! is easier:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let (k1, k2) : (i32, i32) = try!(redis::pipe()
//!     .cmd("SET").arg("key_1").arg(42i).ignore()
//!     .cmd("SET").arg("key_2").arg(43i).ignore()
//!     .cmd("GET").arg("key_1")
//!     .cmd("GET").arg("key_2").query(&con));
//! # Ok(()) }
//! ```
//!
//! If you want the pipeline to be wrapped in a `MULTI`/`EXEC` block you can
//! easily do that by switching the pipeline into `atomic` mode.  From the
//! caller's point of view nothing changes, the pipeline itself will take
//! care of the rest for you:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let (k1, k2) : (i32, i32) = try!(redis::pipe()
//!     .atomic()
//!     .cmd("SET").arg("key_1").arg(42i).ignore()
//!     .cmd("SET").arg("key_2").arg(43i).ignore()
//!     .cmd("GET").arg("key_1")
//!     .cmd("GET").arg("key_2").query(&con));
//! # Ok(()) }
//! ```
//!
//! You can also use high-level commands on pipelines through the
//! `PipelineCommands` trait:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! use redis::PipelineCommands;
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let (k1, k2) : (i32, i32) = try!(redis::pipe()
//!     .atomic()
//!     .set("key_1", 42i).ignore()
//!     .set("key_2", 43i).ignore()
//!     .get("key_1")
//!     .get("key_2").query(&con));
//! # Ok(()) }
//! ```
//!
//! # Transactions
//!
//! Transactions are available through atomic pipelines.  In order to use
//! them in a more simple way you can use the `transaction` function of a
//! connection:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! use redis::{Commands, PipelineCommands};
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let key = "the_key";
//! let (new_val,) : (int,) = try!(redis::transaction(&con, [key].as_slice(), |pipe| {
//!     let old_val : int = try!(con.get(key));
//!     pipe
//!         .set(key, old_val + 1).ignore()
//!         .get(key).query(&con)
//! }));
//! println!("The incremented number is: {}", new_val);
//! # Ok(()) }
//! ```
//!
//! For more information see the `transaction` function.
//!
//! # PubSub
//!
//! Pubsub is currently work in progress but provided through the `PubSub`
//! connection object.  Due to the fact that Rust does not have support
//! for async IO in libnative yet, the API does not provide a way to
//! read messages with any form of timeout yet.
//!
//! Example usage:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! let client = try!(redis::Client::open("redis://127.0.0.1/"));
//! let mut pubsub = try!(client.get_pubsub());
//! try!(pubsub.subscribe("channel_1"));
//! try!(pubsub.subscribe("channel_2"));
//!
//! loop {
//!     let msg = try!(pubsub.get_message());
//!     let payload : String = try!(msg.get_payload());
//!     println!("channel '{}': {}", msg.get_channel_name(), payload);
//! }
//! # }
//! ```
//!
//! # Scripts
//!
//! Lua scripts are supported through the `Script` type in a convenient
//! way (it does not support pipelining currently).  It will automatically
//! load the script if it does not exist and invoke it.
//!
//! Example:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let script = redis::Script::new(r"
//!     return tonumber(ARGV[1]) + tonumber(ARGV[2]);
//! ");
//! let result : int = try!(script.arg(1i).arg(2i).invoke(&con));
//! assert_eq!(result, 3);
//! # Ok(()) }
//! ```

#![crate_name = "redis"]
#![crate_type = "lib"]
#![license = "BSD"]
#![comment = "Bindings and wrapper functions for redis."]

#![deny(non_camel_case_types)]

#![feature(macro_rules)]
#![feature(default_type_params)]
#![feature(slicing_syntax)]

#![experimental]

extern crate url;
extern crate serialize;
extern crate "rust-crypto" as crypto;

/* public api */
pub use parser::{parse_redis_value, Parser};
pub use client::Client;
pub use script::{Script, ScriptInvocation};
pub use connection::{Connection, ConnectionLike, ConnectionInfo,
                     IntoConnectionInfo, PubSub, Msg, transaction,
                     parse_redis_url};
pub use cmd::{cmd, Cmd, pipe, Pipeline, Iter, pack_command};
pub use commands::{
    Commands,
    PipelineCommands,
};

#[doc(hidden)]
pub use types::{
    /* low level values */
    Value,
        Nil,
        Int,
        Data,
        Bulk,
        Okay,
        Status,

    /* error and result types */
    RedisError,
    RedisResult,

    /* error kinds */
    ErrorKind,
        ResponseError,
        TypeError,
        ExecAbortError,
        BusyLoadingError,
        NoScriptError,
        ExtensionError,
        InternalIoError,

    /* utility types */
    InfoDict,
    NumericBehavior,
        NonNumeric,
        NumberIsInteger,
        NumberIsFloat,

    /* conversion traits */
    FromRedisValue,
    ToRedisArgs,

    /* utility functions */
    from_redis_value,
};

mod macros;

mod parser;
mod client;
mod connection;
mod types;
mod script;
mod cmd;
mod commands;
<commit_msg>Fixed dependency example.  This fixes #20<commit_after>//! redis-rs is a rust implementation of a Redis client library.  It exposes
//! a general purpose interface to Redis and also provides specific helpers for
//! commonly used functionality.
//!
//! The crate is called `redis` and you can depend on it via cargo:
//!
//! ```ini
//! [dependencies.redis-rs]
//! git = "https://github.com/mitsuhiko/redis-rs.git"
//! ```
//!
//! # Basic Operation
//!
//! redis-rs exposes to API levels: a low- and a high-level part.  The high-level
//! part does not expose all the functionality of redis and might take some
//! liberties in how it speaks the protocol.  The low-level part of the API
//! allows you to express any request on the redis level.  You can fluently
//! switch between both API levels at any point.
//!
//! ## Connection Handling
//!
//! For connecting to redis you can use a client object which then can produce
//! actual connections.  Connections and clients as well as results of
//! connections and clients are considered `ConnectionLike` objects and
//! can be used anywhere a request is made.
//!
//! The full canonical way to get a connection is to create a client and
//! to ask for a connection from it:
//!
//! ```rust,no_run
//! extern crate redis;
//!
//! fn do_something() -> redis::RedisResult<()> {
//!     let client = try!(redis::Client::open("redis://127.0.0.1/"));
//!     let con = try!(client.get_connection());
//!
//!     /* do something here */
//!
//!     Ok(())
//! }
//! # fn main() {}
//! ```
//!
//! ## Connection Parameters
//!
//! redis-rs knows different ways to define where a connection should
//! go.  The parameter to `Client::open` needs to implement the
//! `IntoConnectionInfo` trait of which there are three implementations:
//!
//! * string slices in `redis://` URL format.
//! * URL objects from the redis-url crate.
//! * `ConnectionInfo` objects.
//!
//! The URL format is `redis://[:<passwd>@]<hostname>[:port][/<db>]`
//!
//! ## Executing Low-Level Commands
//!
//! To execute low-level commands you can use the `cmd` function which allows
//! you to build redis requests.  Once you have configured a command object
//! to your liking you can send a query into any `ConnectionLike` object:
//!
//! ```rust,no_run
//! fn do_something(con: &redis::Connection) -> redis::RedisResult<()> {
//!     let _ : () = try!(redis::cmd("SET").arg("my_key").arg(42i).query(con));
//!     Ok(())
//! }
//! ```
//!
//! Upon querying the return value is a result object.  If you do not care
//! about the actual return value (other than that it is not a failure)
//! you can always type annotate it to the unit type `()`.
//!
//! ## Executing High-Level Commands
//!
//! The high-level interface is similar.  For it to become available you
//! need to use the `Commands` trait in which case all `ConnectionLike`
//! objects the library provides will also have high-level methods which
//! make working with the protocol easier:
//!
//! ```rust,no_run
//! extern crate redis;
//! use redis::Commands;
//!
//! fn do_something(con: &redis::Connection) -> redis::RedisResult<()> {
//!     let _ : () = try!(con.set("my_key", 42i));
//!     Ok(())
//! }
//! # fn main() {}
//! ```
//!
//! Note that high-level commands are work in progress and many are still
//! missing!
//!
//! ## Type Conversions
//!
//! Because redis inherently is mostly type-less and the protocol is not
//! exactly friendly to developers, this library provides flexible support
//! for casting values to the intended results.  This is driven through the
//! `FromRedisValue` and `ToRedisArgs` traits.
//!
//! The `arg` method of the command will accept a wide range of types through
//! the `ToRedisArgs` trait and the `query` method of a command can convert the
//! value to what you expect the function to return through the `FromRedisValue`
//! trait.  This is quite flexible and allows vectors, tuples, hashsets, hashmaps
//! as well as optional values:
//!
//! ```rust,no_run
//! # use redis::Commands;
//! # use std::collections::{HashMap, HashSet};
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let count : i32 = try!(con.get("my_counter"));
//! let count = con.get("my_counter").unwrap_or(0i32);
//! let k : Option<String> = try!(con.get("missing_key"));
//! let name : String = try!(con.get("my_name"));
//! let bin : Vec<u8> = try!(con.get("my_binary"));
//! let map : HashMap<String, i32> = try!(con.hgetall("my_hash"));
//! let keys : Vec<String> = try!(con.hkeys("my_hash"));
//! let mems : HashSet<i32> = try!(con.smembers("my_set"));
//! let (k1, k2) : (String, String) = try!(con.get(["k1", "k2"].as_slice()));
//! # Ok(())
//! # }
//! ```
//!
//! # Iteration Protocol
//!
//! In addition to sending a single query you iterators are also supported.  When
//! used with regular bulk responses they don't give you much over querying and
//! converting into a vector (both use a vector internally) but they can also
//! be used with `SCAN` like commands in which case iteration will send more
//! queries until the cursor is exhausted:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let mut iter : redis::Iter<int> = try!(redis::cmd("SSCAN").arg("my_set")
//!     .cursor_arg(0).iter(&con));
//! for x in iter {
//!     // do something with the item
//! }
//! # Ok(()) }
//! ```
//!
//! As you can see the cursor argument needs to be defined with `cursor_arg`
//! instead of `arg` so that the library knows which argument needs updating
//! as the query is run for more items.
//!
//! # Pipelining
//!
//! In addition to simple queries you can also send command pipelines.  This
//! is provided through the `pipe` function.  It works very similar to sending
//! individual commands but you can send more than one in one go.  This also
//! allows you to ignore individual results so that matching on the end result
//! is easier:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let (k1, k2) : (i32, i32) = try!(redis::pipe()
//!     .cmd("SET").arg("key_1").arg(42i).ignore()
//!     .cmd("SET").arg("key_2").arg(43i).ignore()
//!     .cmd("GET").arg("key_1")
//!     .cmd("GET").arg("key_2").query(&con));
//! # Ok(()) }
//! ```
//!
//! If you want the pipeline to be wrapped in a `MULTI`/`EXEC` block you can
//! easily do that by switching the pipeline into `atomic` mode.  From the
//! caller's point of view nothing changes, the pipeline itself will take
//! care of the rest for you:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let (k1, k2) : (i32, i32) = try!(redis::pipe()
//!     .atomic()
//!     .cmd("SET").arg("key_1").arg(42i).ignore()
//!     .cmd("SET").arg("key_2").arg(43i).ignore()
//!     .cmd("GET").arg("key_1")
//!     .cmd("GET").arg("key_2").query(&con));
//! # Ok(()) }
//! ```
//!
//! You can also use high-level commands on pipelines through the
//! `PipelineCommands` trait:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! use redis::PipelineCommands;
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let (k1, k2) : (i32, i32) = try!(redis::pipe()
//!     .atomic()
//!     .set("key_1", 42i).ignore()
//!     .set("key_2", 43i).ignore()
//!     .get("key_1")
//!     .get("key_2").query(&con));
//! # Ok(()) }
//! ```
//!
//! # Transactions
//!
//! Transactions are available through atomic pipelines.  In order to use
//! them in a more simple way you can use the `transaction` function of a
//! connection:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! use redis::{Commands, PipelineCommands};
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let key = "the_key";
//! let (new_val,) : (int,) = try!(redis::transaction(&con, [key].as_slice(), |pipe| {
//!     let old_val : int = try!(con.get(key));
//!     pipe
//!         .set(key, old_val + 1).ignore()
//!         .get(key).query(&con)
//! }));
//! println!("The incremented number is: {}", new_val);
//! # Ok(()) }
//! ```
//!
//! For more information see the `transaction` function.
//!
//! # PubSub
//!
//! Pubsub is currently work in progress but provided through the `PubSub`
//! connection object.  Due to the fact that Rust does not have support
//! for async IO in libnative yet, the API does not provide a way to
//! read messages with any form of timeout yet.
//!
//! Example usage:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! let client = try!(redis::Client::open("redis://127.0.0.1/"));
//! let mut pubsub = try!(client.get_pubsub());
//! try!(pubsub.subscribe("channel_1"));
//! try!(pubsub.subscribe("channel_2"));
//!
//! loop {
//!     let msg = try!(pubsub.get_message());
//!     let payload : String = try!(msg.get_payload());
//!     println!("channel '{}': {}", msg.get_channel_name(), payload);
//! }
//! # }
//! ```
//!
//! # Scripts
//!
//! Lua scripts are supported through the `Script` type in a convenient
//! way (it does not support pipelining currently).  It will automatically
//! load the script if it does not exist and invoke it.
//!
//! Example:
//!
//! ```rust,no_run
//! # fn do_something() -> redis::RedisResult<()> {
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let script = redis::Script::new(r"
//!     return tonumber(ARGV[1]) + tonumber(ARGV[2]);
//! ");
//! let result : int = try!(script.arg(1i).arg(2i).invoke(&con));
//! assert_eq!(result, 3);
//! # Ok(()) }
//! ```

#![crate_name = "redis"]
#![crate_type = "lib"]
#![license = "BSD"]
#![comment = "Bindings and wrapper functions for redis."]

#![deny(non_camel_case_types)]

#![feature(macro_rules)]
#![feature(default_type_params)]
#![feature(slicing_syntax)]

#![experimental]

extern crate url;
extern crate serialize;
extern crate "rust-crypto" as crypto;

/* public api */
pub use parser::{parse_redis_value, Parser};
pub use client::Client;
pub use script::{Script, ScriptInvocation};
pub use connection::{Connection, ConnectionLike, ConnectionInfo,
                     IntoConnectionInfo, PubSub, Msg, transaction,
                     parse_redis_url};
pub use cmd::{cmd, Cmd, pipe, Pipeline, Iter, pack_command};
pub use commands::{
    Commands,
    PipelineCommands,
};

#[doc(hidden)]
pub use types::{
    /* low level values */
    Value,
        Nil,
        Int,
        Data,
        Bulk,
        Okay,
        Status,

    /* error and result types */
    RedisError,
    RedisResult,

    /* error kinds */
    ErrorKind,
        ResponseError,
        TypeError,
        ExecAbortError,
        BusyLoadingError,
        NoScriptError,
        ExtensionError,
        InternalIoError,

    /* utility types */
    InfoDict,
    NumericBehavior,
        NonNumeric,
        NumberIsInteger,
        NumberIsFloat,

    /* conversion traits */
    FromRedisValue,
    ToRedisArgs,

    /* utility functions */
    from_redis_value,
};

mod macros;

mod parser;
mod client;
mod connection;
mod types;
mod script;
mod cmd;
mod commands;
<|endoftext|>


<commit_before>//! Reminisce is a lightweight library intended to be used for detecting and
//! reading from joysticks at a low level across many different operating
//! systems.
//!
//! Scanning for joysticks
//! ----------------------
//! To scan for joysticks, a `Backend` must be created.
//!
//! Scanning for events
//! -------------------
//! To scan events, a `Backend` must be created and polled.
//!
//! ``` rust
//! use reminisce::{Backend, Native};
//! let mut backend = Native::new();
//! for event in backend.iter() {
//!     println!("{:?}", event);
//! }
//! ```
extern crate libc;
#[cfg(target_os = "linux")]
extern crate inotify;
#[cfg(target_os = "windows")]
#[macro_use] extern crate rustc_bitflags;

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

#[cfg(target_os = "linux")]
extern crate glob;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub mod linux;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub use linux as native;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub mod windows;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub use windows as native;

#[cfg(feature = "sdl")]
pub mod sdl;

#[cfg(feature = "sdl")]
pub use sdl as native;

/// The native joystick backend exposed as a `Backend`.
pub use native::Native;

/// The maximum axis value
pub static MAX_AXIS_VALUE:i16 = 32767;
/// The minimum axis value
pub static MIN_AXIS_VALUE:i16 = -32767;

use std::borrow::Cow;
use std::fmt::Debug;

/// A direction on a joystick.
pub type Axis = u8;

/// A button on a joystick.
pub type Button = u8;

/// A joystick index.

pub type JoystickIndex = u8;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// An event emitted by a joystick
pub enum Event {
    /// Fired when a joystick is connected with its index.
    Connected(JoystickIndex),
    /// Fired when a joystick is disconnected with its index.
    Disconnected(JoystickIndex),
    /// Fired when a button is pressed with the joystick index and the
    /// button's index.
    ButtonPressed(JoystickIndex, Button),
    /// Fired when a button is released with the joystick index and the
    /// button's index.
    ButtonReleased(JoystickIndex, Button),
    /// Fired when a axis is moved with the joystick index, axis index
    /// and its value, which is between `MIN_JOYSTICK_VALUE` and
    /// `MAX_JOYSTICK_VALUE`
    AxisMoved(JoystickIndex, Axis, i16)
}

/// A lightweight Backend that tracks and polls all the available joysticks.
///
/// Each `Backend` has its own event queue tied to the events of the joysticks.
///
/// ``` rust
/// use reminisce::*;
/// let mut backend = Native::new();
/// let mut dir = 0;
/// let mut left = 30;
/// for event in &mut backend {
///     left -= 1;
///     if(left <= 0) { break }
///     match event {
///         Event::AxisMoved(_, 0, nx) =>
///             dir = -1,
///         Event::AxisMoved(_, 1, ny) =>
///             dir = 1,
///         _ => ()
///     }
/// }
/// ```
pub trait Backend: Sized {
    /// The kind of joystick this Backend tracks.
    type Joystick : Joystick;

    /// Create a new Backend and scan for joysticks.
    fn new() -> Self;

    /// Returns the number of joysticks connected.
    fn num_joysticks(&self) -> usize {
        self.joysticks().len()
    }

    /// Return a reference to the joysticks connected.
    fn joysticks(&self) -> &[Self::Joystick];

    /// Poll this Backend non-blockingly for events from any joysticks.
    fn poll(&mut self) -> Option<Event>;

    /// Iterate through the events that haven't been processed yet
    fn iter(&mut self) -> Poller<Self> {
        Poller { backend: self }
    }
}

impl<'a> IntoIterator for &'a mut Native {
    type Item = Event;
    type IntoIter = Poller<'a, Native>;
    fn into_iter(self) -> Poller<'a, Native> {
        self.iter()
    }
}

/// A joystick or gamepad.
pub trait Joystick: Sized {
    /// The error that could be thrown while trying to open the joystick
    type OpenError: Debug;

    /// Attempts to open a joystick from its index
    ///
    /// If an error occurs, this will return the textual representation of that error.
    ///
    /// ``` rust
    /// use reminisce::{Backend, Joystick, Native};
    /// if let Ok(joystick) = <Native as Backend>::Joystick::open(0) {
    ///     println!("{}", joystick.id())
    /// } else {
    ///     println!("No joystick plugged in")
    /// }
    /// ```
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError>;

    /// Check if the joystick is still connected.
    fn connected(&self) -> bool;

    /// Get the identifier of this joystick.
    ///
    /// This is copy-on-write because it can be a borrowed or owned String,
    /// depending on the implementation.
    fn id(&self) -> Cow<str>;

    /// Get the index of this joystick.
    fn index(&self) -> JoystickIndex;

    /// Get the number of axes this joystick has
    ///
    /// This is capped at 6 axes for now.
    fn num_axes(&self) -> Axis;

    /// Get the number of buttons this joystick has
    ///
    /// This is capped at 16 buttons currently.
    fn num_buttons(&self) -> Button;

    /// Get the battery level of this joystick
    ///
    /// Returns none if the joystick is wired or this operation is not supported
    /// by the backend
    fn battery(&self) -> Option<f32>;
}

/// A joystick that tracks its state.
///
/// You must call `process` before you query anything.
pub struct StatefulJoystick<J> where J: Joystick {
    joystick: J,
    buttons: i32,
    axes: Vec<i16>
}
impl<J> StatefulJoystick<J> where J: Joystick {
    /// Get the position of the axis.
    pub fn axis(&self, axis: Axis) -> Option<i16> {
        self.axes.get(axis as usize).cloned()
    }
    /// Check if the button given is being pressed.
    pub fn button(&self, button: Button) -> Option<bool> {
        if button < self.joystick.num_buttons() {
            Some(self.buttons & (1 << button) > 0)
        } else {
            None
        }
    }
    /// Update this joystick's state with the event given.
    pub fn process(&mut self, event: Event) {
        let index = self.joystick.index();
        match event {
            Event::ButtonPressed(i, b) if i == index => {
                self.buttons |= (i as i32) << b;
            },
            Event::ButtonReleased(i, b) if i == index => {
                self.buttons &= !((i as i32) << b);
            },
            Event::AxisMoved(i, a, v) if i == index => {
                self.axes[a as usize] = v;
            },
            _ => ()
        }
    }
}
impl<J> Joystick for StatefulJoystick<J> where J: Joystick {
    type OpenError = J::OpenError;
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError> {
        let joystick = try!(J::open(index));
        let axes = (0..joystick.num_axes()).map(|_| 0).collect();
        Ok(StatefulJoystick {
            joystick: joystick,
            buttons: 0,
            axes: axes
        })
    }
    fn connected(&self) -> bool {
        self.joystick.connected()
    }
    fn id(&self) -> Cow<str> {
        self.joystick.id()
    }
    fn index(&self) -> JoystickIndex {
        self.joystick.index()
    }
    fn num_axes(&self) -> Axis {
        self.joystick.num_axes()
    }
    fn num_buttons(&self) -> Button {
        self.joystick.num_buttons()
    }
    fn battery(&self) -> Option<f32> {
        self.joystick.battery()
    }
}

/// An iterator over a Backend's event queue.
pub struct Poller<'a, J> where J:Backend+'a {
    backend: &'a mut J
}

impl<'a, C> Iterator for Poller<'a, C> where C:Backend {
    type Item = Event;
    /// This calls the `Backend.poll()` method to poll for the next event
    fn next(&mut self) -> Option<Event> {
        self.backend.poll()
    }
}
<commit_msg>Const instead of static where applicable<commit_after>//! Reminisce is a lightweight library intended to be used for detecting and
//! reading from joysticks at a low level across many different operating
//! systems.
//!
//! Scanning for joysticks
//! ----------------------
//! To scan for joysticks, a `Backend` must be created.
//!
//! Scanning for events
//! -------------------
//! To scan events, a `Backend` must be created and polled.
//!
//! ``` rust
//! use reminisce::{Backend, Native};
//! let mut backend = Native::new();
//! for event in backend.iter() {
//!     println!("{:?}", event);
//! }
//! ```
extern crate libc;
#[cfg(target_os = "linux")]
extern crate inotify;
#[cfg(target_os = "windows")]
#[macro_use] extern crate rustc_bitflags;

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

#[cfg(target_os = "linux")]
extern crate glob;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub mod linux;

#[cfg(all(target_os = "linux", not(feature = "sdl")))]
pub use linux as native;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub mod windows;

#[cfg(all(target_os = "windows", not(feature = "sdl")))]
pub use windows as native;

#[cfg(feature = "sdl")]
pub mod sdl;

#[cfg(feature = "sdl")]
pub use sdl as native;

/// The native joystick backend exposed as a `Backend`.
pub use native::Native;

/// The maximum axis value
pub const MAX_AXIS_VALUE:i16 = 32767;
/// The minimum axis value
pub const MIN_AXIS_VALUE:i16 = -32767;

use std::borrow::Cow;
use std::fmt::Debug;

/// A direction on a joystick.
pub type Axis = u8;

/// A button on a joystick.
pub type Button = u8;

/// A joystick index.

pub type JoystickIndex = u8;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// An event emitted by a joystick
pub enum Event {
    /// Fired when a joystick is connected with its index.
    Connected(JoystickIndex),
    /// Fired when a joystick is disconnected with its index.
    Disconnected(JoystickIndex),
    /// Fired when a button is pressed with the joystick index and the
    /// button's index.
    ButtonPressed(JoystickIndex, Button),
    /// Fired when a button is released with the joystick index and the
    /// button's index.
    ButtonReleased(JoystickIndex, Button),
    /// Fired when a axis is moved with the joystick index, axis index
    /// and its value, which is between `MIN_JOYSTICK_VALUE` and
    /// `MAX_JOYSTICK_VALUE`
    AxisMoved(JoystickIndex, Axis, i16)
}

/// A lightweight Backend that tracks and polls all the available joysticks.
///
/// Each `Backend` has its own event queue tied to the events of the joysticks.
///
/// ``` rust
/// use reminisce::*;
/// let mut backend = Native::new();
/// let mut dir = 0;
/// let mut left = 30;
/// for event in &mut backend {
///     left -= 1;
///     if(left <= 0) { break }
///     match event {
///         Event::AxisMoved(_, 0, nx) =>
///             dir = -1,
///         Event::AxisMoved(_, 1, ny) =>
///             dir = 1,
///         _ => ()
///     }
/// }
/// ```
pub trait Backend: Sized {
    /// The kind of joystick this Backend tracks.
    type Joystick : Joystick;

    /// Create a new Backend and scan for joysticks.
    fn new() -> Self;

    /// Returns the number of joysticks connected.
    fn num_joysticks(&self) -> usize {
        self.joysticks().len()
    }

    /// Return a reference to the joysticks connected.
    fn joysticks(&self) -> &[Self::Joystick];

    /// Poll this Backend non-blockingly for events from any joysticks.
    fn poll(&mut self) -> Option<Event>;

    /// Iterate through the events that haven't been processed yet
    fn iter(&mut self) -> Poller<Self> {
        Poller { backend: self }
    }
}

impl<'a> IntoIterator for &'a mut Native {
    type Item = Event;
    type IntoIter = Poller<'a, Native>;
    fn into_iter(self) -> Poller<'a, Native> {
        self.iter()
    }
}

/// A joystick or gamepad.
pub trait Joystick: Sized {
    /// The error that could be thrown while trying to open the joystick
    type OpenError: Debug;

    /// Attempts to open a joystick from its index
    ///
    /// If an error occurs, this will return the textual representation of that error.
    ///
    /// ``` rust
    /// use reminisce::{Backend, Joystick, Native};
    /// if let Ok(joystick) = <Native as Backend>::Joystick::open(0) {
    ///     println!("{}", joystick.id())
    /// } else {
    ///     println!("No joystick plugged in")
    /// }
    /// ```
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError>;

    /// Check if the joystick is still connected.
    fn connected(&self) -> bool;

    /// Get the identifier of this joystick.
    ///
    /// This is copy-on-write because it can be a borrowed or owned String,
    /// depending on the implementation.
    fn id(&self) -> Cow<str>;

    /// Get the index of this joystick.
    fn index(&self) -> JoystickIndex;

    /// Get the number of axes this joystick has
    ///
    /// This is capped at 6 axes for now.
    fn num_axes(&self) -> Axis;

    /// Get the number of buttons this joystick has
    ///
    /// This is capped at 16 buttons currently.
    fn num_buttons(&self) -> Button;

    /// Get the battery level of this joystick
    ///
    /// Returns none if the joystick is wired or this operation is not supported
    /// by the backend
    fn battery(&self) -> Option<f32>;
}

/// A joystick that tracks its state.
///
/// You must call `process` before you query anything.
pub struct StatefulJoystick<J> where J: Joystick {
    joystick: J,
    buttons: i32,
    axes: Vec<i16>
}
impl<J> StatefulJoystick<J> where J: Joystick {
    /// Get the position of the axis.
    pub fn axis(&self, axis: Axis) -> Option<i16> {
        self.axes.get(axis as usize).cloned()
    }
    /// Check if the button given is being pressed.
    pub fn button(&self, button: Button) -> Option<bool> {
        if button < self.joystick.num_buttons() {
            Some(self.buttons & (1 << button) > 0)
        } else {
            None
        }
    }
    /// Update this joystick's state with the event given.
    pub fn process(&mut self, event: Event) {
        let index = self.joystick.index();
        match event {
            Event::ButtonPressed(i, b) if i == index => {
                self.buttons |= (i as i32) << b;
            },
            Event::ButtonReleased(i, b) if i == index => {
                self.buttons &= !((i as i32) << b);
            },
            Event::AxisMoved(i, a, v) if i == index => {
                self.axes[a as usize] = v;
            },
            _ => ()
        }
    }
}
impl<J> Joystick for StatefulJoystick<J> where J: Joystick {
    type OpenError = J::OpenError;
    fn open(index: JoystickIndex) -> Result<Self, Self::OpenError> {
        let joystick = try!(J::open(index));
        let axes = (0..joystick.num_axes()).map(|_| 0).collect();
        Ok(StatefulJoystick {
            joystick: joystick,
            buttons: 0,
            axes: axes
        })
    }
    fn connected(&self) -> bool {
        self.joystick.connected()
    }
    fn id(&self) -> Cow<str> {
        self.joystick.id()
    }
    fn index(&self) -> JoystickIndex {
        self.joystick.index()
    }
    fn num_axes(&self) -> Axis {
        self.joystick.num_axes()
    }
    fn num_buttons(&self) -> Button {
        self.joystick.num_buttons()
    }
    fn battery(&self) -> Option<f32> {
        self.joystick.battery()
    }
}

/// An iterator over a Backend's event queue.
pub struct Poller<'a, J> where J:Backend+'a {
    backend: &'a mut J
}

impl<'a, C> Iterator for Poller<'a, C> where C:Backend {
    type Item = Event;
    /// This calls the `Backend.poll()` method to poll for the next event
    fn next(&mut self) -> Option<Event> {
        self.backend.poll()
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Mul, Sub, Neg};
use variables::{LpExpression, LpConstraint, Constraint};
use variables::LpExpression::*;
use std::rc::Rc;

// Operations trait for any type implementing Into<LpExpressions> trait
pub trait LpOperations<T> where T: Into<LpExpression> {
    /// Less or equal binary syntax for LpExpression
    fn le(&self, lhs_expr: T) -> LpConstraint;
    /// Greater or equal binary syntax for LpExpression
    fn ge(&self, lhs_expr: T) -> LpConstraint;
    /// Equality binary syntax for LpExpression
    fn equal(&self, lhs_expr: T) -> LpConstraint;
}

/// Macro implementing Into<LpExpression> for any type coercing to f32
macro_rules! num_to_into_expr {
    ($type_to:ty) => {
        impl Into<LpExpression> for $type_to {
            fn into(self) -> LpExpression {
                LitVal(self as f32)
            }
        }
    };
}

num_to_into_expr!(f32);
num_to_into_expr!(i32);

impl<'a> Into<LpExpression> for &'a LpExpression {
    fn into(self) -> LpExpression {
        self.clone()
    }
}

// <LpExr> op <LpExpr> where LpExpr is implicit
impl<T: Into<LpExpression> + Clone, U> LpOperations<T> for U where U: Into<LpExpression> + Clone {
    fn le(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::LessOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn ge(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::GreaterOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn equal( &self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Equal, lhs_expr.clone().into()).generalize()
    }
}

// LpExpr + (LpExpr, &LpExpr, f32)
impl<T> Add<T> for LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn add(self, _rhs: T) -> LpExpression {
        AddExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// &LpExpr + (LpExpr, &LpExpr, f32)
impl<'a, T> Add<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn add(self, _rhs: T) -> LpExpression {
        AddExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// f32 + &LpExpr
impl<'a> Add<&'a LpExpression> for f32 {
    type Output = LpExpression;
    fn add(self, _rhs: &'a LpExpression) -> LpExpression {
        AddExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

// LpExpr - (LpExpr, &LpExpr, f32)
impl<T> Sub<T> for LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn sub(self, _rhs: T) -> LpExpression {
        SubExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// &LpExpr - (LpExpr, &LpExpr, f32)
impl<'a, T> Sub<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
    type Output = LpExpression;
    fn sub(self, _rhs: T) -> LpExpression {
        SubExpr(Rc::new(self.clone()), Rc::new(_rhs.into()))
    }
}

// f32 - &LpExpr
impl<'a> Sub<&'a LpExpression> for f32 {
    type Output = LpExpression;
    fn sub(self, _rhs: &'a LpExpression) -> LpExpression {
        SubExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}

impl<'a> Neg for &'a LpExpression {
    type Output = LpExpression;
    fn neg(self) -> LpExpression {
        MulExpr(Rc::new(LitVal(-1.0)), Rc::new(self.clone()))
    }
}

// f32 * LpExpr
impl Mul<LpExpression> for f32 {
    type Output = LpExpression;
    fn mul(self, _rhs: LpExpression) -> LpExpression {
        LpExpression::MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs))
    }
}

// f32 * &LpExp
impl<'a> Mul<&'a LpExpression> for f32 {
    type Output = LpExpression;

    fn mul(self, _rhs: &'a LpExpression) -> LpExpression {
        MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
    }
}
<commit_msg>Dry principle for trait ops and into<commit_after>use std::ops::{Add, Mul, Sub, Neg};
use variables::{LpExpression, LpConstraint, Constraint};
use variables::LpExpression::*;
use std::rc::Rc;

/// Operations trait for any type implementing Into<LpExpressions> trait
pub trait LpOperations<T> where T: Into<LpExpression> {
    /// Less or equal binary syntax for LpExpression
    fn le(&self, lhs_expr: T) -> LpConstraint;
    /// Greater or equal binary syntax for LpExpression
    fn ge(&self, lhs_expr: T) -> LpConstraint;
    /// Equality binary syntax for LpExpression
    fn equal(&self, lhs_expr: T) -> LpConstraint;
}

/// Macro implementing Into<LpExpression> for any type coercing to f32
macro_rules! num_to_into_expr {
    ($type_to:ty) => {
        impl Into<LpExpression> for $type_to {
            fn into(self) -> LpExpression {
                LitVal(self as f32)
            }
        }
    };
}

/// Macro implementing binary operations Into<LpExpression> and &Into<LpExpression>
macro_rules! expr_ops_expr {
    ($trait_name: ident, $f_name: ident, $expr_type: ident) => {
        impl<T> $trait_name<T> for LpExpression where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new(self.clone()), Rc::new(_rhs.into()))
            }
        }

        impl<'a, T> $trait_name<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new(self.clone()), Rc::new(_rhs.into()))
            }
        }
    };
}

/// Macro implementing binary operations for a numeric type
macro_rules! num_ops_expr {
    ($num_type: ty, $trait_name: ident, $f_name: ident) => {
        impl $trait_name<LpExpression> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: LpExpression) -> LpExpression {
                MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs))
            }
        }
        impl<'a> $trait_name<&'a LpExpression> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: &'a LpExpression) -> LpExpression {
                MulExpr(Rc::new(LitVal(self)), Rc::new(_rhs.clone()))
            }
        }
    };
}

/// &LpExpression to LpExpression
impl<'a> Into<LpExpression> for &'a LpExpression {
    fn into(self) -> LpExpression {
        self.clone()
    }
}

/// Implementing LpOperations trait for any Into<LpExpression>
impl<T: Into<LpExpression> + Clone, U> LpOperations<T> for U where U: Into<LpExpression> + Clone {
    fn le(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::LessOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn ge(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::GreaterOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn equal( &self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Equal, lhs_expr.clone().into()).generalize()
    }
}

impl<'a> Neg for &'a LpExpression {
    type Output = LpExpression;
    fn neg(self) -> LpExpression {
        MulExpr(Rc::new(LitVal(-1.0)), Rc::new(self.clone()))
    }
}

num_to_into_expr!(f32);
num_to_into_expr!(i32);

expr_ops_expr!(Add, add, AddExpr);
expr_ops_expr!(Sub, sub, SubExpr);

num_ops_expr!(f32, Add, add);
num_ops_expr!(f32, Mul, mul);
num_ops_expr!(f32, Sub, sub);

<|endoftext|>


<commit_before>use rustc_ast::ast;
use rustc_errors::Applicability;
use rustc_session::Session;
use std::str::FromStr;

/// Deprecation status of attributes known by Clippy.
#[allow(dead_code)]
pub enum DeprecationStatus {
    /// Attribute is deprecated
    Deprecated,
    /// Attribute is deprecated and was replaced by the named attribute
    Replaced(&'static str),
    None,
}

pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[
    ("author", DeprecationStatus::None),
    ("cognitive_complexity", DeprecationStatus::None),
    (
        "cyclomatic_complexity",
        DeprecationStatus::Replaced("cognitive_complexity"),
    ),
    ("dump", DeprecationStatus::None),
];

pub struct LimitStack {
    stack: Vec<u64>,
}

impl Drop for LimitStack {
    fn drop(&mut self) {
        assert_eq!(self.stack.len(), 1);
    }
}

impl LimitStack {
    #[must_use]
    pub fn new(limit: u64) -> Self {
        Self { stack: vec![limit] }
    }
    pub fn limit(&self) -> u64 {
        *self.stack.last().expect("there should always be a value in the stack")
    }
    pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| stack.push(val));
    }
    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
    }
}

pub fn get_attr<'a>(
    sess: &'a Session,
    attrs: &'a [ast::Attribute],
    name: &'static str,
) -> impl Iterator<Item = &'a ast::Attribute> {
    attrs.iter().filter(move |attr| {
        let attr = if let ast::AttrKind::Normal(ref attr) = attr.kind {
            attr
        } else {
            return false;
        };
        let attr_segments = &attr.path.segments;
        if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" {
            if let Some(deprecation_status) =
                BUILTIN_ATTRIBUTES
                    .iter()
                    .find_map(|(builtin_name, deprecation_status)| {
                        if *builtin_name == attr_segments[1].ident.to_string() {
                            Some(deprecation_status)
                        } else {
                            None
                        }
                    })
            {
                let mut db = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute");
                match *deprecation_status {
                    DeprecationStatus::Deprecated => {
                        db.emit();
                        false
                    },
                    DeprecationStatus::Replaced(new_name) => {
                        db.span_suggestion(
                            attr_segments[1].ident.span,
                            "consider using",
                            new_name.to_string(),
                            Applicability::MachineApplicable,
                        );
                        db.emit();
                        false
                    },
                    DeprecationStatus::None => {
                        db.cancel();
                        attr_segments[1].ident.to_string() == name
                    },
                }
            } else {
                sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute");
                false
            }
        } else {
            false
        }
    })
}

fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
    for attr in get_attr(sess, attrs, name) {
        if let Some(ref value) = attr.value_str() {
            if let Ok(value) = FromStr::from_str(&value.as_str()) {
                f(value)
            } else {
                sess.span_err(attr.span, "not a number");
            }
        } else {
            sess.span_err(attr.span, "bad clippy attribute");
        }
    }
}

/// Return true if the attributes contain any of `proc_macro`,
/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
    use rustc_span::Symbol;

    let syms = [
        Symbol::intern("proc_macro"),
        Symbol::intern("proc_macro_derive"),
        Symbol::intern("proc_macro_attribute"),
    ];
    attrs.iter().any(|attr| syms.iter().any(move |&s| attr.check_name(s)))
}
<commit_msg>Cleanup: Use rustc's is_proc_macro_attr<commit_after>use rustc_ast::ast;
use rustc_ast::expand::is_proc_macro_attr;
use rustc_errors::Applicability;
use rustc_session::Session;
use std::str::FromStr;

/// Deprecation status of attributes known by Clippy.
#[allow(dead_code)]
pub enum DeprecationStatus {
    /// Attribute is deprecated
    Deprecated,
    /// Attribute is deprecated and was replaced by the named attribute
    Replaced(&'static str),
    None,
}

pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[
    ("author", DeprecationStatus::None),
    ("cognitive_complexity", DeprecationStatus::None),
    (
        "cyclomatic_complexity",
        DeprecationStatus::Replaced("cognitive_complexity"),
    ),
    ("dump", DeprecationStatus::None),
];

pub struct LimitStack {
    stack: Vec<u64>,
}

impl Drop for LimitStack {
    fn drop(&mut self) {
        assert_eq!(self.stack.len(), 1);
    }
}

impl LimitStack {
    #[must_use]
    pub fn new(limit: u64) -> Self {
        Self { stack: vec![limit] }
    }
    pub fn limit(&self) -> u64 {
        *self.stack.last().expect("there should always be a value in the stack")
    }
    pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| stack.push(val));
    }
    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
        let stack = &mut self.stack;
        parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
    }
}

pub fn get_attr<'a>(
    sess: &'a Session,
    attrs: &'a [ast::Attribute],
    name: &'static str,
) -> impl Iterator<Item = &'a ast::Attribute> {
    attrs.iter().filter(move |attr| {
        let attr = if let ast::AttrKind::Normal(ref attr) = attr.kind {
            attr
        } else {
            return false;
        };
        let attr_segments = &attr.path.segments;
        if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" {
            if let Some(deprecation_status) =
                BUILTIN_ATTRIBUTES
                    .iter()
                    .find_map(|(builtin_name, deprecation_status)| {
                        if *builtin_name == attr_segments[1].ident.to_string() {
                            Some(deprecation_status)
                        } else {
                            None
                        }
                    })
            {
                let mut db = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute");
                match *deprecation_status {
                    DeprecationStatus::Deprecated => {
                        db.emit();
                        false
                    },
                    DeprecationStatus::Replaced(new_name) => {
                        db.span_suggestion(
                            attr_segments[1].ident.span,
                            "consider using",
                            new_name.to_string(),
                            Applicability::MachineApplicable,
                        );
                        db.emit();
                        false
                    },
                    DeprecationStatus::None => {
                        db.cancel();
                        attr_segments[1].ident.to_string() == name
                    },
                }
            } else {
                sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute");
                false
            }
        } else {
            false
        }
    })
}

fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
    for attr in get_attr(sess, attrs, name) {
        if let Some(ref value) = attr.value_str() {
            if let Ok(value) = FromStr::from_str(&value.as_str()) {
                f(value)
            } else {
                sess.span_err(attr.span, "not a number");
            }
        } else {
            sess.span_err(attr.span, "bad clippy attribute");
        }
    }
}

/// Return true if the attributes contain any of `proc_macro`,
/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
    attrs.iter().any(is_proc_macro_attr)
}
<|endoftext|>


<commit_before>// A microframework for Rust.
// Copyright (c) 2014 by Shipeng Feng.
// Licensed under the BSD License, see LICENSE for more details.

//! Pencil is a microframework for Rust inspired by [Flask](http://flask.pocoo.org/).
//!
//! # Installation
//!
//! This crate is called `pencil` and you can depend on it via cargo:
//!
//! ```ini
//! [dependencies.pencil]
//! git = "https://github.com/fengsp/pencil.git"
//! ```
//!
//! # Quickstart
//!
//! A short introduction to Pencil.
//!
//! ## A Minimal Application
//!
//! A minimal Pencil application looks something like this:
//!
//! ```rust,no_run
//! extern crate pencil;
//!
//! use pencil::Pencil;
//! use pencil::{Request, Params, PencilResult, PenValue};
//!
//!
//! fn hello(_: Request, _: Params) -> PencilResult {
//!     PenValue(String::from_str("Hello World!"))
//! }
//!
//!
//! fn main() {
//!     let mut app = Pencil::new("/web/hello");
//!     app.route(r"/", &["GET"], "hello", hello);
//!     app.run();
//! }
//! ```

#![allow(unused_attributes)]
#![crate_name = "pencil"]
#![crate_type = "lib"]
#![license = "BSD"]
#![comment = "A microframework for Rust."]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://fengsp.github.io/pencil/")]
#![experimental]
#![deny(non_camel_case_types)]

extern crate core;
extern crate serialize;
extern crate regex;
extern crate http;

/* public api */
pub use app::Pencil;
pub use types::{
    PencilResult,
        PenValue,
        PenResponse,
        PenError,
    PencilError,
};
pub use datastructures::{
    Headers,
};
pub use wrappers::{
    Request,
    Response,
};
pub use json::jsonify;
pub use config::{
    Config,
};
pub use helpers::{
    make_response,
    PathBound,
    safe_join,
};
pub use serving::{
    run_server,
};
pub use routing::Params;
pub use errors::{
    HTTPError,
};
pub use testing::PencilClient;

mod app;
mod types;
mod datastructures;
mod wrappers;
mod json;
mod config;
mod logging;
mod helpers;
mod serving;
mod errors;
mod routing;
mod testing;
mod httputils;
<commit_msg>Added logo to docs<commit_after>// A microframework for Rust.
// Copyright (c) 2014 by Shipeng Feng.
// Licensed under the BSD License, see LICENSE for more details.

//! Pencil is a microframework for Rust inspired by [Flask](http://flask.pocoo.org/).
//!
//! # Installation
//!
//! This crate is called `pencil` and you can depend on it via cargo:
//!
//! ```ini
//! [dependencies.pencil]
//! git = "https://github.com/fengsp/pencil.git"
//! ```
//!
//! # Quickstart
//!
//! A short introduction to Pencil.
//!
//! ## A Minimal Application
//!
//! A minimal Pencil application looks something like this:
//!
//! ```rust,no_run
//! extern crate pencil;
//!
//! use pencil::Pencil;
//! use pencil::{Request, Params, PencilResult, PenValue};
//!
//!
//! fn hello(_: Request, _: Params) -> PencilResult {
//!     PenValue(String::from_str("Hello World!"))
//! }
//!
//!
//! fn main() {
//!     let mut app = Pencil::new("/web/hello");
//!     app.route(r"/", &["GET"], "hello", hello);
//!     app.run();
//! }
//! ```

#![allow(unused_attributes)]
#![crate_name = "pencil"]
#![crate_type = "lib"]
#![license = "BSD"]
#![comment = "A microframework for Rust."]
#![doc(html_logo_url = "https://raw.githubusercontent.com/fengsp/pencil/master/logo/pencil.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://fengsp.github.io/pencil/")]
#![experimental]
#![deny(non_camel_case_types)]

extern crate core;
extern crate serialize;
extern crate regex;
extern crate http;

/* public api */
pub use app::Pencil;
pub use types::{
    PencilResult,
        PenValue,
        PenResponse,
        PenError,
    PencilError,
};
pub use datastructures::{
    Headers,
};
pub use wrappers::{
    Request,
    Response,
};
pub use json::jsonify;
pub use config::{
    Config,
};
pub use helpers::{
    make_response,
    PathBound,
    safe_join,
};
pub use serving::{
    run_server,
};
pub use routing::Params;
pub use errors::{
    HTTPError,
};
pub use testing::PencilClient;

mod app;
mod types;
mod datastructures;
mod wrappers;
mod json;
mod config;
mod logging;
mod helpers;
mod serving;
mod errors;
mod routing;
mod testing;
mod httputils;
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The implementations of `Rand` for the built-in types.

use std::char;
use std::mem;

use {Rand,Rng};

impl Rand for isize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> isize {
        if mem::size_of::<isize>() == 4 {
            rng.gen::<i32>() as isize
        } else {
            rng.gen::<i64>() as isize
        }
    }
}

impl Rand for i8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i8 {
        rng.next_u32() as i8
    }
}

impl Rand for i16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i16 {
        rng.next_u32() as i16
    }
}

impl Rand for i32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i32 {
        rng.next_u32() as i32
    }
}

impl Rand for i64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i64 {
        rng.next_u64() as i64
    }
}

impl Rand for usize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> usize {
        if mem::size_of::<usize>() == 4 {
            rng.gen::<u32>() as usize
        } else {
            rng.gen::<u64>() as usize
        }
    }
}

impl Rand for u8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u8 {
        rng.next_u32() as u8
    }
}

impl Rand for u16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u16 {
        rng.next_u32() as u16
    }
}

impl Rand for u32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u32 {
        rng.next_u32()
    }
}

impl Rand for u64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u64 {
        rng.next_u64()
    }
}

macro_rules! float_impls {
    ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
        mod $mod_name {
            use {Rand, Rng, Open01, Closed01};

            const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;

            impl Rand for $ty {
                /// Generate a floating point number in the half-open
                /// interval `[0,1)`.
                ///
                /// See `Closed01` for the closed interval `[0,1]`,
                /// and `Open01` for the open interval `(0,1)`.
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> $ty {
                    rng.$method_name()
                }
            }
            impl Rand for Open01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
                    // add a small amount (specifically 2 bits below
                    // the precision of f64/f32 at 1.0), so that small
                    // numbers are larger than 0, but large numbers
                    // aren't pushed to/above 1.
                    Open01(rng.$method_name() + 0.25 / SCALE)
                }
            }
            impl Rand for Closed01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
                    // rescale so that 1.0 - epsilon becomes 1.0
                    // precisely.
                    Closed01(rng.$method_name() * SCALE / (SCALE - 1.0))
                }
            }
        }
    }
}
float_impls! { f64_rand_impls, f64, 53, next_f64 }
float_impls! { f32_rand_impls, f32, 24, next_f32 }

impl Rand for char {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> char {
        // a char is 21 bits
        const CHAR_MASK: u32 = 0x001f_ffff;
        loop {
            // Rejection sampling. About 0.2% of numbers with at most
            // 21-bits are invalid codepoints (surrogates), so this
            // will succeed first go almost every time.
            match char::from_u32(rng.next_u32() & CHAR_MASK) {
                Some(c) => return c,
                None => {}
            }
        }
    }
}

impl Rand for bool {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> bool {
        rng.gen::<u8>() & 1 == 1
    }
}

macro_rules! tuple_impl {
    // use variables to indicate the arity of the tuple
    ($($tyvar:ident),* ) => {
        // the trailing commas are for the 1 tuple
        impl<
            $( $tyvar : Rand ),*
            > Rand for ( $( $tyvar ),* , ) {

            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
                (
                    // use the $tyvar's to get the appropriate number of
                    // repeats (they're not actually needed)
                    $(
                        _rng.gen::<$tyvar>()
                    ),*
                    ,
                )
            }
        }
    }
}

impl Rand for () {
    #[inline]
    fn rand<R: Rng>(_: &mut R) -> () { () }
}
tuple_impl!{A}
tuple_impl!{A, B}
tuple_impl!{A, B, C}
tuple_impl!{A, B, C, D}
tuple_impl!{A, B, C, D, E}
tuple_impl!{A, B, C, D, E, F}
tuple_impl!{A, B, C, D, E, F, G}
tuple_impl!{A, B, C, D, E, F, G, H}
tuple_impl!{A, B, C, D, E, F, G, H, I}
tuple_impl!{A, B, C, D, E, F, G, H, I, J}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}

macro_rules! array_impl {
    {$n:expr, $t:ident $($ts:ident)*} => {
        array_impl!{($n - 1), $($ts)*}

        impl<T> Rand for [T; $n] where T: Rand {
            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] {
                [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
            }
        }
    };
    {$n:expr,} => {
        impl<T> Rand for [T; $n] {
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] { [] }
        }
    };
}

array_impl!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}

impl<T:Rand> Rand for Option<T> {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
        if rng.gen() {
            Some(rng.gen())
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use {Rng, thread_rng, Open01, Closed01};

    struct ConstantRng(u64);
    impl Rng for ConstantRng {
        fn next_u32(&mut self) -> u32 {
            let ConstantRng(v) = *self;
            v as u32
        }
        fn next_u64(&mut self) -> u64 {
            let ConstantRng(v) = *self;
            v
        }
    }

    #[test]
    fn floating_point_edge_cases() {
        // the test for exact equality is correct here.
        assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
        assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
    }

    #[test]
    fn rand_open() {
        // this is unlikely to catch an incorrect implementation that
        // generates exactly 0 or 1, but it keeps it sane.
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Open01(f) = rng.gen::<Open01<f64>>();
            assert!(0.0 < f && f < 1.0);

            let Open01(f) = rng.gen::<Open01<f32>>();
            assert!(0.0 < f && f < 1.0);
        }
    }

    #[test]
    fn rand_closed() {
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Closed01(f) = rng.gen::<Closed01<f64>>();
            assert!(0.0 <= f && f <= 1.0);

            let Closed01(f) = rng.gen::<Closed01<f32>>();
            assert!(0.0 <= f && f <= 1.0);
        }
    }
}
<commit_msg>Fix macro to work with Rust 1.0.0<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The implementations of `Rand` for the built-in types.

use std::char;
use std::mem;

use {Rand,Rng};

impl Rand for isize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> isize {
        if mem::size_of::<isize>() == 4 {
            rng.gen::<i32>() as isize
        } else {
            rng.gen::<i64>() as isize
        }
    }
}

impl Rand for i8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i8 {
        rng.next_u32() as i8
    }
}

impl Rand for i16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i16 {
        rng.next_u32() as i16
    }
}

impl Rand for i32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i32 {
        rng.next_u32() as i32
    }
}

impl Rand for i64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> i64 {
        rng.next_u64() as i64
    }
}

impl Rand for usize {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> usize {
        if mem::size_of::<usize>() == 4 {
            rng.gen::<u32>() as usize
        } else {
            rng.gen::<u64>() as usize
        }
    }
}

impl Rand for u8 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u8 {
        rng.next_u32() as u8
    }
}

impl Rand for u16 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u16 {
        rng.next_u32() as u16
    }
}

impl Rand for u32 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u32 {
        rng.next_u32()
    }
}

impl Rand for u64 {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> u64 {
        rng.next_u64()
    }
}

macro_rules! float_impls {
    ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
        mod $mod_name {
            use {Rand, Rng, Open01, Closed01};

            const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;

            impl Rand for $ty {
                /// Generate a floating point number in the half-open
                /// interval `[0,1)`.
                ///
                /// See `Closed01` for the closed interval `[0,1]`,
                /// and `Open01` for the open interval `(0,1)`.
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> $ty {
                    rng.$method_name()
                }
            }
            impl Rand for Open01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
                    // add a small amount (specifically 2 bits below
                    // the precision of f64/f32 at 1.0), so that small
                    // numbers are larger than 0, but large numbers
                    // aren't pushed to/above 1.
                    Open01(rng.$method_name() + 0.25 / SCALE)
                }
            }
            impl Rand for Closed01<$ty> {
                #[inline]
                fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
                    // rescale so that 1.0 - epsilon becomes 1.0
                    // precisely.
                    Closed01(rng.$method_name() * SCALE / (SCALE - 1.0))
                }
            }
        }
    }
}
float_impls! { f64_rand_impls, f64, 53, next_f64 }
float_impls! { f32_rand_impls, f32, 24, next_f32 }

impl Rand for char {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> char {
        // a char is 21 bits
        const CHAR_MASK: u32 = 0x001f_ffff;
        loop {
            // Rejection sampling. About 0.2% of numbers with at most
            // 21-bits are invalid codepoints (surrogates), so this
            // will succeed first go almost every time.
            match char::from_u32(rng.next_u32() & CHAR_MASK) {
                Some(c) => return c,
                None => {}
            }
        }
    }
}

impl Rand for bool {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> bool {
        rng.gen::<u8>() & 1 == 1
    }
}

macro_rules! tuple_impl {
    // use variables to indicate the arity of the tuple
    ($($tyvar:ident),* ) => {
        // the trailing commas are for the 1 tuple
        impl<
            $( $tyvar : Rand ),*
            > Rand for ( $( $tyvar ),* , ) {

            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
                (
                    // use the $tyvar's to get the appropriate number of
                    // repeats (they're not actually needed)
                    $(
                        _rng.gen::<$tyvar>()
                    ),*
                    ,
                )
            }
        }
    }
}

impl Rand for () {
    #[inline]
    fn rand<R: Rng>(_: &mut R) -> () { () }
}
tuple_impl!{A}
tuple_impl!{A, B}
tuple_impl!{A, B, C}
tuple_impl!{A, B, C, D}
tuple_impl!{A, B, C, D, E}
tuple_impl!{A, B, C, D, E, F}
tuple_impl!{A, B, C, D, E, F, G}
tuple_impl!{A, B, C, D, E, F, G, H}
tuple_impl!{A, B, C, D, E, F, G, H, I}
tuple_impl!{A, B, C, D, E, F, G, H, I, J}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}

macro_rules! array_impl {
    {$n:expr, $t:ident, $($ts:ident,)*} => {
        array_impl!{($n - 1), $($ts,)*}

        impl<T> Rand for [T; $n] where T: Rand {
            #[inline]
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] {
                [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
            }
        }
    };
    {$n:expr,} => {
        impl<T> Rand for [T; $n] {
            fn rand<R: Rng>(_rng: &mut R) -> [T; $n] { [] }
        }
    };
}

array_impl!{32, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,}

impl<T:Rand> Rand for Option<T> {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
        if rng.gen() {
            Some(rng.gen())
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use {Rng, thread_rng, Open01, Closed01};

    struct ConstantRng(u64);
    impl Rng for ConstantRng {
        fn next_u32(&mut self) -> u32 {
            let ConstantRng(v) = *self;
            v as u32
        }
        fn next_u64(&mut self) -> u64 {
            let ConstantRng(v) = *self;
            v
        }
    }

    #[test]
    fn floating_point_edge_cases() {
        // the test for exact equality is correct here.
        assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
        assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
    }

    #[test]
    fn rand_open() {
        // this is unlikely to catch an incorrect implementation that
        // generates exactly 0 or 1, but it keeps it sane.
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Open01(f) = rng.gen::<Open01<f64>>();
            assert!(0.0 < f && f < 1.0);

            let Open01(f) = rng.gen::<Open01<f32>>();
            assert!(0.0 < f && f < 1.0);
        }
    }

    #[test]
    fn rand_closed() {
        let mut rng = thread_rng();
        for _ in 0..1_000 {
            // strict inequalities
            let Closed01(f) = rng.gen::<Closed01<f64>>();
            assert!(0.0 <= f && f <= 1.0);

            let Closed01(f) = rng.gen::<Closed01<f32>>();
            assert!(0.0 <= f && f <= 1.0);
        }
    }
}
<|endoftext|>