<commit_before>// Copyright (c) 2016 Anatoly Ikorsky
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

//! ## mysql-async
//! Tokio based asynchronous MySql client library for rust programming language.
//!
//! ### Installation
//! Library hosted on [crates.io](https://crates.io/crates/mysql_async/).
//!
//! ```toml
//! [dependencies]
//! mysql = "<desired version>"
//! ```
//!
//! ### Example
//!
//! ```rust
//! extern crate futures;
//! #[macro_use]
//! extern crate mysql_async as my;
//! extern crate tokio_core as tokio;
//! // ...
//!
//! use futures::Future;
//! use my::prelude::*;
//! use tokio::reactor::Core;
//! # use std::env;
//!
//! #[derive(Debug, PartialEq, Eq, Clone)]
//! struct Payment {
//!     customer_id: i32,
//!     amount: i32,
//!     account_name: Option<String>,
//! }
//!
//! fn main() {
//!     let mut lp = Core::new().unwrap();
//!
//!     let payments = vec![
//!         Payment { customer_id: 1, amount: 2, account_name: None },
//!         Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
//!         Payment { customer_id: 5, amount: 6, account_name: None },
//!         Payment { customer_id: 7, amount: 8, account_name: None },
//!         Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
//!     ];
//!
//!     # let database_url: String = if let Ok(url) = env::var("DATABASE_URL") {
//!     #     let opts = my::Opts::from_url(&url).expect("DATABASE_URL invalid");
//!     #     if opts.get_db_name().expect("a database name is required").is_empty() {
//!     #         panic!("database name is empty");
//!     #     }
//!     #     url
//!     # } else {
//!     #     "mysql://root:password@127.0.0.1:3307/mysql".into()
//!     # };
//!
//!     let pool = my::Pool::new(database_url, &lp.handle());
//!     let future = pool.get_conn().and_then(|conn| {
//!         // Create temporary table
//!         conn.drop_query(
//!             r"CREATE TEMPORARY TABLE payment (
//!                 customer_id int not null,
//!                 amount int not null,
//!                 account_name text
//!             )"
//!         )
//!     }).and_then(|conn| {
//!         // Save payments
//!         let params = payments.clone().into_iter().map(|payment| {
//!             params! {
//!                 "customer_id" => payment.customer_id,
//!                 "amount" => payment.amount,
//!                 "account_name" => payment.account_name.clone(),
//!             }
//!         });
//!
//!         conn.batch_exec(r"INSERT INTO payment (customer_id, amount, account_name)
//!                         VALUES (:customer_id, :amount, :account_name)", params)
//!     }).and_then(|conn| {
//!         // Load payments from database.
//!         conn.prep_exec("SELECT customer_id, amount, account_name FROM payment", ())
//!     }).and_then(|result| {
//!         // Collect payments
//!         result.map_and_drop(|row| {
//!             let (customer_id, amount, account_name) = my::from_row(row);
//!             Payment {
//!                 customer_id: customer_id,
//!                 amount: amount,
//!                 account_name: account_name,
//!             }
//!         })
//!     }).and_then(|(_ /* conn */, payments)| {
//!         // The destructor of a connection will return it to the pool,
//!         // but pool should be disconnected explicitly because it's
//!         // an asynchronous procedure.
//!         pool.disconnect().map(|_| payments)
//!     });
//!
//!     let loaded_payments = lp.run(future).unwrap();
//!
//!     assert_eq!(loaded_payments, payments);
//! }
//! ```

#![recursion_limit = "1024"]
#![cfg_attr(feature = "nightly", feature(test, const_fn, drop_types_in_const))]

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

extern crate bit_vec;
extern crate byteorder;
#[macro_use]
extern crate error_chain;
extern crate fnv;
#[macro_use]
extern crate futures as lib_futures;
#[cfg(test)]
#[macro_use]
extern crate lazy_static;
extern crate mio;
extern crate mysql_common as myc;
#[cfg(feature = "ssl")]
extern crate native_tls;
extern crate regex;
extern crate serde;
extern crate serde_json;
extern crate tokio_core as tokio;
extern crate tokio_io;
#[cfg(feature = "ssl")]
extern crate tokio_tls;
extern crate twox_hash;
extern crate url;

pub use myc::chrono;
pub use myc::constants as consts;
pub use myc::time;
pub use myc::uuid;

// Until `macro_reexport` stabilisation.
/// This macro is a convenient way to pass named parameters to a statement.
///
/// ```ignore
/// let foo = 42;
/// conn.prep_exec("SELECT :foo, :foo2x", params! {
///     foo,
///     "foo2x" => foo * 2,
/// });
/// ```
#[macro_export]
macro_rules! params {
    () => {};
    (@to_pair $name:expr => $value:expr) => (
        (::std::string::String::from($name), $crate::Value::from($value))
    );
    (@to_pair $name:ident) => (
        (::std::string::String::from(stringify!($name)), $crate::Value::from($name))
    );
    (@expand $vec:expr;) => {};
    (@expand $vec:expr; $name:expr => $value:expr, $($tail:tt)*) => {
        $vec.push(params!(@to_pair $name => $value));
        params!(@expand $vec; $($tail)*);
    };
    (@expand $vec:expr; $name:expr => $value:expr $(, $tail:tt)*) => {
        $vec.push(params!(@to_pair $name => $value));
        params!(@expand $vec; $($tail)*);
    };
    (@expand $vec:expr; $name:ident, $($tail:tt)*) => {
        $vec.push(params!(@to_pair $name));
        params!(@expand $vec; $($tail)*);
    };
    (@expand $vec:expr; $name:ident $(, $tail:tt)*) => {
        $vec.push(params!(@to_pair $name));
        params!(@expand $vec; $($tail)*);
    };
    ($($tail:tt)*) => {
        {
            let mut output = vec![];
            params!(@expand output; $($tail)*);
            output
        }
    };
}

#[macro_use]
pub mod macros;
mod conn;
mod connection_like;
/// Errors used in this crate
pub mod errors;
mod io;
mod local_infile_handler;
mod opts;
mod queryable;

pub type BoxFuture<T> = Box<lib_futures::Future<Item = T, Error = errors::Error>>;

#[doc(inline)]
pub use self::conn::Conn;

#[doc(inline)]
pub use self::conn::pool::Pool;

#[doc(inline)]
pub use self::queryable::transaction::IsolationLevel;

#[doc(inline)]
pub use self::opts::{Opts, OptsBuilder, SslOpts};

#[doc(inline)]
pub use self::local_infile_handler::builtin::WhiteListFsLocalInfileHandler;

#[doc(inline)]
pub use myc::packets::Column;

#[doc(inline)]
pub use myc::row::Row;

#[doc(inline)]
pub use myc::params::Params;

#[doc(inline)]
pub use myc::value::Value;

#[doc(inline)]
pub use myc::row::convert::{from_row, from_row_opt, FromRowError};

#[doc(inline)]
pub use myc::value::convert::{from_value, from_value_opt, FromValueError};

#[doc(inline)]
pub use myc::value::json::{Serialized, Deserialized};

#[doc(inline)]
pub use self::queryable::query_result::QueryResult;

#[doc(inline)]
pub use self::queryable::transaction::{Transaction, TransactionOptions};

#[doc(inline)]
pub use self::queryable::{TextProtocol, BinaryProtocol};

#[doc(inline)]
pub use self::queryable::stmt::Stmt;

/// Futures used in this crate
mod futures {
    pub use queryable::query_result::{ForEachAndDrop, MapAndDrop, ReduceAndDrop, ForEach, Map,
                                      Reduce};
}

/// Traits used in this crate
pub mod prelude {
    #[doc(inline)]
    pub use myc::value::convert::{ConvIr, FromValue, ToValue};
    #[doc(inline)]
    pub use myc::row::convert::FromRow;
    #[doc(inline)]
    pub use queryable::Queryable;
    #[doc(inline)]
    pub use local_infile_handler::LocalInfileHandler;
}

#[cfg(test)]
mod test_misc {
    use std::env;
    use opts;
    lazy_static! {
        pub static ref DATABASE_URL: String = {
            if let Ok(url) = env::var("DATABASE_URL") {
                let opts = opts::Opts::from_url(&url).expect("DATABASE_URL invalid");
                if opts.get_db_name().expect("a database name is required").is_empty() {
                    panic!("database name is empty");
                }
                url
            } else {
                "mysql://root:password@127.0.0.1:3307/mysql".into()
            }
        };
    }
}
<commit_msg>doc: Fix copy-pase error in dependency name.<commit_after>// Copyright (c) 2016 Anatoly Ikorsky
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

//! ## mysql-async
//! Tokio based asynchronous MySql client library for rust programming language.
//!
//! ### Installation
//! Library hosted on [crates.io](https://crates.io/crates/mysql_async/).
//!
//! ```toml
//! [dependencies]
//! mysql_async = "<desired version>"
//! ```
//!
//! ### Example
//!
//! ```rust
//! extern crate futures;
//! #[macro_use]
//! extern crate mysql_async as my;
//! extern crate tokio_core as tokio;
//! // ...
//!
//! use futures::Future;
//! use my::prelude::*;
//! use tokio::reactor::Core;
//! # use std::env;
//!
//! #[derive(Debug, PartialEq, Eq, Clone)]
//! struct Payment {
//!     customer_id: i32,
//!     amount: i32,
//!     account_name: Option<String>,
//! }
//!
//! fn main() {
//!     let mut lp = Core::new().unwrap();
//!
//!     let payments = vec![
//!         Payment { customer_id: 1, amount: 2, account_name: None },
//!         Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
//!         Payment { customer_id: 5, amount: 6, account_name: None },
//!         Payment { customer_id: 7, amount: 8, account_name: None },
//!         Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
//!     ];
//!
//!     # let database_url: String = if let Ok(url) = env::var("DATABASE_URL") {
//!     #     let opts = my::Opts::from_url(&url).expect("DATABASE_URL invalid");
//!     #     if opts.get_db_name().expect("a database name is required").is_empty() {
//!     #         panic!("database name is empty");
//!     #     }
//!     #     url
//!     # } else {
//!     #     "mysql://root:password@127.0.0.1:3307/mysql".into()
//!     # };
//!
//!     let pool = my::Pool::new(database_url, &lp.handle());
//!     let future = pool.get_conn().and_then(|conn| {
//!         // Create temporary table
//!         conn.drop_query(
//!             r"CREATE TEMPORARY TABLE payment (
//!                 customer_id int not null,
//!                 amount int not null,
//!                 account_name text
//!             )"
//!         )
//!     }).and_then(|conn| {
//!         // Save payments
//!         let params = payments.clone().into_iter().map(|payment| {
//!             params! {
//!                 "customer_id" => payment.customer_id,
//!                 "amount" => payment.amount,
//!                 "account_name" => payment.account_name.clone(),
//!             }
//!         });
//!
//!         conn.batch_exec(r"INSERT INTO payment (customer_id, amount, account_name)
//!                         VALUES (:customer_id, :amount, :account_name)", params)
//!     }).and_then(|conn| {
//!         // Load payments from database.
//!         conn.prep_exec("SELECT customer_id, amount, account_name FROM payment", ())
//!     }).and_then(|result| {
//!         // Collect payments
//!         result.map_and_drop(|row| {
//!             let (customer_id, amount, account_name) = my::from_row(row);
//!             Payment {
//!                 customer_id: customer_id,
//!                 amount: amount,
//!                 account_name: account_name,
//!             }
//!         })
//!     }).and_then(|(_ /* conn */, payments)| {
//!         // The destructor of a connection will return it to the pool,
//!         // but pool should be disconnected explicitly because it's
//!         // an asynchronous procedure.
//!         pool.disconnect().map(|_| payments)
//!     });
//!
//!     let loaded_payments = lp.run(future).unwrap();
//!
//!     assert_eq!(loaded_payments, payments);
//! }
//! ```

