<commit_before>use std::fmt;
use std::io::{self, Read};
use std::sync::{Arc, Mutex};

use hyper::client::IntoUrl;
use hyper::header::{Headers, ContentType, Location, Referer, UserAgent, Accept};
use hyper::method::Method;
use hyper::status::StatusCode;
use hyper::version::HttpVersion;
use hyper::{Url};

use serde::{Deserialize, Serialize};
use serde_json;
use serde_urlencoded;

use ::body::{self, Body};
use ::redirect::{RedirectPolicy, check_redirect};

static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

/// A `Client` to make Requests with.
///
/// The Client has various configuration values to tweak, but the defaults
/// are set to what is usually the most commonly desired value.
///
/// The `Client` holds a connection pool internally, so it is advised that
/// you create one and reuse it.
pub struct Client {
    inner: Arc<ClientRef>,  //::hyper::Client,
}

impl Client {
    /// Constructs a new `Client`.
    pub fn new() -> ::Result<Client> {
        let mut client = try!(new_hyper_client());
        client.set_redirect_policy(::hyper::client::RedirectPolicy::FollowNone);
        Ok(Client {
            inner: Arc::new(ClientRef {
                hyper: client,
                redirect_policy: Mutex::new(RedirectPolicy::default()),
            }),
        })
    }

    /// Set a `RedirectPolicy` for this client.
    pub fn redirect(&mut self, policy: RedirectPolicy) {
        *self.inner.redirect_policy.lock().unwrap() = policy;
    }

    /// Convenience method to make a `GET` request to a URL.
    pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Get, url)
    }

    /// Convenience method to make a `POST` request to a URL.
    pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Post, url)
    }

    /// Convenience method to make a `HEAD` request to a URL.
    pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Head, url)
    }

    /// Start building a `Request` with the `Method` and `Url`.
    ///
    /// Returns a `RequestBuilder`, which will allow setting headers and
    /// request body before sending.
    pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
        let url = url.into_url();
        RequestBuilder {
            client: self.inner.clone(),
            method: method,
            url: url,
            _version: HttpVersion::Http11,
            headers: Headers::new(),

            body: None,
        }
    }
}

impl fmt::Debug for Client {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Client")
            .field("redirect_policy", &self.inner.redirect_policy)
            .finish()
    }
}

struct ClientRef {
    hyper: ::hyper::Client,
    redirect_policy: Mutex<RedirectPolicy>,
}

fn new_hyper_client() -> ::Result<::hyper::Client> {
    use hyper_native_tls::NativeTlsClient;
    Ok(::hyper::Client::with_connector(
        ::hyper::client::Pool::with_connector(
            Default::default(),
            ::hyper::net::HttpsConnector::new(
                try!(NativeTlsClient::new()
                     .map_err(|e| ::hyper::Error::Ssl(Box::new(e)))))
        )
    ))
}

/// A builder to construct the properties of a `Request`.
pub struct RequestBuilder {
    client: Arc<ClientRef>,

    method: Method,
    url: Result<Url, ::UrlError>,
    _version: HttpVersion,
    headers: Headers,

    body: Option<::Result<Body>>,
}

impl RequestBuilder {
    /// Add a `Header` to this Request.
    ///
    /// ```no_run
    /// use reqwest::header::UserAgent;
    /// let client = reqwest::Client::new().expect("client failed to construct");
    ///
    /// let res = client.get("https://www.rust-lang.org")
    ///     .header(UserAgent("foo".to_string()))
    ///     .send();
    /// ```
    pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder {
        self.headers.set(header);
        self
    }
    /// Add a set of Headers to the existing ones on this Request.
    ///
    /// The headers will be merged in to any already set.
    pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder {
        self.headers.extend(headers.iter());
        self
    }

    /// Set the request body.
    pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
        self.body = Some(Ok(body.into()));
        self
    }

    /// Send a form body.
    ///
    /// Sets the body to the url encoded serialization of the passed value,
    /// and also sets the `Content-Type: application/www-form-url-encoded`
    /// header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut params = HashMap::new();
    /// params.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .form(&params)
    ///     .send();
    /// ```
    pub fn form<T: Serialize>(mut self, form: &T) -> RequestBuilder {
        let body = serde_urlencoded::to_string(form).map_err(::Error::from);
        self.headers.set(ContentType::form_url_encoded());
        self.body = Some(body.map(|b| b.into()));
        self
    }

    /// Send a JSON body.
    ///
    /// Sets the body to the JSON serialization of the passed value, and
    /// also sets the `Content-Type: application/json` header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut map = HashMap::new();
    /// map.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .json(&map)
    ///     .send();
    /// ```
    pub fn json<T: Serialize>(mut self, json: &T) -> RequestBuilder {
        let body = serde_json::to_vec(json).expect("serde to_vec cannot fail");
        self.headers.set(ContentType::json());
        self.body = Some(Ok(body.into()));
        self
    }

    /// Constructs the Request and sends it the target URL, returning a Response.
    pub fn send(mut self) -> ::Result<Response> {
        if !self.headers.has::<UserAgent>() {
            self.headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
        }

        if !self.headers.has::<Accept>() {
            self.headers.set(Accept::star());
        }

        let client = self.client;
        let mut method = self.method;
        let mut url = try!(self.url);
        let mut headers = self.headers;
        let mut body = match self.body {
            Some(b) => Some(try!(b)),
            None => None,
        };

        let mut urls = Vec::new();

        loop {
            let res = {
                debug!("request {:?} \"{}\"", method, url);
                let mut req = client.hyper.request(method.clone(), url.clone())
                    .headers(headers.clone());

                if let Some(ref mut b) = body {
                    let body = body::as_hyper_body(b);
                    req = req.body(body);
                }

                try!(req.send())
            };

            let should_redirect = match res.status {
                StatusCode::MovedPermanently |
                StatusCode::Found |
                StatusCode::SeeOther => {
                    body = None;
                    match method {
                        Method::Get | Method::Head => {},
                        _ => {
                            method = Method::Get;
                        }
                    }
                    true
                },
                StatusCode::TemporaryRedirect |
                StatusCode::PermanentRedirect => {
                    if let Some(ref body) = body {
                        body::can_reset(body)
                    } else {
                        true
                    }
                },
                _ => false,
            };

            if should_redirect {
                let loc = {
                    let loc = res.headers.get::<Location>().map(|loc| url.join(loc));
                    if let Some(loc) = loc {
                        loc
                    } else {
                        return Ok(Response {
                            inner: res
                        });
                    }
                };

                url = match loc {
                    Ok(loc) => {
                        headers.set(Referer(url.to_string()));
                        urls.push(url);
                        if check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls)? {
                            loc
                        } else {
                            debug!("redirect_policy disallowed redirection to '{}'", loc);
                            return Ok(Response {
                                inner: res
                            })
                        }
                    },
                    Err(e) => {
                        debug!("Location header had invalid URI: {:?}", e);
                        return Ok(Response {
                            inner: res
                        })
                    }
                };

                debug!("redirecting to {:?} '{}'", method, url);

                //TODO: removeSensitiveHeaders(&mut headers, &url);
            } else {
                return Ok(Response {
                    inner: res
                });
            }
        }
    }
}

impl fmt::Debug for RequestBuilder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("RequestBuilder")
            .field("method", &self.method)
            .field("url", &self.url)
            .field("headers", &self.headers)
            .finish()
    }
}

/// A Response to a submitted `Request`.
pub struct Response {
    inner: ::hyper::client::Response,
}

impl Response {
    /// Get the `StatusCode`.
    #[inline]
    pub fn status(&self) -> &StatusCode {
        &self.inner.status
    }

    /// Get the `Headers`.
    #[inline]
    pub fn headers(&self) -> &Headers {
        &self.inner.headers
    }

    /// Get the `HttpVersion`.
    #[inline]
    pub fn version(&self) -> &HttpVersion {
        &self.inner.version
    }

    /// Try and deserialize the response body as JSON.
    #[inline]
    pub fn json<T: Deserialize>(&mut self) -> ::Result<T> {
        serde_json::from_reader(self).map_err(::Error::from)
    }
}

/// Read the body of the Response.
impl Read for Response {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl fmt::Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Response")
            .field("status", self.status())
            .field("headers", self.headers())
            .field("version", self.version())
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ::body;
    use hyper::method::Method;
    use hyper::Url;
    use hyper::header::{Host, Headers, ContentType};
    use std::collections::HashMap;
    use serde_urlencoded;
    use serde_json;

    #[test]
    fn basic_get_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.get(some_url);

        assert_eq!(r.method, Method::Get);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_head_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.head(some_url);

        assert_eq!(r.method, Method::Head);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_post_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.post(some_url);

        assert_eq!(r.method, Method::Post);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn add_header() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        // Add a copy of the header to the request builder
        r = r.header(header.clone());

        // then check it was actually added
        assert_eq!(r.headers.get::<Host>(), Some(&header));
    }

    #[test]
    fn add_headers() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        let mut headers = Headers::new();
        headers.set(header);

        // Add a copy of the headers to the request builder
        r = r.headers(headers.clone());

        // then make sure they were added correctly
        assert_eq!(r.headers, headers);
    }

    #[test]
    fn add_body() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let body = "Some interesting content";

        r = r.body(body);

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        assert_eq!(buf, body);
    }

    #[test]
    fn add_form() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut form_data = HashMap::new();
        form_data.insert("foo", "bar");

        r = r.form(&form_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::form_url_encoded()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_urlencoded::to_string(&form_data).unwrap();
        assert_eq!(buf, body_should_be);
    }

    #[test]
    fn add_json() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut json_data = HashMap::new();
        json_data.insert("foo", "bar");

        r = r.json(&json_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::json()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_json::to_string(&json_data).unwrap();
        assert_eq!(buf, body_should_be);
    }
}
<commit_msg>added in PUT functionality<commit_after>use std::fmt;
use std::io::{self, Read};
use std::sync::{Arc, Mutex};

