<commit_before><commit_msg>Refactor tmp dir in outer<commit_after><|endoftext|>


<commit_before>extern crate bragi;
extern crate iron_test;
extern crate serde_json;
use super::BragiHandler;
use super::get_values;
use super::get_value;
use super::get_types;
use super::count_types;

pub fn bragi_features_test(es_wrapper: ::ElasticSearchWrapper) {
    let bragi = BragiHandler::new(format!("{}/munin", es_wrapper.host()));

    // *********************************
    // We load the OSM dataset and three-cities bano dataset
    // the current dataset are thus (load order matters):
    // - osm_fixture.osm.pbf (including ways)
    // - bano-three_cities
    // *********************************
    let osm2mimir = concat!(env!("OUT_DIR"), "/../../../osm2mimir");
    ::launch_and_assert(osm2mimir,
                        vec!["--input=./tests/fixtures/osm_fixture.osm.pbf".into(),
                             "--import-way".into(),
                             "--level=8".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let bano2mimir = concat!(env!("OUT_DIR"), "/../../../bano2mimir");
    ::launch_and_assert(bano2mimir,
                        vec!["--input=./tests/fixtures/bano-three_cities.csv".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let stops2mimir = concat!(env!("OUT_DIR"), "/../../../stops2mimir");
    ::launch_and_assert(stops2mimir,
                        vec!["--input=./tests/fixtures/stops.txt".into(),
                             "--dataset=dataset1".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    addr_by_id_test(&bragi);
    admin_by_id_test(&bragi);
    street_by_id_test(&bragi);
    stop_by_id_test(&bragi);
}

fn admin_by_id_test(bragi: &BragiHandler) {
    let all_20 = bragi.get("/features/admin:fr:77288");
    assert_eq!(all_20.len(), 1);
    let types = get_types(&all_20);
    let count = count_types(&types, "city");
    assert_eq!(count, 1);

    assert_eq!(get_values(&all_20, "id"),
               vec!["admin:fr:77288"]);
}

fn street_by_id_test(bragi: &BragiHandler) {
    let all_20 = bragi.get("/features/161162362");
    assert_eq!(all_20.len(), 1);
    let types = get_types(&all_20);

    let count = count_types(&types, "street");
    assert_eq!(count, 1);

    assert_eq!(get_values(&all_20, "id"),
               vec!["161162362"]);
}

fn addr_by_id_test(bragi: &BragiHandler) {
    let all_20 = bragi.get("/features/addr:2.68385;48.50539");
    assert_eq!(all_20.len(), 1);
    let types = get_types(&all_20);
    let count = count_types(&types, "house");
    assert_eq!(count, 1);
    assert_eq!(get_values(&all_20, "id"),
               vec!["addr:2.68385;48.50539"]);
}

fn stop_by_id_test(bragi: &BragiHandler) {
    // search with id
    let response = bragi.get("/features/stop_area:SA:second_station?pt_dataset=dataset1");
    assert_eq!(response.len(), 1);
    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"),
               "stop_area:SA:second_station");

}
<commit_msg>correction<commit_after>extern crate bragi;
extern crate iron_test;
extern crate serde_json;
use super::BragiHandler;
use super::get_values;
use super::get_value;
use super::get_types;
use super::count_types;

pub fn bragi_features_test(es_wrapper: ::ElasticSearchWrapper) {
    let bragi = BragiHandler::new(format!("{}/munin", es_wrapper.host()));

    // *********************************
    // We load the OSM dataset and three-cities bano dataset
    // the current dataset are thus (load order matters):
    // - osm_fixture.osm.pbf (including ways)
    // - bano-three_cities
    // *********************************
    let osm2mimir = concat!(env!("OUT_DIR"), "/../../../osm2mimir");
    ::launch_and_assert(osm2mimir,
                        vec!["--input=./tests/fixtures/osm_fixture.osm.pbf".into(),
                             "--import-way".into(),
                             "--level=8".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let bano2mimir = concat!(env!("OUT_DIR"), "/../../../bano2mimir");
    ::launch_and_assert(bano2mimir,
                        vec!["--input=./tests/fixtures/bano-three_cities.csv".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let stops2mimir = concat!(env!("OUT_DIR"), "/../../../stops2mimir");
    ::launch_and_assert(stops2mimir,
                        vec!["--input=./tests/fixtures/stops.txt".into(),
                             "--dataset=dataset1".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    addr_by_id_test(&bragi);
    admin_by_id_test(&bragi);
    street_by_id_test(&bragi);
    stop_by_id_test(&bragi);
}

fn admin_by_id_test(bragi: &BragiHandler) {
    let all_20 = bragi.get("/features/admin:fr:77288");
    assert_eq!(all_20.len(), 1);
    let types = get_types(&all_20);
    let count = count_types(&types, "city");
    assert_eq!(count, 1);

    assert_eq!(get_values(&all_20, "id"), vec!["admin:fr:77288"]);
}

fn street_by_id_test(bragi: &BragiHandler) {
    let all_20 = bragi.get("/features/161162362");
    assert_eq!(all_20.len(), 1);
    let types = get_types(&all_20);

    let count = count_types(&types, "street");
    assert_eq!(count, 1);

    assert_eq!(get_values(&all_20, "id"), vec!["161162362"]);
}

fn addr_by_id_test(bragi: &BragiHandler) {
    let all_20 = bragi.get("/features/addr:2.68385;48.50539");
    assert_eq!(all_20.len(), 1);
    let types = get_types(&all_20);
    let count = count_types(&types, "house");
    assert_eq!(count, 1);
    assert_eq!(get_values(&all_20, "id"), vec!["addr:2.68385;48.50539"]);
}

fn stop_by_id_test(bragi: &BragiHandler) {
    // search with id
    let response = bragi.get("/features/stop_area:SA:second_station?pt_dataset=dataset1");
    assert_eq!(response.len(), 1);
    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");

}
<|endoftext|>


<commit_before>// ToDO: add tests
<commit_msg>test(groups): Add tests<commit_after>use crate::common::util::*;
use std::env;

#[test]
fn test_groups() {
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.run();
    println!("result.stdout {}", result.stdout);
    println!("result.stderr = {}", result.stderr);
    if env::var("USER").is_ok()
        && env::var("USER").unwrap() == "runner"
        && result.stdout.trim().is_empty()
    {
        // In the CI, some server are failing to return the group.
        // As seems to be a configuration issue, ignoring it
        return;
    }
    assert!(result.success);
    assert!(!result.stdout.trim().is_empty());
}

#[test]
fn test_groups_arg() {
    // get the username with the "id -un" command
    let result = TestScenario::new("id").ucmd_keepenv().arg("-un").run();
    println!("result.stdout {}", result.stdout);
    println!("result.stderr = {}", result.stderr);
    let s1 = String::from(result.stdout.trim());
    if s1.parse::<f64>().is_ok() {
        // In the CI, some server are failing to return id -un.
        // So, if we are getting a uid, just skip this test
        // As seems to be a configuration issue, ignoring it
        return;
    }

    println!("result.stdout {}", result.stdout);
    println!("result.stderr = {}", result.stderr);
    assert!(result.success);
    assert!(!result.stdout.is_empty());
    let username = result.stdout.trim();

    // call groups with the user name to check that we
    // are getting something
    let (_, mut ucmd) = at_and_ucmd!();
    let result = ucmd.arg(username).run();
    println!("result.stdout {}", result.stdout);
    println!("result.stderr = {}", result.stderr);
    assert!(result.success);
    assert!(!result.stdout.is_empty());
}
<|endoftext|>


<commit_before>use tokio_core;
use futures::future::*;

use azure::service_bus::event_hub::send_event;
use azure::core::errors::AzureError;

use time::Duration;

use crypto::sha2::Sha256;
use crypto::hmac::Hmac;

pub struct Client {
    handle: tokio_core::reactor::Handle,
    namespace: String,
    event_hub: String,
    policy_name: String,
    hmac: Hmac<Sha256>,
}

impl Client {
    pub fn new(
        handle: tokio_core::reactor::Handle,
        namespace: &str,
        event_hub: &str,
        policy_name: &str,
        key: &str,
    ) -> Client {
        let mut v_hmac_key: Vec<u8> = Vec::new();
        v_hmac_key.extend(key.as_bytes());
        let hmac = Hmac::new(Sha256::new(), &v_hmac_key);

        Client {
            handle: handle,
            namespace: namespace.to_owned(),
            event_hub: event_hub.to_owned(),
            policy_name: policy_name.to_owned(),
            hmac: hmac,
        }
    }

    pub fn send_event(
        &mut self,
        event_body: &str,
        duration: Duration,
    ) -> impl Future<Item = (), Error = AzureError> {
        {
            send_event(
                &self.handle.clone(),
                &self.namespace,
                &self.event_hub,
                &self.policy_name,
                &mut self.hmac,
                event_body,
                duration,
            )
        }
    }
}

#[cfg(test)]
mod test {
    #[allow(unused_imports)]
    use super::Client;

    #[test]
    pub fn client_ctor() {
        Client::new("namespace", "event_hub", "policy", "key");
    }

    #[test]
    pub fn client_enc() {
        use crypto::mac::Mac;
        use base64;

        let str_to_sign = "This must be secret!";

        let mut c = Client::new("namespace", "event_hub", "policy", "key");

        c.hmac.input(str_to_sign.as_bytes());
        let sig = base64::encode(c.hmac.result().code());

        assert_eq!(sig, "2UNXaoPpeJBAhh6qxmTqXyNzTpOflGO6IhxegeUQBcU=");
    }
}
<commit_msg>fixed tests<commit_after>use tokio_core;
use futures::future::*;

use azure::service_bus::event_hub::send_event;
use azure::core::errors::AzureError;

use time::Duration;

use crypto::sha2::Sha256;
use crypto::hmac::Hmac;

pub struct Client {
    handle: tokio_core::reactor::Handle,
    namespace: String,
    event_hub: String,
    policy_name: String,
    hmac: Hmac<Sha256>,
}

impl Client {
    pub fn new(
        handle: tokio_core::reactor::Handle,
        namespace: &str,
        event_hub: &str,
        policy_name: &str,
        key: &str,
    ) -> Client {
        let mut v_hmac_key: Vec<u8> = Vec::new();
        v_hmac_key.extend(key.as_bytes());
        let hmac = Hmac::new(Sha256::new(), &v_hmac_key);

        Client {
            handle: handle,
            namespace: namespace.to_owned(),
            event_hub: event_hub.to_owned(),
            policy_name: policy_name.to_owned(),
            hmac: hmac,
        }
    }

    pub fn send_event(
        &mut self,
        event_body: &str,
        duration: Duration,
    ) -> impl Future<Item = (), Error = AzureError> {
        {
            send_event(
                &self.handle.clone(),
                &self.namespace,
                &self.event_hub,
                &self.policy_name,
                &mut self.hmac,
                event_body,
                duration,
            )
        }
    }
}

#[cfg(test)]
mod test {
    #[allow(unused_imports)]
    use super::Client;

    #[test]
    pub fn client_enc() {
        use crypto::mac::Mac;
        use base64;
        use tokio_core::reactor::Core;

        let str_to_sign = "This must be secret!";

        let core = Core::new().unwrap();
        let mut c = Client::new(core.handle(), "namespace", "event_hub", "policy", "key");

        c.hmac.input(str_to_sign.as_bytes());
        let sig = base64::encode(c.hmac.result().code());

        assert_eq!(sig, "2UNXaoPpeJBAhh6qxmTqXyNzTpOflGO6IhxegeUQBcU=");
    }
}
<|endoftext|>


<commit_before>/// Internal namespace.
pub mod internal
{

  ///
  /// Internals of a test suite.
  ///

  #[ macro_export ]
  macro_rules! impls
  {

    () => {};

    (
      $( #[ $Meta : meta ] )*
      $( pub )?
      fn $Name : ident
      $( $Rest : tt )*
    )
    =>
    {
      $crate::impls!
      {
        as DEFINE_FN
        as META $( #[ $Meta ] )*
        as VIS $( pub )?
        as NAME $Name
        as INPUT ()
        as OUTPUT
        as BLOCK {}
        as REST
          $( #[ $Meta ] )*
          $( pub )? fn $Name
          $( $Rest )*
      }
    };

    // (
    //   $( #[ $Meta : meta ] )*
    //   fn $Name : ident
    //   // $( < $( $ParamName : ident : $ParamType : ty ),* > )?
    //   // $Input : tt
    //   // $( -> $Output : ty )?
    //   // $Block : block
    //   $( $Rest : tt )*
    // )
    // =>
    // {
    //   $crate::impls!
    //   {
    //     as DEFINE_FN
    //     as META $( #[ $Meta ] )*
    //     as VIS
    //     as NAME $Name
    //     as INPUT ()
    //     as OUTPUT
    //     as BLOCK {}
    //     as REST
    //       $( #[ $Meta ] )*
    //       fn $Name
    //       // $Input $( -> $Output )?
    //       // $Block
    //       $( $Rest )*
    //   }
    // };

//     (
//       $( #[ $Meta : meta ] )*
//       pub
//       fn $Name : ident
//       $Input : tt
//       $( -> $Output : ty )?
//       $Block : block
//       $( $Rest : tt )*
//     )
//     =>
//     {
//       $crate::impls!
//       {
//         as DEFINE_FN
//         as META $( #[ $Meta ] )*
//         as VIS pub
//         as NAME $Name
//         as INPUT $Input
//         as OUTPUT $( -> $Output )?
//         as BLOCK $Block
//         as REST
//           $( #[ $Meta ] )*
//           pub fn $Name $Input $( -> $Output )?
//           $Block
//           $( $Rest )*
//       }
//     };
//
//     (
//       $( #[ $Meta : meta ] )*
//       fn $Name : ident
//       $Input : tt
//       $( -> $Output : ty )?
//       $Block : block
//       $( $Rest : tt )*
//     )
//     =>
//     {
//       $crate::impls!
//       {
//         as DEFINE_FN
//         as META $( #[ $Meta ] )*
//         as VIS
//         as NAME $Name
//         as INPUT $Input
//         as OUTPUT $( -> $Output )?
//         as BLOCK $Block
//         as REST
//           $( #[ $Meta ] )*
//           fn $Name $Input $( -> $Output )?
//           $Block
//           $( $Rest )*
//       }
//     };

    (
      as DEFINE_FN
      as META $( #[ $Meta : meta ] )*
      as VIS $( pub )*
      as NAME $Name : ident
      as INPUT $Input : tt
      as OUTPUT $( -> $Output : ty )?
      as BLOCK $Block : block
      as REST
        $Item : item
        $( $Rest : tt )*
    )
    =>
    {
      // #[ deny( unused_macros ) ]
      macro_rules! $Name
      {
        () =>
        {
          $Item
        };
        // ( as AS $Name : ident ) =>
        // {
        //   $( #[ $Meta ] )*
        //   fn $Name
        // };
      }

      $crate::impls!
      {
        $( $Rest )*
      }
    };

  }

  ///
  /// Index of items.
  ///

  #[ macro_export ]
  macro_rules! index
  {

    () => { };

    (
      $Name : ident ,
      $( $Rest : tt )*
    )
    =>
    {
      $Name!();
      $crate::index!( $( $Rest )* );
    };

  }

  ///
  /// Index of items.
  ///

  #[ macro_export ]
  macro_rules! ignore_macro
  {

    () => { };

    (
      $Name : ident ,
      $( $Rest : tt )*
    )
    =>
    {
      $Name!();
      stringify!( $crate::index!( $( $Rest )* ) );
    };

  }

//   ///
//   /// Index of items.
//   ///
//
//   #[ macro_export ]
//   macro_rules! index2
//   {
//
//     () => { };
//
//     (
//       $Name : ident ,
//       $( $Rest : tt )*
//     )
//     =>
//     {{
//       $Name!();
//       $crate::index2!( as ACT $( $Rest )* );
//     }};
//
//     ( as ACT ) => { };
//
//     (
//       as ACT
//       $Name : ident ,
//       $( $Rest : tt )*
//     )
//     =>
//     {
//       $Name!();
//       $crate::index2!( as ACT $( $Rest )* );
//     };
//
//   }

  pub use impls;
  pub use index;
  pub use ignore_macro;
}

/// Exposed namespace of the module.
pub mod exposed
{
  // use super::internal as i;
  pub use super::prelude::*;
}

pub use exposed::*;

/// Prelude to use: `use wtools::prelude::*`.
pub mod prelude
{
  use super::internal as i;
  pub use i::impls;
  pub use i::index;
  pub use i::ignore_macro;
}
<commit_msg>evolve automata<commit_after>/// Internal namespace.
pub mod internal
{

  ///
  /// Internals of a test suite.
  ///

  #[ macro_export ]
  macro_rules! impls
  {

    () => {};

    (
      $( #[ $Meta : meta ] )*
      $Vis : vis
      fn $Name : ident
      $( $Rest : tt )*
    )
    =>
    {
      $crate::impls!
      {
        @DEFINE_FN
        @META $( #[ $Meta ] )*
        @VIS{ $Vis }
        @NAME $Name
        // @INPUT ()
        // @OUTPUT
        // @BLOCK {}
        @REST
          $( #[ $Meta ] )*
          $Vis fn $Name
          $( $Rest )*
      }
    };

    // (
    //   $( #[ $Meta : meta ] )*
    //   fn $Name : ident
    //   // $( < $( $ParamName : ident : $ParamType : ty ),* > )?
    //   // $Input : tt
    //   // $( -> $Output : ty )?
    //   // $Block : block
    //   $( $Rest : tt )*
    // )
    // =>
    // {
    //   $crate::impls!
    //   {
    //     @DEFINE_FN
    //     @META $( #[ $Meta ] )*
    //     @VIS
    //     @NAME $Name
    //     @INPUT ()
    //     @OUTPUT
    //     @BLOCK {}
    //     @REST
    //       $( #[ $Meta ] )*
    //       fn $Name
    //       // $Input $( -> $Output )?
    //       // $Block
    //       $( $Rest )*
    //   }
    // };

//     (
//       $( #[ $Meta : meta ] )*
//       pub
//       fn $Name : ident
//       $Input : tt
//       $( -> $Output : ty )?
//       $Block : block
//       $( $Rest : tt )*
//     )
//     =>
//     {
//       $crate::impls!
//       {
//         @DEFINE_FN
//         @META $( #[ $Meta ] )*
//         @VIS pub
//         @NAME $Name
//         @INPUT $Input
//         @OUTPUT $( -> $Output )?
//         @BLOCK $Block
//         @REST
//           $( #[ $Meta ] )*
//           pub fn $Name $Input $( -> $Output )?
//           $Block
//           $( $Rest )*
//       }
//     };
//
//     (
//       $( #[ $Meta : meta ] )*
//       fn $Name : ident
//       $Input : tt
//       $( -> $Output : ty )?
//       $Block : block
//       $( $Rest : tt )*
//     )
//     =>
//     {
//       $crate::impls!
//       {
//         @DEFINE_FN
//         @META $( #[ $Meta ] )*
//         @VIS
//         @NAME $Name
//         @INPUT $Input
//         @OUTPUT $( -> $Output )?
//         @BLOCK $Block
//         @REST
//           $( #[ $Meta ] )*
//           fn $Name $Input $( -> $Output )?
//           $Block
//           $( $Rest )*
//       }
//     };

    (
      @DEFINE_FN
      @META $( #[ $Meta : meta ] )*
      @VIS{ $Vis : vis }
      @NAME $Name : ident
      // @INPUT $Input : tt
      // @OUTPUT $( -> $Output : ty )?
      // @BLOCK $Block : block
      @REST
        $Item : item
        $( $Rest : tt )*
    )
    =>
    {
      // #[ deny( unused_macros ) ]
      macro_rules! $Name
      {
        () =>
        {
          $Item
        };
        // ( @AS $Name : ident ) =>
        // {
        //   $( #[ $Meta ] )*
        //   fn $Name
        // };
      }

      $crate::impls!
      {
        $( $Rest )*
      }
    };

  }

  ///
  /// Index of items.
  ///

  #[ macro_export ]
  macro_rules! index
  {

    () => { };

    (
      $Name : ident ,
      $( $Rest : tt )*
    )
    =>
    {
      $Name!();
      $crate::index!( $( $Rest )* );
    };

  }

  ///
  /// Index of items.
  ///

  #[ macro_export ]
  macro_rules! ignore_macro
  {

    () => { };

    (
      $Name : ident ,
      $( $Rest : tt )*
    )
    =>
    {
      $Name!();
      stringify!( $crate::index!( $( $Rest )* ) );
    };

  }

  pub use impls;
  pub use index;
  pub use ignore_macro;
}

/// Exposed namespace of the module.
pub mod exposed
{
  // use super::internal as i;
  pub use super::prelude::*;
}

pub use exposed::*;

/// Prelude to use: `use wtools::prelude::*`.
pub mod prelude
{
  use super::internal as i;
  pub use i::impls;
  pub use i::index;
  pub use i::ignore_macro;
}
<|endoftext|>


<commit_before>use std::collections;
use std::fmt;
use std::error::Error as ErrorTrait;

use rustc_serialize::json;
use rustc_serialize::json::ToJson;

use hyper::header;

use url;

use iron::prelude::*;
use iron::modifiers::Header;
use iron::status;

use urlencoded;

// FIXME: oauth module should not be concerned with serialization
#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
pub struct OauthRequest {
    pub session: Session,
    pub state: Option<String>,
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
pub struct Session {
    pub client_id: String,
    pub uri: url::Url,
    pub permissions: collections::HashMap<String, CategoryPermissions>
}

impl Session {
    pub fn permissions_for_category(&self, category: &str) -> Option<&CategoryPermissions> {
        match self.permissions.get(category) {
            Some(x) => Some(x),
            None => self.permissions.get("")
        }
    }

    pub fn identifier(&self) -> String {
        // FIXME: Ugly
        match self.uri.origin() {
            url::Origin::Tuple(scheme, host, port) => url::Url::parse(
                format!("{}://{}:{}", scheme, host, port)
            ).unwrap().serialize(),
            _ => panic!("Invalid URL: {:?}", self.uri)
        }
    }
}

impl ToJson for Session {
    fn to_json(&self) -> json::Json {
        json::Json::Object({
            let mut rv = collections::BTreeMap::new();
            rv.insert("client_id".to_owned(), self.client_id.to_json());
            rv.insert("uri".to_owned(), self.uri.serialize().to_json());
            rv.insert("permissions".to_owned(), self.permissions.to_json());
            rv
        })
    }
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone, Copy)]
pub struct CategoryPermissions {
    pub can_read: bool,
    pub can_write: bool
}

impl ToJson for CategoryPermissions {
    // ToJson for passing to template
    fn to_json(&self) -> json::Json {
        json::Json::Object({
            let mut rv = collections::BTreeMap::new();
            rv.insert("can_read".to_owned(), self.can_read.to_json());
            rv.insert("can_write".to_owned(), self.can_write.to_json());
            rv
        })
    }
}

impl ToJson for OauthRequest {
    // ToJson for passing to template
    fn to_json(&self) -> json::Json {
        self.session.to_json()
    }
}

fn expect_param(query: &urlencoded::QueryMap, key: &str) -> Result<String, Error> {
    match query.get(key) {
        Some(x) if x.len() == 1 => Ok(x[0].clone()),
        _ => Err({
            let mut rv = Error::new(ErrorKind::InvalidRequest);
            rv.msg = Some(format!("Missing query parameter: {:?}", key));
            rv
        })
    }
}

impl OauthRequest {
    pub fn from_http(request: &mut Request) -> Result<Self, Error> {
        let query = match request.get_ref::<urlencoded::UrlEncodedQuery>().ok() {
            Some(x) => x,
            None => return Err({
                let mut e = Error::new(ErrorKind::InvalidRequest);
                e.msg = Some("No query parameters.".to_owned());
                e
            })
        };

        let mut rv = OauthRequest {
            session: Session {
                client_id: "".to_owned(),
                uri: match url::Url::parse(&try!(expect_param(query, "redirect_uri"))[..]) {
                    Ok(x) => x,
                    Err(e) => return Err({
                        let mut ne = Error::new(ErrorKind::InvalidRequest);
                        ne.msg = Some(format!("{}", e));
                        ne
                    })
                },
                permissions: collections::HashMap::new()
            },
            state: expect_param(query, "state").ok()
        };

        rv.session.client_id = match expect_param(query, "client_id") {
            Ok(x) => x,
            Err(mut e) => {
                e.request = Some(rv);
                return Err(e);
            }
        };

        let scope = match expect_param(query, "scope") {
            Ok(x) => x,
            Err(mut e) => {
                e.request = Some(rv);
                return Err(e);
            }
        };

        let scope_err = |x| { Err({
            let mut e = Error::new(ErrorKind::InvalidScope);
            e.msg = Some("Invalid scope.".to_owned());
            e.request = Some(x);
            e
        }) };

        for category_permission in scope.split(' ') {
            let parts = category_permission.split(':').collect::<Vec<_>>();
            if parts.len() != 2 { return scope_err(rv); }

            let (category, permission) = (parts[0], parts[1]);
            if category.len() == 0 || permission.len() == 0 { return scope_err(rv); }

            let key = (if category == "*" { "" } else { category }).to_owned();
            if rv.session.permissions.get(&key).is_some() { return scope_err(rv); }

            rv.session.permissions.insert(key, CategoryPermissions {
                can_read: permission.contains("r"),
                can_write: permission.contains("w")
            });
        }

        Ok(rv)
    }

    pub fn grant(self, token: String) -> Grant {
        Grant { request: self, token: token }
    }

    pub fn reject(self) -> Error {
        let mut e = Error::new(ErrorKind::AccessDenied);
        e.request = Some(self);
        e
    }
}

pub struct Grant {
    pub request: OauthRequest,
    pub token: String
}

impl HttpResponder for Grant {
    fn get_redirect_uri(&self) -> Option<url::Url> {
        Some(self.request.session.uri.clone())
    }

    fn get_redirect_uri_params(&self) -> collections::BTreeMap<String, String> {
        let mut rv = collections::BTreeMap::new();
        rv.insert("access_token".to_owned(), self.token.clone());
        self.request.state.as_ref().map(|x| rv.insert("state".to_owned(), x.clone()));
        rv
    }
}

#[derive(Debug)]
pub struct Error {
    pub kind: ErrorKind,
    pub request: Option<OauthRequest>,
    pub error_uri: Option<url::Url>,
    pub msg: Option<String>
}

impl Error {
    pub fn new(kind: ErrorKind) -> Self {
        Error {
            kind: kind,
            request: None,
            error_uri: None,
            msg: None
        }
    }
}

#[derive(Debug)]
#[allow(dead_code)]
pub enum ErrorKind {
    InvalidRequest,
    UnauthorizedClient,
    AccessDenied,
    UnsupportedResponseType,
    InvalidScope,
    ServerError,
    TemporarilyUnavailable
}

impl ErrorKind {
    fn as_snake_case(&self) -> &str {
        match *self {
            ErrorKind::InvalidRequest => "invalid_request",
            ErrorKind::UnauthorizedClient => "unauthorized_client",
            ErrorKind::AccessDenied => "access_denied",
            ErrorKind::UnsupportedResponseType => "unsupported_response_type",
            ErrorKind::InvalidScope => "invalid_scope",
            ErrorKind::ServerError => "server_error",
            ErrorKind::TemporarilyUnavailable => "temporarily_unavailable"
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.description().fmt(f) }
}

impl ErrorTrait for Error {
    fn description(&self) -> &str {
        match self.msg {
            Some(ref x) => x,
            None => self.kind.as_snake_case()
        }
    }
    fn cause(&self) -> Option<&ErrorTrait> { None }
}

pub trait HttpResponder {
    fn get_redirect_uri(&self) -> Option<url::Url>;
    fn get_redirect_uri_params(&self) -> collections::BTreeMap<String, String>;

    fn get_response(&self) -> Option<Response> {
        self.get_redirect_uri()
            .map(|mut uri| {
                uri.fragment = Some(url::form_urlencoded::serialize(self.get_redirect_uri_params()));
                Response::with(status::Found)
                 // Do not use Redirect modifier here, we need to handle custom URI schemes as well
                 .set(Header(header::Location(uri.serialize())))
            })
    }
}

impl HttpResponder for Error {
    fn get_redirect_uri(&self) -> Option<url::Url> {
        self.request.as_ref().map(|req| req.session.uri.clone())
    }

    fn get_redirect_uri_params(&self) -> collections::BTreeMap<String, String> {
        let mut rv = collections::BTreeMap::new();
        rv.insert("error".to_owned(), self.kind.as_snake_case().to_owned());
        self.msg.as_ref().map(|x| rv.insert("error_description".to_owned(), x.clone()));
        self.request.as_ref().map(|req| req.state.as_ref().map(|state| rv.insert("state".to_owned(), state.clone())));
        rv
    }
}
<commit_msg>fixup<commit_after>use std::collections;
use std::fmt;
use std::error::Error as ErrorTrait;

use rustc_serialize::json;
use rustc_serialize::json::ToJson;

use hyper::header;

use url;

use iron::prelude::*;
use iron::modifiers::Header;
use iron::status;

use urlencoded;

// FIXME: oauth module should not be concerned with serialization
#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
pub struct OauthRequest {
    pub session: Session,
    pub state: Option<String>,
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
pub struct Session {
    pub client_id: String,
    pub uri: url::Url,
    pub permissions: collections::HashMap<String, CategoryPermissions>
}

impl Session {
    pub fn permissions_for_category(&self, category: &str) -> Option<&CategoryPermissions> {
        match self.permissions.get(category) {
            Some(x) => Some(x),
            None => self.permissions.get("")
        }
    }

    pub fn identifier(&self) -> String {
        // FIXME: Ugly
        match self.uri.origin() {
            url::Origin::Tuple(scheme, host, port) => url::Url::parse(
                &format!("{}://{}:{}", scheme, host, port)[..]
            ).unwrap().serialize(),
            _ => panic!("Invalid URL: {:?}", self.uri)
        }
    }
}

impl ToJson for Session {
    fn to_json(&self) -> json::Json {
        json::Json::Object({
            let mut rv = collections::BTreeMap::new();
            rv.insert("client_id".to_owned(), self.client_id.to_json());
            rv.insert("uri".to_owned(), self.uri.serialize().to_json());
            rv.insert("permissions".to_owned(), self.permissions.to_json());
            rv
        })
    }
}

#[derive(RustcDecodable, RustcEncodable, Debug, Clone, Copy)]
pub struct CategoryPermissions {
    pub can_read: bool,
    pub can_write: bool
}

impl ToJson for CategoryPermissions {
    // ToJson for passing to template
    fn to_json(&self) -> json::Json {
        json::Json::Object({
            let mut rv = collections::BTreeMap::new();
            rv.insert("can_read".to_owned(), self.can_read.to_json());
            rv.insert("can_write".to_owned(), self.can_write.to_json());
            rv
        })
    }
}

impl ToJson for OauthRequest {
    // ToJson for passing to template
    fn to_json(&self) -> json::Json {
        self.session.to_json()
    }
}

fn expect_param(query: &urlencoded::QueryMap, key: &str) -> Result<String, Error> {
    match query.get(key) {
        Some(x) if x.len() == 1 => Ok(x[0].clone()),
        _ => Err({
            let mut rv = Error::new(ErrorKind::InvalidRequest);
            rv.msg = Some(format!("Missing query parameter: {:?}", key));
            rv
        })
    }
}

impl OauthRequest {
    pub fn from_http(request: &mut Request) -> Result<Self, Error> {
        let query = match request.get_ref::<urlencoded::UrlEncodedQuery>().ok() {
            Some(x) => x,
            None => return Err({
                let mut e = Error::new(ErrorKind::InvalidRequest);
                e.msg = Some("No query parameters.".to_owned());
                e
            })
        };

        let mut rv = OauthRequest {
            session: Session {
                client_id: "".to_owned(),
                uri: match url::Url::parse(&try!(expect_param(query, "redirect_uri"))[..]) {
                    Ok(x) => x,
                    Err(e) => return Err({
                        let mut ne = Error::new(ErrorKind::InvalidRequest);
                        ne.msg = Some(format!("{}", e));
                        ne
                    })
                },
                permissions: collections::HashMap::new()
            },
            state: expect_param(query, "state").ok()
        };

        rv.session.client_id = match expect_param(query, "client_id") {
            Ok(x) => x,
            Err(mut e) => {
                e.request = Some(rv);
                return Err(e);
            }
        };

        let scope = match expect_param(query, "scope") {
            Ok(x) => x,
            Err(mut e) => {
                e.request = Some(rv);
                return Err(e);
            }
        };

        let scope_err = |x| { Err({
            let mut e = Error::new(ErrorKind::InvalidScope);
            e.msg = Some("Invalid scope.".to_owned());
            e.request = Some(x);
            e
        }) };

        for category_permission in scope.split(' ') {
            let parts = category_permission.split(':').collect::<Vec<_>>();
            if parts.len() != 2 { return scope_err(rv); }

            let (category, permission) = (parts[0], parts[1]);
            if category.len() == 0 || permission.len() == 0 { return scope_err(rv); }

            let key = (if category == "*" { "" } else { category }).to_owned();
            if rv.session.permissions.get(&key).is_some() { return scope_err(rv); }

            rv.session.permissions.insert(key, CategoryPermissions {
                can_read: permission.contains("r"),
                can_write: permission.contains("w")
            });
        }

        Ok(rv)
    }

    pub fn grant(self, token: String) -> Grant {
        Grant { request: self, token: token }
    }

    pub fn reject(self) -> Error {
        let mut e = Error::new(ErrorKind::AccessDenied);
        e.request = Some(self);
        e
    }
}

pub struct Grant {
    pub request: OauthRequest,
    pub token: String
}

impl HttpResponder for Grant {
    fn get_redirect_uri(&self) -> Option<url::Url> {
        Some(self.request.session.uri.clone())
    }

    fn get_redirect_uri_params(&self) -> collections::BTreeMap<String, String> {
        let mut rv = collections::BTreeMap::new();
        rv.insert("access_token".to_owned(), self.token.clone());
        self.request.state.as_ref().map(|x| rv.insert("state".to_owned(), x.clone()));
        rv
    }
}

#[derive(Debug)]
pub struct Error {
    pub kind: ErrorKind,
    pub request: Option<OauthRequest>,
    pub error_uri: Option<url::Url>,
    pub msg: Option<String>
}

impl Error {
    pub fn new(kind: ErrorKind) -> Self {
        Error {
            kind: kind,
            request: None,
            error_uri: None,
            msg: None
        }
    }
}

#[derive(Debug)]
#[allow(dead_code)]
pub enum ErrorKind {
    InvalidRequest,
    UnauthorizedClient,
    AccessDenied,
    UnsupportedResponseType,
    InvalidScope,
    ServerError,
    TemporarilyUnavailable
}

impl ErrorKind {
    fn as_snake_case(&self) -> &str {
        match *self {
            ErrorKind::InvalidRequest => "invalid_request",
            ErrorKind::UnauthorizedClient => "unauthorized_client",
            ErrorKind::AccessDenied => "access_denied",
            ErrorKind::UnsupportedResponseType => "unsupported_response_type",
            ErrorKind::InvalidScope => "invalid_scope",
            ErrorKind::ServerError => "server_error",
            ErrorKind::TemporarilyUnavailable => "temporarily_unavailable"
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.description().fmt(f) }
}

impl ErrorTrait for Error {
    fn description(&self) -> &str {
        match self.msg {
            Some(ref x) => x,
            None => self.kind.as_snake_case()
        }
    }
    fn cause(&self) -> Option<&ErrorTrait> { None }
}

pub trait HttpResponder {
    fn get_redirect_uri(&self) -> Option<url::Url>;
    fn get_redirect_uri_params(&self) -> collections::BTreeMap<String, String>;

    fn get_response(&self) -> Option<Response> {
        self.get_redirect_uri()
            .map(|mut uri| {
                uri.fragment = Some(url::form_urlencoded::serialize(self.get_redirect_uri_params()));
                Response::with(status::Found)
                 // Do not use Redirect modifier here, we need to handle custom URI schemes as well
                 .set(Header(header::Location(uri.serialize())))
            })
    }
}

impl HttpResponder for Error {
    fn get_redirect_uri(&self) -> Option<url::Url> {
        self.request.as_ref().map(|req| req.session.uri.clone())
    }

    fn get_redirect_uri_params(&self) -> collections::BTreeMap<String, String> {
        let mut rv = collections::BTreeMap::new();
        rv.insert("error".to_owned(), self.kind.as_snake_case().to_owned());
        self.msg.as_ref().map(|x| rv.insert("error_description".to_owned(), x.clone()));
        self.request.as_ref().map(|req| req.state.as_ref().map(|state| rv.insert("state".to_owned(), state.clone())));
        rv
    }
}
<|endoftext|>


<commit_before>#![allow(clippy::blacklisted_name)]
use tokio::sync::{mpsc, oneshot};
use tokio::task;
use tokio_test::{assert_ok, assert_pending, assert_ready};

use futures::future::poll_fn;
use std::task::Poll::Ready;

#[tokio::test]
async fn sync_one_lit_expr_comma() {
    let foo = tokio::select! {
        foo = async { 1 } => foo,
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn nested_one() {
    let foo = tokio::select! {
        foo = async { 1 } => tokio::select! {
            bar = async { foo } => bar,
        },
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_lit_expr_no_comma() {
    let foo = tokio::select! {
        foo = async { 1 } => foo
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_lit_expr_block() {
    let foo = tokio::select! {
        foo = async { 1 } => { foo }
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_await() {
    let foo = tokio::select! {
        foo = one() => foo,
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_ident() {
    let one = one();

    let foo = tokio::select! {
        foo = one => foo,
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_two() {
    use std::cell::Cell;

    let cnt = Cell::new(0);

    let res = tokio::select! {
        foo = async {
            cnt.set(cnt.get() + 1);
            1
        } => foo,
        bar = async {
            cnt.set(cnt.get() + 1);
            2
        } => bar,
    };

    assert_eq!(1, cnt.get());
    assert!(res == 1 || res == 2);
}

#[tokio::test]
async fn drop_in_fut() {
    let s = "hello".to_string();

    let res = tokio::select! {
        foo = async {
            let v = one().await;
            drop(s);
            v
        } => foo
    };

    assert_eq!(res, 1);
}

#[tokio::test]
async fn one_ready() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (_tx2, rx2) = oneshot::channel::<i32>();

    tx1.send(1).unwrap();

    let v = tokio::select! {
        res = rx1 => {
            assert_ok!(res)
        },
        _ = rx2 => unreachable!(),
    };

    assert_eq!(1, v);
}

#[tokio::test]
async fn select_streams() {
    let (tx1, mut rx1) = mpsc::unbounded_channel::<i32>();
    let (tx2, mut rx2) = mpsc::unbounded_channel::<i32>();

    tokio::spawn(async move {
        assert_ok!(tx2.send(1));
        task::yield_now().await;

        assert_ok!(tx1.send(2));
        task::yield_now().await;

        assert_ok!(tx2.send(3));
        task::yield_now().await;

        drop((tx1, tx2));
    });

    let mut rem = true;
    let mut msgs = vec![];

    while rem {
        tokio::select! {
            Some(x) = rx1.recv() => {
                msgs.push(x);
            }
            Some(y) = rx2.recv() => {
                msgs.push(y);
            }
            else => {
                rem = false;
            }
        }
    }

    msgs.sort_unstable();
    assert_eq!(&msgs[..], &[1, 2, 3]);
}

#[tokio::test]
async fn move_uncompleted_futures() {
    let (tx1, mut rx1) = oneshot::channel::<i32>();
    let (tx2, mut rx2) = oneshot::channel::<i32>();

    tx1.send(1).unwrap();
    tx2.send(2).unwrap();

    let ran;

    tokio::select! {
        res = &mut rx1 => {
            assert_eq!(1, assert_ok!(res));
            assert_eq!(2, assert_ok!(rx2.await));
            ran = true;
        },
        res = &mut rx2 => {
            assert_eq!(2, assert_ok!(res));
            assert_eq!(1, assert_ok!(rx1.await));
            ran = true;
        },
    }

    assert!(ran);
}

#[tokio::test]
async fn nested() {
    let res = tokio::select! {
        x = async { 1 } => {
            tokio::select! {
                y = async { 2 } => x + y,
            }
        }
    };

    assert_eq!(res, 3);
}

#[tokio::test]
async fn struct_size() {
    use futures::future;
    use std::mem;

    let fut = async {
        let ready = future::ready(0i32);

        tokio::select! {
            _ = ready => {},
        }
    };

    assert!(mem::size_of_val(&fut) <= 32);

    let fut = async {
        let ready1 = future::ready(0i32);
        let ready2 = future::ready(0i32);

        tokio::select! {
            _ = ready1 => {},
            _ = ready2 => {},
        }
    };

    assert!(mem::size_of_val(&fut) <= 40);

    let fut = async {
        let ready1 = future::ready(0i32);
        let ready2 = future::ready(0i32);
        let ready3 = future::ready(0i32);

        tokio::select! {
            _ = ready1 => {},
            _ = ready2 => {},
            _ = ready3 => {},
        }
    };

    assert!(mem::size_of_val(&fut) <= 48);
}

#[tokio::test]
async fn mutable_borrowing_future_with_same_borrow_in_block() {
    let mut value = 234;

    tokio::select! {
        _ = require_mutable(&mut value) => { },
        _ = async_noop() => {
            value += 5;
        },
    }

    assert!(value >= 234);
}

#[tokio::test]
async fn mutable_borrowing_future_with_same_borrow_in_block_and_else() {
    let mut value = 234;

    tokio::select! {
        _ = require_mutable(&mut value) => { },
        _ = async_noop() => {
            value += 5;
        },
        else => {
            value += 27;
        },
    }

    assert!(value >= 234);
}

#[tokio::test]
async fn future_panics_after_poll() {
    use tokio_test::task;

    let (tx, rx) = oneshot::channel();

    let mut polled = false;

    let f = poll_fn(|_| {
        assert!(!polled);
        polled = true;
        Ready(None::<()>)
    });

    let mut f = task::spawn(async {
        tokio::select! {
            Some(_) = f => unreachable!(),
            ret = rx => ret.unwrap(),
        }
    });

    assert_pending!(f.poll());
    assert_pending!(f.poll());

    assert_ok!(tx.send(1));

    let res = assert_ready!(f.poll());
    assert_eq!(1, res);
}

#[tokio::test]
async fn disable_with_if() {
    use tokio_test::task;

    let f = poll_fn(|_| panic!());
    let (tx, rx) = oneshot::channel();

    let mut f = task::spawn(async {
        tokio::select! {
            _ = f, if false => unreachable!(),
            _ = rx => (),
        }
    });

    assert_pending!(f.poll());

    assert_ok!(tx.send(()));
    assert!(f.is_woken());

    assert_ready!(f.poll());
}

#[tokio::test]
async fn join_with_select() {
    use tokio_test::task;

    let (tx1, mut rx1) = oneshot::channel();
    let (tx2, mut rx2) = oneshot::channel();

    let mut f = task::spawn(async {
        let mut a = None;
        let mut b = None;

        while a.is_none() || b.is_none() {
            tokio::select! {
                v1 = &mut rx1, if a.is_none() => a = Some(assert_ok!(v1)),
                v2 = &mut rx2, if b.is_none() => b = Some(assert_ok!(v2))
            }
        }

        (a.unwrap(), b.unwrap())
    });

    assert_pending!(f.poll());

    assert_ok!(tx1.send(123));
    assert!(f.is_woken());
    assert_pending!(f.poll());

    assert_ok!(tx2.send(456));
    assert!(f.is_woken());
    let (a, b) = assert_ready!(f.poll());

    assert_eq!(a, 123);
    assert_eq!(b, 456);
}

#[tokio::test]
async fn use_future_in_if_condition() {
    use tokio::time::{self, Duration};

    let sleep = time::sleep(Duration::from_millis(50));
    tokio::pin!(sleep);

    tokio::select! {
        _ = time::sleep(Duration::from_millis(50)), if false => {
            panic!("if condition ignored")
        }
        _ = async { 1u32 } => {
        }
    }
}

#[tokio::test]
async fn many_branches() {
    let num = tokio::select! {
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
    };

    assert_eq!(1, num);
}

#[tokio::test]
async fn never_branch_no_warnings() {
    let t = tokio::select! {
        _ = async_never() => 0,
        one_async_ready = one() => one_async_ready,
    };
    assert_eq!(t, 1);
}

async fn one() -> usize {
    1
}

async fn require_mutable(_: &mut i32) {}
async fn async_noop() {}

async fn async_never() -> ! {
    use tokio::time::Duration;
    loop {
        tokio::time::sleep(Duration::from_millis(10)).await;
    }
}

// From https://github.com/tokio-rs/tokio/issues/2857
#[tokio::test]
async fn mut_on_left_hand_side() {
    let v = async move {
        let ok = async { 1 };
        tokio::pin!(ok);
        tokio::select! {
            mut a = &mut ok => {
                a += 1;
                a
            }
        }
    }
    .await;
    assert_eq!(v, 2);
}

#[tokio::test]
async fn biased_one_not_ready() {
    let (_tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = oneshot::channel::<i32>();
    let (tx3, rx3) = oneshot::channel::<i32>();

    tx2.send(2).unwrap();
    tx3.send(3).unwrap();

    let v = tokio::select! {
        biased;

        _ = rx1 => unreachable!(),
        res = rx2 => {
            assert_ok!(res)
        },
        _ = rx3 => {
            panic!("This branch should never be activated because `rx2` should be polled before `rx3` due to `biased;`.")
        }
    };

    assert_eq!(2, v);
}

#[tokio::test]
async fn biased_eventually_ready() {
    use tokio::task::yield_now;

    let one = async {};
    let two = async { yield_now().await };
    let three = async { yield_now().await };

    let mut count = 0u8;

    tokio::pin!(one, two, three);

    loop {
        tokio::select! {
            biased;

            _ = &mut two, if count < 2 => {
                count += 1;
                assert_eq!(count, 2);
            }
            _ = &mut three, if count < 3 => {
                count += 1;
                assert_eq!(count, 3);
            }
            _ = &mut one, if count < 1 => {
                count += 1;
                assert_eq!(count, 1);
            }
            else => break,
        }
    }

    assert_eq!(count, 3);
}
<commit_msg>chore: fix CI for Rust 1.52 (#3758)<commit_after>#![allow(clippy::blacklisted_name)]
use tokio::sync::{mpsc, oneshot};
use tokio::task;
use tokio_test::{assert_ok, assert_pending, assert_ready};

use futures::future::poll_fn;
use std::task::Poll::Ready;

#[tokio::test]
async fn sync_one_lit_expr_comma() {
    let foo = tokio::select! {
        foo = async { 1 } => foo,
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn nested_one() {
    let foo = tokio::select! {
        foo = async { 1 } => tokio::select! {
            bar = async { foo } => bar,
        },
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_lit_expr_no_comma() {
    let foo = tokio::select! {
        foo = async { 1 } => foo
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_lit_expr_block() {
    let foo = tokio::select! {
        foo = async { 1 } => { foo }
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_await() {
    let foo = tokio::select! {
        foo = one() => foo,
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_one_ident() {
    let one = one();

    let foo = tokio::select! {
        foo = one => foo,
    };

    assert_eq!(foo, 1);
}

#[tokio::test]
async fn sync_two() {
    use std::cell::Cell;

    let cnt = Cell::new(0);

    let res = tokio::select! {
        foo = async {
            cnt.set(cnt.get() + 1);
            1
        } => foo,
        bar = async {
            cnt.set(cnt.get() + 1);
            2
        } => bar,
    };

    assert_eq!(1, cnt.get());
    assert!(res == 1 || res == 2);
}

#[tokio::test]
async fn drop_in_fut() {
    let s = "hello".to_string();

    let res = tokio::select! {
        foo = async {
            let v = one().await;
            drop(s);
            v
        } => foo
    };

    assert_eq!(res, 1);
}

#[tokio::test]
async fn one_ready() {
    let (tx1, rx1) = oneshot::channel::<i32>();
    let (_tx2, rx2) = oneshot::channel::<i32>();

    tx1.send(1).unwrap();

    let v = tokio::select! {
        res = rx1 => {
            assert_ok!(res)
        },
        _ = rx2 => unreachable!(),
    };

    assert_eq!(1, v);
}

#[tokio::test]
async fn select_streams() {
    let (tx1, mut rx1) = mpsc::unbounded_channel::<i32>();
    let (tx2, mut rx2) = mpsc::unbounded_channel::<i32>();

    tokio::spawn(async move {
        assert_ok!(tx2.send(1));
        task::yield_now().await;

        assert_ok!(tx1.send(2));
        task::yield_now().await;

        assert_ok!(tx2.send(3));
        task::yield_now().await;

        drop((tx1, tx2));
    });

    let mut rem = true;
    let mut msgs = vec![];

    while rem {
        tokio::select! {
            Some(x) = rx1.recv() => {
                msgs.push(x);
            }
            Some(y) = rx2.recv() => {
                msgs.push(y);
            }
            else => {
                rem = false;
            }
        }
    }

    msgs.sort_unstable();
    assert_eq!(&msgs[..], &[1, 2, 3]);
}

#[tokio::test]
async fn move_uncompleted_futures() {
    let (tx1, mut rx1) = oneshot::channel::<i32>();
    let (tx2, mut rx2) = oneshot::channel::<i32>();

    tx1.send(1).unwrap();
    tx2.send(2).unwrap();

    let ran;

    tokio::select! {
        res = &mut rx1 => {
            assert_eq!(1, assert_ok!(res));
            assert_eq!(2, assert_ok!(rx2.await));
            ran = true;
        },
        res = &mut rx2 => {
            assert_eq!(2, assert_ok!(res));
            assert_eq!(1, assert_ok!(rx1.await));
            ran = true;
        },
    }

    assert!(ran);
}

#[tokio::test]
async fn nested() {
    let res = tokio::select! {
        x = async { 1 } => {
            tokio::select! {
                y = async { 2 } => x + y,
            }
        }
    };

    assert_eq!(res, 3);
}

#[tokio::test]
async fn struct_size() {
    use futures::future;
    use std::mem;

    let fut = async {
        let ready = future::ready(0i32);

        tokio::select! {
            _ = ready => {},
        }
    };

    assert!(mem::size_of_val(&fut) <= 32);

    let fut = async {
        let ready1 = future::ready(0i32);
        let ready2 = future::ready(0i32);

        tokio::select! {
            _ = ready1 => {},
            _ = ready2 => {},
        }
    };

    assert!(mem::size_of_val(&fut) <= 40);

    let fut = async {
        let ready1 = future::ready(0i32);
        let ready2 = future::ready(0i32);
        let ready3 = future::ready(0i32);

        tokio::select! {
            _ = ready1 => {},
            _ = ready2 => {},
            _ = ready3 => {},
        }
    };

    assert!(mem::size_of_val(&fut) <= 48);
}

#[tokio::test]
async fn mutable_borrowing_future_with_same_borrow_in_block() {
    let mut value = 234;

    tokio::select! {
        _ = require_mutable(&mut value) => { },
        _ = async_noop() => {
            value += 5;
        },
    }

    assert!(value >= 234);
}

#[tokio::test]
async fn mutable_borrowing_future_with_same_borrow_in_block_and_else() {
    let mut value = 234;

    tokio::select! {
        _ = require_mutable(&mut value) => { },
        _ = async_noop() => {
            value += 5;
        },
        else => {
            value += 27;
        },
    }

    assert!(value >= 234);
}

#[tokio::test]
async fn future_panics_after_poll() {
    use tokio_test::task;

    let (tx, rx) = oneshot::channel();

    let mut polled = false;

    let f = poll_fn(|_| {
        assert!(!polled);
        polled = true;
        Ready(None::<()>)
    });

    let mut f = task::spawn(async {
        tokio::select! {
            Some(_) = f => unreachable!(),
            ret = rx => ret.unwrap(),
        }
    });

    assert_pending!(f.poll());
    assert_pending!(f.poll());

    assert_ok!(tx.send(1));

    let res = assert_ready!(f.poll());
    assert_eq!(1, res);
}

#[tokio::test]
async fn disable_with_if() {
    use tokio_test::task;

    let f = poll_fn(|_| panic!());
    let (tx, rx) = oneshot::channel();

    let mut f = task::spawn(async {
        tokio::select! {
            _ = f, if false => unreachable!(),
            _ = rx => (),
        }
    });

    assert_pending!(f.poll());

    assert_ok!(tx.send(()));
    assert!(f.is_woken());

    assert_ready!(f.poll());
}

#[tokio::test]
async fn join_with_select() {
    use tokio_test::task;

    let (tx1, mut rx1) = oneshot::channel();
    let (tx2, mut rx2) = oneshot::channel();

    let mut f = task::spawn(async {
        let mut a = None;
        let mut b = None;

        while a.is_none() || b.is_none() {
            tokio::select! {
                v1 = &mut rx1, if a.is_none() => a = Some(assert_ok!(v1)),
                v2 = &mut rx2, if b.is_none() => b = Some(assert_ok!(v2))
            }
        }

        (a.unwrap(), b.unwrap())
    });

    assert_pending!(f.poll());

    assert_ok!(tx1.send(123));
    assert!(f.is_woken());
    assert_pending!(f.poll());

    assert_ok!(tx2.send(456));
    assert!(f.is_woken());
    let (a, b) = assert_ready!(f.poll());

    assert_eq!(a, 123);
    assert_eq!(b, 456);
}

#[tokio::test]
async fn use_future_in_if_condition() {
    use tokio::time::{self, Duration};

    tokio::select! {
        _ = time::sleep(Duration::from_millis(50)), if false => {
            panic!("if condition ignored")
        }
        _ = async { 1u32 } => {
        }
    }
}

#[tokio::test]
async fn many_branches() {
    let num = tokio::select! {
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
        x = async { 1 } => x,
    };

    assert_eq!(1, num);
}

#[tokio::test]
async fn never_branch_no_warnings() {
    let t = tokio::select! {
        _ = async_never() => 0,
        one_async_ready = one() => one_async_ready,
    };
    assert_eq!(t, 1);
}

async fn one() -> usize {
    1
}

async fn require_mutable(_: &mut i32) {}
async fn async_noop() {}

async fn async_never() -> ! {
    use tokio::time::Duration;
    loop {
        tokio::time::sleep(Duration::from_millis(10)).await;
    }
}

// From https://github.com/tokio-rs/tokio/issues/2857
#[tokio::test]
async fn mut_on_left_hand_side() {
    let v = async move {
        let ok = async { 1 };
        tokio::pin!(ok);
        tokio::select! {
            mut a = &mut ok => {
                a += 1;
                a
            }
        }
    }
    .await;
    assert_eq!(v, 2);
}

#[tokio::test]
async fn biased_one_not_ready() {
    let (_tx1, rx1) = oneshot::channel::<i32>();
    let (tx2, rx2) = oneshot::channel::<i32>();
    let (tx3, rx3) = oneshot::channel::<i32>();

    tx2.send(2).unwrap();
    tx3.send(3).unwrap();

    let v = tokio::select! {
        biased;

        _ = rx1 => unreachable!(),
        res = rx2 => {
            assert_ok!(res)
        },
        _ = rx3 => {
            panic!("This branch should never be activated because `rx2` should be polled before `rx3` due to `biased;`.")
        }
    };

    assert_eq!(2, v);
}

#[tokio::test]
async fn biased_eventually_ready() {
    use tokio::task::yield_now;

    let one = async {};
    let two = async { yield_now().await };
    let three = async { yield_now().await };

    let mut count = 0u8;

    tokio::pin!(one, two, three);

    loop {
        tokio::select! {
            biased;

            _ = &mut two, if count < 2 => {
                count += 1;
                assert_eq!(count, 2);
            }
            _ = &mut three, if count < 3 => {
                count += 1;
                assert_eq!(count, 3);
            }
            _ = &mut one, if count < 1 => {
                count += 1;
                assert_eq!(count, 1);
            }
            else => break,
        }
    }

    assert_eq!(count, 3);
}
<|endoftext|>


<commit_before>//! Extension methods for `Stream` based on record-by-record transformation.

use Data;
use dataflow::{Stream, Scope};
use dataflow::channels::pact::Pipeline;
use dataflow::operators::unary::Unary;
use drain::DrainExt;

/// Extension trait for `Stream`.
pub trait Map<S: Scope, D: Data> {
    /// Consumes each element of the stream and yields a new element.
    fn map<D2: Data, L: Fn(D)->D2+'static>(&self, logic: L) -> Stream<S, D2>;
    /// Updates each element of the stream and yields the element.
    fn map_in_place<L: Fn(&mut D)+'static>(&self, logic: L) -> Stream<S, D>;
    /// Consumes each element of the stream and yields some number of new elements.
    fn flat_map<I: Iterator, L: Fn(D)->I+'static>(&self, logic: L) -> Stream<S, I::Item> where I::Item: Data;
}

impl<S: Scope, D: Data> Map<S, D> for Stream<S, D> {
    fn map<D2: Data, L: Fn(D)->D2+'static>(&self, logic: L) -> Stream<S, D2> {
        self.unary_stream(Pipeline, "Map", move |input, output| {
            while let Some((time, data)) = input.next() {
                output.session(time).give_iterator(data.drain_temp().map(|x| logic(x)));
            }
        })
    }
    fn map_in_place<L: Fn(&mut D)+'static>(&self, logic: L) -> Stream<S, D> {
        self.unary_stream(Pipeline, "MapInPlace", move |input, output| {
            while let Some((time, data)) = input.next() {
                for datum in data.iter_mut() { logic(datum); }
                output.session(time).give_content(data);
            }
        })
    }
    fn flat_map<I: Iterator, L: Fn(D)->I+'static>(&self, logic: L) -> Stream<S, I::Item> where I::Item: Data {
        self.unary_stream(Pipeline, "FlatMap", move |input, output| {
            while let Some((time, data)) = input.next() {
                output.session(time).give_iterator(data.drain_temp().flat_map(|x| logic(x)));
            }
        })
    }
}
<commit_msg>filter_map<commit_after>//! Extension methods for `Stream` based on record-by-record transformation.

use Data;
use dataflow::{Stream, Scope};
use dataflow::channels::pact::Pipeline;
use dataflow::operators::unary::Unary;
use drain::DrainExt;

/// Extension trait for `Stream`.
pub trait Map<S: Scope, D: Data> {
    /// Consumes each element of the stream and yields a new element.
    fn map<D2: Data, L: Fn(D)->D2+'static>(&self, logic: L) -> Stream<S, D2>;
    /// Updates each element of the stream and yields the element.
    fn map_in_place<L: Fn(&mut D)+'static>(&self, logic: L) -> Stream<S, D>;
    /// Consumes each element of the stream and yields some number of new elements.
    fn flat_map<I: Iterator, L: Fn(D)->I+'static>(&self, logic: L) -> Stream<S, I::Item> where I::Item: Data;
    ///
    fn filter_map2<D2: Data, L: Fn(D)->Option<D2>+'static>(&self, logic: L) -> Stream<S, D2>;
}

impl<S: Scope, D: Data> Map<S, D> for Stream<S, D> {
    fn map<D2: Data, L: Fn(D)->D2+'static>(&self, logic: L) -> Stream<S, D2> {
        self.unary_stream(Pipeline, "Map", move |input, output| {
            while let Some((time, data)) = input.next() {
                output.session(time).give_iterator(data.drain_temp().map(|x| logic(x)));
            }
        })
    }
    fn map_in_place<L: Fn(&mut D)+'static>(&self, logic: L) -> Stream<S, D> {
        self.unary_stream(Pipeline, "MapInPlace", move |input, output| {
            while let Some((time, data)) = input.next() {
                for datum in data.iter_mut() { logic(datum); }
                output.session(time).give_content(data);
            }
        })
    }
    fn flat_map<I: Iterator, L: Fn(D)->I+'static>(&self, logic: L) -> Stream<S, I::Item> where I::Item: Data {
        self.unary_stream(Pipeline, "FlatMap", move |input, output| {
            while let Some((time, data)) = input.next() {
                output.session(time).give_iterator(data.drain_temp().flat_map(|x| logic(x)));
            }
        })
    }
    fn filter_map2<D2: Data, L: Fn(D)->Option<D2>+'static>(&self, logic: L) -> Stream<S, D2> {
        self.unary_stream(Pipeline, "FlatMap", move |input, output| {
            while let Some((time, data)) = input.next() {
                output.session(time).give_iterator(data.drain_temp().filter_map(|x| logic(x)));
            }
        })
    }
}
<|endoftext|>


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

//! The binomial distribution.

use Rng;
use distributions::{Distribution, Bernoulli};
use distributions::log_gamma::log_gamma;
use std::f64::consts::PI;

/// The binomial distribution `Binomial(n, p)`.
///
/// This distribution has density function:
/// `f(k) = n!/(k! (n-k)!) p^k (1-p)^(n-k)` for `k >= 0`.
///
/// # Example
///
/// ```
/// use rand::distributions::{Binomial, Distribution};
///
/// let bin = Binomial::new(20, 0.3);
/// let v = bin.sample(&mut rand::thread_rng());
/// println!("{} is from a binomial distribution", v);
/// ```
#[derive(Clone, Copy, Debug)]
pub struct Binomial {
    /// Number of trials.
    n: u64,
    /// Probability of success.
    p: f64,
}

impl Binomial {
    /// Construct a new `Binomial` with the given shape parameters `n` (number
    /// of trials) and `p` (probability of success).
    ///
    /// Panics if `p <= 0` or `p >= 1`.
    pub fn new(n: u64, p: f64) -> Binomial {
        assert!(p > 0.0, "Binomial::new called with p <= 0");
        assert!(p < 1.0, "Binomial::new called with p >= 1");
        Binomial { n, p }
    }
}

impl Distribution<u64> for Binomial {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
        // For low n, it is faster to sample directly. For both methods,
        // performance is independent of p. On Intel Haswell CPU this method
        // appears to be faster for approx n < 300.
        if self.n < 300 {
            let mut result = 0;
            let d = Bernoulli::new(self.p);
            for _ in 0 .. self.n {
                result += rng.sample(d) as u32;
            }
            return result as u64;
        }

        // binomial distribution is symmetrical with respect to p -> 1-p, k -> n-k
        // switch p so that it is less than 0.5 - this allows for lower expected values
        // we will just invert the result at the end
        let p = if self.p <= 0.5 {
            self.p
        } else {
            1.0 - self.p
        };

        // prepare some cached values
        let float_n = self.n as f64;
        let ln_fact_n = log_gamma(float_n + 1.0);
        let pc = 1.0 - p;
        let log_p = p.ln();
        let log_pc = pc.ln();
        let expected = self.n as f64 * p;
        let sq = (expected * (2.0 * pc)).sqrt();

        let mut lresult;

        loop {
            let mut comp_dev: f64;
            // we use the lorentzian distribution as the comparison distribution
            // f(x) ~ 1/(1+x/^2)
            loop {
                // draw from the lorentzian distribution
                comp_dev = (PI*rng.gen::<f64>()).tan();
                // shift the peak of the comparison ditribution
                lresult = expected + sq * comp_dev;
                // repeat the drawing until we are in the range of possible values
                if lresult >= 0.0 && lresult < float_n + 1.0 {
                    break;
                }
            }

            // the result should be discrete
            lresult = lresult.floor();

            let log_binomial_dist = ln_fact_n - log_gamma(lresult+1.0) -
                log_gamma(float_n - lresult + 1.0) + lresult*log_p + (float_n - lresult)*log_pc;
            // this is the binomial probability divided by the comparison probability
            // we will generate a uniform random value and if it is larger than this,
            // we interpret it as a value falling out of the distribution and repeat
            let comparison_coeff = (log_binomial_dist.exp() * sq) * (1.2 * (1.0 + comp_dev*comp_dev));

            if comparison_coeff >= rng.gen() {
                break;
            }
        }

        // invert the result for p < 0.5
        if p != self.p {
            self.n - lresult as u64
        } else {
            lresult as u64
        }
    }
}

#[cfg(test)]
mod test {
    use Rng;
    use distributions::Distribution;
    use super::Binomial;

    fn test_binomial_mean_and_variance<R: Rng>(n: u64, p: f64, rng: &mut R) {
        let binomial = Binomial::new(n, p);

        let expected_mean = n as f64 * p;
        let expected_variance = n as f64 * p * (1.0 - p);

        let mut results = [0.0; 1000];
        for i in results.iter_mut() { *i = binomial.sample(rng) as f64; }

        let mean = results.iter().sum::<f64>() / results.len() as f64;
        assert!((mean as f64 - expected_mean).abs() < expected_mean / 50.0);

        let variance =
            results.iter().map(|x| (x - mean) * (x - mean)).sum::<f64>()
            / results.len() as f64;
        assert!((variance - expected_variance).abs() < expected_variance / 10.0);
    }

    #[test]
    fn test_binomial() {
        let mut rng = ::test::rng(123);
        test_binomial_mean_and_variance(150, 0.1, &mut rng);
        test_binomial_mean_and_variance(70, 0.6, &mut rng);
        test_binomial_mean_and_variance(40, 0.5, &mut rng);
        test_binomial_mean_and_variance(20, 0.7, &mut rng);
        test_binomial_mean_and_variance(20, 0.5, &mut rng);
    }

    #[test]
    #[should_panic]
    fn test_binomial_invalid_lambda_zero() {
        Binomial::new(20, 0.0);
    }

    #[test]
    #[should_panic]
    fn test_binomial_invalid_lambda_neg() {
        Binomial::new(20, -10.0);
    }
}
<commit_msg>Binomial: allow p to be 0 or 1<commit_after>// Copyright 2016-2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The binomial distribution.

use Rng;
use distributions::{Distribution, Bernoulli};
use distributions::log_gamma::log_gamma;
use std::f64::consts::PI;

/// The binomial distribution `Binomial(n, p)`.
///
/// This distribution has density function:
/// `f(k) = n!/(k! (n-k)!) p^k (1-p)^(n-k)` for `k >= 0`.
///
/// # Example
///
/// ```
/// use rand::distributions::{Binomial, Distribution};
///
/// let bin = Binomial::new(20, 0.3);
/// let v = bin.sample(&mut rand::thread_rng());
/// println!("{} is from a binomial distribution", v);
/// ```
#[derive(Clone, Copy, Debug)]
pub struct Binomial {
    /// Number of trials.
    n: u64,
    /// Probability of success.
    p: f64,
}

impl Binomial {
    /// Construct a new `Binomial` with the given shape parameters `n` (number
    /// of trials) and `p` (probability of success).
    ///
    /// Panics if `p < 0` or `p > 1`.
    pub fn new(n: u64, p: f64) -> Binomial {
        assert!(p >= 0.0, "Binomial::new called with p < 0");
        assert!(p <= 1.0, "Binomial::new called with p > 1");
        Binomial { n, p }
    }
}

impl Distribution<u64> for Binomial {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
        // Handle these values directly.
        if self.p == 0.0 {
            return 0;
        } else if self.p == 1.0 {
            return self.n;
        }

        // For low n, it is faster to sample directly. For both methods,
        // performance is independent of p. On Intel Haswell CPU this method
        // appears to be faster for approx n < 300.
        if self.n < 300 {
            let mut result = 0;
            let d = Bernoulli::new(self.p);
            for _ in 0 .. self.n {
                result += rng.sample(d) as u32;
            }
            return result as u64;
        }

        // binomial distribution is symmetrical with respect to p -> 1-p, k -> n-k
        // switch p so that it is less than 0.5 - this allows for lower expected values
        // we will just invert the result at the end
        let p = if self.p <= 0.5 {
            self.p
        } else {
            1.0 - self.p
        };

        // prepare some cached values
        let float_n = self.n as f64;
        let ln_fact_n = log_gamma(float_n + 1.0);
        let pc = 1.0 - p;
        let log_p = p.ln();
        let log_pc = pc.ln();
        let expected = self.n as f64 * p;
        let sq = (expected * (2.0 * pc)).sqrt();

        let mut lresult;

        loop {
            let mut comp_dev: f64;
            // we use the lorentzian distribution as the comparison distribution
            // f(x) ~ 1/(1+x/^2)
            loop {
                // draw from the lorentzian distribution
                comp_dev = (PI*rng.gen::<f64>()).tan();
                // shift the peak of the comparison ditribution
                lresult = expected + sq * comp_dev;
                // repeat the drawing until we are in the range of possible values
                if lresult >= 0.0 && lresult < float_n + 1.0 {
                    break;
                }
            }

            // the result should be discrete
            lresult = lresult.floor();

            let log_binomial_dist = ln_fact_n - log_gamma(lresult+1.0) -
                log_gamma(float_n - lresult + 1.0) + lresult*log_p + (float_n - lresult)*log_pc;
            // this is the binomial probability divided by the comparison probability
            // we will generate a uniform random value and if it is larger than this,
            // we interpret it as a value falling out of the distribution and repeat
            let comparison_coeff = (log_binomial_dist.exp() * sq) * (1.2 * (1.0 + comp_dev*comp_dev));

            if comparison_coeff >= rng.gen() {
                break;
            }
        }

        // invert the result for p < 0.5
        if p != self.p {
            self.n - lresult as u64
        } else {
            lresult as u64
        }
    }
}

#[cfg(test)]
mod test {
    use Rng;
    use distributions::Distribution;
    use super::Binomial;

    fn test_binomial_mean_and_variance<R: Rng>(n: u64, p: f64, rng: &mut R) {
        let binomial = Binomial::new(n, p);

        let expected_mean = n as f64 * p;
        let expected_variance = n as f64 * p * (1.0 - p);

        let mut results = [0.0; 1000];
        for i in results.iter_mut() { *i = binomial.sample(rng) as f64; }

        let mean = results.iter().sum::<f64>() / results.len() as f64;
        assert!((mean as f64 - expected_mean).abs() < expected_mean / 50.0);

        let variance =
            results.iter().map(|x| (x - mean) * (x - mean)).sum::<f64>()
            / results.len() as f64;
        assert!((variance - expected_variance).abs() < expected_variance / 10.0);
    }

    #[test]
    fn test_binomial() {
        let mut rng = ::test::rng(351);
        test_binomial_mean_and_variance(150, 0.1, &mut rng);
        test_binomial_mean_and_variance(70, 0.6, &mut rng);
        test_binomial_mean_and_variance(40, 0.5, &mut rng);
        test_binomial_mean_and_variance(20, 0.7, &mut rng);
        test_binomial_mean_and_variance(20, 0.5, &mut rng);
    }

    #[test]
    fn test_binomial_end_points() {
        let mut rng = ::test::rng(352);
        assert_eq!(rng.sample(Binomial::new(20, 0.0)), 0);
        assert_eq!(rng.sample(Binomial::new(20, 1.0)), 20);
    }

    #[test]
    #[should_panic]
    fn test_binomial_invalid_lambda_neg() {
        Binomial::new(20, -10.0);
    }
}
<|endoftext|>


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

//! A vector type intended to be used for collecting from iterators onto the stack.
//!
//! Space for up to N elements is provided on the stack.  If more elements are collected, Vec is
//! used to store the values on the heap. SmallVec is similar to AccumulateVec, but adds
//! the ability to push elements.
//!
//! The N above is determined by Array's implementor, by way of an associated constant.

use std::ops::{Deref, DerefMut};
use std::iter::{IntoIterator, FromIterator};
use std::fmt::{self, Debug};
use std::mem;
use std::ptr;

use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};

use accumulate_vec::{IntoIter, AccumulateVec};
use array_vec::Array;

pub struct SmallVec(AccumulateVec);

impl Clone for SmallVec
    where A: Array,
          A::Element: Clone {
    fn clone(&self) -> Self {
        SmallVec(self.0.clone())
    }
}

impl Debug for SmallVec
    where A: Array + Debug,
          A::Element: Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("SmallVec").field(&self.0).finish()
    }
}

impl SmallVec {
    pub fn new() -> Self {
        SmallVec(AccumulateVec::new())
    }

    pub fn is_array(&self) -> bool {
        self.0.is_array()
    }

    pub fn with_capacity(cap: usize) -> Self {
        let mut vec = SmallVec::new();
        vec.reserve(cap);
        vec
    }

    pub fn one(el: A::Element) -> Self {
        SmallVec(AccumulateVec::one(el))
    }

    pub fn many<I: IntoIterator<Item=A::Element>>(els: I) -> Self {
        SmallVec(AccumulateVec::many(els))
    }

    pub fn expect_one(self, err: &'static str) -> A::Element {
        assert!(self.len() == 1, err);
        match self.0 {
            AccumulateVec::Array(arr) => arr.into_iter().next().unwrap(),
            AccumulateVec::Heap(vec) => vec.into_iter().next().unwrap(),
        }
    }

    /// Will reallocate onto the heap if needed.
    pub fn push(&mut self, el: A::Element) {
        self.reserve(1);
        match self.0 {
            AccumulateVec::Array(ref mut array) => array.push(el),
            AccumulateVec::Heap(ref mut vec) => vec.push(el),
        }
    }

    pub fn reserve(&mut self, n: usize) {
        match self.0 {
            AccumulateVec::Array(_) => {
                if self.len() + n > A::LEN {
                    let len = self.len();
                    let array = mem::replace(&mut self.0,
                            AccumulateVec::Heap(Vec::with_capacity(len + n)));
                    if let AccumulateVec::Array(array) = array {
                        match self.0 {
                            AccumulateVec::Heap(ref mut vec) => vec.extend(array),
                            _ => unreachable!()
                        }
                    }
                }
            }
            AccumulateVec::Heap(ref mut vec) => vec.reserve(n)
        }
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        match self.0 {
            AccumulateVec::Array(ref mut arr) => arr.set_len(len),
            AccumulateVec::Heap(ref mut vec) => vec.set_len(len),
        }
    }

    pub fn insert(&mut self, index: usize, element: A::Element) {
        let len = self.len();

        // Reserve space for shifting elements to the right
        self.reserve(1);

        assert!(index <= len);

        unsafe {
            // infallible
            // The spot to put the new value
            {
                let p = self.as_mut_ptr().offset(index as isize);
                // Shift everything over to make space. (Duplicating the
                // `index`th element into two consecutive places.)
                ptr::copy(p, p.offset(1), len - index);
                // Write it in, overwriting the first copy of the `index`th
                // element.
                ptr::write(p, element);
            }
            self.set_len(len + 1);
        }
    }

    pub fn truncate(&mut self, len: usize) {
        unsafe {
            while len < self.len() {
                // Decrement len before the drop_in_place(), so a panic on Drop
                // doesn't re-drop the just-failed value.
                let newlen = self.len() - 1;
                self.set_len(newlen);
                ::std::ptr::drop_in_place(self.get_unchecked_mut(newlen));
            }
        }
    }
}

impl Deref for SmallVec {
    type Target = AccumulateVec;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for SmallVec {
    fn deref_mut(&mut self) -> &mut AccumulateVec {
        &mut self.0
    }
}

impl FromIterator for SmallVec {
    fn from_iter(iter: I) -> Self where I: IntoIterator<Item=A::Element> {
        SmallVec(iter.into_iter().collect())
    }
}

impl Extend for SmallVec {
    fn extend<I: IntoIterator<Item=A::Element>>(&mut self, iter: I) {
        let iter = iter.into_iter();
        self.reserve(iter.size_hint().0);
        for el in iter {
            self.push(el);
        }
    }
}

impl IntoIterator for SmallVec {
    type Item = A::Element;
    type IntoIter = IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl Default for SmallVec {
    fn default() -> SmallVec {
        SmallVec::new()
    }
}

impl Encodable for SmallVec
    where A: Array,
          A::Element: Encodable {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_seq(self.len(), |s| {
            for (i, e) in self.iter().enumerate() {
                s.emit_seq_elt(i, |s| e.encode(s))?;
            }
            Ok(())
        })
    }
}

impl Decodable for SmallVec
    where A: Array,
          A::Element: Decodable {
    fn decode<D: Decoder>(d: &mut D) -> Result<SmallVec, D::Error> {
        d.read_seq(|d, len| {
            (0..len).map(|i| d.read_seq_elt(i, |d| Decodable::decode(d))).collect()
        })
    }
}
<commit_msg>Rollup merge of #52859 - ljedrz:smallvec_true_extend, r=Mark-Simulacrum<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A vector type intended to be used for collecting from iterators onto the stack.
//!
//! Space for up to N elements is provided on the stack.  If more elements are collected, Vec is
//! used to store the values on the heap. SmallVec is similar to AccumulateVec, but adds
//! the ability to push elements.
//!
//! The N above is determined by Array's implementor, by way of an associated constant.

use std::ops::{Deref, DerefMut};
use std::iter::{IntoIterator, FromIterator};
use std::fmt::{self, Debug};
use std::mem;
use std::ptr;

use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};

use accumulate_vec::{IntoIter, AccumulateVec};
use array_vec::Array;

pub struct SmallVec(AccumulateVec);

impl Clone for SmallVec
    where A: Array,
          A::Element: Clone {
    fn clone(&self) -> Self {
        SmallVec(self.0.clone())
    }
}

impl Debug for SmallVec
    where A: Array + Debug,
          A::Element: Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("SmallVec").field(&self.0).finish()
    }
}

impl SmallVec {
    pub fn new() -> Self {
        SmallVec(AccumulateVec::new())
    }

    pub fn is_array(&self) -> bool {
        self.0.is_array()
    }

    pub fn with_capacity(cap: usize) -> Self {
        let mut vec = SmallVec::new();
        vec.reserve(cap);
        vec
    }

    pub fn one(el: A::Element) -> Self {
        SmallVec(AccumulateVec::one(el))
    }

    pub fn many<I: IntoIterator<Item=A::Element>>(els: I) -> Self {
        SmallVec(AccumulateVec::many(els))
    }

    pub fn expect_one(self, err: &'static str) -> A::Element {
        assert!(self.len() == 1, err);
        match self.0 {
            AccumulateVec::Array(arr) => arr.into_iter().next().unwrap(),
            AccumulateVec::Heap(vec) => vec.into_iter().next().unwrap(),
        }
    }

    /// Will reallocate onto the heap if needed.
    pub fn push(&mut self, el: A::Element) {
        self.reserve(1);
        match self.0 {
            AccumulateVec::Array(ref mut array) => array.push(el),
            AccumulateVec::Heap(ref mut vec) => vec.push(el),
        }
    }

    pub fn reserve(&mut self, n: usize) {
        match self.0 {
            AccumulateVec::Array(_) => {
                if self.len() + n > A::LEN {
                    let len = self.len();
                    let array = mem::replace(&mut self.0,
                            AccumulateVec::Heap(Vec::with_capacity(len + n)));
                    if let AccumulateVec::Array(array) = array {
                        match self.0 {
                            AccumulateVec::Heap(ref mut vec) => vec.extend(array),
                            _ => unreachable!()
                        }
                    }
                }
            }
            AccumulateVec::Heap(ref mut vec) => vec.reserve(n)
        }
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        match self.0 {
            AccumulateVec::Array(ref mut arr) => arr.set_len(len),
            AccumulateVec::Heap(ref mut vec) => vec.set_len(len),
        }
    }

    pub fn insert(&mut self, index: usize, element: A::Element) {
        let len = self.len();

        // Reserve space for shifting elements to the right
        self.reserve(1);

        assert!(index <= len);

        unsafe {
            // infallible
            // The spot to put the new value
            {
                let p = self.as_mut_ptr().offset(index as isize);
                // Shift everything over to make space. (Duplicating the
                // `index`th element into two consecutive places.)
                ptr::copy(p, p.offset(1), len - index);
                // Write it in, overwriting the first copy of the `index`th
                // element.
                ptr::write(p, element);
            }
            self.set_len(len + 1);
        }
    }

    pub fn truncate(&mut self, len: usize) {
        unsafe {
            while len < self.len() {
                // Decrement len before the drop_in_place(), so a panic on Drop
                // doesn't re-drop the just-failed value.
                let newlen = self.len() - 1;
                self.set_len(newlen);
                ::std::ptr::drop_in_place(self.get_unchecked_mut(newlen));
            }
        }
    }
}

impl Deref for SmallVec {
    type Target = AccumulateVec;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for SmallVec {
    fn deref_mut(&mut self) -> &mut AccumulateVec {
        &mut self.0
    }
}

impl FromIterator for SmallVec {
    fn from_iter(iter: I) -> Self where I: IntoIterator<Item=A::Element> {
        SmallVec(iter.into_iter().collect())
    }
}

impl Extend for SmallVec {
    fn extend<I: IntoIterator<Item=A::Element>>(&mut self, iter: I) {
        if self.is_array() {
            let iter = iter.into_iter();
            self.reserve(iter.size_hint().0);

            for el in iter {
                self.push(el);
            }
        } else {
            match self.0 {
                AccumulateVec::Heap(ref mut vec) => vec.extend(iter),
                _ => unreachable!()
            }
        }
    }
}

impl IntoIterator for SmallVec {
    type Item = A::Element;
    type IntoIter = IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl Default for SmallVec {
    fn default() -> SmallVec {
        SmallVec::new()
    }
}

impl Encodable for SmallVec
    where A: Array,
          A::Element: Encodable {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_seq(self.len(), |s| {
            for (i, e) in self.iter().enumerate() {
                s.emit_seq_elt(i, |s| e.encode(s))?;
            }
            Ok(())
        })
    }
}

impl Decodable for SmallVec
    where A: Array,
          A::Element: Decodable {
    fn decode<D: Decoder>(d: &mut D) -> Result<SmallVec, D::Error> {
        d.read_seq(|d, len| {
            (0..len).map(|i| d.read_seq_elt(i, |d| Decodable::decode(d))).collect()
        })
    }
}

#[cfg(test)]
mod tests {
    extern crate test;
    use self::test::Bencher;

    use super::*;

    #[bench]
    fn fill_small_vec_1_10_with_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 1]> = SmallVec::with_capacity(10);

            sv.extend(0..10);
        })
    }

    #[bench]
    fn fill_small_vec_1_10_wo_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 1]> = SmallVec::new();

            sv.extend(0..10);
        })
    }

    #[bench]
    fn fill_small_vec_8_10_with_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 8]> = SmallVec::with_capacity(10);

            sv.extend(0..10);
        })
    }

    #[bench]
    fn fill_small_vec_8_10_wo_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 8]> = SmallVec::new();

            sv.extend(0..10);
        })
    }

    #[bench]
    fn fill_small_vec_32_10_with_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 32]> = SmallVec::with_capacity(10);

            sv.extend(0..10);
        })
    }

    #[bench]
    fn fill_small_vec_32_10_wo_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 32]> = SmallVec::new();

            sv.extend(0..10);
        })
    }

    #[bench]
    fn fill_small_vec_1_50_with_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 1]> = SmallVec::with_capacity(50);

            sv.extend(0..50);
        })
    }

    #[bench]
    fn fill_small_vec_1_50_wo_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 1]> = SmallVec::new();

            sv.extend(0..50);
        })
    }

    #[bench]
    fn fill_small_vec_8_50_with_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 8]> = SmallVec::with_capacity(50);

            sv.extend(0..50);
        })
    }

    #[bench]
    fn fill_small_vec_8_50_wo_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 8]> = SmallVec::new();

            sv.extend(0..50);
        })
    }

    #[bench]
    fn fill_small_vec_32_50_with_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 32]> = SmallVec::with_capacity(50);

            sv.extend(0..50);
        })
    }

    #[bench]
    fn fill_small_vec_32_50_wo_cap(b: &mut Bencher) {
        b.iter(|| {
            let mut sv: SmallVec<[usize; 32]> = SmallVec::new();

            sv.extend(0..50);
        })
    }
}
<|endoftext|>