#![recursion_limit = "1024"]
#![cfg_attr(feature = "nightly", feature(test, const_fn, drop_types_in_const))]

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

extern crate bit_vec;
extern crate byteorder;
#[macro_use]
extern crate error_chain;
extern crate fnv;
#[macro_use]
extern crate futures as lib_futures;
#[cfg(test)]
#[macro_use]
extern crate lazy_static;
extern crate mio;
extern crate mysql_common as myc;
#[cfg(feature = "ssl")]
extern crate native_tls;
extern crate regex;
extern crate serde;
extern crate serde_json;
extern crate tokio_core as tokio;
extern crate tokio_io;
#[cfg(feature = "ssl")]
extern crate tokio_tls;
extern crate twox_hash;
extern crate url;

pub use myc::chrono;
pub use myc::constants as consts;
pub use myc::time;
pub use myc::uuid;

// Until `macro_reexport` stabilisation.
/// This macro is a convenient way to pass named parameters to a statement.
///
/// ```ignore
/// let foo = 42;
/// conn.prep_exec("SELECT :foo, :foo2x", params! {
///     foo,
///     "foo2x" => foo * 2,
/// });
/// ```
#[macro_export]
macro_rules! params {
    () => {};
    (@to_pair $name:expr => $value:expr) => (
        (::std::string::String::from($name), $crate::Value::from($value))
    );
    (@to_pair $name:ident) => (
        (::std::string::String::from(stringify!($name)), $crate::Value::from($name))
    );
    (@expand $vec:expr;) => {};
    (@expand $vec:expr; $name:expr => $value:expr, $($tail:tt)*) => {
        $vec.push(params!(@to_pair $name => $value));
        params!(@expand $vec; $($tail)*);
    };
    (@expand $vec:expr; $name:expr => $value:expr $(, $tail:tt)*) => {
        $vec.push(params!(@to_pair $name => $value));
        params!(@expand $vec; $($tail)*);
    };
    (@expand $vec:expr; $name:ident, $($tail:tt)*) => {
        $vec.push(params!(@to_pair $name));
        params!(@expand $vec; $($tail)*);
    };
    (@expand $vec:expr; $name:ident $(, $tail:tt)*) => {
        $vec.push(params!(@to_pair $name));
        params!(@expand $vec; $($tail)*);
    };
    ($($tail:tt)*) => {
        {
            let mut output = vec![];
            params!(@expand output; $($tail)*);
            output
        }
    };
}

#[macro_use]
pub mod macros;
mod conn;
mod connection_like;
/// Errors used in this crate
pub mod errors;
mod io;
mod local_infile_handler;
mod opts;
mod queryable;

pub type BoxFuture<T> = Box<lib_futures::Future<Item = T, Error = errors::Error>>;

#[doc(inline)]
pub use self::conn::Conn;

#[doc(inline)]
pub use self::conn::pool::Pool;

#[doc(inline)]
pub use self::queryable::transaction::IsolationLevel;

#[doc(inline)]
pub use self::opts::{Opts, OptsBuilder, SslOpts};

#[doc(inline)]
pub use self::local_infile_handler::builtin::WhiteListFsLocalInfileHandler;

#[doc(inline)]
pub use myc::packets::Column;

#[doc(inline)]
pub use myc::row::Row;

#[doc(inline)]
pub use myc::params::Params;

#[doc(inline)]
pub use myc::value::Value;

#[doc(inline)]
pub use myc::row::convert::{from_row, from_row_opt, FromRowError};

#[doc(inline)]
pub use myc::value::convert::{from_value, from_value_opt, FromValueError};

#[doc(inline)]
pub use myc::value::json::{Serialized, Deserialized};

#[doc(inline)]
pub use self::queryable::query_result::QueryResult;

#[doc(inline)]
pub use self::queryable::transaction::{Transaction, TransactionOptions};

#[doc(inline)]
pub use self::queryable::{TextProtocol, BinaryProtocol};

#[doc(inline)]
pub use self::queryable::stmt::Stmt;

/// Futures used in this crate
mod futures {
    pub use queryable::query_result::{ForEachAndDrop, MapAndDrop, ReduceAndDrop, ForEach, Map,
                                      Reduce};
}

/// Traits used in this crate
pub mod prelude {
    #[doc(inline)]
    pub use myc::value::convert::{ConvIr, FromValue, ToValue};
    #[doc(inline)]
    pub use myc::row::convert::FromRow;
    #[doc(inline)]
    pub use queryable::Queryable;
    #[doc(inline)]
    pub use local_infile_handler::LocalInfileHandler;
}

#[cfg(test)]
mod test_misc {
    use std::env;
    use opts;
    lazy_static! {
        pub static ref DATABASE_URL: String = {
            if let Ok(url) = env::var("DATABASE_URL") {
                let opts = opts::Opts::from_url(&url).expect("DATABASE_URL invalid");
                if opts.get_db_name().expect("a database name is required").is_empty() {
                    panic!("database name is empty");
                }
                url
            } else {
                "mysql://root:password@127.0.0.1:3307/mysql".into()
            }
        };
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub};

#[derive(Debug,PartialEq,Eq)]
pub struct LimitVal {
    Val : u8,
    Max : u8,
    Min : u8,
    //Fix : Fn(u8) -> u8 //This caused wierd issues, ignore for now.
}

impl Add for LimitVal {
    type Output = LimitVal;

    fn add(self, other: LimitVal) -> LimitVal {
        let mut result: LimitVal = LimitVal{Val: 0, Max: 0, Min: 0}; //hack
        result.Val = self.Val + other.Val;
        result.Max = if(self.Max > other.Max){
                        other.Max // choose the smallest one
                    }else{
                        self.Max
                    };
        result.Min = if(self.Min > other.Min){
                        self.Min // choose the biggest one
                    }else{
                        other.Min
                    };
        result
    }
}

#[cfg(test)]
mod tests {
    /*
    Can always put in own file, then would need:
    extern crate adder; (or whatever)
    and then namespace:: the functions.
    */
    use super::*;

    #[test]
    fn test_add() {
        let mut x: LimitVal = LimitVal{Val: 2, Max: 10, Min: 0};
        let mut y: LimitVal = LimitVal{Val: 3, Max: 10, Min: 0};

        let z = x + y;
        assert_eq!(z.Val,5);
    }
}
<commit_msg>use builder pattern instead of directly defining stuff.<commit_after>use std::ops::{Add, Sub};

#[derive(Debug,PartialEq,Eq)]
pub struct LimitVal {
    Val : u8,
    Max : u8,
    Min : u8,
    //Fix : Fn(u8) -> u8 //This caused wierd issues, ignore for now.
}

impl Add for LimitVal {
    type Output = LimitVal;

    fn add(self, other: LimitVal) -> LimitVal {
        let mut result: LimitVal = LimitVal::new().Min(0).Max(0).Val(0).finalize(); //hack
        result.Val = self.Val + other.Val;
        result.Max = if(self.Max > other.Max){
                        other.Max // choose the smallest one
                    }else{
                        self.Max
                    };
        result.Min = if(self.Min > other.Min){
                        self.Min // choose the biggest one
                    }else{
                        other.Min
                    };
        result
    }
}

impl LimitVal {
    fn new() -> LimitVal {
            LimitVal{Val: 0, Max: 0, Min: 0}
        }
    fn Max(&mut self , val:u8) -> &mut LimitVal{
        self.Max  = val;
        self
    }
    fn Min(&mut self , val:u8) -> &mut LimitVal{
        self.Min  = val;
        self
    }
    fn Val(&mut self , val:u8) -> &mut LimitVal{
        self.Val  = val;
        self
    }
    fn finalize(&self) -> LimitVal{
        LimitVal{Max: self.Max, Min: self.Min, Val: self.Val}
    }

}

#[cfg(test)]
mod tests {
    /*
    Can always put in own file, then would need:
    extern crate adder; (or whatever)
    and then namespace:: the functions.
    */
    use super::*;

    #[test]
    fn test_add() {
        let x: LimitVal = LimitVal::new().Min(10).Max(0).Val(2).finalize();
        let y: LimitVal = LimitVal::new().Min(10).Max(0).Val(3).finalize();

        let z = x + y;
        assert_eq!(z.Val,5);
    }
}
<|endoftext|>


<commit_before>//! # urlshortener
//!
//! An easy library for retrieving short urls.
//!
//! ## Installation
//!
//! Add the following dependency to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! urlshortener = "0.3"
//! ```
//!
//! And add this to your root file:
//!
//! ```no_run
//! extern crate urlshortener;
//! ```
//!
//! ## Usage
//!
//! Creating a short URL via a specified provider is very simple:
//!
//! ```no_run
//! use urlshortener::{Provider, UrlShortener};
//!
//! let us = UrlShortener::new();
//! let short_url = us.generate("https://my-long-url.com", Provider::IsGd);
//! ```
//!
//! Or attempting all URL shorteners until one is successfully generated:
//!
//! ```no_run
//! use urlshortener::{Provider, UrlShortener};
//!
//! let us = UrlShortener::new();
//! let short_url = us.try_generate("https://my-long-url.com");
//! ```

#[macro_use]
extern crate log;
extern crate hyper;

pub mod providers;

pub use providers::{Provider, providers};

use providers::{parse, request};
use hyper::Client;
use std::io::{ErrorKind, Error, Read};
use std::time::Duration;

/// Url shortener - the way to retrieve a short url.
pub struct UrlShortener {
    client: Client,
}

impl UrlShortener {
    /// Creates new `UrlShortener`.
    pub fn new() -> UrlShortener {
        let mut client = hyper::Client::new();
        client.set_read_timeout(Some(Duration::from_secs(3)));

        UrlShortener {
            client: client,
        }
    }

    /// Try to generate a short URL from each provider, iterating over each
    /// provider until a short URL is successfully generated.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use urlshortener::UrlShortener;
    ///
    /// let us = UrlShortener::new();
    /// let long_url = "https://rust-lang.org";
    /// let short_url = us.try_generate(long_url);
    /// ```
    ///
    /// # Errors
    ///
    /// Returns an `Error<ErrorKind::Other>` if there is an error generating a
    /// short URL from all providers.
    pub fn try_generate(&self, url: &str) -> Result<String, Error> {
        let mut providers = providers();

        let x = 0usize;

        loop {
            if providers.len() == 0 {
                break
            }

            // This would normally have the potential to panic, except that a
            // check to ensure there is an element at this index is performed.
            let provider = providers.remove(x);
            let res = self.generate(url, provider);

            if let Ok(s) = res {
                return Ok(s)
            } else {
                warn!("Failed to get short link from service: {}",
                      res.unwrap_err());
            }
        }
        error!("Failed to get short link from any service");
        Err(Error::new(ErrorKind::Other, "Failed to get short link from any service"))
    }