use hyper::client::IntoUrl;
use hyper::header::{Headers, ContentType, Location, Referer, UserAgent, Accept};
use hyper::method::Method;
use hyper::status::StatusCode;
use hyper::version::HttpVersion;
use hyper::{Url};

use serde::{Deserialize, Serialize};
use serde_json;
use serde_urlencoded;

use ::body::{self, Body};
use ::redirect::{RedirectPolicy, check_redirect};

static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

/// A `Client` to make Requests with.
///
/// The Client has various configuration values to tweak, but the defaults
/// are set to what is usually the most commonly desired value.
///
/// The `Client` holds a connection pool internally, so it is advised that
/// you create one and reuse it.
pub struct Client {
    inner: Arc<ClientRef>,  //::hyper::Client,
}

impl Client {
    /// Constructs a new `Client`.
    pub fn new() -> ::Result<Client> {
        let mut client = try!(new_hyper_client());
        client.set_redirect_policy(::hyper::client::RedirectPolicy::FollowNone);
        Ok(Client {
            inner: Arc::new(ClientRef {
                hyper: client,
                redirect_policy: Mutex::new(RedirectPolicy::default()),
            }),
        })
    }

    /// Set a `RedirectPolicy` for this client.
    pub fn redirect(&mut self, policy: RedirectPolicy) {
        *self.inner.redirect_policy.lock().unwrap() = policy;
    }

    /// Convenience method to make a `GET` request to a URL.
    pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Get, url)
    }

    /// Convenience method to make a `POST` request to a URL.
    pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Post, url)
    }

    /// Convenience method to make a `PUT` request to a URL.
    pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Put, url)
    }

    /// Convenience method to make a `HEAD` request to a URL.
    pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::Head, url)
    }

    /// Start building a `Request` with the `Method` and `Url`.
    ///
    /// Returns a `RequestBuilder`, which will allow setting headers and
    /// request body before sending.
    pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
        let url = url.into_url();
        RequestBuilder {
            client: self.inner.clone(),
            method: method,
            url: url,
            _version: HttpVersion::Http11,
            headers: Headers::new(),

            body: None,
        }
    }
}

impl fmt::Debug for Client {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Client")
            .field("redirect_policy", &self.inner.redirect_policy)
            .finish()
    }
}

struct ClientRef {
    hyper: ::hyper::Client,
    redirect_policy: Mutex<RedirectPolicy>,
}

fn new_hyper_client() -> ::Result<::hyper::Client> {
    use hyper_native_tls::NativeTlsClient;
    Ok(::hyper::Client::with_connector(
        ::hyper::client::Pool::with_connector(
            Default::default(),
            ::hyper::net::HttpsConnector::new(
                try!(NativeTlsClient::new()
                     .map_err(|e| ::hyper::Error::Ssl(Box::new(e)))))
        )
    ))
}

/// A builder to construct the properties of a `Request`.
pub struct RequestBuilder {
    client: Arc<ClientRef>,

    method: Method,
    url: Result<Url, ::UrlError>,
    _version: HttpVersion,
    headers: Headers,

    body: Option<::Result<Body>>,
}

impl RequestBuilder {
    /// Add a `Header` to this Request.
    ///
    /// ```no_run
    /// use reqwest::header::UserAgent;
    /// let client = reqwest::Client::new().expect("client failed to construct");
    ///
    /// let res = client.get("https://www.rust-lang.org")
    ///     .header(UserAgent("foo".to_string()))
    ///     .send();
    /// ```
    pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder {
        self.headers.set(header);
        self
    }
    /// Add a set of Headers to the existing ones on this Request.
    ///
    /// The headers will be merged in to any already set.
    pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder {
        self.headers.extend(headers.iter());
        self
    }

    /// Set the request body.
    pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
        self.body = Some(Ok(body.into()));
        self
    }

    /// Send a form body.
    ///
    /// Sets the body to the url encoded serialization of the passed value,
    /// and also sets the `Content-Type: application/www-form-url-encoded`
    /// header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut params = HashMap::new();
    /// params.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .form(&params)
    ///     .send();
    /// ```
    pub fn form<T: Serialize>(mut self, form: &T) -> RequestBuilder {
        let body = serde_urlencoded::to_string(form).map_err(::Error::from);
        self.headers.set(ContentType::form_url_encoded());
        self.body = Some(body.map(|b| b.into()));
        self
    }

    /// Send a JSON body.
    ///
    /// Sets the body to the JSON serialization of the passed value, and
    /// also sets the `Content-Type: application/json` header.
    ///
    /// ```no_run
    /// # use std::collections::HashMap;
    /// let mut map = HashMap::new();
    /// map.insert("lang", "rust");
    ///
    /// let client = reqwest::Client::new().unwrap();
    /// let res = client.post("http://httpbin.org")
    ///     .json(&map)
    ///     .send();
    /// ```
    pub fn json<T: Serialize>(mut self, json: &T) -> RequestBuilder {
        let body = serde_json::to_vec(json).expect("serde to_vec cannot fail");
        self.headers.set(ContentType::json());
        self.body = Some(Ok(body.into()));
        self
    }

    /// Constructs the Request and sends it the target URL, returning a Response.
    pub fn send(mut self) -> ::Result<Response> {
        if !self.headers.has::<UserAgent>() {
            self.headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
        }

        if !self.headers.has::<Accept>() {
            self.headers.set(Accept::star());
        }

        let client = self.client;
        let mut method = self.method;
        let mut url = try!(self.url);
        let mut headers = self.headers;
        let mut body = match self.body {
            Some(b) => Some(try!(b)),
            None => None,
        };

        let mut urls = Vec::new();

        loop {
            let res = {
                debug!("request {:?} \"{}\"", method, url);
                let mut req = client.hyper.request(method.clone(), url.clone())
                    .headers(headers.clone());

                if let Some(ref mut b) = body {
                    let body = body::as_hyper_body(b);
                    req = req.body(body);
                }

                try!(req.send())
            };

            let should_redirect = match res.status {
                StatusCode::MovedPermanently |
                StatusCode::Found |
                StatusCode::SeeOther => {
                    body = None;
                    match method {
                        Method::Get | Method::Head => {},
                        _ => {
                            method = Method::Get;
                        }
                    }
                    true
                },
                StatusCode::TemporaryRedirect |
                StatusCode::PermanentRedirect => {
                    if let Some(ref body) = body {
                        body::can_reset(body)
                    } else {
                        true
                    }
                },
                _ => false,
            };

            if should_redirect {
                let loc = {
                    let loc = res.headers.get::<Location>().map(|loc| url.join(loc));
                    if let Some(loc) = loc {
                        loc
                    } else {
                        return Ok(Response {
                            inner: res
                        });
                    }
                };

                url = match loc {
                    Ok(loc) => {
                        headers.set(Referer(url.to_string()));
                        urls.push(url);
                        if check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls)? {
                            loc
                        } else {
                            debug!("redirect_policy disallowed redirection to '{}'", loc);
                            return Ok(Response {
                                inner: res
                            })
                        }
                    },
                    Err(e) => {
                        debug!("Location header had invalid URI: {:?}", e);
                        return Ok(Response {
                            inner: res
                        })
                    }
                };

                debug!("redirecting to {:?} '{}'", method, url);

                //TODO: removeSensitiveHeaders(&mut headers, &url);
            } else {
                return Ok(Response {
                    inner: res
                });
            }
        }
    }
}

impl fmt::Debug for RequestBuilder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("RequestBuilder")
            .field("method", &self.method)
            .field("url", &self.url)
            .field("headers", &self.headers)
            .finish()
    }
}

/// A Response to a submitted `Request`.
pub struct Response {
    inner: ::hyper::client::Response,
}

impl Response {
    /// Get the `StatusCode`.
    #[inline]
    pub fn status(&self) -> &StatusCode {
        &self.inner.status
    }

    /// Get the `Headers`.
    #[inline]
    pub fn headers(&self) -> &Headers {
        &self.inner.headers
    }

    /// Get the `HttpVersion`.
    #[inline]
    pub fn version(&self) -> &HttpVersion {
        &self.inner.version
    }

    /// Try and deserialize the response body as JSON.
    #[inline]
    pub fn json<T: Deserialize>(&mut self) -> ::Result<T> {
        serde_json::from_reader(self).map_err(::Error::from)
    }
}

/// Read the body of the Response.
impl Read for Response {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl fmt::Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Response")
            .field("status", self.status())
            .field("headers", self.headers())
            .field("version", self.version())
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ::body;
    use hyper::method::Method;
    use hyper::Url;
    use hyper::header::{Host, Headers, ContentType};
    use std::collections::HashMap;
    use serde_urlencoded;
    use serde_json;

    #[test]
    fn basic_get_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.get(some_url);

        assert_eq!(r.method, Method::Get);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_head_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.head(some_url);

        assert_eq!(r.method, Method::Head);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_post_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let r = client.post(some_url);

        assert_eq!(r.method, Method::Post);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn basic_put_request() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com";
        let r = client.put(some_url);