<commit_before>use super::*;

#[test]
fn allocator_param() {
    use crate::alloc::AllocErr;

    // Writing a test of integration between third-party
    // allocators and `RawVec` is a little tricky because the `RawVec`
    // API does not expose fallible allocation methods, so we
    // cannot check what happens when allocator is exhausted
    // (beyond detecting a panic).
    //
    // Instead, this just checks that the `RawVec` methods do at
    // least go through the Allocator API when it reserves

    // storage.

    // A dumb allocator that consumes a fixed amount of fuel
    // before allocation attempts start failing.
    struct BoundedAlloc {
        fuel: usize,
    }
    unsafe impl AllocRef for BoundedAlloc {
        fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
            let size = layout.size();
            if size > self.fuel {
                return Err(AllocErr);
            }
            match Global.alloc(layout, init) {
                ok @ Ok(_) => {
                    self.fuel -= size;
                    ok
                }
                err @ Err(_) => err,
            }
        }
        unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
            unsafe { Global.dealloc(ptr, layout) }
        }
    }

    let a = BoundedAlloc { fuel: 500 };
    let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
    assert_eq!(v.alloc.fuel, 450);
    v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
    assert_eq!(v.alloc.fuel, 250);
}

#[test]
fn reserve_does_not_overallocate() {
    {
        let mut v: RawVec<u32> = RawVec::new();
        // First, `reserve` allocates like `reserve_exact`.
        v.reserve(0, 9);
        assert_eq!(9, v.capacity());
    }

    {
        let mut v: RawVec<u32> = RawVec::new();
        v.reserve(0, 7);
        assert_eq!(7, v.capacity());
        // 97 is more than double of 7, so `reserve` should work
        // like `reserve_exact`.
        v.reserve(7, 90);
        assert_eq!(97, v.capacity());
    }

    {
        let mut v: RawVec<u32> = RawVec::new();
        v.reserve(0, 12);
        assert_eq!(12, v.capacity());
        v.reserve(12, 3);
        // 3 is less than half of 12, so `reserve` must grow
        // exponentially. At the time of writing this test grow
        // factor is 2, so new capacity is 24, however, grow factor
        // of 1.5 is OK too. Hence `>= 18` in assert.
        assert!(v.capacity() >= 12 + 12 / 2);
    }
}
<commit_msg>Remove blank line<commit_after>use super::*;