    /// Attempts to get a short URL using the specified provider.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use urlshortener::{Provider, UrlShortener};
    ///
    /// let us = UrlShortener::new();
    /// let long_url = "http://rust-lang.org";
    /// let short_url = us.generate(long_url, Provider::IsGd);
    /// ```
    ///
    /// # Errors
    ///
    /// Returns an `Error<<ErrorKind::Other>` if there is an error generating a
    /// short URL from the given provider due to either:
    ///
    /// a. a decode error;
    /// b. the service being unavailable
    pub fn generate(&self, url: &str, provider: Provider) -> Result<String, Error> {
        let response_opt = request(url, &self.client, provider);

        if let Some(mut response) = response_opt {
            if response.status.is_success() {
                let mut short_url = String::new();
                if try!(response.read_to_string(&mut short_url)) > 0 {
                    if let Some(s) = parse(&short_url, provider) {
                        return Ok(s)
                    } else {
                        return Err(Error::new(ErrorKind::Other, "Decode error"))
                    }
                }
            }
        }
        Err(Error::new(ErrorKind::Other, "Service is unavailable"))
    }
}
<commit_msg>Add tests to test provider usage<commit_after>//! # urlshortener
//!
//! An easy library for retrieving short urls.
//!
//! ## Installation
//!
//! Add the following dependency to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! urlshortener = "0.3"
//! ```
//!
//! And add this to your root file:
//!
//! ```no_run
//! extern crate urlshortener;
//! ```
//!
//! ## Usage
//!
//! Creating a short URL via a specified provider is very simple:
//!
//! ```no_run
//! use urlshortener::{Provider, UrlShortener};
//!
//! let us = UrlShortener::new();
//! let short_url = us.generate("https://my-long-url.com", Provider::IsGd);
//! ```
//!
//! Or attempting all URL shorteners until one is successfully generated:
//!
//! ```no_run
//! use urlshortener::{Provider, UrlShortener};
//!
//! let us = UrlShortener::new();
//! let short_url = us.try_generate("https://my-long-url.com");
//! ```

#[macro_use]
extern crate log;
extern crate hyper;

pub mod providers;

pub use providers::{Provider, providers};

use providers::{parse, request};
use hyper::Client;
use std::io::{ErrorKind, Error, Read};
use std::time::Duration;

/// Url shortener - the way to retrieve a short url.
pub struct UrlShortener {
    client: Client,
}

impl UrlShortener {
    /// Creates new `UrlShortener`.
    pub fn new() -> UrlShortener {
        let mut client = hyper::Client::new();
        client.set_read_timeout(Some(Duration::from_secs(3)));

        UrlShortener {
            client: client,
        }
    }

    /// Try to generate a short URL from each provider, iterating over each
    /// provider until a short URL is successfully generated.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use urlshortener::UrlShortener;
    ///
    /// let us = UrlShortener::new();
    /// let long_url = "https://rust-lang.org";
    /// let short_url = us.try_generate(long_url);
    /// ```
    ///
    /// # Errors
    ///
    /// Returns an `Error<ErrorKind::Other>` if there is an error generating a
    /// short URL from all providers.
    pub fn try_generate(&self, url: &str) -> Result<String, Error> {
        let mut providers = providers();

        let x = 0usize;

        loop {
            if providers.len() == 0 {
                break
            }

            // This would normally have the potential to panic, except that a
            // check to ensure there is an element at this index is performed.
            let provider = providers.remove(x);
            let res = self.generate(url, provider);

            if let Ok(s) = res {
                return Ok(s)
            } else {
                warn!("Failed to get short link from service: {}",
                      res.unwrap_err());
            }
        }
        error!("Failed to get short link from any service");
        Err(Error::new(ErrorKind::Other, "Failed to get short link from any service"))
    }

    /// Attempts to get a short URL using the specified provider.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use urlshortener::{Provider, UrlShortener};
    ///
    /// let us = UrlShortener::new();
    /// let long_url = "http://rust-lang.org";
    /// let short_url = us.generate(long_url, Provider::IsGd);
    /// ```
    ///
    /// # Errors
    ///
    /// Returns an `Error<<ErrorKind::Other>` if there is an error generating a
    /// short URL from the given provider due to either:
    ///
    /// a. a decode error;
    /// b. the service being unavailable
    pub fn generate(&self, url: &str, provider: Provider) -> Result<String, Error> {
        let response_opt = request(url, &self.client, provider);

        if let Some(mut response) = response_opt {
            if response.status.is_success() {
                let mut short_url = String::new();
                if try!(response.read_to_string(&mut short_url)) > 0 {
                    if let Some(s) = parse(&short_url, provider) {
                        return Ok(s)
                    } else {
                        return Err(Error::new(ErrorKind::Other, "Decode error"))
                    }
                }
            }
        }
        Err(Error::new(ErrorKind::Other, "Service is unavailable"))
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn providers() {
        let us = ::UrlShortener::new();
        let url = "https://google.com";

        for provider in ::providers() {
            assert!(us.generate(url, provider).is_ok());
        }
    }
}
<|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;

pub use lua_tables::LuaTable;

pub mod functions_read;
pub mod lua_tables;
pub mod userdata;

mod ffi;
mod functions_write;
mod rust_tables;
mod tuples;
mod values;

/**
 * Main object of the library
 */
pub struct Lua {
    lua: *mut ffi::lua_State,
    must_be_closed: bool,
    inside_callback: bool           // if true, we are inside a callback
}

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

/**
 * Should be implemented by whatever type is pushable on the Lua stack
 */
pub trait Pushable: ::std::any::Any {
    /**
     * Pushes the value on the top of the stack
     * Must return the number of elements pushed
     */
    fn push_to_lua(self, lua: &mut Lua) -> uint {
        self.push_as_userdata(lua)
    }

    /**
     * Pushes the value on the top of the stack as a user data
     * This means that the value will only be readable as itself and not convertible to anything
     * Also, objects pushed as userdata will not be cloned by Lua
     */
    fn push_as_userdata(self, lua: &mut Lua) -> uint {
        userdata::push_userdata(self, lua)
    }

    /**
     * Pushes over another element
     */
    fn push_over<'a>(self, mut over: LoadedVariable<'a>)
        -> (LoadedVariable<'a>, uint)
    {
        let val = self.push_to_lua(over.lua);
        over.size += val;
        (over, val)
    }
}

/**
 * Should be implemented by types that can be read by consomming a LoadedVariable
 */
pub trait ConsumeReadable<'a> {
    /**
     * Returns the LoadedVariable in case of failure
     */
    fn read_from_variable(var: LoadedVariable<'a>) -> Result<Self, LoadedVariable<'a>>;
}

/**
 * Should be implemented by whatever type can be read by copy from the Lua stack
 */
pub trait CopyReadable : Clone + ::std::any::Any {
    /**
     * # Arguments
     *  * `lua` - The Lua object to read from
     *  * `index` - The index on the stack to read from
     */
    fn read_from_lua(lua: &mut Lua, index: i32) -> Option<Self> {
        userdata::read_copy_userdata(lua, index)
    }
}

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

/**
 * Error that can happen when executing Lua code
 */
#[deriving(Show)]
pub enum LuaError {
    /**
     * There was a syntax error when parsing the Lua code
     */
    SyntaxError(String),

    /**
     * There was an error during execution of the Lua code (for example not enough parameters for a function call)
     */
    ExecutionError(String),

    /**
     * The call to `execute` has requested the wrong type of data
     */
    WrongType
}

// 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 ffi::lua_State) -> libc::c_int {
    let err = unsafe { ffi::lua_tostring(lua, -1) };
    fail!("PANIC: unprotected error in call to Lua API ({})\n", err);
}

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 { ffi::lua_newstate(alloc, std::ptr::mut_null()) };
        if lua.is_null() {
            fail!("lua_newstate failed");
        }

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

        Lua { lua: lua, must_be_closed: true, inside_callback: false }
    }

    /**
     * Takes an existing lua_State and build a Lua object from it
     * # Arguments
     *  * close_at_the_end: if true, lua_close will be called on the lua_State on the destructor
     */
    pub unsafe fn from_existing_state<T>(lua: *mut T, close_at_the_end: bool) -> Lua {
        Lua { lua: std::mem::transmute(lua), must_be_closed: close_at_the_end, inside_callback: false }
    }

    /**
     * Opens all standard Lua libraries
     * This is done by calling `luaL_openlibs`
     */
    pub fn openlibs(&mut self) {
        unsafe { ffi::luaL_openlibs(self.lua) }
    }

    /**
     * Executes some Lua code on the context
     */
    pub fn execute<T: CopyReadable>(&mut self, code: &str) -> Result<T, LuaError> {
        let mut f = try!(functions_read::LuaFunction::load(self, code));
        f.call()
    }

    /**
     * Executes some Lua code on the context
     */
    pub fn execute_from_reader<T: CopyReadable, R: std::io::Reader + 'static>(&mut self, code: R) -> Result<T, LuaError> {
        let mut f = try!(functions_read::LuaFunction::load_from_reader(self, code));
        f.call()
    }

    /**
     * Reads the value of a global variable
     */
    pub fn get<'a, I: Str, V: ConsumeReadable<'a>>(&'a mut self, index: I) -> Option<V> {
        unsafe { ffi::lua_getglobal(self.lua, index.as_slice().to_c_str().unwrap()); }
        ConsumeReadable::read_from_variable(LoadedVariable { lua: self, size: 1 }).ok()
    }

    /**
     * Modifies the value of a global variable
     */
    pub fn set<I: Str, V: Pushable>(&mut self, index: I, value: V) {
        value.push_to_lua(self);
        unsafe { ffi::lua_setglobal(self.lua, index.as_slice().to_c_str().unwrap()); }
    }
}

impl Drop for Lua {
    fn drop(&mut self) {
        if self.must_be_closed {
            unsafe { ffi::lua_close(self.lua) }
        }
    }
}

// TODO: this destructor crashes 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 { ffi::lua_pop(self.lua.lua, self.size as libc::c_int) }
    }
}*/

/*impl<'a> LoadedVariable<'a> {
    fn pop_nb(mut self, nb: uint) -> LoadedVariable<'a> {
        assert!(nb <= self.size);
        unsafe { ffi::lua_pop(self.lua.lua, nb as libc::c_int); }
        self.size -= nb;
        self
    }
}*/

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

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

    #[test]
    fn execute() {
        let mut lua = super::Lua::new();

        let val: int = lua.execute("return 5").unwrap();
        assert_eq!(val, 5);
    }

    // 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>crate_id => crate_name<commit_after>#![crate_name = "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;