        assert_eq!(r.method, Method::Put);
        assert_eq!(r.url, Url::parse(some_url));
    }

    #[test]
    fn add_header() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        // Add a copy of the header to the request builder
        r = r.header(header.clone());

        // then check it was actually added
        assert_eq!(r.headers.get::<Host>(), Some(&header));
    }

    #[test]
    fn add_headers() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let header = Host {
            hostname: "google.com".to_string(),
            port: None,
        };

        let mut headers = Headers::new();
        headers.set(header);

        // Add a copy of the headers to the request builder
        r = r.headers(headers.clone());

        // then make sure they were added correctly
        assert_eq!(r.headers, headers);
    }

    #[test]
    fn add_body() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let body = "Some interesting content";

        r = r.body(body);

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        assert_eq!(buf, body);
    }

    #[test]
    fn add_form() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut form_data = HashMap::new();
        form_data.insert("foo", "bar");

        r = r.form(&form_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::form_url_encoded()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_urlencoded::to_string(&form_data).unwrap();
        assert_eq!(buf, body_should_be);
    }

    #[test]
    fn add_json() {
        let client = Client::new().unwrap();
        let some_url = "https://google.com/";
        let mut r = client.post(some_url);

        let mut json_data = HashMap::new();
        json_data.insert("foo", "bar");

        r = r.json(&json_data);

        // Make sure the content type was set
        assert_eq!(r.headers.get::<ContentType>(), Some(&ContentType::json()));

        let buf = body::read_to_string(r.body.unwrap().unwrap()).unwrap();

        let body_should_be = serde_json::to_string(&json_data).unwrap();
        assert_eq!(buf, body_should_be);
    }
}
<|endoftext|>


<commit_before>#![allow(
    clippy::eq_op,
    clippy::items_after_statements,
    clippy::needless_pass_by_value,
    clippy::shadow_unrelated,
    clippy::wildcard_imports
)]

mod common;

use self::common::*;
use anyhow::{anyhow, ensure};
use std::future;

#[test]
fn test_messages() {
    assert_eq!("oh no!", bail_literal().unwrap_err().to_string());
    assert_eq!("oh no!", bail_fmt().unwrap_err().to_string());
    assert_eq!("oh no!", bail_error().unwrap_err().to_string());
}

#[test]
fn test_ensure() {
    let f = || {
        ensure!(1 + 1 == 2, "This is correct");
        Ok(())
    };
    assert!(f().is_ok());

    let v = 1;
    let f = || {
        ensure!(v + v == 2, "This is correct, v: {}", v);
        Ok(())
    };
    assert!(f().is_ok());

    let f = || {
        ensure!(v + v == 1, "This is not correct, v: {}", v);
        Ok(())
    };
    assert!(f().is_err());

    let f = || {
        ensure!(v + v == 1);
        Ok(())
    };
    assert_eq!(
        f().unwrap_err().to_string(),
        "Condition failed: `v + v == 1`",
    );
}

#[test]
fn test_temporaries() {
    fn require_send_sync(_: impl Send + Sync) {}

    require_send_sync(async {
        // If anyhow hasn't dropped any temporary format_args it creates by the
        // time it's done evaluating, those will stick around until the
        // semicolon, which is on the other side of the await point, making the
        // enclosing future non-Send.
        future::ready(anyhow!("...")).await;
    });
}

#[test]
fn test_brace_escape() {
    let err = anyhow!("unterminated ${{..}} expression");
    assert_eq!("unterminated ${..} expression", err.to_string());
}
<commit_msg>Add regression test of issue 186<commit_after>#![allow(
    clippy::eq_op,
    clippy::items_after_statements,
    clippy::needless_pass_by_value,
    clippy::shadow_unrelated,
    clippy::wildcard_imports
)]

mod common;

use self::common::*;
use anyhow::{anyhow, ensure};
use std::cell::Cell;
use std::future;

#[test]
fn test_messages() {
    assert_eq!("oh no!", bail_literal().unwrap_err().to_string());
    assert_eq!("oh no!", bail_fmt().unwrap_err().to_string());
    assert_eq!("oh no!", bail_error().unwrap_err().to_string());
}

#[test]
fn test_ensure() {
    let f = || {
        ensure!(1 + 1 == 2, "This is correct");
        Ok(())
    };
    assert!(f().is_ok());

    let v = 1;
    let f = || {
        ensure!(v + v == 2, "This is correct, v: {}", v);
        Ok(())
    };
    assert!(f().is_ok());

    let f = || {
        ensure!(v + v == 1, "This is not correct, v: {}", v);
        Ok(())
    };
    assert!(f().is_err());

    let f = || {
        ensure!(v + v == 1);
        Ok(())
    };
    assert_eq!(
        f().unwrap_err().to_string(),
        "Condition failed: `v + v == 1`",
    );
}

#[test]
fn test_temporaries() {
    fn require_send_sync(_: impl Send + Sync) {}

    require_send_sync(async {
        // If anyhow hasn't dropped any temporary format_args it creates by the
        // time it's done evaluating, those will stick around until the
        // semicolon, which is on the other side of the await point, making the
        // enclosing future non-Send.
        future::ready(anyhow!("...")).await;
    });

    fn message(cell: Cell<&str>) -> &str {
        cell.get()
    }

    require_send_sync(async {
        future::ready(anyhow!(message(Cell::new("...")))).await;
    });
}

#[test]
fn test_brace_escape() {
    let err = anyhow!("unterminated ${{..}} expression");
    assert_eq!("unterminated ${..} expression", err.to_string());
}
<|endoftext|>


<commit_before>use piston_window::color;
use piston_window::types::Color;

// Lifted and modified from Conrod
macro_rules! make_color {
    ($r:expr, $g:expr, $b:expr) => ([$r as f32 / 255.0, $g as f32 / 255.0, $b as f32 / 255.0, 1.0]);
    ($r:expr, $g:expr, $b:expr, $a:expr) => ([$r as f32 / 255.0, $g as f32 / 255.0, $b as f32 / 255.0, $a as f32 / 255.0]);
}

// Tetromino colors
pub const CYAN: Color = make_color!(0x00, 0xff, 0xff);
pub const BLUE: Color = make_color!(0x34, 0x65, 0xA4);
pub const ORANGE: Color = make_color!(0xF5, 0x79, 0x00);
pub const YELLOW: Color = make_color!(0xED, 0xD4, 0x00);
pub const LIME: Color = make_color!(0x80, 0xFF, 0x00);
pub const PURPLE: Color = make_color!(0x75, 0x50, 0x7B);
pub const RED: Color = make_color!(0xCC, 0x00, 0x00);

//Grid color
pub const GREY: Color = [0.05, 0.05, 0.05, 1.0];<commit_msg>make the grey stand out a bit more<commit_after>use piston_window::color;
use piston_window::types::Color;

// Lifted and modified from Conrod
macro_rules! make_color {
    ($r:expr, $g:expr, $b:expr) => ([$r as f32 / 255.0, $g as f32 / 255.0, $b as f32 / 255.0, 1.0]);
    ($r:expr, $g:expr, $b:expr, $a:expr) => ([$r as f32 / 255.0, $g as f32 / 255.0, $b as f32 / 255.0, $a as f32 / 255.0]);
}

// Tetromino colors
pub const CYAN: Color = make_color!(0x00, 0xff, 0xff);
pub const BLUE: Color = make_color!(0x34, 0x65, 0xA4);
pub const ORANGE: Color = make_color!(0xF5, 0x79, 0x00);
pub const YELLOW: Color = make_color!(0xED, 0xD4, 0x00);
pub const LIME: Color = make_color!(0x80, 0xFF, 0x00);
pub const PURPLE: Color = make_color!(0x75, 0x50, 0x7B);
pub const RED: Color = make_color!(0xCC, 0x00, 0x00);

//Grid color
pub const GREY: Color = [0.15, 0.15, 0.15, 1.0];
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::str;

use common::{Literal, SqlType};
use keywords::escape_if_keyword;

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum FunctionExpression {
    Avg(Column, bool),
    Count(Column, bool),
    CountStar,
    Sum(Column, bool),
    Max(Column),
    Min(Column),
    GroupConcat(Column, String),
}

impl Display for FunctionExpression {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FunctionExpression::Avg(ref col, d) if d => {
                write!(f, "avg(distinct {})", col.name.as_str())
            }
            FunctionExpression::Count(ref col, d) if d => {
                write!(f, "count(distinct {})", col.name.as_str())
            }
            FunctionExpression::Sum(ref col, d) if d => {
                write!(f, "sum(distinct {})", col.name.as_str())
            }

            FunctionExpression::Avg(ref col, _) => write!(f, "avg({})", col.name.as_str()),
            FunctionExpression::Count(ref col, _) => write!(f, "count({})", col.name.as_str()),
            FunctionExpression::CountStar => write!(f, "count(*)"),
            FunctionExpression::Sum(ref col, _) => write!(f, "sum({})", col.name.as_str()),
            FunctionExpression::Max(ref col) => write!(f, "max({})", col.name.as_str()),
            FunctionExpression::Min(ref col) => write!(f, "min({})", col.name.as_str()),
            FunctionExpression::GroupConcat(ref col, ref s) => {
                write!(f, "group_concat({}, {})", col.name.as_str(), s)
            }
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Column {
    pub name: String,
    pub alias: Option<String>,
    pub table: Option<String>,
    pub function: Option<Box<FunctionExpression>>,
}

impl fmt::Display for Column {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref table) = self.table {
            write!(
                f,
                "{}.{}",
                escape_if_keyword(table),
                escape_if_keyword(&self.name)
            )?;
        } else {
            write!(f, "{}", escape_if_keyword(&self.name))?;
        }
        if let Some(ref alias) = self.alias {
            write!(f, " AS {}", escape_if_keyword(alias))?;
        }
        Ok(())
    }
}

impl<'a> From<&'a str> for Column {
    fn from(c: &str) -> Column {
        match c.find(".") {
            None => Column {
                name: String::from(c),
                alias: None,
                table: None,
                function: None,
            },
            Some(i) => Column {
                name: String::from(&c[i + 1..]),
                alias: None,
                table: Some(String::from(&c[0..i])),
                function: None,
            },
        }
    }
}