#[test]
fn allocator_param() {
    use crate::alloc::AllocErr;

    // Writing a test of integration between third-party
    // allocators and `RawVec` is a little tricky because the `RawVec`
    // API does not expose fallible allocation methods, so we
    // cannot check what happens when allocator is exhausted
    // (beyond detecting a panic).
    //
    // Instead, this just checks that the `RawVec` methods do at
    // least go through the Allocator API when it reserves
    // storage.

    // A dumb allocator that consumes a fixed amount of fuel
    // before allocation attempts start failing.
    struct BoundedAlloc {
        fuel: usize,
    }
    unsafe impl AllocRef for BoundedAlloc {
        fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
            let size = layout.size();
            if size > self.fuel {
                return Err(AllocErr);
            }
            match Global.alloc(layout, init) {
                ok @ Ok(_) => {
                    self.fuel -= size;
                    ok
                }
                err @ Err(_) => err,
            }
        }
        unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
            unsafe { Global.dealloc(ptr, layout) }
        }
    }

    let a = BoundedAlloc { fuel: 500 };
    let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
    assert_eq!(v.alloc.fuel, 450);
    v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
    assert_eq!(v.alloc.fuel, 250);
}

#[test]
fn reserve_does_not_overallocate() {
    {
        let mut v: RawVec<u32> = RawVec::new();
        // First, `reserve` allocates like `reserve_exact`.
        v.reserve(0, 9);
        assert_eq!(9, v.capacity());
    }

    {
        let mut v: RawVec<u32> = RawVec::new();
        v.reserve(0, 7);
        assert_eq!(7, v.capacity());
        // 97 is more than double of 7, so `reserve` should work
        // like `reserve_exact`.
        v.reserve(7, 90);
        assert_eq!(97, v.capacity());
    }

    {
        let mut v: RawVec<u32> = RawVec::new();
        v.reserve(0, 12);
        assert_eq!(12, v.capacity());
        v.reserve(12, 3);
        // 3 is less than half of 12, so `reserve` must grow
        // exponentially. At the time of writing this test grow
        // factor is 2, so new capacity is 24, however, grow factor
        // of 1.5 is OK too. Hence `>= 18` in assert.
        assert!(v.capacity() >= 12 + 12 / 2);
    }
}
<|endoftext|>