pub use lua_tables::LuaTable;

pub mod functions_read;
pub mod lua_tables;
pub mod userdata;

mod ffi;
mod functions_write;
mod rust_tables;
mod tuples;
mod values;

/**
 * Main object of the library
 */
pub struct Lua {
    lua: *mut ffi::lua_State,
    must_be_closed: bool,
    inside_callback: bool           // if true, we are inside a callback
}

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

/**
 * Should be implemented by whatever type is pushable on the Lua stack
 */
pub trait Pushable: ::std::any::Any {
    /**
     * Pushes the value on the top of the stack
     * Must return the number of elements pushed
     */
    fn push_to_lua(self, lua: &mut Lua) -> uint {
        self.push_as_userdata(lua)
    }

    /**
     * Pushes the value on the top of the stack as a user data
     * This means that the value will only be readable as itself and not convertible to anything
     * Also, objects pushed as userdata will not be cloned by Lua
     */
    fn push_as_userdata(self, lua: &mut Lua) -> uint {
        userdata::push_userdata(self, lua)
    }

    /**
     * Pushes over another element
     */
    fn push_over<'a>(self, mut over: LoadedVariable<'a>)
        -> (LoadedVariable<'a>, uint)
    {
        let val = self.push_to_lua(over.lua);
        over.size += val;
        (over, val)
    }
}

/**
 * Should be implemented by types that can be read by consomming a LoadedVariable
 */
pub trait ConsumeReadable<'a> {
    /**
     * Returns the LoadedVariable in case of failure
     */
    fn read_from_variable(var: LoadedVariable<'a>) -> Result<Self, LoadedVariable<'a>>;
}

/**
 * Should be implemented by whatever type can be read by copy from the Lua stack
 */
pub trait CopyReadable : Clone + ::std::any::Any {
    /**
     * # Arguments
     *  * `lua` - The Lua object to read from
     *  * `index` - The index on the stack to read from
     */
    fn read_from_lua(lua: &mut Lua, index: i32) -> Option<Self> {
        userdata::read_copy_userdata(lua, index)
    }
}

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

/**
 * Error that can happen when executing Lua code
 */
#[deriving(Show)]
pub enum LuaError {
    /**
     * There was a syntax error when parsing the Lua code
     */
    SyntaxError(String),

    /**
     * There was an error during execution of the Lua code (for example not enough parameters for a function call)
     */
    ExecutionError(String),

    /**
     * The call to `execute` has requested the wrong type of data
     */
    WrongType
}

// 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 ffi::lua_State) -> libc::c_int {
    let err = unsafe { ffi::lua_tostring(lua, -1) };
    fail!("PANIC: unprotected error in call to Lua API ({})\n", err);
}

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 { ffi::lua_newstate(alloc, std::ptr::mut_null()) };
        if lua.is_null() {
            fail!("lua_newstate failed");
        }

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

        Lua { lua: lua, must_be_closed: true, inside_callback: false }
    }

    /**
     * Takes an existing lua_State and build a Lua object from it
     * # Arguments
     *  * close_at_the_end: if true, lua_close will be called on the lua_State on the destructor
     */
    pub unsafe fn from_existing_state<T>(lua: *mut T, close_at_the_end: bool) -> Lua {
        Lua { lua: std::mem::transmute(lua), must_be_closed: close_at_the_end, inside_callback: false }
    }

    /**
     * Opens all standard Lua libraries
     * This is done by calling `luaL_openlibs`
     */
    pub fn openlibs(&mut self) {
        unsafe { ffi::luaL_openlibs(self.lua) }
    }

    /**
     * Executes some Lua code on the context
     */
    pub fn execute<T: CopyReadable>(&mut self, code: &str) -> Result<T, LuaError> {
        let mut f = try!(functions_read::LuaFunction::load(self, code));
        f.call()
    }

    /**
     * Executes some Lua code on the context
     */
    pub fn execute_from_reader<T: CopyReadable, R: std::io::Reader + 'static>(&mut self, code: R) -> Result<T, LuaError> {
        let mut f = try!(functions_read::LuaFunction::load_from_reader(self, code));
        f.call()
    }

    /**
     * Reads the value of a global variable
     */
    pub fn get<'a, I: Str, V: ConsumeReadable<'a>>(&'a mut self, index: I) -> Option<V> {
        unsafe { ffi::lua_getglobal(self.lua, index.as_slice().to_c_str().unwrap()); }
        ConsumeReadable::read_from_variable(LoadedVariable { lua: self, size: 1 }).ok()
    }

    /**
     * Modifies the value of a global variable
     */
    pub fn set<I: Str, V: Pushable>(&mut self, index: I, value: V) {
        value.push_to_lua(self);
        unsafe { ffi::lua_setglobal(self.lua, index.as_slice().to_c_str().unwrap()); }
    }
}

impl Drop for Lua {
    fn drop(&mut self) {
        if self.must_be_closed {
            unsafe { ffi::lua_close(self.lua) }
        }
    }
}

// TODO: this destructor crashes 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 { ffi::lua_pop(self.lua.lua, self.size as libc::c_int) }
    }
}*/

/*impl<'a> LoadedVariable<'a> {
    fn pop_nb(mut self, nb: uint) -> LoadedVariable<'a> {
        assert!(nb <= self.size);
        unsafe { ffi::lua_pop(self.lua.lua, nb as libc::c_int); }
        self.size -= nb;
        self
    }
}*/

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

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

    #[test]
    fn execute() {
        let mut lua = super::Lua::new();

        let val: int = lua.execute("return 5").unwrap();
        assert_eq!(val, 5);
    }

    // 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>#![feature(core, rustc_private, plugin_registrar)]

extern crate rustc;
extern crate syntax;

use rustc::plugin::registry::Registry;
use syntax::ptr::P;
use syntax::ext::base;
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::codemap::Span;
use syntax::ast;
use syntax::ast::Visibility;
use syntax::ast::ItemStatic;
use syntax::ast::Sign::Plus;
use syntax::ast::Mutability::MutImmutable;
use syntax::ast::Lit_::{LitChar, LitInt, LitStr};
use syntax::ast::Ty_::TyFixedLengthVec;
use syntax::ast::LitIntType::UnsuffixedIntLit;
use syntax::parse::token;

/// Construct a `ast::Ty_::TyPath` corresponding to `path`
fn make_ty_path<'cx>(cx: &'cx mut ExtCtxt, sp: Span, path: Vec<&str>) -> P<ast::Ty> {
    let path = path.iter().map(|p| { cx.ident_of(p) }).collect::<Vec<_>>();
    cx.ty_path(cx.path(sp, path))
}

/// Generate an `ast::Expr` for `'a' as libc::c_char`
fn make_char_cast<'cx>(cx: &'cx mut ExtCtxt, sp: Span, c: char) -> P<ast::Expr> {
    let path = make_ty_path(cx, sp, vec!["libc", "c_char"]);
    cx.expr_cast(sp, cx.expr_lit(sp, LitChar(c)), path)
}

/// Ensure `expr` is a string literal, and return either Some(&str) or None.
fn extract_literal<'cx, 'a>(cx: &'cx mut ExtCtxt, expr: &'a P<ast::Expr>) -> Option<&'a str> {
    if let ast::ExprLit(ref lit) = expr.node {
        if let ast::LitStr(ref s, _) = lit.node {
            Some(s.get())
        } else {
            cx.span_err(expr.span, "expected a string literal");
            None
        }
    } else {
        cx.span_err(expr.span, "expected a string literal");
        None
    }
}

/// Construct an attribute #[foo]
fn make_attr_word<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: &str) -> ast::Attribute {
    cx.attribute(sp, cx.meta_word(sp, token::intern_and_get_ident(name)))
}

/// Construct an attribute #[foo(bar)] or #[baz(biff, quux, ...)]
fn make_attr_list<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: &str, list: Vec<&str>) -> ast::Attribute {
   let words = list.iter().map(|w| { cx.meta_word(sp, token::intern_and_get_ident(w)) }).collect::<Vec<_>>();
   cx.attribute(sp, cx.meta_list(sp, token::intern_and_get_ident(name), words))
}

/// Expansion for `declare_static_raw_cstr!`
/// `declare_static_raw_cstr!("foo", "hello")` -> `static foo: [libc::c_char; 6] = ['h' as libc::c_char, ..., 0 as libc::c_char];`
fn expand_declare_static_raw_cstr<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                     -> Box<base::MacResult + 'cx> {
    let exprs = match base::get_exprs_from_tts(cx, sp, tts) {
        Some(e) => e,
        None => return base::DummyResult::expr(sp)
    };

    let mut it = exprs.iter();
    let e_name = if let Some(expr) = it.next() {
        extract_literal(cx, expr)
    } else {
        cx.span_err(sp, "expected 2 arguments, found 0");
        None
    };
    let e_lit = if let Some(expr) = it.next() {
        extract_literal(cx, expr)
    } else {
        cx.span_err(sp, "expected 2 arguments, found 1");
        None
    };

    match (e_name, e_lit, it.count()) {
        // name, literal, and no other arguments remaining
        (Some(name), Some(s), 0) => {
            // append null terminator to make it a cstring
            let lit = format!("{}\0", s);

            // build RHS of the statement
            let rhs = lit.as_slice().chars().map(|c| { make_char_cast(cx, sp, c) }).collect::<Vec<_>>();
            let rhs = cx.expr_vec(sp, rhs);

            // the type of the item is a fixed length vector of libc::c_char
            let path = make_ty_path(cx, sp, vec!["libc", "c_char"]);
            let ty = cx.ty(sp, TyFixedLengthVec(path, cx.expr_lit(sp, LitInt(lit.len() as u64, UnsuffixedIntLit(Plus)))));

            // #[no_mangle] #[allow(dead_code, non_upper_case_globals)]
            let attrs = vec![
                make_attr_word(cx, sp, "no_mangle"),
                make_attr_list(cx, sp, "allow", vec!["dead_code", "non_upper_case_globals"])
            ];

            // XXX: have to manually construct the item here because we can't set the visibility otherwise.
            let item = P(ast::Item {
                ident: cx.ident_of(name),
                attrs: attrs,
                id: ast::DUMMY_NODE_ID,
                node: ast::ItemStatic(ty, MutImmutable, rhs),
                vis: Visibility::Public,
                span: sp
            });
            base::MacItems::new(vec![item].into_iter())
        }
        (_, _, rest) => {
            if rest > 0 {
                cx.span_err(sp, format!("expected 2 arguments, found {}", rest + 2).as_slice());
            }
            base::DummyResult::expr(sp)
        }
    }
}

/// Declare a `pub static [libc::c_char; N]`, where N is the length of the supplied string, plus 1.
/// The resulting item is a raw, null-terminated C string that becomes exported as an unmangled
/// symbol for use in dynamic libraries.
///
/// `export_cstr!(foo, "hello")` expands to:
///
/// `#[no_mangle] #[allow(dead_code, non_upper_case_globals)]
/// pub static foo: [libc::c_char; 6] = ['h' as libc::c_char, ..., 0 as libc::c_char];`
#[macro_export]
macro_rules! export_cstr {
    ($name:ident, $lit:expr) => (
        declare_static_raw_cstr!(stringify!($name), $lit);
    );
}

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