impl Ord for Column {
    fn cmp(&self, other: &Column) -> Ordering {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => self.name.cmp(&other.name),
                x => x,
            }
        } else {
            self.name.cmp(&other.name)
        }
    }
}

impl PartialOrd for Column {
    fn partial_cmp(&self, other: &Column) -> Option<Ordering> {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => Some(self.name.cmp(&other.name)),
                x => Some(x),
            }
        } else if self.table.is_none() && other.table.is_none() {
            Some(self.name.cmp(&other.name))
        } else {
            None
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum ColumnConstraint {
    NotNull,
    Collation(String),
    DefaultValue(Literal),
    AutoIncrement,
    PrimaryKey,
    Unique,
}

impl fmt::Display for ColumnConstraint {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ColumnConstraint::NotNull => write!(f, "NOT NULL"),
            ColumnConstraint::Collation(ref collation) => write!(f, "COLLATE {}", collation),
            ColumnConstraint::DefaultValue(ref literal) => {
                write!(f, "DEFAULT {}", literal.to_string())
            }
            ColumnConstraint::AutoIncrement => write!(f, "AUTO_INCREMENT"),
            ColumnConstraint::PrimaryKey => write!(f, "PRIMARY KEY"),
            ColumnConstraint::Unique => write!(f, "UNIQUE"),
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ColumnSpecification {
    pub column: Column,
    pub sql_type: SqlType,
    pub constraints: Vec<ColumnConstraint>,
}

impl fmt::Display for ColumnSpecification {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} {}",
            escape_if_keyword(&self.column.name),
            self.sql_type
        )?;
        for constraint in self.constraints.iter() {
            write!(f, " {}", constraint)?;
        }
        Ok(())
    }
}

impl ColumnSpecification {
    pub fn new(c: Column, t: SqlType) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: vec![],
        }
    }

    pub fn with_constraints(
        c: Column,
        t: SqlType,
        ccs: Vec<ColumnConstraint>,
    ) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: ccs,
        }
    }
}

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

    #[test]
    fn column_from_str() {
        let s = "table.col";
        let c = Column::from(s);

        assert_eq!(
            c,
            Column {
                name: String::from("col"),
                alias: None,
                table: Some(String::from("table")),
                function: None,
            }
        );
    }
}
<commit_msg>Fix function column display bug<commit_after>use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::str;

use common::{Literal, SqlType};
use keywords::escape_if_keyword;

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum FunctionExpression {
    Avg(Column, bool),
    Count(Column, bool),
    CountStar,
    Sum(Column, bool),
    Max(Column),
    Min(Column),
    GroupConcat(Column, String),
}

impl Display for FunctionExpression {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FunctionExpression::Avg(ref col, d) if d => {
                write!(f, "avg(distinct {})", col.name.as_str())
            }
            FunctionExpression::Count(ref col, d) if d => {
                write!(f, "count(distinct {})", col.name.as_str())
            }
            FunctionExpression::Sum(ref col, d) if d => {
                write!(f, "sum(distinct {})", col.name.as_str())
            }

            FunctionExpression::Avg(ref col, _) => write!(f, "avg({})", col.name.as_str()),
            FunctionExpression::Count(ref col, _) => write!(f, "count({})", col.name.as_str()),
            FunctionExpression::CountStar => write!(f, "count(*)"),
            FunctionExpression::Sum(ref col, _) => write!(f, "sum({})", col.name.as_str()),
            FunctionExpression::Max(ref col) => write!(f, "max({})", col.name.as_str()),
            FunctionExpression::Min(ref col) => write!(f, "min({})", col.name.as_str()),
            FunctionExpression::GroupConcat(ref col, ref s) => {
                write!(f, "group_concat({}, {})", col.name.as_str(), s)
            }
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Column {
    pub name: String,
    pub alias: Option<String>,
    pub table: Option<String>,
    pub function: Option<Box<FunctionExpression>>,
}

impl fmt::Display for Column {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref table) = self.table {
            write!(
                f,
                "{}.{}",
                escape_if_keyword(table),
                escape_if_keyword(&self.name)
            )?;
        } else if let Some(ref function) = self.function {
            write!(f, "{}", *function)?;
        } else {
            write!(f, "{}", escape_if_keyword(&self.name))?;
        }
        if let Some(ref alias) = self.alias {
            write!(f, " AS {}", escape_if_keyword(alias))?;
        }
        Ok(())
    }
}

impl<'a> From<&'a str> for Column {
    fn from(c: &str) -> Column {
        match c.find(".") {
            None => Column {
                name: String::from(c),
                alias: None,
                table: None,
                function: None,
            },
            Some(i) => Column {
                name: String::from(&c[i + 1..]),
                alias: None,
                table: Some(String::from(&c[0..i])),
                function: None,
            },
        }
    }
}

impl Ord for Column {
    fn cmp(&self, other: &Column) -> Ordering {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => self.name.cmp(&other.name),
                x => x,
            }
        } else {
            self.name.cmp(&other.name)
        }
    }
}

impl PartialOrd for Column {
    fn partial_cmp(&self, other: &Column) -> Option<Ordering> {
        if self.table.is_some() && other.table.is_some() {
            match self.table.cmp(&other.table) {
                Ordering::Equal => Some(self.name.cmp(&other.name)),
                x => Some(x),
            }
        } else if self.table.is_none() && other.table.is_none() {
            Some(self.name.cmp(&other.name))
        } else {
            None
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum ColumnConstraint {
    NotNull,
    Collation(String),
    DefaultValue(Literal),
    AutoIncrement,
    PrimaryKey,
    Unique,
}

impl fmt::Display for ColumnConstraint {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ColumnConstraint::NotNull => write!(f, "NOT NULL"),
            ColumnConstraint::Collation(ref collation) => write!(f, "COLLATE {}", collation),
            ColumnConstraint::DefaultValue(ref literal) => {
                write!(f, "DEFAULT {}", literal.to_string())
            }
            ColumnConstraint::AutoIncrement => write!(f, "AUTO_INCREMENT"),
            ColumnConstraint::PrimaryKey => write!(f, "PRIMARY KEY"),
            ColumnConstraint::Unique => write!(f, "UNIQUE"),
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ColumnSpecification {
    pub column: Column,
    pub sql_type: SqlType,
    pub constraints: Vec<ColumnConstraint>,
}

impl fmt::Display for ColumnSpecification {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} {}",
            escape_if_keyword(&self.column.name),
            self.sql_type
        )?;
        for constraint in self.constraints.iter() {
            write!(f, " {}", constraint)?;
        }
        Ok(())
    }
}

impl ColumnSpecification {
    pub fn new(c: Column, t: SqlType) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: vec![],
        }
    }

    pub fn with_constraints(
        c: Column,
        t: SqlType,
        ccs: Vec<ColumnConstraint>,
    ) -> ColumnSpecification {
        ColumnSpecification {
            column: c,
            sql_type: t,
            constraints: ccs,
        }
    }
}

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

    #[test]
    fn column_from_str() {
        let s = "table.col";
        let c = Column::from(s);

        assert_eq!(
            c,
            Column {
                name: String::from("col"),
                alias: None,
                table: Some(String::from("table")),
                function: None,
            }
        );
    }

    #[test]
    fn print_function_column() {
        let c1 = Column {
            name: "".into(), // must be present, but will be ignored
            alias: Some("foo".into()),
            table: None,
            function: Some(Box::new(FunctionExpression::CountStar)),
        };
        let c2 = Column {
            name: "".into(), // must be present, but will be ignored
            alias: None,
            table: None,
            function: Some(Box::new(FunctionExpression::CountStar)),
        };

        assert_eq!(format!("{}", c1), "count(*) AS foo");
        assert_eq!(format!("{}", c2), "count(*)");
    }

}
<|endoftext|>


<commit_before>// $ cargo bench --features full --bench rust
//
// Syn only, useful for profiling:
// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full --bench rust

#![cfg_attr(not(syn_only), feature(rustc_private))]

#[path = "../tests/repo/mod.rs"]
mod repo;

use std::fs;
use std::time::{Duration, Instant};

#[cfg(not(syn_only))]
mod tokenstream_parse {
    use proc_macro2::TokenStream;
    use std::str::FromStr;

    pub fn bench(content: &str) -> Result<(), ()> {
        TokenStream::from_str(content).map(drop).map_err(drop)
    }
}

mod syn_parse {
    pub fn bench(content: &str) -> Result<(), ()> {
        syn::parse_file(content).map(drop).map_err(drop)
    }
}

#[cfg(not(syn_only))]
mod libsyntax_parse {
    extern crate rustc_data_structures;
    extern crate rustc_span;
    extern crate syntax;

    use rustc_data_structures::sync::Lrc;
    use rustc_span::FileName;
    use syntax::edition::Edition;
    use syntax::errors::{emitter::Emitter, DiagnosticBuilder, Handler};
    use syntax::parse::ParseSess;
    use syntax::source_map::{FilePathMapping, SourceMap};

    pub fn bench(content: &str) -> Result<(), ()> {
        struct SilentEmitter;

        impl Emitter for SilentEmitter {
            fn emit_diagnostic(&mut self, _db: &DiagnosticBuilder) {}
        }

        syntax::with_globals(Edition::Edition2018, || {
            let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
            let emitter = Box::new(SilentEmitter);
            let handler = Handler::with_emitter(false, None, emitter);
            let sess = ParseSess::with_span_handler(handler, cm);
            if let Err(mut diagnostic) = syntax::parse::parse_crate_from_source_str(
                FileName::Custom("bench".to_owned()),
                content.to_owned(),
                &sess,
            ) {
                diagnostic.cancel();
                return Err(());
            };
            Ok(())
        })
    }
}

#[cfg(not(syn_only))]
mod read_from_disk {
    pub fn bench(content: &str) -> Result<(), ()> {
        let _ = content;
        Ok(())
    }
}

fn exec(mut codepath: impl FnMut(&str) -> Result<(), ()>) -> Duration {
    let begin = Instant::now();
    let mut success = 0;
    let mut total = 0;

    walkdir::WalkDir::new("tests/rust/src")
        .into_iter()
        .filter_entry(repo::base_dir_filter)
        .for_each(|entry| {
            let entry = entry.unwrap();
            let path = entry.path();
            if path.is_dir() {
                return;
            }
            let content = fs::read_to_string(path).unwrap();
            let ok = codepath(&content).is_ok();
            success += ok as usize;
            total += 1;
            if !ok {
                eprintln!("FAIL {}", path.display());
            }
        });

    assert_eq!(success, total);
    begin.elapsed()
}

fn main() {
    repo::clone_rust();

    macro_rules! testcases {
        ($($(#[$cfg:meta])* $name:path,)*) => {
            vec![
                $(
                    $(#[$cfg])*
                    (stringify!($name), $name as fn(&str) -> Result<(), ()>),
                )*
            ]
        };
    }

    #[cfg(not(syn_only))]
    {
        let mut lines = 0;
        let mut files = 0;
        exec(|content| {
            lines += content.lines().count();
            files += 1;
            Ok(())
        });
        eprintln!("\n{} lines in {} files", lines, files);
    }

    for (name, f) in testcases!(
        #[cfg(not(syn_only))]
        read_from_disk::bench,
        #[cfg(not(syn_only))]
        tokenstream_parse::bench,
        syn_parse::bench,
        #[cfg(not(syn_only))]
        libsyntax_parse::bench,
    ) {
        eprint!("{:20}", format!("{}:", name));
        let elapsed = exec(f);
        eprintln!(
            "elapsed={}.{:03}s",
            elapsed.as_secs(),
            elapsed.subsec_millis(),
        );
    }
    eprintln!();
}
<commit_msg>Update benchmark for libsyntax nightly changes<commit_after>// $ cargo bench --features full --bench rust
//
// Syn only, useful for profiling:
// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full --bench rust

#![cfg_attr(not(syn_only), feature(rustc_private))]

#[path = "../tests/repo/mod.rs"]
mod repo;

use std::fs;
use std::time::{Duration, Instant};

#[cfg(not(syn_only))]
mod tokenstream_parse {
    use proc_macro2::TokenStream;
    use std::str::FromStr;

    pub fn bench(content: &str) -> Result<(), ()> {
        TokenStream::from_str(content).map(drop).map_err(drop)
    }
}

mod syn_parse {
    pub fn bench(content: &str) -> Result<(), ()> {
        syn::parse_file(content).map(drop).map_err(drop)
    }
}

#[cfg(not(syn_only))]
mod libsyntax_parse {
    extern crate rustc_data_structures;
    extern crate rustc_parse;
    extern crate rustc_span;
    extern crate syntax;

    use rustc_data_structures::sync::Lrc;
    use rustc_span::FileName;
    use syntax::edition::Edition;
    use syntax::errors::{emitter::Emitter, Diagnostic, Handler};
    use syntax::sess::ParseSess;
    use syntax::source_map::{FilePathMapping, SourceMap};

    pub fn bench(content: &str) -> Result<(), ()> {
        struct SilentEmitter;

        impl Emitter for SilentEmitter {
            fn emit_diagnostic(&mut self, _diag: &Diagnostic) {}
            fn source_map(&self) -> Option<&Lrc<SourceMap>> {
                None
            }
        }

        syntax::with_globals(Edition::Edition2018, || {
            let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
            let emitter = Box::new(SilentEmitter);
            let handler = Handler::with_emitter(false, None, emitter);
            let sess = ParseSess::with_span_handler(handler, cm);
            if let Err(mut diagnostic) = rustc_parse::parse_crate_from_source_str(
                FileName::Custom("bench".to_owned()),
                content.to_owned(),
                &sess,
            ) {
                diagnostic.cancel();
                return Err(());
            };
            Ok(())
        })
    }
}

#[cfg(not(syn_only))]
mod read_from_disk {
    pub fn bench(content: &str) -> Result<(), ()> {
        let _ = content;
        Ok(())
    }
}

fn exec(mut codepath: impl FnMut(&str) -> Result<(), ()>) -> Duration {
    let begin = Instant::now();
    let mut success = 0;
    let mut total = 0;

    walkdir::WalkDir::new("tests/rust/src")
        .into_iter()
        .filter_entry(repo::base_dir_filter)
        .for_each(|entry| {
            let entry = entry.unwrap();
            let path = entry.path();
            if path.is_dir() {
                return;
            }
            let content = fs::read_to_string(path).unwrap();
            let ok = codepath(&content).is_ok();
            success += ok as usize;
            total += 1;
            if !ok {
                eprintln!("FAIL {}", path.display());
            }
        });

    assert_eq!(success, total);
    begin.elapsed()
}

fn main() {
    repo::clone_rust();

    macro_rules! testcases {
        ($($(#[$cfg:meta])* $name:path,)*) => {
            vec![
                $(
                    $(#[$cfg])*
                    (stringify!($name), $name as fn(&str) -> Result<(), ()>),
                )*
            ]
        };
    }

    #[cfg(not(syn_only))]
    {
        let mut lines = 0;
        let mut files = 0;
        exec(|content| {
            lines += content.lines().count();
            files += 1;
            Ok(())
        });
        eprintln!("\n{} lines in {} files", lines, files);
    }

    for (name, f) in testcases!(
        #[cfg(not(syn_only))]
        read_from_disk::bench,
        #[cfg(not(syn_only))]
        tokenstream_parse::bench,
        syn_parse::bench,
        #[cfg(not(syn_only))]
        libsyntax_parse::bench,
    ) {
        eprint!("{:20}", format!("{}:", name));
        let elapsed = exec(f);
        eprintln!(
            "elapsed={}.{:03}s",
            elapsed.as_secs(),
            elapsed.subsec_millis(),
        );
    }
    eprintln!();
}
<|endoftext|>


<commit_before>enum Monster {
  ScubaArgentine(int, int, int, int),
  IndustrialRaverMonster(int, int, int, int)
}

impl Monster {
  fn attack(&self) {
    match *self {
      ScubaArgentine(l, s, c, w) => println(fmt!("The monster attacks for %d damage.", w)),
      IndustrialRaverMonster(l, s, c, w) => println(fmt!("The monster attacks for %d damage.", w))
    }
  }
}

fn main() {
  let irm = IndustrialRaverMonster(46, 35, 91, 2);
  irm.attack();
}
<commit_msg>DwemthysArray using traits<commit_after>trait Monster {
  fn attack(&self);
  fn new() -> Self;
}

struct IndustrialRaverMonkey {
  life: int,
  strength: int,
  charisma: int,
  weapon: int
}

struct DwarvenAngel {
  life: int,
  strength: int,
  charisma: int,
  weapon: int
}

struct AssistantViceTentacleAndOmbudsman {
  life: int,
  strength: int,
  charisma: int,
  weapon: int
}

struct TeethDeer {
  life: int,
  strength: int,
  charisma: int,
  weapon: int
}

struct IntrepidDecomposedCyclist {
  life: int,
  strength: int,
  charisma: int,
  weapon: int
}

struct Dragon {
  life: int,
  strength: int,
  charisma: int,
  weapon: int
}

impl Monster for IndustrialRaverMonkey {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.strength));
  }

  fn new() -> IndustrialRaverMonkey {
    IndustrialRaverMonkey {life: 46, strength: 35, charisma: 91, weapon: 2}
  }
}

impl Monster for DwarvenAngel {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.strength));
  }

  fn new() -> DwarvenAngel {
    DwarvenAngel {life: 540, strength: 6, charisma: 144, weapon: 50}
  }
}

impl Monster for AssistantViceTentacleAndOmbudsman {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.strength));
  }

  fn new() -> AssistantViceTentacleAndOmbudsman {
    AssistantViceTentacleAndOmbudsman {life: 320, strength: 6, charisma: 144, weapon: 50}
  }
}

impl Monster for TeethDeer {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.strength));
  }

  fn new() -> TeethDeer {
    TeethDeer {life: 655, strength: 192, charisma: 19, weapon: 109}
  }
}

impl Monster for IntrepidDecomposedCyclist {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.strength));
  }

  fn new() -> IntrepidDecomposedCyclist {
    IntrepidDecomposedCyclist {life: 901, strength: 560, charisma: 422, weapon: 105}
  }
}

impl Monster for Dragon {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.strength));
  }

  fn new() -> Dragon {
    Dragon {life: 1340, strength: 451, charisma: 1020, weapon: 939}
  }
}

fn monsters_attack(monsters: &[@Monster]) {
  for monster in monsters.iter() {
    monster.attack();
  }
}

fn main() {
  let monkey: @IndustrialRaverMonkey               = @Monster::new();
  let angel: @DwarvenAngel                         = @Monster::new();
  let tentacle: @AssistantViceTentacleAndOmbudsman = @Monster::new();
  let deer: @TeethDeer                             = @Monster::new();
  let cyclist: @IntrepidDecomposedCyclist          = @Monster::new();
  let dragon: @Dragon                              = @Monster::new();

  let dwemthys_vector: @[@Monster] = @[monkey as @Monster, angel as @Monster, tentacle as @Monster, deer as @Monster, cyclist as @Monster, dragon as @Monster];

  monsters_attack(dwemthys_vector);
}
<|endoftext|>