<commit_msg>Use i8 instead of libc::c_char to simplify crate usage<commit_after>#![feature(core, rustc_private, plugin_registrar)]

extern crate rustc;
extern crate syntax;

use rustc::plugin::registry::Registry;
use syntax::ptr::P;
use syntax::ext::base;
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::codemap::Span;
use syntax::ast;
use syntax::ast::Visibility;
use syntax::ast::ItemStatic;
use syntax::ast::Sign::Plus;
use syntax::ast::Mutability::MutImmutable;
use syntax::ast::Lit_::{LitChar, LitInt, LitStr};
use syntax::ast::Ty_::TyFixedLengthVec;
use syntax::ast::LitIntType::UnsuffixedIntLit;
use syntax::parse::token;

/// Generate an `ast::Expr` for `'a' as i8`
fn make_char_cast<'cx>(cx: &'cx mut ExtCtxt, sp: Span, c: char) -> P<ast::Expr> {
    let path = cx.ty_path(cx.path_ident(sp, cx.ident_of("i8")));
    cx.expr_cast(sp, cx.expr_lit(sp, LitChar(c)), path)
}

/// Ensure `expr` is a string literal, and return either Some(&str) or None.
fn extract_literal<'cx, 'a>(cx: &'cx mut ExtCtxt, expr: &'a P<ast::Expr>) -> Option<&'a str> {
    if let ast::ExprLit(ref lit) = expr.node {
        if let ast::LitStr(ref s, _) = lit.node {
            Some(s.get())
        } else {
            cx.span_err(expr.span, "expected a string literal");
            None
        }
    } else {
        cx.span_err(expr.span, "expected a string literal");
        None
    }
}

/// Construct an attribute #[foo]
fn make_attr_word<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: &str) -> ast::Attribute {
    cx.attribute(sp, cx.meta_word(sp, token::intern_and_get_ident(name)))
}

/// Construct an attribute #[foo(bar)] or #[baz(biff, quux, ...)]
fn make_attr_list<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: &str, list: Vec<&str>) -> ast::Attribute {
   let words = list.iter().map(|w| { cx.meta_word(sp, token::intern_and_get_ident(w)) }).collect::<Vec<_>>();
   cx.attribute(sp, cx.meta_list(sp, token::intern_and_get_ident(name), words))
}

/// Expansion for `declare_static_raw_cstr!`
/// `declare_static_raw_cstr!("foo", "hello")` expands to:
///
/// `#[no_mangle] #[allow(dead_code, non_upper_case_globals)]
/// pub static foo: [i8; 6] = ['h' as i8, 'e' as i8, ..., 0 as i8];`
fn expand_declare_static_raw_cstr<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                     -> Box<base::MacResult + 'cx> {
    let exprs = match base::get_exprs_from_tts(cx, sp, tts) {
        Some(e) => e,
        None => return base::DummyResult::expr(sp)
    };

    let mut it = exprs.iter();
    let e_name = if let Some(expr) = it.next() {
        extract_literal(cx, expr)
    } else {
        cx.span_err(sp, "expected 2 arguments, found 0");
        None
    };
    let e_lit = if let Some(expr) = it.next() {
        extract_literal(cx, expr)
    } else {
        cx.span_err(sp, "expected 2 arguments, found 1");
        None
    };

    match (e_name, e_lit, it.count()) {
        // name, literal, and no other arguments remaining
        (Some(name), Some(s), 0) => {
            // append null terminator to make it a cstring
            let lit = format!("{}\0", s);

            // build RHS of the statement
            let rhs = lit.as_slice().chars().map(|c| { make_char_cast(cx, sp, c) }).collect::<Vec<_>>();
            let rhs = cx.expr_vec(sp, rhs);

            // the type of the item is a fixed length vector of i8
            let path = cx.ty_path(cx.path_ident(sp, cx.ident_of("i8")));
            let ty = cx.ty(sp, TyFixedLengthVec(path, cx.expr_lit(sp, LitInt(lit.len() as u64, UnsuffixedIntLit(Plus)))));

            // #[no_mangle] #[allow(dead_code, non_upper_case_globals)]
            let attrs = vec![
                make_attr_word(cx, sp, "no_mangle"),
                make_attr_list(cx, sp, "allow", vec!["dead_code", "non_upper_case_globals"])
            ];

            // XXX: have to manually construct the item here because we can't set the visibility otherwise.
            let item = P(ast::Item {
                ident: cx.ident_of(name),
                attrs: attrs,
                id: ast::DUMMY_NODE_ID,
                node: ast::ItemStatic(ty, MutImmutable, rhs),
                vis: Visibility::Public,
                span: sp
            });
            base::MacItems::new(vec![item].into_iter())
        }
        (_, _, rest) => {
            if rest > 0 {
                cx.span_err(sp, format!("expected 2 arguments, found {}", rest + 2).as_slice());
            }
            base::DummyResult::expr(sp)
        }
    }
}

/// Declare a `pub static [i8; N]`, where N is the length of the supplied string, plus 1.
/// The resulting item is a raw, null-terminated C string that becomes exported as an unmangled
/// symbol for use in dynamic libraries.
///
/// `export_cstr!(foo, "hello")` expands to:
///
/// `#[no_mangle] #[allow(dead_code, non_upper_case_globals)]
/// pub static foo: [i8; 6] = ['h' as i8, 'e' as i8', ..., 0 as i8];`
#[macro_export]
macro_rules! export_cstr {
    ($name:ident, $lit:expr) => (
        declare_static_raw_cstr!(stringify!($name), $lit);
    );
}

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

<|endoftext|>


<commit_before>#![crate_type="lib"]
#[macro_use]
extern crate log;
extern crate env_logger;

extern crate base;
extern crate vm;
extern crate parser;
extern crate check;
<commit_msg>Reexport the sub-crates in the embed_lang crate<commit_after>#![crate_type="lib"]
#[macro_use]
extern crate log;
extern crate env_logger;

mod crates {
    extern crate base;
    extern crate parser;
    extern crate check;
    extern crate vm;
}

pub use crates::base;
pub use crates::parser;
pub use crates::check;
pub use crates::vm;
<|endoftext|>


<commit_before>#![feature(libc)]
#![feature(std_misc)]

extern crate libc;

use libc::c_void;
use std::ffi::CString;
use std::ptr;

pub mod ffi;
pub use ffi::{IPaddress, _TCPsocket, _SDLNet_SocketSet, _SDLNet_GenericSocket};

pub struct TCPsocket {
    opaque_ptr: *const _TCPsocket,
}
pub struct SocketSet {
    opaque_ptr: *const _SDLNet_SocketSet,
}
#[repr(C)]
pub struct CustTCPSocket {
    ready: i32,
}

pub static EMPTY_SOCKET_SET: SocketSet = SocketSet {opaque_ptr: 0 as *const _SDLNet_SocketSet};
pub static EMPTY_TCPSOCKET: TCPsocket = TCPsocket {opaque_ptr: 0 as *const _TCPsocket};

pub fn init() -> bool { unsafe { ffi::SDLNet_Init() == 0 } }
pub fn quit() -> () { unsafe { ffi::SDLNet_Quit(); } }
pub fn get_error() -> String {
    unsafe {
        let raw = &ffi::SDLNet_GetError();
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

// Returns an IPaddress struct if successful in becoming a host on the given port
pub fn become_host(port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0};
    let result = unsafe { ffi::SDLNet_ResolveHost(&mut address, ptr::null() , port) };
    if result == 0 {
        Some(address)
    } else {
        None
    }
}

// Resolves the host from the given IP and port
pub fn resolve_host(host: &str, port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0 };
    let result = unsafe { ffi::SDLNet_ResolveHost(&mut address, CString::from_slice(host.as_bytes()).as_ptr(), port) };
    if result == 0 {
        Some(address)
    } else {
        None
    }
}

// Resolves the given IP from the given IPaddress struct
pub fn resolve_ip(mut address: IPaddress) -> String {
    unsafe {
        let raw = &ffi::SDLNet_ResolveIP(&mut address);
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

// Returns a TCPsocket from the data given in the IPaddress object
pub fn tcp_open(address: &mut IPaddress) -> Option<TCPsocket> {
    unsafe {
        let socket = ffi::SDLNet_TCP_Open(address);
        if socket as *const _TCPsocket != ptr::null() {
            Some(TCPsocket { opaque_ptr: socket })
        } else {
            None
        }
    }
}

// Closes the given TCPsocket
pub fn tcp_close(sock: &TCPsocket) -> () {
    unsafe {
        ffi::SDLNet_TCP_Close(sock.opaque_ptr)
    }
}

// Accepts a TCP connection on the given socket, returning the new socket of the connection
pub fn tcp_accept(server: &TCPsocket) -> Option<TCPsocket> {
    unsafe {
        let socket =  ffi::SDLNet_TCP_Accept(server.opaque_ptr);
        if socket as *const _TCPsocket != ptr::null() {
            Some(TCPsocket { opaque_ptr: socket})
        } else {
            None
        }
    }
}

pub fn tcp_get_peer_address(sock: &TCPsocket) -> Option<IPaddress> {
    unsafe {
        let possible_addr = ffi::SDLNet_TCP_GetPeerAddress(sock.opaque_ptr);
        if possible_addr as *const IPaddress == ptr::null() {
            None
        } else {
            Some(ptr::read(possible_addr))
        }
    }
}

// Writes the data out
pub fn tcp_send(sock: &TCPsocket, data: &mut [u8]) -> i32 {
    unsafe {
        ffi::SDLNet_TCP_Send(sock.opaque_ptr, &data[0] as *const u8 as *const c_void, data.len() as i32)
    }
}

// Receives incoming data
pub fn tcp_recv(sock: &TCPsocket, data: &mut [u8]) -> i32 {
    unsafe {
        ffi::SDLNet_TCP_Recv(sock.opaque_ptr, &mut data[0] as *mut u8 as *mut c_void, data.len() as i32)
    }
}

// Allocates a socket set to hold the given number of sockets
pub fn alloc_socket_set(maxsockets: i32) -> SocketSet {
    unsafe {
        SocketSet { opaque_ptr: ffi::SDLNet_AllocSocketSet(maxsockets) }
    }
}

// Frees the given socket set
pub fn free_socket_set(set: &SocketSet) -> () {
    unsafe {
        ffi::SDLNet_FreeSocketSet(set.opaque_ptr);
    }
}

// Adds a given socket to the given socket set
pub fn add_socket(set: &SocketSet, sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_AddSocket(set.opaque_ptr, sock.opaque_ptr)
    }
}

// Maybe should take in the box here as it may get deleted.... not sure
pub fn del_socket(set: &SocketSet, sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_DelSocket(set.opaque_ptr, sock.opaque_ptr)
    }
}

// Returns the incoming data amount  on the given socketset
pub fn check_sockets(set: &SocketSet, timeout: u32) -> i32 {
    unsafe {
        ffi::SDLNet_CheckSockets(set.opaque_ptr, timeout)
    }
}

pub fn socket_ready(sock: &TCPsocket) -> bool {
    unsafe {
        (std::mem::transmute::<*const ffi::_TCPsocket,&CustTCPSocket>(sock.opaque_ptr)).ready != 0
    }
}
<commit_msg>Make the opaque_ptrs public.<commit_after>#![feature(libc)]
#![feature(std_misc)]

extern crate libc;

use libc::c_void;
use std::ffi::CString;
use std::ptr;

pub mod ffi;
pub use ffi::{IPaddress, _TCPsocket, _SDLNet_SocketSet, _SDLNet_GenericSocket};

pub struct TCPsocket {
    pub opaque_ptr: *const _TCPsocket,
}
pub struct SocketSet {
    pub opaque_ptr: *const _SDLNet_SocketSet,
}
#[repr(C)]
pub struct CustTCPSocket {
    ready: i32,
}

//pub static EMPTY_SOCKET_SET: SocketSet = SocketSet {opaque_ptr: 0 as *const _SDLNet_SocketSet};
//pub static EMPTY_TCPSOCKET: TCPsocket = TCPsocket {opaque_ptr: 0 as *const _TCPsocket};

pub fn init() -> bool { unsafe { ffi::SDLNet_Init() == 0 } }
pub fn quit() -> () { unsafe { ffi::SDLNet_Quit(); } }
pub fn get_error() -> String {
    unsafe {
        let raw = &ffi::SDLNet_GetError();
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

// Returns an IPaddress struct if successful in becoming a host on the given port
pub fn become_host(port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0};
    let result = unsafe { ffi::SDLNet_ResolveHost(&mut address, ptr::null() , port) };
    if result == 0 {
        Some(address)
    } else {
        None
    }
}

// Resolves the host from the given IP and port
pub fn resolve_host(host: &str, port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0 };
    let result = unsafe { ffi::SDLNet_ResolveHost(&mut address, CString::from_slice(host.as_bytes()).as_ptr(), port) };
    if result == 0 {
        Some(address)
    } else {
        None
    }
}

// Resolves the given IP from the given IPaddress struct
pub fn resolve_ip(mut address: IPaddress) -> String {
    unsafe {
        let raw = &ffi::SDLNet_ResolveIP(&mut address);
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

// Returns a TCPsocket from the data given in the IPaddress object
pub fn tcp_open(address: &mut IPaddress) -> Option<TCPsocket> {
    unsafe {
        let socket = ffi::SDLNet_TCP_Open(address);
        if socket as *const _TCPsocket != ptr::null() {
            Some(TCPsocket { opaque_ptr: socket })
        } else {
            None
        }
    }
}

// Closes the given TCPsocket
pub fn tcp_close(sock: &TCPsocket) -> () {
    unsafe {
        ffi::SDLNet_TCP_Close(sock.opaque_ptr)
    }
}

// Accepts a TCP connection on the given socket, returning the new socket of the connection
pub fn tcp_accept(server: &TCPsocket) -> Option<TCPsocket> {
    unsafe {
        let socket =  ffi::SDLNet_TCP_Accept(server.opaque_ptr);
        if socket as *const _TCPsocket != ptr::null() {
            Some(TCPsocket { opaque_ptr: socket})
        } else {
            None
        }
    }
}

pub fn tcp_get_peer_address(sock: &TCPsocket) -> Option<IPaddress> {
    unsafe {
        let possible_addr = ffi::SDLNet_TCP_GetPeerAddress(sock.opaque_ptr);
        if possible_addr as *const IPaddress == ptr::null() {
            None
        } else {
            Some(ptr::read(possible_addr))
        }
    }
}

// Writes the data out
pub fn tcp_send(sock: &TCPsocket, data: &mut [u8]) -> i32 {
    unsafe {
        ffi::SDLNet_TCP_Send(sock.opaque_ptr, &data[0] as *const u8 as *const c_void, data.len() as i32)
    }
}

// Receives incoming data
pub fn tcp_recv(sock: &TCPsocket, data: &mut [u8]) -> i32 {
    unsafe {
        ffi::SDLNet_TCP_Recv(sock.opaque_ptr, &mut data[0] as *mut u8 as *mut c_void, data.len() as i32)
    }
}

// Allocates a socket set to hold the given number of sockets
pub fn alloc_socket_set(maxsockets: i32) -> SocketSet {
    unsafe {
        SocketSet { opaque_ptr: ffi::SDLNet_AllocSocketSet(maxsockets) }
    }
}

// Frees the given socket set
pub fn free_socket_set(set: &SocketSet) -> () {
    unsafe {
        ffi::SDLNet_FreeSocketSet(set.opaque_ptr);
    }
}

// Adds a given socket to the given socket set
pub fn add_socket(set: &SocketSet, sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_AddSocket(set.opaque_ptr, sock.opaque_ptr)
    }
}

// Maybe should take in the box here as it may get deleted.... not sure
pub fn del_socket(set: &SocketSet, sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_DelSocket(set.opaque_ptr, sock.opaque_ptr)
    }
}

// Returns the incoming data amount  on the given socketset
pub fn check_sockets(set: &SocketSet, timeout: u32) -> i32 {
    unsafe {
        ffi::SDLNet_CheckSockets(set.opaque_ptr, timeout)
    }
}

pub fn socket_ready(sock: &TCPsocket) -> bool {
    unsafe {
        (std::mem::transmute::<*const ffi::_TCPsocket,&CustTCPSocket>(sock.opaque_ptr)).ready != 0
    }
}
<|endoftext|>


<commit_before>//! This crate implements the backend server for https://crates.io/
//!
//! All implemented routes are defined in the [middleware](fn.middleware.html) function and
//! implemented in the [keyword](keyword/index.html), [krate](krate/index.html),
//! [user](user/index.html) and [version](version/index.html) modules.
//#![deny(warnings)]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![recursion_limit="128"]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate ammonia;
extern crate chrono;
extern crate comrak;
extern crate curl;
extern crate diesel_full_text_search;
extern crate dotenv;
extern crate flate2;
extern crate git2;
extern crate hex;
extern crate license_exprs;
extern crate oauth2;
extern crate openssl;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate rand;
extern crate s3;
extern crate semver;
extern crate serde;
extern crate tar;
extern crate time;
extern crate toml;
extern crate url;
extern crate lettre;
extern crate env_logger;

extern crate conduit;
extern crate conduit_conditional_get;
extern crate conduit_cookie;
extern crate cookie;
extern crate conduit_git_http_backend;
extern crate conduit_log_requests;
extern crate conduit_middleware;
extern crate conduit_router;
extern crate conduit_static;

pub use app::App;
pub use self::badge::Badge;
pub use self::category::Category;
pub use config::Config;
pub use self::dependency::Dependency;
pub use self::download::VersionDownload;
pub use self::keyword::Keyword;
pub use self::krate::Crate;
pub use self::user::User;
pub use self::version::Version;
pub use self::uploaders::{Uploader, Bomb};

use std::sync::Arc;
use std::error::Error;

use conduit_router::RouteBuilder;
use conduit_middleware::MiddlewareBuilder;

use util::{C, R, R404};

pub mod app;
pub mod badge;
pub mod categories;
pub mod category;
pub mod config;
pub mod crate_owner_invitation;
pub mod db;
pub mod dependency;
pub mod dist;
pub mod download;
pub mod git;
pub mod http;
pub mod keyword;
pub mod krate;
pub mod owner;
pub mod render;
pub mod schema;
pub mod token;
pub mod upload;
pub mod uploaders;
pub mod user;
pub mod util;
pub mod version;

mod local_upload;
mod pagination;

/// Used for setting different values depending on whether the app is being run in production,
/// in development, or for testing.
///
/// The app's `config.env` value is set in *src/bin/server.rs* to `Production` if the environment
/// variable `HEROKU` is set and `Development` otherwise. `config.env` is set to `Test`
/// unconditionally in *src/test/all.rs*.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Env {
    Development,
    Test,
    Production,
}

/// Used for setting different values depending on the type of registry this instance is.
///
/// `Primary` indicates this instance is a primary registry that is the source of truth for these
/// crates' information. `ReadOnlyMirror` indicates this instanceis a read-only mirror of crate
/// information that exists on another instance.
///
/// The app's `config.mirror` value is set in *src/bin/server.rs* to `ReadOnlyMirror` if the
/// `MIRROR` environment variable is set and to `Primary` otherwise.
///
/// There may be more ways to run crates.io servers in the future, such as a
/// mirror that also has private crates that crates.io does not have.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Replica {
    Primary,
    ReadOnlyMirror,
}