<commit_before>use std::io::File;

use collections::treemap::TreeMap;
use serialize::json::ToJson;

use quire::parse;
use J = serialize::json;

use Pid1 = super::linux;
use super::yamlutil::{get_string, get_dict, get_list, get_command, get_bool};
use super::yamlutil::{get_ranges};

#[deriving(Show)]
pub enum SuperviseMode {
    WaitAll,
    StopOnFailure,
    Restart,
}

pub enum Executor {
    Shell(String),
    Plain(Vec<String>),
    Supervise(SuperviseMode, TreeMap<String, Command>),
}

pub struct Command {
    pub pid1mode: Pid1::Pid1Mode,
    pub execute: Executor,
    pub work_dir: Option<String>,
    pub container: Option<String>,
    pub accepts_arguments: bool,
    pub environ: TreeMap<String, String>,
    pub inherit_environ: Vec<String>,
    pub description: Option<String>,
    pub resolv_conf: bool,
}

pub struct Variant {
    pub default: Option<String>,
    pub options: Vec<String>,
}

#[deriving(Clone)]
pub struct Range {
    pub start: uint,
    pub end: uint,
}

pub struct Container {
    pub default_command: Option<Vec<String>>,
    pub command_wrapper: Option<Vec<String>>,
    pub shell: Vec<String>,
    pub builder: String,
    pub provision: Option<String>,
    pub parameters: TreeMap<String, String>,
    pub environ_file: Option<String>,
    pub environ: TreeMap<String, String>,
    pub uids: Vec<Range>,
    pub gids: Vec<Range>,
}

pub struct Config {
    pub commands: TreeMap<String, Command>,
    pub variants: TreeMap<String, Variant>,
    pub containers: TreeMap<String, Container>,
}

impl Range {
    pub fn new(start: uint, end: uint) -> Range {
        return Range { start: start, end: end };
    }
    pub fn len(&self) -> uint {
        return self.end - self.start + 1;
    }
    pub fn shift(&self, val: uint) -> Range {
        assert!(self.end - self.start + 1 >= val);
        return Range::new(self.start + val, self.end);
    }
}

fn find_config_path(work_dir: &Path) -> Option<(Path, Path)> {
    let mut dir = work_dir.clone();
    loop {
        let fname = dir.join_many([".vagga", "vagga.yaml"]);
        if fname.exists() {
            return Some((dir, fname));
        }
        let fname = dir.join("vagga.yaml");
        if fname.exists() {
            return Some((dir, fname));
        }
        if !dir.pop() {
            return None;
        }
    }
}