/// Configures routes, sessions, logging, and other middleware.
///
/// Called from *src/bin/server.rs*.
pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
    let mut api_router = RouteBuilder::new();

    api_router.get("/crates", C(krate::index));
    api_router.get("/crates/:crate_id", C(krate::show));
    api_router.put("/crates/new", C(krate::new));
    api_router.get("/crates/:crate_id/:version", C(version::show));
    api_router.get("/crates/:crate_id/:version/download", C(krate::download));
    api_router.get("/crates/:crate_id/:version/readme", C(krate::readme));
    api_router.get(
        "/crates/:crate_id/:version/dependencies",
        C(version::dependencies),
    );
    api_router.get(
        "/crates/:crate_id/:version/downloads",
        C(version::downloads),
    );
    api_router.get("/crates/:crate_id/:version/authors", C(version::authors));
    // Used to generate download graphs
    api_router.get("/crates/:crate_id/downloads", C(krate::downloads));
    api_router.get("/crates/:crate_id/versions", C(krate::versions));
    api_router.put("/crates/:crate_id/follow", C(krate::follow));
    api_router.delete("/crates/:crate_id/follow", C(krate::unfollow));
    api_router.get("/crates/:crate_id/following", C(krate::following));
    // This endpoint may now be redundant, check frontend to see if it is
    // being used
    api_router.get("/crates/:crate_id/owners", C(krate::owners));
    api_router.get("/crates/:crate_id/owner_team", C(krate::owner_team));
    api_router.get("/crates/:crate_id/owner_user", C(krate::owner_user));
    api_router.put("/crates/:crate_id/owners", C(krate::add_owners));
    api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
    api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
    api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
    api_router.get(
        "/crates/:crate_id/reverse_dependencies",
        C(krate::reverse_dependencies),
    );
    api_router.get("/versions", C(version::index));
    api_router.get("/versions/:version_id", C(version::show));
    api_router.get("/keywords", C(keyword::index));
    api_router.get("/keywords/:keyword_id", C(keyword::show));
    api_router.get("/categories", C(category::index));
    api_router.get("/categories/:category_id", C(category::show));
    api_router.get("/category_slugs", C(category::slugs));
    api_router.get("/users/:user_id", C(user::show));
    api_router.put("/users/:user_id", C(user::update_user));
    api_router.get("/users/:user_id/stats", C(user::stats));
    api_router.get("/teams/:team_id", C(user::show_team));
    api_router.get("/me", C(user::me));
    api_router.get("/me/updates", C(user::updates));
    api_router.get("/me/tokens", C(token::list));
    api_router.post("/me/tokens", C(token::new));
    api_router.delete("/me/tokens/:id", C(token::revoke));
    api_router.get(
        "/me/crate_owner_invitations",
        C(crate_owner_invitation::list),
    );
    api_router.get("/summary", C(krate::summary));
    api_router.put("/confirm/:email_token", C(user::confirm_user_email));
    api_router.put("/users/:user_id/resend", C(user::regenerate_token_and_send));
    let api_router = Arc::new(R404(api_router));

    let mut router = RouteBuilder::new();

    // Mount the router under the /api/v1 path so we're at least somewhat at the
    // liberty to change things in the future!
    router.get("/api/v1/*path", R(api_router.clone()));
    router.put("/api/v1/*path", R(api_router.clone()));
    router.post("/api/v1/*path", R(api_router.clone()));
    router.head("/api/v1/*path", R(api_router.clone()));
    router.delete("/api/v1/*path", R(api_router));

    router.get("/authorize_url", C(user::github_authorize));
    router.get("/authorize", C(user::github_access_token));
    router.delete("/logout", C(user::logout));

    // Only serve the local checkout of the git index in development mode.
    // In production, for crates.io, cargo gets the index from
    // https://github.com/rust-lang/crates.io-index directly.
    let env = app.config.env;
    if env == Env::Development {
        let s = conduit_git_http_backend::Serve(app.git_repo_checkout.clone());
        let s = Arc::new(s);
        router.get("/git/index/*path", R(s.clone()));
        router.post("/git/index/*path", R(s));
    }

    let mut m = MiddlewareBuilder::new(R404(router));

    if env == Env::Development {
        // DebugMiddleware is defined below to print logs for each request.
        m.add(DebugMiddleware);
        m.around(local_upload::Middleware::default());
    }

    if env != Env::Test {
        m.add(conduit_log_requests::LogRequests(log::LogLevel::Info));
    }

    m.around(util::Head::default());
    m.add(conduit_conditional_get::ConditionalGet);
    m.add(conduit_cookie::Middleware::new());
    m.add(conduit_cookie::SessionMiddleware::new(
        "cargo_session",
        cookie::Key::from_master(app.session_key.as_bytes()),
        env == Env::Production,
    ));
    if env == Env::Production {
        m.add(http::SecurityHeadersMiddleware::new(&app.config.uploader));
    }
    m.add(app::AppMiddleware::new(app));

    // Sets the current user on each request.
    m.add(user::Middleware);

    // Serve the static files in the *dist* directory, which are the frontend assets.
    // Not needed for the backend tests.
    if env != Env::Test {
        m.around(dist::Middleware::default());
    }

    return m;

    struct DebugMiddleware;

    impl conduit_middleware::Middleware for DebugMiddleware {
        fn before(&self, req: &mut conduit::Request) -> Result<(), Box<Error + Send>> {
            println!("  version: {}", req.http_version());
            println!("  method: {:?}", req.method());
            println!("  scheme: {:?}", req.scheme());
            println!("  host: {:?}", req.host());
            println!("  path: {}", req.path());
            println!("  query_string: {:?}", req.query_string());
            println!("  remote_addr: {:?}", req.remote_addr());
            for &(k, ref v) in &req.headers().all() {
                println!("  hdr: {}={:?}", k, v);
            }
            Ok(())
        }
        fn after(
            &self,
            _req: &mut conduit::Request,
            res: Result<conduit::Response, Box<Error + Send>>,
        ) -> Result<conduit::Response, Box<Error + Send>> {
            res.map(|res| {
                println!("  <- {:?}", res.status);
                for (k, v) in &res.headers {
                    println!("  <- {} {:?}", k, v);
                }
                res
            })
        }
    }
}

/// Convenience function for getting the current server time in UTC.
pub fn now() -> time::Timespec {
    time::now_utc().to_timespec()
}

/// Convenience function for getting a time in RFC 3339 format.
///
/// Example: `2012-02-22T14:53:18Z`. Used for returning time values in JSON API responses.
pub fn encode_time(ts: time::Timespec) -> String {
    time::at_utc(ts).rfc3339().to_string()
}

/// Convenience function requiring that an environment variable is set.
///
/// Ensures that we've initialized the dotenv crate in order to read environment variables
/// from a *.env* file if present. Don't use this for optionally set environment variables.
///
/// # Panics
///
/// Panics if the environment variable with the name passed in as an argument is not defined
/// in the current environment.
pub fn env(s: &str) -> String {
    dotenv::dotenv().ok();
    ::std::env::var(s).unwrap_or_else(|_| panic!("must have `{}` defined", s))
}

sql_function!(lower, lower_t, (x: ::diesel::types::Text) -> ::diesel::types::Text);
<commit_msg>add back warnings as errors<commit_after>//! This crate implements the backend server for https://crates.io/
//!
//! All implemented routes are defined in the [middleware](fn.middleware.html) function and
//! implemented in the [keyword](keyword/index.html), [krate](krate/index.html),
//! [user](user/index.html) and [version](version/index.html) modules.
#![deny(warnings)]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![recursion_limit="128"]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate ammonia;
extern crate chrono;
extern crate comrak;
extern crate curl;
extern crate diesel_full_text_search;
extern crate dotenv;
extern crate flate2;
extern crate git2;
extern crate hex;
extern crate license_exprs;
extern crate oauth2;
extern crate openssl;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate rand;
extern crate s3;
extern crate semver;
extern crate serde;
extern crate tar;
extern crate time;
extern crate toml;
extern crate url;
extern crate lettre;
extern crate env_logger;

extern crate conduit;
extern crate conduit_conditional_get;
extern crate conduit_cookie;
extern crate cookie;
extern crate conduit_git_http_backend;
extern crate conduit_log_requests;
extern crate conduit_middleware;
extern crate conduit_router;
extern crate conduit_static;

pub use app::App;
pub use self::badge::Badge;
pub use self::category::Category;
pub use config::Config;
pub use self::dependency::Dependency;
pub use self::download::VersionDownload;
pub use self::keyword::Keyword;
pub use self::krate::Crate;
pub use self::user::User;
pub use self::version::Version;
pub use self::uploaders::{Uploader, Bomb};

use std::sync::Arc;
use std::error::Error;

use conduit_router::RouteBuilder;
use conduit_middleware::MiddlewareBuilder;

use util::{C, R, R404};

pub mod app;
pub mod badge;
pub mod categories;
pub mod category;
pub mod config;
pub mod crate_owner_invitation;
pub mod db;
pub mod dependency;
pub mod dist;
pub mod download;
pub mod git;
pub mod http;
pub mod keyword;
pub mod krate;
pub mod owner;
pub mod render;
pub mod schema;
pub mod token;
pub mod upload;
pub mod uploaders;
pub mod user;
pub mod util;
pub mod version;

mod local_upload;
mod pagination;

/// Used for setting different values depending on whether the app is being run in production,
/// in development, or for testing.
///
/// The app's `config.env` value is set in *src/bin/server.rs* to `Production` if the environment
/// variable `HEROKU` is set and `Development` otherwise. `config.env` is set to `Test`
/// unconditionally in *src/test/all.rs*.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Env {
    Development,
    Test,
    Production,
}

/// Used for setting different values depending on the type of registry this instance is.
///
/// `Primary` indicates this instance is a primary registry that is the source of truth for these
/// crates' information. `ReadOnlyMirror` indicates this instanceis a read-only mirror of crate
/// information that exists on another instance.
///
/// The app's `config.mirror` value is set in *src/bin/server.rs* to `ReadOnlyMirror` if the
/// `MIRROR` environment variable is set and to `Primary` otherwise.
///
/// There may be more ways to run crates.io servers in the future, such as a
/// mirror that also has private crates that crates.io does not have.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Replica {
    Primary,
    ReadOnlyMirror,
}

/// Configures routes, sessions, logging, and other middleware.
///
/// Called from *src/bin/server.rs*.
pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
    let mut api_router = RouteBuilder::new();

    api_router.get("/crates", C(krate::index));
    api_router.get("/crates/:crate_id", C(krate::show));
    api_router.put("/crates/new", C(krate::new));
    api_router.get("/crates/:crate_id/:version", C(version::show));
    api_router.get("/crates/:crate_id/:version/download", C(krate::download));
    api_router.get("/crates/:crate_id/:version/readme", C(krate::readme));
    api_router.get(
        "/crates/:crate_id/:version/dependencies",
        C(version::dependencies),
    );
    api_router.get(
        "/crates/:crate_id/:version/downloads",
        C(version::downloads),
    );
    api_router.get("/crates/:crate_id/:version/authors", C(version::authors));
    // Used to generate download graphs
    api_router.get("/crates/:crate_id/downloads", C(krate::downloads));
    api_router.get("/crates/:crate_id/versions", C(krate::versions));
    api_router.put("/crates/:crate_id/follow", C(krate::follow));
    api_router.delete("/crates/:crate_id/follow", C(krate::unfollow));
    api_router.get("/crates/:crate_id/following", C(krate::following));
    // This endpoint may now be redundant, check frontend to see if it is
    // being used
    api_router.get("/crates/:crate_id/owners", C(krate::owners));
    api_router.get("/crates/:crate_id/owner_team", C(krate::owner_team));
    api_router.get("/crates/:crate_id/owner_user", C(krate::owner_user));
    api_router.put("/crates/:crate_id/owners", C(krate::add_owners));
    api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
    api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
    api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
    api_router.get(
        "/crates/:crate_id/reverse_dependencies",
        C(krate::reverse_dependencies),
    );
    api_router.get("/versions", C(version::index));
    api_router.get("/versions/:version_id", C(version::show));
    api_router.get("/keywords", C(keyword::index));
    api_router.get("/keywords/:keyword_id", C(keyword::show));
    api_router.get("/categories", C(category::index));
    api_router.get("/categories/:category_id", C(category::show));
    api_router.get("/category_slugs", C(category::slugs));
    api_router.get("/users/:user_id", C(user::show));
    api_router.put("/users/:user_id", C(user::update_user));
    api_router.get("/users/:user_id/stats", C(user::stats));
    api_router.get("/teams/:team_id", C(user::show_team));
    api_router.get("/me", C(user::me));
    api_router.get("/me/updates", C(user::updates));
    api_router.get("/me/tokens", C(token::list));
    api_router.post("/me/tokens", C(token::new));
    api_router.delete("/me/tokens/:id", C(token::revoke));
    api_router.get(
        "/me/crate_owner_invitations",
        C(crate_owner_invitation::list),
    );
    api_router.get("/summary", C(krate::summary));
    api_router.put("/confirm/:email_token", C(user::confirm_user_email));
    api_router.put("/users/:user_id/resend", C(user::regenerate_token_and_send));
    let api_router = Arc::new(R404(api_router));

    let mut router = RouteBuilder::new();

    // Mount the router under the /api/v1 path so we're at least somewhat at the
    // liberty to change things in the future!
    router.get("/api/v1/*path", R(api_router.clone()));
    router.put("/api/v1/*path", R(api_router.clone()));
    router.post("/api/v1/*path", R(api_router.clone()));
    router.head("/api/v1/*path", R(api_router.clone()));
    router.delete("/api/v1/*path", R(api_router));

    router.get("/authorize_url", C(user::github_authorize));
    router.get("/authorize", C(user::github_access_token));
    router.delete("/logout", C(user::logout));

    // Only serve the local checkout of the git index in development mode.
    // In production, for crates.io, cargo gets the index from
    // https://github.com/rust-lang/crates.io-index directly.
    let env = app.config.env;
    if env == Env::Development {
        let s = conduit_git_http_backend::Serve(app.git_repo_checkout.clone());
        let s = Arc::new(s);
        router.get("/git/index/*path", R(s.clone()));
        router.post("/git/index/*path", R(s));
    }

    let mut m = MiddlewareBuilder::new(R404(router));

    if env == Env::Development {
        // DebugMiddleware is defined below to print logs for each request.
        m.add(DebugMiddleware);
        m.around(local_upload::Middleware::default());
    }

    if env != Env::Test {
        m.add(conduit_log_requests::LogRequests(log::LogLevel::Info));
    }

    m.around(util::Head::default());
    m.add(conduit_conditional_get::ConditionalGet);
    m.add(conduit_cookie::Middleware::new());
    m.add(conduit_cookie::SessionMiddleware::new(
        "cargo_session",
        cookie::Key::from_master(app.session_key.as_bytes()),
        env == Env::Production,
    ));
    if env == Env::Production {
        m.add(http::SecurityHeadersMiddleware::new(&app.config.uploader));
    }
    m.add(app::AppMiddleware::new(app));

    // Sets the current user on each request.
    m.add(user::Middleware);

    // Serve the static files in the *dist* directory, which are the frontend assets.
    // Not needed for the backend tests.
    if env != Env::Test {
        m.around(dist::Middleware::default());
    }

    return m;

    struct DebugMiddleware;

    impl conduit_middleware::Middleware for DebugMiddleware {
        fn before(&self, req: &mut conduit::Request) -> Result<(), Box<Error + Send>> {
            println!("  version: {}", req.http_version());
            println!("  method: {:?}", req.method());
            println!("  scheme: {:?}", req.scheme());
            println!("  host: {:?}", req.host());
            println!("  path: {}", req.path());
            println!("  query_string: {:?}", req.query_string());
            println!("  remote_addr: {:?}", req.remote_addr());
            for &(k, ref v) in &req.headers().all() {
                println!("  hdr: {}={:?}", k, v);
            }
            Ok(())
        }
        fn after(
            &self,
            _req: &mut conduit::Request,
            res: Result<conduit::Response, Box<Error + Send>>,
        ) -> Result<conduit::Response, Box<Error + Send>> {
            res.map(|res| {
                println!("  <- {:?}", res.status);
                for (k, v) in &res.headers {
                    println!("  <- {} {:?}", k, v);
                }
                res
            })
        }
    }
}