pub fn get_supervise(map: &TreeMap<String, J::Json>)
    -> Result<Option<(SuperviseMode, TreeMap<String, Command>)>, String>
{
    let mode = match map.find(&"supervise-mode".to_string()) {
        Some(&J::String(ref val)) => match val.as_slice() {
            "wait-all" => WaitAll,
            "stop-on-failure" => StopOnFailure,
            "restart" => Restart,
            _ => return Err(format!("The `supervise-mode` can be one of
                `wait-all`, `stop-on-failure` (default) or `restart`")),
        },
        None => StopOnFailure,
        _ => return Err(format!("The `supervise-mode` must be string")),
    };
    let mut commands = TreeMap::new();
    let ocommands = match map.find(&"supervise".to_string()) {
        None => return Ok(None),
        Some(&J::Object(ref map)) => map,
        _ => return Err(format!("The `supervise` must be mapping")),
    };
    for (name, jcmd) in ocommands.iter() {
        let cmd = try!(parse_command(name, jcmd));
        commands.insert(name.clone(), cmd);
    }
    return Ok(Some((mode, commands)));
}

fn one<T>(opt: &Option<T>) -> int {
    return if opt.is_some() { 1 } else { 0 };
}

fn parse_command(name: &String, jcmd: &J::Json) -> Result<Command, String> {
    let dcmd = match jcmd {
        &J::Object(ref dict) => dict,
        _ => return Err(format!(
            "Command {} must be mapping", name)),
    };

    let run = get_string(jcmd, "run");
    let command = get_command(jcmd, "command");
    let supervise = try!(get_supervise(*dcmd));
    if one(&run) + one(&command) + one(&supervise) != 1 {
        return Err(format!("Expected exactly one of \
            `command` or `run` or `supervise` for command {}",
            name));
    }
    let container = get_string(jcmd, "container");
    if container.is_none() && supervise.is_none() {
        return Err(format!("The `container` is required for command {}",
                           name));
    }
    let mut accepts_arguments = false;
    let executor = if run.is_some() {
        Shell(run.unwrap())
    } else if command.is_some() {
        accepts_arguments = true;
        Plain(command.unwrap())
    } else if supervise.is_some() {
        let (mode, svcs) = supervise.unwrap();
        Supervise(mode, svcs)
    } else {
        unreachable!();
    };
    let accepts_arguments = get_bool(jcmd, "accepts-arguments")
        //  By default accept arguments only by command
        //  because "sh -c" only uses arguments if there is
        //  $1, $2.. used in the expression
        .unwrap_or(accepts_arguments);
    return Ok(Command {
        pid1mode: match get_string(jcmd, "pid1mode") {
            Some(ref s) if s.as_slice() == "wait" => Pid1::Wait,
            Some(ref s) if s.as_slice() == "wait-all-children"
                => Pid1::WaitAllChildren,
            Some(ref s) if s.as_slice() == "exec" => Pid1::Exec,
            None => Pid1::Wait,
            _ => return Err(format!("The pid1mode must be one of `wait`, \
                `wait-all-children` or `exec` for command {}", name)),
            },
        execute: executor,
        container: container,
        work_dir: get_string(jcmd, "work-dir"),
        accepts_arguments: accepts_arguments,
        environ: get_dict(jcmd, "environ"),
        inherit_environ: get_list(jcmd, "inherit-environ"),
        description: get_string(jcmd, "description"),
        resolv_conf: get_bool(jcmd, "resolv_conf").unwrap_or(true),
    });
}

pub fn find_config(work_dir: &Path) -> Result<(Config, Path), String>{
    let (cfg_dir, filename) = match find_config_path(work_dir) {
        Some(pair) => pair,
        None => return Err(format!(
            "Config not found in path {}", work_dir.display())),
    };
    let fname = filename.display();
    let data = match File::open(&filename).read_to_str() {
        Ok(data) => data,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };
    let json = match parse(data.as_slice(), |doc| {
        return doc.to_json();
    }) {
        Ok(json) => json,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };

    let mut config = Config {
        commands: TreeMap::new(),
        variants: TreeMap::new(),
        containers: TreeMap::new(),
    };

    let root = match json {
        J::Object(val) => val,
        _ => return Err(format!("{}: root node must be mapping", fname)),
    };

    match root.find(&"commands".to_string()) {
        Some(&J::Object(ref commands)) => {
            for (name, jcmd) in commands.iter() {
                let cmd = try!(parse_command(name, jcmd));
                config.commands.insert(name.clone(), cmd);
            }
        }
        Some(_) => return Err(format!(
            "{}: commands key must be mapping", fname)),
        None => {}
    }

    match root.find(&"containers".to_string()) {
        Some(&J::Object(ref containers)) => {
            for (name, jcont) in containers.iter() {
                let cont = Container {
                    default_command: get_command(jcont, "default-command"),
                    command_wrapper: get_command(jcont, "command-wrapper"),
                    shell: get_command(jcont, "shell").unwrap_or(
                        vec!("/bin/sh".to_string(), "-c".to_string())),
                    builder: get_string(jcont, "builder")
                             .unwrap_or("nix".to_string()),
                    parameters: get_dict(jcont, "parameters"),
                    environ: get_dict(jcont, "environ"),
                    environ_file: get_string(jcont, "environ-file"),
                    provision: get_string(jcont, "provision"),
                    uids: get_ranges(jcont, "uids"),
                    gids: get_ranges(jcont, "gids"),
                };
                config.containers.insert(name.clone(), cont);
            }
        }
        Some(_) => return Err(format!(
            "{}: containers key must be mapping", fname)),
        None => {}
    }

    match root.find(&"variants".to_string()) {
        Some(&J::Object(ref variants)) => {
            for (name, jvar) in variants.iter() {
                let var = Variant {
                    default: get_string(jvar, "default"),
                    options: get_list(jvar, "options"),
                };
                config.variants.insert(name.clone(), var);
            }
        }
        Some(_) => return Err(format!(
            "{}: variants key must be mapping", fname)),
        None => {}
    }

    return Ok((config, cfg_dir));
}
<commit_msg>Better debugging of uid/gid ranges<commit_after>use std::io::File;

use collections::treemap::TreeMap;
use serialize::json::ToJson;

use quire::parse;
use J = serialize::json;

use Pid1 = super::linux;
use super::yamlutil::{get_string, get_dict, get_list, get_command, get_bool};
use super::yamlutil::{get_ranges};

#[deriving(Show)]
pub enum SuperviseMode {
    WaitAll,
    StopOnFailure,
    Restart,
}

pub enum Executor {
    Shell(String),
    Plain(Vec<String>),
    Supervise(SuperviseMode, TreeMap<String, Command>),
}

pub struct Command {
    pub pid1mode: Pid1::Pid1Mode,
    pub execute: Executor,
    pub work_dir: Option<String>,
    pub container: Option<String>,
    pub accepts_arguments: bool,
    pub environ: TreeMap<String, String>,
    pub inherit_environ: Vec<String>,
    pub description: Option<String>,
    pub resolv_conf: bool,
}

pub struct Variant {
    pub default: Option<String>,
    pub options: Vec<String>,
}

#[deriving(Clone, Show)]
pub struct Range {
    pub start: uint,
    pub end: uint,
}

pub struct Container {
    pub default_command: Option<Vec<String>>,
    pub command_wrapper: Option<Vec<String>>,
    pub shell: Vec<String>,
    pub builder: String,
    pub provision: Option<String>,
    pub parameters: TreeMap<String, String>,
    pub environ_file: Option<String>,
    pub environ: TreeMap<String, String>,
    pub uids: Vec<Range>,
    pub gids: Vec<Range>,
}

pub struct Config {
    pub commands: TreeMap<String, Command>,
    pub variants: TreeMap<String, Variant>,
    pub containers: TreeMap<String, Container>,
}

impl Range {
    pub fn new(start: uint, end: uint) -> Range {
        return Range { start: start, end: end };
    }
    pub fn len(&self) -> uint {
        return self.end - self.start + 1;
    }
    pub fn shift(&self, val: uint) -> Range {
        assert!(self.end - self.start + 1 >= val);
        return Range::new(self.start + val, self.end);
    }
}

fn find_config_path(work_dir: &Path) -> Option<(Path, Path)> {
    let mut dir = work_dir.clone();
    loop {
        let fname = dir.join_many([".vagga", "vagga.yaml"]);
        if fname.exists() {
            return Some((dir, fname));
        }
        let fname = dir.join("vagga.yaml");
        if fname.exists() {
            return Some((dir, fname));
        }
        if !dir.pop() {
            return None;
        }
    }
}

pub fn get_supervise(map: &TreeMap<String, J::Json>)
    -> Result<Option<(SuperviseMode, TreeMap<String, Command>)>, String>
{
    let mode = match map.find(&"supervise-mode".to_string()) {
        Some(&J::String(ref val)) => match val.as_slice() {
            "wait-all" => WaitAll,
            "stop-on-failure" => StopOnFailure,
            "restart" => Restart,
            _ => return Err(format!("The `supervise-mode` can be one of
                `wait-all`, `stop-on-failure` (default) or `restart`")),
        },
        None => StopOnFailure,
        _ => return Err(format!("The `supervise-mode` must be string")),
    };
    let mut commands = TreeMap::new();
    let ocommands = match map.find(&"supervise".to_string()) {
        None => return Ok(None),
        Some(&J::Object(ref map)) => map,
        _ => return Err(format!("The `supervise` must be mapping")),
    };
    for (name, jcmd) in ocommands.iter() {
        let cmd = try!(parse_command(name, jcmd));
        commands.insert(name.clone(), cmd);
    }
    return Ok(Some((mode, commands)));
}

fn one<T>(opt: &Option<T>) -> int {
    return if opt.is_some() { 1 } else { 0 };
}

fn parse_command(name: &String, jcmd: &J::Json) -> Result<Command, String> {
    let dcmd = match jcmd {
        &J::Object(ref dict) => dict,
        _ => return Err(format!(
            "Command {} must be mapping", name)),
    };

    let run = get_string(jcmd, "run");
    let command = get_command(jcmd, "command");
    let supervise = try!(get_supervise(*dcmd));
    if one(&run) + one(&command) + one(&supervise) != 1 {
        return Err(format!("Expected exactly one of \
            `command` or `run` or `supervise` for command {}",
            name));
    }
    let container = get_string(jcmd, "container");
    if container.is_none() && supervise.is_none() {
        return Err(format!("The `container` is required for command {}",
                           name));
    }
    let mut accepts_arguments = false;
    let executor = if run.is_some() {
        Shell(run.unwrap())
    } else if command.is_some() {
        accepts_arguments = true;
        Plain(command.unwrap())
    } else if supervise.is_some() {
        let (mode, svcs) = supervise.unwrap();
        Supervise(mode, svcs)
    } else {
        unreachable!();
    };
    let accepts_arguments = get_bool(jcmd, "accepts-arguments")
        //  By default accept arguments only by command
        //  because "sh -c" only uses arguments if there is
        //  $1, $2.. used in the expression
        .unwrap_or(accepts_arguments);
    return Ok(Command {
        pid1mode: match get_string(jcmd, "pid1mode") {
            Some(ref s) if s.as_slice() == "wait" => Pid1::Wait,
            Some(ref s) if s.as_slice() == "wait-all-children"
                => Pid1::WaitAllChildren,
            Some(ref s) if s.as_slice() == "exec" => Pid1::Exec,
            None => Pid1::Wait,
            _ => return Err(format!("The pid1mode must be one of `wait`, \
                `wait-all-children` or `exec` for command {}", name)),
            },
        execute: executor,
        container: container,
        work_dir: get_string(jcmd, "work-dir"),
        accepts_arguments: accepts_arguments,
        environ: get_dict(jcmd, "environ"),
        inherit_environ: get_list(jcmd, "inherit-environ"),
        description: get_string(jcmd, "description"),
        resolv_conf: get_bool(jcmd, "resolv_conf").unwrap_or(true),
    });
}

pub fn find_config(work_dir: &Path) -> Result<(Config, Path), String>{
    let (cfg_dir, filename) = match find_config_path(work_dir) {
        Some(pair) => pair,
        None => return Err(format!(
            "Config not found in path {}", work_dir.display())),
    };
    let fname = filename.display();
    let data = match File::open(&filename).read_to_str() {
        Ok(data) => data,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };
    let json = match parse(data.as_slice(), |doc| {
        return doc.to_json();
    }) {
        Ok(json) => json,
        Err(e) => return Err(format!("{}: {}", fname, e)),
    };

    let mut config = Config {
        commands: TreeMap::new(),
        variants: TreeMap::new(),
        containers: TreeMap::new(),
    };

    let root = match json {
        J::Object(val) => val,
        _ => return Err(format!("{}: root node must be mapping", fname)),
    };

    match root.find(&"commands".to_string()) {
        Some(&J::Object(ref commands)) => {
            for (name, jcmd) in commands.iter() {
                let cmd = try!(parse_command(name, jcmd));
                config.commands.insert(name.clone(), cmd);
            }
        }
        Some(_) => return Err(format!(
            "{}: commands key must be mapping", fname)),
        None => {}
    }

    match root.find(&"containers".to_string()) {
        Some(&J::Object(ref containers)) => {
            for (name, jcont) in containers.iter() {
                let cont = Container {
                    default_command: get_command(jcont, "default-command"),
                    command_wrapper: get_command(jcont, "command-wrapper"),
                    shell: get_command(jcont, "shell").unwrap_or(
                        vec!("/bin/sh".to_string(), "-c".to_string())),
                    builder: get_string(jcont, "builder")
                             .unwrap_or("nix".to_string()),
                    parameters: get_dict(jcont, "parameters"),
                    environ: get_dict(jcont, "environ"),
                    environ_file: get_string(jcont, "environ-file"),
                    provision: get_string(jcont, "provision"),
                    uids: get_ranges(jcont, "uids"),
                    gids: get_ranges(jcont, "gids"),
                };
                config.containers.insert(name.clone(), cont);
            }
        }
        Some(_) => return Err(format!(
            "{}: containers key must be mapping", fname)),
        None => {}
    }

    match root.find(&"variants".to_string()) {
        Some(&J::Object(ref variants)) => {
            for (name, jvar) in variants.iter() {
                let var = Variant {
                    default: get_string(jvar, "default"),
                    options: get_list(jvar, "options"),
                };
                config.variants.insert(name.clone(), var);
            }
        }
        Some(_) => return Err(format!(
            "{}: variants key must be mapping", fname)),
        None => {}
    }

    return Ok((config, cfg_dir));
}
<|endoftext|>


<commit_before>extern crate num as libnum;

pub mod math {

	pub mod linalg {

		pub trait Metric<T> {
			fn norm(&self) -> T;
		}

		pub mod matrix;
		pub mod vector;
	}

	pub mod utils;
}

pub mod optim {

}<commit_msg>TODO comment.<commit_after>extern crate num as libnum;

pub mod math {

	pub mod linalg {

		pub trait Metric<T> {
			fn norm(&self) -> T;
		}

		pub mod matrix;
		pub mod vector;
	}

	// this should be private and tested in document.
	pub mod utils;
}

pub mod optim {

}<|endoftext|>


<commit_before>use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::io::Write;
use std::collections::btree_map::BTreeMap;
use std::collections::btree_set::BTreeSet;
use std::iter::Iterator;

use sbsqsort;

macro_rules! errorln(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

pub struct Recommender {
  categories : BTreeMap<String, BTreeSet<String>>,
  pages : BTreeMap<String, BTreeSet<String>>,
}

impl Recommender {
  pub fn load_knowlege(path : String) -> Recommender  {
    let file = match File::open(path) {
        Ok(file) => file,
        Err(..)  => panic!("room"),
    };

    let reader = BufReader::new(&file);

    let mut categories = BTreeMap::new();
    let mut pages      = BTreeMap::new();

    for line in reader.lines().filter_map(|result| result.ok()) {
      let data : Vec<&str> = line.split(" ").collect();
      match data.len()  {
        0 => {
          errorln!("empty line found");
          continue;
        },
        1 => {
          errorln!("{} contains no categories", data[0]);
          continue;
        }
        _ => {}
      }

      let key = data[0];

      let page = pages.entry(String::from(key))
                      .or_insert(BTreeSet::new());

      for &category in data[1..].iter() {
        let category = String::from(category);

        page.insert(category.clone());
        categories.entry(category.clone())
                  .or_insert(BTreeSet::new())
                  .insert(String::from(key));
      }
    }

    let ret = Recommender {
      categories: categories,
      pages: pages
    };

    return ret;
  }

  pub fn recommend(self, categories : Vec<String>) -> Vec<String> {
    let mut ranked_pages = BTreeMap::new();

    for category in categories.iter() {
      match self.categories.get(category) {
        Some(self_cat) => {
          for page in self_cat.iter() {
            match self.pages.get(page) {
              Some(pages) => {
                ranked_pages.entry(page.clone())
                            .or_insert(
                                Recommender::similarity(categories.iter(), pages.iter()));
              },
              _ => {}
            }
          }
        },
        _ => {}
      }
    }

    let mut keys : Vec<String> = ranked_pages.keys().cloned().collect();
    let mut values : Vec<u64> = ranked_pages.values().cloned().collect();
    sbsqsort::quicksort(&mut values, &mut keys);

    return keys;
  }

  fn similarity<'a, S: Iterator<Item = &'a String>, T: Clone + Iterator<Item = &'a String>>(a : S, b : T) -> u64 {
     let mut found_in_both = 0;
     let mut cnt_a = 0;
     let mut cnt_b = 0;

     for _ in b.clone() { cnt_b += 1; }
     for c in a {
      cnt_a += 1;
      for d in b.clone() {
        if c == d {
          found_in_both += 1;
          break;
        }
      }
     }

     return 1000 * ((2 * found_in_both) as u64 / (cnt_a + cnt_b)) as u64;
  }
}

<commit_msg>more descriptive error messages<commit_after>use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::io::Write;
use std::collections::btree_map::BTreeMap;
use std::collections::btree_set::BTreeSet;
use std::iter::Iterator;

use sbsqsort;

macro_rules! errorln(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e),
        }
    )
);

pub struct Recommender {
  categories : BTreeMap<String, BTreeSet<String>>,
  pages : BTreeMap<String, BTreeSet<String>>,
}

impl Recommender {
  pub fn load_knowlege(path : String) -> Recommender  {
    let file = match File::open(path) {
        Ok(file) => file,
        Err(e)  => panic!("Error occured opening knowlege file: {} ", e),
    };

    let reader = BufReader::new(&file);

    let mut categories = BTreeMap::new();
    let mut pages      = BTreeMap::new();

    for line in reader.lines().filter_map(|result| result.ok()) {
      let data : Vec<&str> = line.split(" ").collect();
      match data.len()  {
        0 => {
          errorln!("empty line found");
          continue;
        },
        1 => {
          errorln!("{} contains no categories", data[0]);
          continue;
        }
        _ => {}
      }

      let key = data[0];

      let page = pages.entry(String::from(key))
                      .or_insert(BTreeSet::new());

      for &category in data[1..].iter() {
        let category = String::from(category);

        page.insert(category.clone());
        categories.entry(category.clone())
                  .or_insert(BTreeSet::new())
                  .insert(String::from(key));
      }
    }

    let ret = Recommender {
      categories: categories,
      pages: pages
    };

    return ret;
  }

  pub fn recommend(self, categories : Vec<String>) -> Vec<String> {
    let mut ranked_pages = BTreeMap::new();

    for category in categories.iter() {
      match self.categories.get(category) {
        Some(self_cat) => {
          for page in self_cat.iter() {
            match self.pages.get(page) {
              Some(pages) => {
                ranked_pages.entry(page.clone())
                            .or_insert(
                                Recommender::similarity(categories.iter(), pages.iter()));
              },
              _ => {}
            }
          }
        },
        _ => {}
      }
    }

    let mut keys : Vec<String> = ranked_pages.keys().cloned().collect();
    let mut values : Vec<u64> = ranked_pages.values().cloned().collect();
    sbsqsort::quicksort(&mut values, &mut keys);

    return keys;
  }

  fn similarity<'a, S: Iterator<Item = &'a String>, T: Clone + Iterator<Item = &'a String>>(a : S, b : T) -> u64 {
     let mut found_in_both = 0;
     let mut cnt_a = 0;
     let mut cnt_b = 0;

     for _ in b.clone() { cnt_b += 1; }
     for c in a {
      cnt_a += 1;
      for d in b.clone() {
        if c == d {
          found_in_both += 1;
          break;
        }
      }
     }

     return 1000 * ((2 * found_in_both) as u64 / (cnt_a + cnt_b)) as u64;
  }
}