/// Convenience function for getting the current server time in UTC.
pub fn now() -> time::Timespec {
    time::now_utc().to_timespec()
}

/// Convenience function for getting a time in RFC 3339 format.
///
/// Example: `2012-02-22T14:53:18Z`. Used for returning time values in JSON API responses.
pub fn encode_time(ts: time::Timespec) -> String {
    time::at_utc(ts).rfc3339().to_string()
}

/// Convenience function requiring that an environment variable is set.
///
/// Ensures that we've initialized the dotenv crate in order to read environment variables
/// from a *.env* file if present. Don't use this for optionally set environment variables.
///
/// # Panics
///
/// Panics if the environment variable with the name passed in as an argument is not defined
/// in the current environment.
pub fn env(s: &str) -> String {
    dotenv::dotenv().ok();
    ::std::env::var(s).unwrap_or_else(|_| panic!("must have `{}` defined", s))
}

sql_function!(lower, lower_t, (x: ::diesel::types::Text) -> ::diesel::types::Text);
<|endoftext|>


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

//! A user friendly graphics engine.

extern crate time;
extern crate graphics;
extern crate opengles;
extern crate glfw;

pub mod game;
pub mod shader_utils;
pub mod game_window;
pub mod gl;

<commit_msg>Reexport under top module<commit_after>#![crate_id = "piston"]
#![deny(missing_doc)]

//! A user friendly graphics engine.

extern crate time;
extern crate graphics;
extern crate opengles;
extern crate glfw;

pub use Game = game::Game;
pub use GameWindow = game_window::GameWindow;
pub use Settings = game::Settings;
pub use Gl = gl::Gl;

pub mod shader_utils;

mod game;
mod game_window;
mod gl;

<|endoftext|>


<commit_before>extern crate byteorder;

/// OSC data types, see [OSC 1.0
/// specification](http://opensoundcontrol.org/spec-1_0) for details
pub mod types;
/// Provides a decoding method for OSC packets
pub mod decoder;
/// TODO
pub mod encoder;
/// Utilities, g.e. IP address parsing
pub mod utils;
/// Contains custom errors
pub mod errors;

#[test]
fn it_works() {
}
<commit_msg>Remove placeholder function<commit_after>extern crate byteorder;

/// OSC data types, see [OSC 1.0
/// specification](http://opensoundcontrol.org/spec-1_0) for details
pub mod types;
/// Provides a decoding method for OSC packets
pub mod decoder;
/// TODO
pub mod encoder;
/// Utilities, g.e. IP address parsing
pub mod utils;
/// Contains custom errors
pub mod errors;
<|endoftext|>


<commit_before>// Streambuffer -- Fast asynchronous file reading
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! Streambuffer, a library for fast asynchronous file reading.
//!
//! # Examples
//!
//! TODO: Add example.

#![warn(missing_docs)]

use std::io;
use std::fs;
use std::os::unix::io::AsRawFd;
use std::path::Path;

extern crate libc;

/// A memory-mapped file.
pub struct StreamBuffer {
  buffer: *const u8,
  length: usize,
}

fn map_file(file: &fs::File) -> io::Result<(*const u8, usize)> {
    let fd = file.as_raw_fd();
    let length = try!(file.metadata()).len();

    if length > usize::max_value() as u64 {
        return Err(io::Error::new(io::ErrorKind::Other, "file is larger than address space"));
    }

    if length == 0 {
        return Err(io::Error::new(io::ErrorKind::Other, "file has size zero"));
    }

    let null = 0 as *mut libc::c_void;
    let result = unsafe {
        libc::mmap(null, length as usize, libc::PROT_READ, libc::MAP_PRIVATE, fd, 0)
    };

    if result == libc::MAP_FAILED {
        Err(io::Error::last_os_error())
    } else {
        Ok((result as *const u8, length as usize))
    }
}

fn unmap_file(buffer: *const u8, length: usize) {
    let result = unsafe {
        libc::munmap(buffer as *mut libc::c_void, length)
    };

    // `munmap` only fails due to incorrect usage, which is a program error, not a runtime failure.
    assert!(result == 0);
}

impl StreamBuffer {
    /// Maps the file at `path` into memory.
    ///
    /// TODO: Document what happens when the file is changed after opening.
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<StreamBuffer> {
        // Open the `fs::File` so we get all of std's error handling for free, then use it to
        // extract the file descriptor. The file is closed again when it goes out of scope, but
        // `mmap` only requires the descriptor to be open for the `mmap` call, so this is fine.
        let file = try!(fs::File::open(path));
        let (buffer, length) = try!(map_file(&file));
        let fstream = StreamBuffer {
            buffer: buffer,
            length: length,
        };
        Ok(fstream)
    }
}

impl Drop for StreamBuffer {
    fn drop(&mut self) {
        unmap_file(self.buffer, self.length);
    }
}

#[test]
fn open_file() {
    let fstream = StreamBuffer::open("src/lib.rs");
    assert!(fstream.is_ok());
}
<commit_msg>Add as_slice() method to StreamBuffer<commit_after>// Streambuffer -- Fast asynchronous file reading
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! Streambuffer, a library for fast asynchronous file reading.
//!
//! # Examples
//!
//! Map a file into memory and access it as an array of bytes. This is simple and will generally
//! outperform `Read::read_to_end()`, but it will block upon first access.
//!
//! ```
//! use streambuffer::StreamBuffer;
//! let fstream = StreamBuffer::open("src/lib.rs").unwrap();
//! let buffer = fstream.as_slice();
//! assert_eq!(buffer[3..49], b"Streambuffer -- Fast asynchronous file reading"[..]);
//! ```
//!
//! TODO: More and better (non-blocking) examples.

#![warn(missing_docs)]

use std::io;
use std::fs;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::slice;

extern crate libc;

/// A memory-mapped file.
pub struct StreamBuffer {
  buffer: *const u8,
  length: usize,
}

fn map_file(file: &fs::File) -> io::Result<(*const u8, usize)> {
    let fd = file.as_raw_fd();
    let length = try!(file.metadata()).len();

    if length > usize::max_value() as u64 {
        return Err(io::Error::new(io::ErrorKind::Other, "file is larger than address space"));
    }

    if length == 0 {
        return Err(io::Error::new(io::ErrorKind::Other, "file has size zero"));
    }

    let null = 0 as *mut libc::c_void;
    let result = unsafe {
        libc::mmap(null, length as usize, libc::PROT_READ, libc::MAP_PRIVATE, fd, 0)
    };

    if result == libc::MAP_FAILED {
        Err(io::Error::last_os_error())
    } else {
        Ok((result as *const u8, length as usize))
    }
}

fn unmap_file(buffer: *const u8, length: usize) {
    let result = unsafe {
        libc::munmap(buffer as *mut libc::c_void, length)
    };

    // `munmap` only fails due to incorrect usage, which is a program error, not a runtime failure.
    assert!(result == 0);
}

impl StreamBuffer {
    /// Maps the file at `path` into memory.
    ///
    /// TODO: Document what happens when the file is changed after opening.
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<StreamBuffer> {
        // Open the `fs::File` so we get all of std's error handling for free, then use it to
        // extract the file descriptor. The file is closed again when it goes out of scope, but
        // `mmap` only requires the descriptor to be open for the `mmap` call, so this is fine.
        let file = try!(fs::File::open(path));
        let (buffer, length) = try!(map_file(&file));
        let fstream = StreamBuffer {
            buffer: buffer,
            length: length,
        };
        Ok(fstream)
    }

    /// Returns the file contents as a slice.
    ///
    /// Accessing elements of the slice might cause a page fault,
    /// blocking until the data has been read from disk.
    pub fn as_slice(&self) -> &[u8] {
       unsafe { slice::from_raw_parts(self.buffer, self.length) }
    }
}

impl Drop for StreamBuffer {
    fn drop(&mut self) {
        unmap_file(self.buffer, self.length);
    }
}

#[test]
fn open_file() {
    let fstream = StreamBuffer::open("src/lib.rs");
    assert!(fstream.is_ok());
}
<|endoftext|>