<|endoftext|>


<commit_before>use std::convert::From;
use std::error;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::io;
use std::result;

use data::{MAX_KEY_SIZE, MAX_VALUE_SIZE};

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    InvalidFileId(u32),
    InvalidKeySize(usize),
    InvalidValueSize(usize),
    InvalidChecksum { expected: u32, found: u32 },
    InvalidPath(String),
}

pub type Result<T> = result::Result<T, Error>;

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            Error::Io(ref err) => write!(f, "IO error: {}", err),
            Error::InvalidFileId(file_id) => write!(f, "Invalid file id: {}", file_id),
            Error::InvalidKeySize(size) => {
                write!(f,
                       "Invalid key size, max: {}, found: {}",
                       MAX_KEY_SIZE,
                       size)
            }
            Error::InvalidValueSize(size) => {
                write!(f,
                       "Invalid value size, max: {}, found: {}",
                       MAX_VALUE_SIZE,
                       size)
            }
            Error::InvalidChecksum { expected, found } => {
                write!(f,
                       "Invalid checksum, expected: {}, found: {}",
                       expected,
                       found)
            }
            Error::InvalidPath(ref path) => write!(f, "Invalid path provided: {}", path),
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Io(ref err) => err.description(),
            Error::InvalidFileId(..) => "Invalid file id",
            Error::InvalidChecksum { .. } => "Invalid checksum",
            Error::InvalidKeySize(..) => "Invalid key size",
            Error::InvalidValueSize(..) => "Invalid value size",
            Error::InvalidPath(..) => "Invalid path",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Io(ref err) => Some(err),
            _ => None,
        }
    }
}
<commit_msg>document errors module<commit_after>use std::convert::From;
use std::error;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::io;
use std::result;

use data::{MAX_KEY_SIZE, MAX_VALUE_SIZE};

/// Basic type to represent all possible errors that can occur when interacting with a `Cask`.
#[derive(Debug)]
pub enum Error {
    /// IO error.
    Io(io::Error),
    /// Tried to perform an operation on an invalid `file_id`.
    InvalidFileId(u32),
    /// Invalid key size, i.e. larger than the maximum key size.
    InvalidKeySize(usize),
    /// Invalid value size, i.e. larger than the maximum value size.
    InvalidValueSize(usize),
    /// Invalid checksum found, potential data corruption.
    InvalidChecksum { expected: u32, found: u32 },
    /// Invalid path provided.
    InvalidPath(String),
}

/// Value returned from potentially-error operations.
pub type Result<T> = result::Result<T, Error>;

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            Error::Io(ref err) => write!(f, "IO error: {}", err),
            Error::InvalidFileId(file_id) => write!(f, "Invalid file id: {}", file_id),
            Error::InvalidKeySize(size) => {
                write!(f,
                       "Invalid key size, max: {}, found: {}",
                       MAX_KEY_SIZE,
                       size)
            }
            Error::InvalidValueSize(size) => {
                write!(f,
                       "Invalid value size, max: {}, found: {}",
                       MAX_VALUE_SIZE,
                       size)
            }
            Error::InvalidChecksum { expected, found } => {
                write!(f,
                       "Invalid checksum, expected: {}, found: {}",
                       expected,
                       found)
            }
            Error::InvalidPath(ref path) => write!(f, "Invalid path provided: {}", path),
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Io(ref err) => err.description(),
            Error::InvalidFileId(..) => "Invalid file id",
            Error::InvalidChecksum { .. } => "Invalid checksum",
            Error::InvalidKeySize(..) => "Invalid key size",
            Error::InvalidValueSize(..) => "Invalid value size",
            Error::InvalidPath(..) => "Invalid path",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Io(ref err) => Some(err),
            _ => None,
        }
    }
}
<|endoftext|>


<commit_before>pub use std::clone::Clone;
pub use std::cmp::{Eq, PartialEq};
pub use std::convert::From;
pub use std::default::Default;
pub use std::fmt::{self, Debug, Formatter};
pub use std::hash::{Hash, Hasher};
pub use std::marker::Copy;
pub use std::option::Option::{None, Some};
pub use std::result::Result::{Err, Ok};

pub use proc_macro2::{Span, TokenStream as TokenStream2};

pub use span::IntoSpans;

#[cfg(feature = "proc-macro")]
pub use proc_macro::TokenStream;

#[cfg(feature = "printing")]
pub use quote::{ToTokens, TokenStreamExt};

#[allow(non_camel_case_types)]
pub type bool = help::Bool;
#[allow(non_camel_case_types)]
pub type str = help::Str;

mod help {
    pub type Bool = bool;
    pub type Str = str;
}
<commit_msg>Fix building on wasm32 target.<commit_after>pub use std::clone::Clone;
pub use std::cmp::{Eq, PartialEq};
pub use std::convert::From;
pub use std::default::Default;
pub use std::fmt::{self, Debug, Formatter};
pub use std::hash::{Hash, Hasher};
pub use std::marker::Copy;
pub use std::option::Option::{None, Some};
pub use std::result::Result::{Err, Ok};

pub use proc_macro2::{Span, TokenStream as TokenStream2};

pub use span::IntoSpans;

#[cfg(all(
    not(all(target_arch = "wasm32", target_os = "unknown")),
    feature = "proc-macro"
))]
pub use proc_macro::TokenStream;

#[cfg(feature = "printing")]
pub use quote::{ToTokens, TokenStreamExt};

#[allow(non_camel_case_types)]
pub type bool = help::Bool;
#[allow(non_camel_case_types)]
pub type str = help::Str;

mod help {
    pub type Bool = bool;
    pub type Str = str;
}
<|endoftext|>