<commit_before>use std::error::Error;
use std::io::Write;
use std::io::stderr;

/// Print an Error type and its cause recursively
///
/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases
/// which each recursion into the errors cause. The error description is used to visualize what
/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next
/// line.
///
/// Example output:
///
/// ```ignore
/// Error    1 : Some error -- caused by:
/// Error    2 : Some other error -- caused by:
/// Error    3 : Yet another Error -- caused by:
/// ...
///
/// Error <NNNN> : <Error description>
/// ```
pub fn trace_error(e: &Error) {
    print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
    write!(stderr(), "\n").ok();
}

/// Print an Error type and its cause recursively, but only `max` levels
///
/// Output is the same as for `trace_error()`, though there are only `max` levels printed.
pub fn trace_error_maxdepth(e: &Error, max: u64) {
    let n = count_error_causes(e);
    write!(stderr(),
    "{}/{} Levels of errors will be printed\n", (if max > n { n } else { max }), n).ok();
    print_trace_maxdepth(n, e, max);
    write!(stderr(), "").ok();
}

/// Print an Error type and its cause recursively with the debug!() macro
///
/// Output is the same as for `trace_error()`.
pub fn trace_error_dbg(e: &Error) {
    print_trace_dbg(0, e);
}

/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
///
/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
/// processed.
fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
    if e.cause().is_some() && idx > 0 {
        match print_trace_maxdepth(idx - 1, e.cause().unwrap(), max) {
            None    => write!(stderr(), "\n").ok(),
            Some(_) => write!(stderr(), " -- caused:\n").ok(),
        };
    } else {
        write!(stderr(), "\n").ok();
    }
    write!(stderr(), "Error {:>4} : {}", idx, e.description()).ok();
    e.cause()
}

/// Count errors in Error::cause() recursively
fn count_error_causes(e: &Error) -> u64 {
    1 + if e.cause().is_some() { count_error_causes(e.cause().unwrap()) } else { 0 }
}

fn print_trace_dbg(idx: u64, e: &Error) {
    debug!("Error {:>4} : {}", idx, e.description());
    if e.cause().is_some() {
        debug!(" -- caused by:");
        print_trace_dbg(idx + 1, e.cause().unwrap());
    }
}

<commit_msg>Make trace() output a bit nicer<commit_after>use std::error::Error;
use std::io::Write;
use std::io::stderr;

/// Print an Error type and its cause recursively
///
/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases
/// which each recursion into the errors cause. The error description is used to visualize what
/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next
/// line.
///
/// Example output:
///
/// ```ignore
/// Error    1 : Some error -- caused by:
/// Error    2 : Some other error -- caused by:
/// Error    3 : Yet another Error -- caused by:
/// ...
///
/// Error <NNNN> : <Error description>
/// ```
pub fn trace_error(e: &Error) {
    print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
    write!(stderr(), "\n").ok();
}

/// Print an Error type and its cause recursively, but only `max` levels
///
/// Output is the same as for `trace_error()`, though there are only `max` levels printed.
pub fn trace_error_maxdepth(e: &Error, max: u64) {
    let n = count_error_causes(e);
    write!(stderr(),
    "{}/{} Levels of errors will be printed\n", (if max > n { n } else { max }), n).ok();
    print_trace_maxdepth(n, e, max);
    write!(stderr(), "").ok();
}

/// Print an Error type and its cause recursively with the debug!() macro
///
/// Output is the same as for `trace_error()`.
pub fn trace_error_dbg(e: &Error) {
    print_trace_dbg(0, e);
}

/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
///
/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
/// processed.
fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
    if e.cause().is_some() && idx > 0 {
        match print_trace_maxdepth(idx - 1, e.cause().unwrap(), max) {
            None    => write!(stderr(), "\n").ok(),
            Some(_) => write!(stderr(), " -- caused:\n").ok(),
        };
    } else {
        write!(stderr(), "\n").ok();
    }
    write!(stderr(), "ERROR[{:>4}]: {}", idx, e.description()).ok();
    e.cause()
}

/// Count errors in Error::cause() recursively
fn count_error_causes(e: &Error) -> u64 {
    1 + if e.cause().is_some() { count_error_causes(e.cause().unwrap()) } else { 0 }
}

fn print_trace_dbg(idx: u64, e: &Error) {
    debug!("ERROR[{:>4}]: {}", idx, e.description());
    if e.cause().is_some() {
        debug!(" -- caused by:");
        print_trace_dbg(idx + 1, e.cause().unwrap());
    }
}

<|endoftext|>


<commit_before>extern crate threescalers;

use threescalers::request::*;
use threescalers::apicall::*;
use threescalers::service::*;
use threescalers::application::*;

use std::collections::HashMap;

#[test]
fn returns_auth_request_from_service_id_pkey_and_app_id() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

/// Given the path of a Request instance, returns a tuple where the first
/// element is the endpoint included in the path, and the second is a HashMap
/// with the parameters and their values.
fn parse_path(path: &str) -> (String, HashMap<&str, &str>) {
    let split_path: Vec<&str> = path.split("?").collect();
    let endpoint = split_path[0];
    let url_params = split_path[1];

    let mut res_params = HashMap::new();

    let param_values: Vec<Vec<&str>> = url_params
        .split("&")
        .map(|param| param.split("=").collect()).collect();

    for param_val in param_values {
        res_params.insert(param_val[0], param_val[1]);
    }

    (endpoint.to_owned(), res_params)
}
<commit_msg>tests/apicall: add integration tests for auth calls<commit_after>extern crate threescalers;

use threescalers::request::*;
use threescalers::apicall::*;
use threescalers::service::*;
use threescalers::application::*;
use threescalers::user::*;

use std::collections::HashMap;

#[test]
fn returns_auth_request_from_service_id_pkey_and_app_id() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_app_id_and_user_id() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore] // TODO: fix code to pass test
fn returns_auth_request_from_service_id_pkey_app_id_and_oauth_user() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let user_oauth_token = "a_user_token";
    let user = User::from_oauth_token(user_oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("access_token", user_oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_app_id_and_app_key() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app_key = "an_app_key";
    let app = Application::from_app_id_and_key(app_id, app_key);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("app_key", app_key);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_app_id_app_key_and_user_id() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app_key = "an_app_key";
    let app = Application::from_app_id_and_key(app_id, app_key);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("app_key", app_key);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore] // TODO: fix code to pass test
fn returns_auth_request_from_service_id_pkey_app_id_app_key_and_oauth_user() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app_key = "an_app_key";
    let app = Application::from_app_id_and_key(app_id, app_key);
    let user_oauth_token = "a_user_token";
    let user = User::from_oauth_token(user_oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("app_key", app_key);
    expected_params.insert("access_token", user_oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_and_user_key() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let user_key = "a_user_key";
    let app = Application::from_user_key(user_key);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("user_key", user_key);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_user_key_and_user_id() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let user_key = "a_user_key";
    let app = Application::from_user_key(user_key);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("user_key", user_key);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore] // TODO: fix code to pass test
fn returns_auth_request_from_service_id_pkey_user_key_and_oauth_user() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let user_key = "a_user_key";
    let app = Application::from_user_key(user_key);
    let user_oauth_token = "a_user_token";
    let user = User::from_oauth_token(user_oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("user_key", user_key);
    expected_params.insert("access_token", user_oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_and_oauth_token() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let oauth_token = "an_app_token";
    let app = Application::from_oauth_token(oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("access_token", oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_pkey_oauth_token_and_user_id() {
    let provider_key = "a_provider_key";
    let creds = Credentials::from_key(provider_key);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let oauth_token = "an_app_token";
    let app = Application::from_oauth_token(oauth_token);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("provider_key", provider_key);
    expected_params.insert("service_id", service_id);
    expected_params.insert("access_token", oauth_token);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore]
fn returns_auth_request_from_service_id_pkey_oauth_token_and_oauth_user() {
    // TODO fix code. It should not be possible to create an Info instance with
    // using a token for the app and another for the user.
}

#[test]
fn returns_auth_request_from_service_id_token_and_app_id() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_app_id_and_user_id() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore] // TODO: fix code to pass test
fn returns_auth_request_from_service_id_token_app_id_and_oauth_user() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app = Application::from_app_id(app_id);
    let user_oauth_token = "a_user_token";
    let user = User::from_oauth_token(user_oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("access_token", user_oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_app_id_and_app_key() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app_key = "an_app_key";
    let app = Application::from_app_id_and_key(app_id, app_key);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("app_key", app_key);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_app_id_app_key_and_user_id() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app_key = "an_app_key";
    let app = Application::from_app_id_and_key(app_id, app_key);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("app_key", app_key);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore] // TODO: fix code to pass test
fn returns_auth_request_from_service_id_token_app_id_app_key_and_oauth_user() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let app_id = "an_app_id";
    let app_key = "an_app_key";
    let app = Application::from_app_id_and_key(app_id, app_key);
    let user_oauth_token = "a_user_token";
    let user = User::from_oauth_token(user_oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("app_id", app_id);
    expected_params.insert("app_key", app_key);
    expected_params.insert("access_token", user_oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_and_user_key() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let user_key = "a_user_key";
    let app = Application::from_user_key(user_key);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("user_key", user_key);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_user_key_and_user_id() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let user_key = "a_user_key";
    let app = Application::from_user_key(user_key);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("user_key", user_key);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore] // TODO: fix code to pass test
fn returns_auth_request_from_service_id_token_user_key_and_oauth_user() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let user_key = "a_user_key";
    let app = Application::from_user_key(user_key);
    let oauth_user_token = "a_user_token";
    let user = User::from_oauth_token(oauth_user_token);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("user_key", user_key);
    expected_params.insert("access_token", oauth_user_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_and_oauth_token() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let oauth_token = "an_app_token";
    let app = Application::from_oauth_token(oauth_token);
    let call = Info::new(Type::Authorize, &service, &app, None);

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("access_token", oauth_token);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
fn returns_auth_request_from_service_id_token_oauth_token_and_user_id() {
    let service_token = "a_service_token";
    let creds = Credentials::from_token(service_token);
    let service_id = "a_service_id";
    let service = Service::new(service_id, creds);
    let oauth_token = "an_app_token";
    let app = Application::from_oauth_token(oauth_token);
    let user_id = "a_user_id";
    let user = User::from_user_id(user_id);
    let call = Info::new(Type::Authorize, &service, &app, Some(&user));

    let result = call.to_request();
    let (res_endpoint, res_params) = parse_path(result.path());

    let mut expected_params = HashMap::new();
    expected_params.insert("service_token", service_token);
    expected_params.insert("service_id", service_id);
    expected_params.insert("access_token", oauth_token);
    expected_params.insert("user_id", user_id);

    assert_eq!("GET", result.method());
    assert_eq!("/transactions/oauth_authorize.xml", res_endpoint);
    assert_eq!(expected_params, res_params);
}

#[test]
#[ignore]
fn returns_auth_request_from_service_id_token_oauth_token_and_oauth_user() {
    // TODO fix code. It should not be possible to create an Info instance with
    // using a token for the app and another for the user.
}

/// Given the path of a Request instance, returns a tuple where the first
/// element is the endpoint included in the path, and the second is a HashMap
/// with the parameters and their values.
fn parse_path(path: &str) -> (String, HashMap<&str, &str>) {
    let split_path: Vec<&str> = path.split("?").collect();
    let endpoint = split_path[0];
    let url_params = split_path[1];

    let mut res_params = HashMap::new();

    let param_values: Vec<Vec<&str>> = url_params
        .split("&")
        .map(|param| param.split("=").collect()).collect();

    for param_val in param_values {
        res_params.insert(param_val[0], param_val[1]);
    }

    (endpoint.to_owned(), res_params)
}
<|endoftext|>


<commit_before>//! Payload stream
use std::cell::RefCell;
use std::collections::VecDeque;
use std::pin::Pin;
use std::rc::{Rc, Weak};
use std::task::{Context, Poll};

use actix_utils::task::LocalWaker;
use bytes::Bytes;
use futures_core::Stream;

use crate::error::PayloadError;

/// max buffer size 32k
pub(crate) const MAX_BUFFER_SIZE: usize = 32_768;

#[derive(Debug, PartialEq)]
pub enum PayloadStatus {
    Read,
    Pause,
    Dropped,
}

/// Buffered stream of bytes chunks
///
/// Payload stores chunks in a vector. First chunk can be received with
/// `.readany()` method. Payload stream is not thread safe. Payload does not
/// notify current task when new data is available.
///
/// Payload stream can be used as `Response` body stream.
#[derive(Debug)]
pub struct Payload {
    inner: Rc<RefCell<Inner>>,
}

impl Payload {
    /// Create payload stream.
    ///
    /// This method construct two objects responsible for bytes stream
    /// generation.
    ///
    /// * `PayloadSender` - *Sender* side of the stream
    ///
    /// * `Payload` - *Receiver* side of the stream
    pub fn create(eof: bool) -> (PayloadSender, Payload) {
        let shared = Rc::new(RefCell::new(Inner::new(eof)));

        (
            PayloadSender {
                inner: Rc::downgrade(&shared),
            },
            Payload { inner: shared },
        )
    }

    /// Create empty payload
    #[doc(hidden)]
    pub fn empty() -> Payload {
        Payload {
            inner: Rc::new(RefCell::new(Inner::new(true))),
        }
    }

    /// Length of the data in this payload
    #[cfg(test)]
    pub fn len(&self) -> usize {
        self.inner.borrow().len()
    }

    /// Is payload empty
    #[cfg(test)]
    pub fn is_empty(&self) -> bool {
        self.inner.borrow().len() == 0
    }

    /// Put unused data back to payload
    #[inline]
    pub fn unread_data(&mut self, data: Bytes) {
        self.inner.borrow_mut().unread_data(data);
    }

    #[inline]
    pub fn readany(
        &mut self,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
        self.inner.borrow_mut().readany(cx)
    }
}

impl Stream for Payload {
    type Item = Result<Bytes, PayloadError>;

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
        self.inner.borrow_mut().readany(cx)
    }
}

/// Sender part of the payload stream
pub struct PayloadSender {
    inner: Weak<RefCell<Inner>>,
}

impl PayloadSender {
    #[inline]
    pub fn set_error(&mut self, err: PayloadError) {
        if let Some(shared) = self.inner.upgrade() {
            shared.borrow_mut().set_error(err)
        }
    }

    #[inline]
    pub fn feed_eof(&mut self) {
        if let Some(shared) = self.inner.upgrade() {
            shared.borrow_mut().feed_eof()
        }
    }

    #[inline]
    pub fn feed_data(&mut self, data: Bytes) {
        if let Some(shared) = self.inner.upgrade() {
            shared.borrow_mut().feed_data(data)
        }
    }

    #[inline]
    pub fn need_read(&self, cx: &mut Context<'_>) -> PayloadStatus {
        // we check need_read only if Payload (other side) is alive,
        // otherwise always return true (consume payload)
        if let Some(shared) = self.inner.upgrade() {
            if shared.borrow().need_read {
                PayloadStatus::Read
            } else {
                shared.borrow_mut().io_task.register(cx.waker());
                PayloadStatus::Pause
            }
        } else {
            PayloadStatus::Dropped
        }
    }
}

#[derive(Debug)]
struct Inner {
    len: usize,
    eof: bool,
    err: Option<PayloadError>,
    need_read: bool,
    items: VecDeque<Bytes>,
    task: LocalWaker,
    io_task: LocalWaker,
}

impl Inner {
    fn new(eof: bool) -> Self {
        Inner {
            eof,
            len: 0,
            err: None,
            items: VecDeque::new(),
            need_read: true,
            task: LocalWaker::new(),
            io_task: LocalWaker::new(),
        }
    }

    #[inline]
    fn set_error(&mut self, err: PayloadError) {
        self.err = Some(err);
    }

    #[inline]
    fn feed_eof(&mut self) {
        self.eof = true;
    }

    #[inline]
    fn feed_data(&mut self, data: Bytes) {
        self.len += data.len();
        self.items.push_back(data);
        self.need_read = self.len < MAX_BUFFER_SIZE;
        self.task.wake();
    }

    #[cfg(test)]
    fn len(&self) -> usize {
        self.len
    }

    fn readany(
        &mut self,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
        if let Some(data) = self.items.pop_front() {
            self.len -= data.len();
            self.need_read = self.len < MAX_BUFFER_SIZE;

            if self.need_read && !self.eof {
                self.task.register(cx.waker());
            }
            self.io_task.wake();
            Poll::Ready(Some(Ok(data)))
        } else if let Some(err) = self.err.take() {
            Poll::Ready(Some(Err(err)))
        } else if self.eof {
            Poll::Ready(None)
        } else {
            self.need_read = true;
            self.task.register(cx.waker());
            self.io_task.wake();
            Poll::Pending
        }
    }

    fn unread_data(&mut self, data: Bytes) {
        self.len += data.len();
        self.items.push_front(data);
    }
}

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

    #[actix_rt::test]
    async fn test_unread_data() {
        let (_, mut payload) = Payload::create(false);

        payload.unread_data(Bytes::from("data"));
        assert!(!payload.is_empty());
        assert_eq!(payload.len(), 4);

        assert_eq!(
            Bytes::from("data"),
            poll_fn(|cx| payload.readany(cx)).await.unwrap().unwrap()
        );
    }
}
<commit_msg>remove localwaker from h1::payload (#2051)<commit_after>//! Payload stream
use std::cell::RefCell;
use std::collections::VecDeque;
use std::pin::Pin;
use std::rc::{Rc, Weak};
use std::task::{Context, Poll, Waker};

use bytes::Bytes;
use futures_core::Stream;

use crate::error::PayloadError;

/// max buffer size 32k
pub(crate) const MAX_BUFFER_SIZE: usize = 32_768;

#[derive(Debug, PartialEq)]
pub enum PayloadStatus {
    Read,
    Pause,
    Dropped,
}

/// Buffered stream of bytes chunks
///
/// Payload stores chunks in a vector. First chunk can be received with
/// `.readany()` method. Payload stream is not thread safe. Payload does not
/// notify current task when new data is available.
///
/// Payload stream can be used as `Response` body stream.
#[derive(Debug)]
pub struct Payload {
    inner: Rc<RefCell<Inner>>,
}

impl Payload {
    /// Create payload stream.
    ///
    /// This method construct two objects responsible for bytes stream
    /// generation.
    ///
    /// * `PayloadSender` - *Sender* side of the stream
    ///
    /// * `Payload` - *Receiver* side of the stream
    pub fn create(eof: bool) -> (PayloadSender, Payload) {
        let shared = Rc::new(RefCell::new(Inner::new(eof)));

        (
            PayloadSender {
                inner: Rc::downgrade(&shared),
            },
            Payload { inner: shared },
        )
    }

    /// Create empty payload
    #[doc(hidden)]
    pub fn empty() -> Payload {
        Payload {
            inner: Rc::new(RefCell::new(Inner::new(true))),
        }
    }

    /// Length of the data in this payload
    #[cfg(test)]
    pub fn len(&self) -> usize {
        self.inner.borrow().len()
    }

    /// Is payload empty
    #[cfg(test)]
    pub fn is_empty(&self) -> bool {
        self.inner.borrow().len() == 0
    }

    /// Put unused data back to payload
    #[inline]
    pub fn unread_data(&mut self, data: Bytes) {
        self.inner.borrow_mut().unread_data(data);
    }

    #[inline]
    pub fn readany(
        &mut self,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
        self.inner.borrow_mut().readany(cx)
    }
}

impl Stream for Payload {
    type Item = Result<Bytes, PayloadError>;

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
        self.inner.borrow_mut().readany(cx)
    }
}

/// Sender part of the payload stream
pub struct PayloadSender {
    inner: Weak<RefCell<Inner>>,
}

impl PayloadSender {
    #[inline]
    pub fn set_error(&mut self, err: PayloadError) {
        if let Some(shared) = self.inner.upgrade() {
            shared.borrow_mut().set_error(err)
        }
    }

    #[inline]
    pub fn feed_eof(&mut self) {
        if let Some(shared) = self.inner.upgrade() {
            shared.borrow_mut().feed_eof()
        }
    }

    #[inline]
    pub fn feed_data(&mut self, data: Bytes) {
        if let Some(shared) = self.inner.upgrade() {
            shared.borrow_mut().feed_data(data)
        }
    }

    #[inline]
    pub fn need_read(&self, cx: &mut Context<'_>) -> PayloadStatus {
        // we check need_read only if Payload (other side) is alive,
        // otherwise always return true (consume payload)
        if let Some(shared) = self.inner.upgrade() {
            if shared.borrow().need_read {
                PayloadStatus::Read
            } else {
                shared.borrow_mut().register_io(cx);
                PayloadStatus::Pause
            }
        } else {
            PayloadStatus::Dropped
        }
    }
}

#[derive(Debug)]
struct Inner {
    len: usize,
    eof: bool,
    err: Option<PayloadError>,
    need_read: bool,
    items: VecDeque<Bytes>,
    task: Option<Waker>,
    io_task: Option<Waker>,
}

impl Inner {
    fn new(eof: bool) -> Self {
        Inner {
            eof,
            len: 0,
            err: None,
            items: VecDeque::new(),
            need_read: true,
            task: None,
            io_task: None,
        }
    }

    /// Wake up future waiting for payload data to be available.
    fn wake(&mut self) {
        if let Some(waker) = self.task.take() {
            waker.wake();
        }
    }

    /// Wake up future feeding data to Payload.
    fn wake_io(&mut self) {
        if let Some(waker) = self.io_task.take() {
            waker.wake();
        }
    }

    /// Register future waiting data from payload.
    /// Waker would be used in `Inner::wake`
    fn register(&mut self, cx: &mut Context<'_>) {
        if self
            .task
            .as_ref()
            .map(|w| !cx.waker().will_wake(w))
            .unwrap_or(true)
        {
            self.task = Some(cx.waker().clone());
        }
    }

    // Register future feeding data to payload.
    /// Waker would be used in `Inner::wake_io`
    fn register_io(&mut self, cx: &mut Context<'_>) {
        if self
            .io_task
            .as_ref()
            .map(|w| !cx.waker().will_wake(w))
            .unwrap_or(true)
        {
            self.io_task = Some(cx.waker().clone());
        }
    }

    #[inline]
    fn set_error(&mut self, err: PayloadError) {
        self.err = Some(err);
    }

    #[inline]
    fn feed_eof(&mut self) {
        self.eof = true;
    }

    #[inline]
    fn feed_data(&mut self, data: Bytes) {
        self.len += data.len();
        self.items.push_back(data);
        self.need_read = self.len < MAX_BUFFER_SIZE;
        self.wake();
    }

    #[cfg(test)]
    fn len(&self) -> usize {
        self.len
    }

    fn readany(
        &mut self,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
        if let Some(data) = self.items.pop_front() {
            self.len -= data.len();
            self.need_read = self.len < MAX_BUFFER_SIZE;

            if self.need_read && !self.eof {
                self.register(cx);
            }
            self.wake_io();
            Poll::Ready(Some(Ok(data)))
        } else if let Some(err) = self.err.take() {
            Poll::Ready(Some(Err(err)))
        } else if self.eof {
            Poll::Ready(None)
        } else {
            self.need_read = true;
            self.register(cx);
            self.wake_io();
            Poll::Pending
        }
    }

    fn unread_data(&mut self, data: Bytes) {
        self.len += data.len();
        self.items.push_front(data);
    }
}

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

    #[actix_rt::test]
    async fn test_unread_data() {
        let (_, mut payload) = Payload::create(false);

        payload.unread_data(Bytes::from("data"));
        assert!(!payload.is_empty());
        assert_eq!(payload.len(), 4);

        assert_eq!(
            Bytes::from("data"),
            poll_fn(|cx| payload.readany(cx)).await.unwrap().unwrap()
        );
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

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

use std::mem::replace;
use test::Bencher;
use num::{BigInt, BigUint, Zero, One, FromPrimitive};
use num::bigint::RandBigInt;
use rand::{SeedableRng, StdRng};

fn get_rng() -> StdRng {
    let seed: &[_] = &[1, 2, 3, 4];
    SeedableRng::from_seed(seed)
}

fn multiply_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x * &y);
}

fn divide_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x / &y);
}

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

fn fib(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        let f2 = f0 + &f1;
        f0 = replace(&mut f1, f2);
    }
    f0
}

#[bench]
fn multiply_0(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 8);
}

#[bench]
fn multiply_1(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 16);
}

#[bench]
fn multiply_2(b: &mut Bencher) {
    multiply_bench(b, 1 << 16, 1 << 16);
}

#[bench]
fn divide_0(b: &mut Bencher) {
    divide_bench(b, 1 << 8, 1 << 6);
}

#[bench]
fn divide_1(b: &mut Bencher) {
    divide_bench(b, 1 << 12, 1 << 8);
}

#[bench]
fn divide_2(b: &mut Bencher) {
    divide_bench(b, 1 << 16, 1 << 12);
}

#[bench]
fn factorial_100(b: &mut Bencher) {
    b.iter(|| factorial(100));
}

#[bench]
fn fib_100(b: &mut Bencher) {
    b.iter(|| fib(100));
}

#[bench]
fn fac_to_string(b: &mut Bencher) {
    let fac = factorial(100);
    b.iter(|| fac.to_string());
}

#[bench]
fn fib_to_string(b: &mut Bencher) {
    let fib = fib(100);
    b.iter(|| fib.to_string());
}

fn to_str_radix_bench(b: &mut Bencher, radix: u32) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    b.iter(|| x.to_str_radix(radix));
}

#[bench]
fn to_str_radix_02(b: &mut Bencher) {
    to_str_radix_bench(b, 2);
}

#[bench]
fn to_str_radix_08(b: &mut Bencher) {
    to_str_radix_bench(b, 8);
}

#[bench]
fn to_str_radix_10(b: &mut Bencher) {
    to_str_radix_bench(b, 10);
}

#[bench]
fn to_str_radix_16(b: &mut Bencher) {
    to_str_radix_bench(b, 16);
}

#[bench]
fn to_str_radix_36(b: &mut Bencher) {
    to_str_radix_bench(b, 36);
}

fn from_str_radix_bench(b: &mut Bencher, radix: u32) {
    use num::Num;
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    let s = x.to_str_radix(radix);
    assert_eq!(x, BigInt::from_str_radix(&s, radix).unwrap());
    b.iter(|| BigInt::from_str_radix(&s, radix));
}

#[bench]
fn from_str_radix_02(b: &mut Bencher) {
    from_str_radix_bench(b, 2);
}

#[bench]
fn from_str_radix_08(b: &mut Bencher) {
    from_str_radix_bench(b, 8);
}

#[bench]
fn from_str_radix_10(b: &mut Bencher) {
    from_str_radix_bench(b, 10);
}

#[bench]
fn from_str_radix_16(b: &mut Bencher) {
    from_str_radix_bench(b, 16);
}

#[bench]
fn from_str_radix_36(b: &mut Bencher) {
    from_str_radix_bench(b, 36);
}

#[bench]
fn shr(b: &mut Bencher) {
    let n = { let one : BigUint = One::one(); one << 1000 };
    b.iter(|| {
        let mut m = n.clone();
        for _ in 0..10 {
            m = m >> 1;
        }
    })
}

#[bench]
fn hash(b: &mut Bencher) {
    use std::collections::HashSet;
    let mut rng = get_rng();
    let v: Vec<BigInt> = (1000..2000).map(|bits| rng.gen_bigint(bits)).collect();
    b.iter(|| {
        let h: HashSet<&BigInt> = v.iter().collect();
        assert_eq!(h.len(), v.len());
    });
}

#[bench]
fn pow_bench(b: &mut Bencher) {
    b.iter(|| {
        let upper = 250_usize;
        for i in 2..upper + 1 {
            for j in 2..upper + 1 {
                let i_big = BigUint::from_usize(i).unwrap();
                num::pow(i_big, j);
            }
        }
    });
}
<commit_msg>Reduce the size of the BigUint pow benchmark<commit_after>#![feature(test)]

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

use std::mem::replace;
use test::Bencher;
use num::{BigInt, BigUint, Zero, One, FromPrimitive};
use num::bigint::RandBigInt;
use rand::{SeedableRng, StdRng};

fn get_rng() -> StdRng {
    let seed: &[_] = &[1, 2, 3, 4];
    SeedableRng::from_seed(seed)
}

fn multiply_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x * &y);
}

fn divide_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x / &y);
}

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

fn fib(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        let f2 = f0 + &f1;
        f0 = replace(&mut f1, f2);
    }
    f0
}

#[bench]
fn multiply_0(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 8);
}

#[bench]
fn multiply_1(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 16);
}

#[bench]
fn multiply_2(b: &mut Bencher) {
    multiply_bench(b, 1 << 16, 1 << 16);
}

#[bench]
fn divide_0(b: &mut Bencher) {
    divide_bench(b, 1 << 8, 1 << 6);
}

#[bench]
fn divide_1(b: &mut Bencher) {
    divide_bench(b, 1 << 12, 1 << 8);
}

#[bench]
fn divide_2(b: &mut Bencher) {
    divide_bench(b, 1 << 16, 1 << 12);
}

#[bench]
fn factorial_100(b: &mut Bencher) {
    b.iter(|| factorial(100));
}

#[bench]
fn fib_100(b: &mut Bencher) {
    b.iter(|| fib(100));
}

#[bench]
fn fac_to_string(b: &mut Bencher) {
    let fac = factorial(100);
    b.iter(|| fac.to_string());
}

#[bench]
fn fib_to_string(b: &mut Bencher) {
    let fib = fib(100);
    b.iter(|| fib.to_string());
}

fn to_str_radix_bench(b: &mut Bencher, radix: u32) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    b.iter(|| x.to_str_radix(radix));
}

#[bench]
fn to_str_radix_02(b: &mut Bencher) {
    to_str_radix_bench(b, 2);
}

#[bench]
fn to_str_radix_08(b: &mut Bencher) {
    to_str_radix_bench(b, 8);
}

#[bench]
fn to_str_radix_10(b: &mut Bencher) {
    to_str_radix_bench(b, 10);
}

#[bench]
fn to_str_radix_16(b: &mut Bencher) {
    to_str_radix_bench(b, 16);
}

#[bench]
fn to_str_radix_36(b: &mut Bencher) {
    to_str_radix_bench(b, 36);
}

fn from_str_radix_bench(b: &mut Bencher, radix: u32) {
    use num::Num;
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    let s = x.to_str_radix(radix);
    assert_eq!(x, BigInt::from_str_radix(&s, radix).unwrap());
    b.iter(|| BigInt::from_str_radix(&s, radix));
}

#[bench]
fn from_str_radix_02(b: &mut Bencher) {
    from_str_radix_bench(b, 2);
}

#[bench]
fn from_str_radix_08(b: &mut Bencher) {
    from_str_radix_bench(b, 8);
}

#[bench]
fn from_str_radix_10(b: &mut Bencher) {
    from_str_radix_bench(b, 10);
}

#[bench]
fn from_str_radix_16(b: &mut Bencher) {
    from_str_radix_bench(b, 16);
}

#[bench]
fn from_str_radix_36(b: &mut Bencher) {
    from_str_radix_bench(b, 36);
}

#[bench]
fn shr(b: &mut Bencher) {
    let n = { let one : BigUint = One::one(); one << 1000 };
    b.iter(|| {
        let mut m = n.clone();
        for _ in 0..10 {
            m = m >> 1;
        }
    })
}

#[bench]
fn hash(b: &mut Bencher) {
    use std::collections::HashSet;
    let mut rng = get_rng();
    let v: Vec<BigInt> = (1000..2000).map(|bits| rng.gen_bigint(bits)).collect();
    b.iter(|| {
        let h: HashSet<&BigInt> = v.iter().collect();
        assert_eq!(h.len(), v.len());
    });
}

#[bench]
fn pow_bench(b: &mut Bencher) {
    b.iter(|| {
        let upper = 100_usize;
        for i in 2..upper + 1 {
            for j in 2..upper + 1 {
                let i_big = BigUint::from_usize(i).unwrap();
                num::pow(i_big, j);
            }
        }
    });
}
<|endoftext|>


<commit_before>use std::slice;
use std::fmt;
use std::fs::File;
use std::io::Seek;
use std::io::SeekFrom::Start;
use std::io;

pub const PHDR_SIZE: usize = 64;

pub const PT_NULL: u32 = 0;
pub const PT_LOAD: u32 = 1;
pub const PT_DYNAMIC: u32 = 2;
pub const PT_INTERP: u32 = 3;
pub const PT_NOTE: u32 = 4;
pub const PT_SHLIB: u32 = 5;
pub const PT_PHDR: u32 = 6;
pub const PT_TLS: u32 = 7;
pub const PT_NUM: u32 = 8;
pub const PT_LOOS: u32 = 0x60000000;
pub const PT_GNU_EH_FRAME: u32 = 0x6474e550;
pub const PT_GNU_STACK: u32 = 0x6474e551;
pub const PT_GNU_RELRO: u32 = 0x6474e552;
pub const PT_LOSUNW: u32 = 0x6ffffffa;
pub const PT_SUNWBSS: u32 = 0x6ffffffa;
pub const PT_SUNWSTACK: u32 = 0x6ffffffb;
pub const PT_HISUNW: u32 = 0x6fffffff;
pub const PT_HIOS: u32 = 0x6fffffff;
pub const PT_LOPROC: u32 = 0x70000000;
pub const PT_HIPROC: u32 = 0x7fffffff;

/// Segment is executable
pub const PF_X: u32 = 1 << 0;

/// Segment is writable
pub const PF_W: u32 = 1 << 1;

/// Segment is readable
pub const PF_R: u32 = 1 << 2;

#[repr(C)]
#[derive(Clone, PartialEq, Default)]
pub struct ProgramHeader {
    pub p_type: u32,
    pub p_flags: u32,
    pub p_offset: u64,
    pub p_vaddr: u64,
    pub p_paddr: u64,
    pub p_filesz: u64,
    pub p_memsz: u64,
    pub p_align: u64,
}

fn pt_to_str(pt: u32) -> &'static str {
    match pt {
        PT_NULL => "PT_NULL",
        PT_LOAD => "PT_LOAD",
        PT_DYNAMIC => "PT_DYNAMIC",
        PT_INTERP => "PT_INTERP",
        PT_NOTE => "PT_NOTE",
        PT_SHLIB => "PT_SHLIB",
        PT_PHDR => "PT_PHDR",
        PT_TLS => "PT_TLS",
        PT_NUM => "PT_NUM",
        PT_LOOS => "PT_LOOS",
        PT_GNU_EH_FRAME => "PT_GNU_EH_FRAME",
        PT_GNU_STACK => "PT_GNU_STACK",
        PT_GNU_RELRO => "PT_GNU_RELRO",
        PT_SUNWBSS => "PT_SUNWBSS",
        PT_SUNWSTACK => "PT_SUNWSTACK",
        PT_HIOS => "PT_HIOS",
        PT_LOPROC => "PT_LOPROC",
        PT_HIPROC => "PT_HIPROC",
        _ => "UNKNOWN_PT",
    }
}

impl fmt::Debug for ProgramHeader {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "p_type: {} p_flags 0x{:x} p_offset: 0x{:x} p_vaddr: 0x{:x} p_paddr: 0x{:x} \
                p_filesz: 0x{:x} p_memsz: 0x{:x} p_align: {}",
               pt_to_str(self.p_type),
               self.p_flags,
               self.p_offset,
               self.p_vaddr,
               self.p_paddr,
               self.p_filesz,
               self.p_memsz,
               self.p_align)
    }
}

impl ProgramHeader {
    pub fn from_bytes(bytes: &[u8], phnum: usize) -> Vec<ProgramHeader> {
        let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr() as *mut ProgramHeader, phnum) };
        let mut phdrs = Vec::with_capacity(phnum);
        phdrs.extend_from_slice(bytes);
        phdrs
    }

    pub unsafe fn from_raw_parts<'a>(phdrp: *const ProgramHeader,
                                     phnum: usize)
                                     -> &'a [ProgramHeader] {
        slice::from_raw_parts(phdrp, phnum)
    }

#[cfg(not(feature = "no_endian_fd"))]
    pub fn from_fd(fd: &mut File, offset: u64, count: usize, is_lsb: bool) -> io::Result<Vec<ProgramHeader>> {
        use byteorder::{LittleEndian,BigEndian,ReadBytesExt};

        let mut phdrs = vec![];
        try!(fd.seek(Start(offset)));
        for _ in 0..count {
            let mut phdr = ProgramHeader::default();
            if is_lsb {
                phdr.p_type = try!(fd.read_u32::<LittleEndian>());
                phdr.p_flags = try!(fd.read_u32::<LittleEndian>());
                phdr.p_offset = try!(fd.read_u64::<LittleEndian>());
                phdr.p_vaddr = try!(fd.read_u64::<LittleEndian>());
                phdr.p_paddr = try!(fd.read_u64::<LittleEndian>());
                phdr.p_filesz = try!(fd.read_u64::<LittleEndian>());
                phdr.p_memsz = try!(fd.read_u64::<LittleEndian>());
                phdr.p_align = try!(fd.read_u64::<LittleEndian>());
            } else {
                phdr.p_type = try!(fd.read_u32::<BigEndian>());
                phdr.p_flags = try!(fd.read_u32::<BigEndian>());
                phdr.p_offset = try!(fd.read_u64::<BigEndian>());
                phdr.p_vaddr = try!(fd.read_u64::<BigEndian>());
                phdr.p_paddr = try!(fd.read_u64::<BigEndian>());
                phdr.p_filesz = try!(fd.read_u64::<BigEndian>());
                phdr.p_memsz = try!(fd.read_u64::<BigEndian>());
                phdr.p_align = try!(fd.read_u64::<BigEndian>());
            }
            phdrs.push(phdr);
        }

        Ok(phdrs)
    }

#[cfg(feature = "no_endian_fd")]
    pub fn from_fd(fd: &mut File, offset: u64, count: usize, _: bool) -> io::Result<Vec<ProgramHeader>> {
        use std::io::Read;
        let mut phdrs = [0u8; count * PHDR_SIZE];
        try!(fd.seek(Start(offset)));
        try!(fd.read(&mut phdrs));
        Ok(ProgramHeader::from_bytes(&mut phdrs, count))
    }
}
<commit_msg>elf.program_header: remove &mut<commit_after>use std::slice;
use std::fmt;
use std::fs::File;
use std::io::Seek;
use std::io::SeekFrom::Start;
use std::io;

pub const PHDR_SIZE: usize = 64;

pub const PT_NULL: u32 = 0;
pub const PT_LOAD: u32 = 1;
pub const PT_DYNAMIC: u32 = 2;
pub const PT_INTERP: u32 = 3;
pub const PT_NOTE: u32 = 4;
pub const PT_SHLIB: u32 = 5;
pub const PT_PHDR: u32 = 6;
pub const PT_TLS: u32 = 7;
pub const PT_NUM: u32 = 8;
pub const PT_LOOS: u32 = 0x60000000;
pub const PT_GNU_EH_FRAME: u32 = 0x6474e550;
pub const PT_GNU_STACK: u32 = 0x6474e551;
pub const PT_GNU_RELRO: u32 = 0x6474e552;
pub const PT_LOSUNW: u32 = 0x6ffffffa;
pub const PT_SUNWBSS: u32 = 0x6ffffffa;
pub const PT_SUNWSTACK: u32 = 0x6ffffffb;
pub const PT_HISUNW: u32 = 0x6fffffff;
pub const PT_HIOS: u32 = 0x6fffffff;
pub const PT_LOPROC: u32 = 0x70000000;
pub const PT_HIPROC: u32 = 0x7fffffff;

/// Segment is executable
pub const PF_X: u32 = 1 << 0;

/// Segment is writable
pub const PF_W: u32 = 1 << 1;

/// Segment is readable
pub const PF_R: u32 = 1 << 2;

#[repr(C)]
#[derive(Clone, PartialEq, Default)]
pub struct ProgramHeader {
    pub p_type: u32,
    pub p_flags: u32,
    pub p_offset: u64,
    pub p_vaddr: u64,
    pub p_paddr: u64,
    pub p_filesz: u64,
    pub p_memsz: u64,
    pub p_align: u64,
}

fn pt_to_str(pt: u32) -> &'static str {
    match pt {
        PT_NULL => "PT_NULL",
        PT_LOAD => "PT_LOAD",
        PT_DYNAMIC => "PT_DYNAMIC",
        PT_INTERP => "PT_INTERP",
        PT_NOTE => "PT_NOTE",
        PT_SHLIB => "PT_SHLIB",
        PT_PHDR => "PT_PHDR",
        PT_TLS => "PT_TLS",
        PT_NUM => "PT_NUM",
        PT_LOOS => "PT_LOOS",
        PT_GNU_EH_FRAME => "PT_GNU_EH_FRAME",
        PT_GNU_STACK => "PT_GNU_STACK",
        PT_GNU_RELRO => "PT_GNU_RELRO",
        PT_SUNWBSS => "PT_SUNWBSS",
        PT_SUNWSTACK => "PT_SUNWSTACK",
        PT_HIOS => "PT_HIOS",
        PT_LOPROC => "PT_LOPROC",
        PT_HIPROC => "PT_HIPROC",
        _ => "UNKNOWN_PT",
    }
}

impl fmt::Debug for ProgramHeader {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "p_type: {} p_flags 0x{:x} p_offset: 0x{:x} p_vaddr: 0x{:x} p_paddr: 0x{:x} \
                p_filesz: 0x{:x} p_memsz: 0x{:x} p_align: {}",
               pt_to_str(self.p_type),
               self.p_flags,
               self.p_offset,
               self.p_vaddr,
               self.p_paddr,
               self.p_filesz,
               self.p_memsz,
               self.p_align)
    }
}

impl ProgramHeader {
    pub fn from_bytes(bytes: &[u8], phnum: usize) -> Vec<ProgramHeader> {
        let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr() as *mut ProgramHeader, phnum) };
        let mut phdrs = Vec::with_capacity(phnum);
        phdrs.extend_from_slice(bytes);
        phdrs
    }

    pub unsafe fn from_raw_parts<'a>(phdrp: *const ProgramHeader,
                                     phnum: usize)
                                     -> &'a [ProgramHeader] {
        slice::from_raw_parts(phdrp, phnum)
    }

#[cfg(not(feature = "no_endian_fd"))]
    pub fn from_fd(fd: &mut File, offset: u64, count: usize, is_lsb: bool) -> io::Result<Vec<ProgramHeader>> {
        use byteorder::{LittleEndian,BigEndian,ReadBytesExt};

        let mut phdrs = vec![];
        try!(fd.seek(Start(offset)));
        for _ in 0..count {
            let mut phdr = ProgramHeader::default();
            if is_lsb {
                phdr.p_type = try!(fd.read_u32::<LittleEndian>());
                phdr.p_flags = try!(fd.read_u32::<LittleEndian>());
                phdr.p_offset = try!(fd.read_u64::<LittleEndian>());
                phdr.p_vaddr = try!(fd.read_u64::<LittleEndian>());
                phdr.p_paddr = try!(fd.read_u64::<LittleEndian>());
                phdr.p_filesz = try!(fd.read_u64::<LittleEndian>());
                phdr.p_memsz = try!(fd.read_u64::<LittleEndian>());
                phdr.p_align = try!(fd.read_u64::<LittleEndian>());
            } else {
                phdr.p_type = try!(fd.read_u32::<BigEndian>());
                phdr.p_flags = try!(fd.read_u32::<BigEndian>());
                phdr.p_offset = try!(fd.read_u64::<BigEndian>());
                phdr.p_vaddr = try!(fd.read_u64::<BigEndian>());
                phdr.p_paddr = try!(fd.read_u64::<BigEndian>());
                phdr.p_filesz = try!(fd.read_u64::<BigEndian>());
                phdr.p_memsz = try!(fd.read_u64::<BigEndian>());
                phdr.p_align = try!(fd.read_u64::<BigEndian>());
            }
            phdrs.push(phdr);
        }

        Ok(phdrs)
    }

#[cfg(feature = "no_endian_fd")]
    pub fn from_fd(fd: &mut File, offset: u64, count: usize, _: bool) -> io::Result<Vec<ProgramHeader>> {
        use std::io::Read;
        let mut phdrs = [0u8; count * PHDR_SIZE];
        try!(fd.seek(Start(offset)));
        try!(fd.read(&mut phdrs));
        Ok(ProgramHeader::from_bytes(&phdrs, count))
    }
}
<|endoftext|>


<commit_before>// compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts
// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff

use std::ptr::NonNull;

pub struct LinkedList {
    head: Option<NonNull<Node>>,
    tail: Option<NonNull<Node>>,
}

pub struct Node {
    next: Option<NonNull<Node>>,
}

impl LinkedList {
    pub fn new() -> Self {
        Self { head: None, tail: None }
    }

    pub fn append(&mut self, other: &mut Self) {
        match self.tail {
            None => { },
            Some(mut tail) => {
                // `as_mut` is okay here because we have exclusive access to the entirety
                // of both lists.
                if let Some(other_head) = other.head.take() {
                    unsafe {
                        tail.as_mut().next = Some(other_head);
                    }
                }
            }
        }
    }
}

fn main() {
    let mut one = LinkedList::new();
    let mut two = LinkedList::new();
    one.append(&mut two);
}
<commit_msg>Ignore now-broken mir-opt test<commit_after>// compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts
// ignore-test
// FIXME: the pass is unsound and causes ICEs in the MIR validator

// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff

use std::ptr::NonNull;

pub struct LinkedList {
    head: Option<NonNull<Node>>,
    tail: Option<NonNull<Node>>,
}

pub struct Node {
    next: Option<NonNull<Node>>,
}

impl LinkedList {
    pub fn new() -> Self {
        Self { head: None, tail: None }
    }

    pub fn append(&mut self, other: &mut Self) {
        match self.tail {
            None => {}
            Some(mut tail) => {
                // `as_mut` is okay here because we have exclusive access to the entirety
                // of both lists.
                if let Some(other_head) = other.head.take() {
                    unsafe {
                        tail.as_mut().next = Some(other_head);
                    }
                }
            }
        }
    }
}

fn main() {
    let mut one = LinkedList::new();
    let mut two = LinkedList::new();
    one.append(&mut two);
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};

struct MyVisitor {
    types: @mut ~[~str],
}

impl TyVisitor for MyVisitor {
    fn visit_bot(&self) -> bool {
        self.types.push(~"bot");
        error!("visited bot type");
        true
    }
    fn visit_nil(&self) -> bool {
        self.types.push(~"nil");
        error!("visited nil type");
        true
    }
    fn visit_bool(&self) -> bool {
        self.types.push(~"bool");
        error!("visited bool type");
        true
    }
    fn visit_int(&self) -> bool {
        self.types.push(~"int");
        error!("visited int type");
        true
    }
    fn visit_i8(&self) -> bool {
        self.types.push(~"i8");
        error!("visited i8 type");
        true
    }
    fn visit_i16(&self) -> bool {
        self.types.push(~"i16");
        error!("visited i16 type");
        true
    }
    fn visit_i32(&self) -> bool { true }
    fn visit_i64(&self) -> bool { true }

    fn visit_uint(&self) -> bool { true }
    fn visit_u8(&self) -> bool { true }
    fn visit_u16(&self) -> bool { true }
    fn visit_u32(&self) -> bool { true }
    fn visit_u64(&self) -> bool { true }

    fn visit_float(&self) -> bool { true }
    fn visit_f32(&self) -> bool { true }
    fn visit_f64(&self) -> bool { true }

    fn visit_char(&self) -> bool { true }
    fn visit_str(&self) -> bool { true }

    fn visit_estr_box(&self) -> bool { true }
    fn visit_estr_uniq(&self) -> bool { true }
    fn visit_estr_slice(&self) -> bool { true }
    fn visit_estr_fixed(&self,
                        _sz: uint, _sz: uint,
                        _align: uint) -> bool { true }

    fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }

    fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_evec_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool {
        self.types.push(~"[");
        unsafe {
            visit_tydesc(inner, (@*self) as @TyVisitor);
        }
        self.types.push(~"]");
        true
    }
    fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint,
                        _mtbl: uint, _inner: *TyDesc) -> bool { true }

    fn visit_enter_rec(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }
    fn visit_rec_field(&self, _i: uint, _name: &str,
                       _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_rec(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_class(&self, _n_fields: uint,
                         _sz: uint, _align: uint) -> bool { true }
    fn visit_class_field(&self, _i: uint, _name: &str,
                         _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_class(&self, _n_fields: uint,
                         _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_tup(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }
    fn visit_tup_field(&self, _i: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_tup(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_enum(&self, _n_variants: uint,
                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
                        _sz: uint, _align: uint) -> bool { true }
    fn visit_enter_enum_variant(&self,
                                _variant: uint,
                                _disr_val: int,
                                _n_fields: uint,
                                _name: &str) -> bool { true }
    fn visit_enum_variant_field(&self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_enum_variant(&self,
                                _variant: uint,
                                _disr_val: int,
                                _n_fields: uint,
                                _name: &str) -> bool { true }
    fn visit_leave_enum(&self,
                        _n_variants: uint,
                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
                        _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_fn(&self, _purity: uint, _proto: uint,
                      _n_inputs: uint, _retstyle: uint) -> bool { true }
    fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { true }
    fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_fn(&self, _purity: uint, _proto: uint,
                      _n_inputs: uint, _retstyle: uint) -> bool { true }

    fn visit_trait(&self) -> bool { true }
    fn visit_var(&self) -> bool { true }
    fn visit_var_integral(&self) -> bool { true }
    fn visit_param(&self, _i: uint) -> bool { true }
    fn visit_self(&self) -> bool { true }
    fn visit_type(&self) -> bool { true }
    fn visit_opaque_box(&self) -> bool { true }
    fn visit_constr(&self, _inner: *TyDesc) -> bool { true }
    fn visit_closure_ptr(&self, _ck: uint) -> bool { true }
}

fn visit_ty<T>(v: @TyVisitor) {
    unsafe {
        visit_tydesc(get_tydesc::<T>(), v);
    }
}

pub fn main() {
    let v = @MyVisitor {types: @mut ~[]};
    let vv = v as @TyVisitor;

    visit_ty::<bool>(vv);
    visit_ty::<int>(vv);
    visit_ty::<i8>(vv);
    visit_ty::<i16>(vv);
    visit_ty::<~[int]>(vv);

    for v.types.each |&s| {
        println(fmt!("type: %s", s));
    }
    assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]);
}
<commit_msg>Fix reflect-visit-type for iterator changes<commit_after>// Copyright 2012 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.

use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};

struct MyVisitor {
    types: @mut ~[~str],
}

impl TyVisitor for MyVisitor {
    fn visit_bot(&self) -> bool {
        self.types.push(~"bot");
        error!("visited bot type");
        true
    }
    fn visit_nil(&self) -> bool {
        self.types.push(~"nil");
        error!("visited nil type");
        true
    }
    fn visit_bool(&self) -> bool {
        self.types.push(~"bool");
        error!("visited bool type");
        true
    }
    fn visit_int(&self) -> bool {
        self.types.push(~"int");
        error!("visited int type");
        true
    }
    fn visit_i8(&self) -> bool {
        self.types.push(~"i8");
        error!("visited i8 type");
        true
    }
    fn visit_i16(&self) -> bool {
        self.types.push(~"i16");
        error!("visited i16 type");
        true
    }
    fn visit_i32(&self) -> bool { true }
    fn visit_i64(&self) -> bool { true }

    fn visit_uint(&self) -> bool { true }
    fn visit_u8(&self) -> bool { true }
    fn visit_u16(&self) -> bool { true }
    fn visit_u32(&self) -> bool { true }
    fn visit_u64(&self) -> bool { true }

    fn visit_float(&self) -> bool { true }
    fn visit_f32(&self) -> bool { true }
    fn visit_f64(&self) -> bool { true }

    fn visit_char(&self) -> bool { true }
    fn visit_str(&self) -> bool { true }

    fn visit_estr_box(&self) -> bool { true }
    fn visit_estr_uniq(&self) -> bool { true }
    fn visit_estr_slice(&self) -> bool { true }
    fn visit_estr_fixed(&self,
                        _sz: uint, _sz: uint,
                        _align: uint) -> bool { true }

    fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }

    fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_evec_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool {
        self.types.push(~"[");
        unsafe {
            visit_tydesc(inner, (@*self) as @TyVisitor);
        }
        self.types.push(~"]");
        true
    }
    fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint,
                        _mtbl: uint, _inner: *TyDesc) -> bool { true }

    fn visit_enter_rec(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }
    fn visit_rec_field(&self, _i: uint, _name: &str,
                       _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_rec(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_class(&self, _n_fields: uint,
                         _sz: uint, _align: uint) -> bool { true }
    fn visit_class_field(&self, _i: uint, _name: &str,
                         _mtbl: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_class(&self, _n_fields: uint,
                         _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_tup(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }
    fn visit_tup_field(&self, _i: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_tup(&self, _n_fields: uint,
                       _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_enum(&self, _n_variants: uint,
                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
                        _sz: uint, _align: uint) -> bool { true }
    fn visit_enter_enum_variant(&self,
                                _variant: uint,
                                _disr_val: int,
                                _n_fields: uint,
                                _name: &str) -> bool { true }
    fn visit_enum_variant_field(&self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_enum_variant(&self,
                                _variant: uint,
                                _disr_val: int,
                                _n_fields: uint,
                                _name: &str) -> bool { true }
    fn visit_leave_enum(&self,
                        _n_variants: uint,
                        _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
                        _sz: uint, _align: uint) -> bool { true }

    fn visit_enter_fn(&self, _purity: uint, _proto: uint,
                      _n_inputs: uint, _retstyle: uint) -> bool { true }
    fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { true }
    fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { true }
    fn visit_leave_fn(&self, _purity: uint, _proto: uint,
                      _n_inputs: uint, _retstyle: uint) -> bool { true }

    fn visit_trait(&self) -> bool { true }
    fn visit_var(&self) -> bool { true }
    fn visit_var_integral(&self) -> bool { true }
    fn visit_param(&self, _i: uint) -> bool { true }
    fn visit_self(&self) -> bool { true }
    fn visit_type(&self) -> bool { true }
    fn visit_opaque_box(&self) -> bool { true }
    fn visit_constr(&self, _inner: *TyDesc) -> bool { true }
    fn visit_closure_ptr(&self, _ck: uint) -> bool { true }
}

fn visit_ty<T>(v: @TyVisitor) {
    unsafe {
        visit_tydesc(get_tydesc::<T>(), v);
    }
}

pub fn main() {
    let v = @MyVisitor {types: @mut ~[]};
    let vv = v as @TyVisitor;

    visit_ty::<bool>(vv);
    visit_ty::<int>(vv);
    visit_ty::<i8>(vv);
    visit_ty::<i16>(vv);
    visit_ty::<~[int]>(vv);

    for v.types.iter().advance |&s| {
        println(fmt!("type: %s", s));
    }
    assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]);
}
<|endoftext|>


<commit_before>extern crate rusoto_mock;

use crate::generated::{
    GetQueueUrlError, GetQueueUrlRequest, MessageAttributeValue, ReceiveMessageRequest,
    SendMessageRequest, Sqs, SqsClient,
};
use std::collections::HashMap;

use self::rusoto_mock::*;
use rusoto_core::param::Params;
use rusoto_core::signature::SignedRequest;
use rusoto_core::signature::SignedRequestPayload;
use rusoto_core::{Region, RusotoError};
use serde_urlencoded;

#[tokio::test]
async fn should_serialize_map_parameters_in_request_body() {
    let mock = MockRequestDispatcher::with_status(200)
        .with_body(
            r#"<?xml version="1.0" encoding="UTF-8"?>
        <SendMessageResponse>
            <SendMessageResult>
                <MD5OfMessageBody>
                    fafb00f5732ab283681e124bf8747ed1
                </MD5OfMessageBody>
                <MD5OfMessageAttributes>
            3ae8f24a165a8cedc005670c81a27295
                </MD5OfMessageAttributes>
                <MessageId>
                    5fea7756-0ea4-451a-a703-a558b933e274
                </MessageId>
            </SendMessageResult>
            <ResponseMetadata>
                <RequestId>
                    27daac76-34dd-47df-bd01-1f6e873584a0
                </RequestId>
            </ResponseMetadata>
        </SendMessageResponse>"#,
        )
        .with_request_checker(|request: &SignedRequest| {
            println!("{:#?}", request.params);

            assert_eq!("POST", request.method);
            assert_eq!("/", request.path);
            if let Some(SignedRequestPayload::Buffer(ref buffer)) = request.payload {
                let params: Params = serde_urlencoded::from_bytes(buffer).unwrap();
                assert_eq!(
                    Some(&Some("test_attribute_name".to_owned())),
                    params.get("MessageAttribute.1.Name")
                );
                assert_eq!(
                    Some(&Some("test_attribute_value".to_owned())),
                    params.get("MessageAttribute.1.Value.StringValue")
                );
                assert_eq!(
                    Some(&Some("String".to_owned())),
                    params.get("MessageAttribute.1.Value.DataType")
                );
            } else {
                panic!("Unexpected request.payload: {:?}", request.payload);
            }
        });

    let mut message_attributes = HashMap::new();

    message_attributes.insert(
        "test_attribute_name".to_owned(),
        MessageAttributeValue {
            string_value: Some("test_attribute_value".to_owned()),
            data_type: "String".to_owned(),
            ..Default::default()
        },
    );
    let request = SendMessageRequest {
        message_body: "foo".to_owned(),
        queue_url: "bar".to_owned(),
        message_attributes: Some(message_attributes),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let _result = client.send_message(request).await.unwrap();
}

#[tokio::test]
async fn should_fix_issue_323() {
    let mock = MockRequestDispatcher::with_status(200)
        .with_body(
            r#"<?xml version="1.0" encoding="UTF-8"?>
        <ReceiveMessageResponse>
            <ReceiveMessageResult>
            <Message>
                <MessageId>
                5fea7756-0ea4-451a-a703-a558b933e274
                </MessageId>
                <ReceiptHandle>
                MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+Cw
                Lj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QE
                auMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=
                </ReceiptHandle>
                <MD5OfBody>
                fafb00f5732ab283681e124bf8747ed1
                </MD5OfBody>
                This is a test message
                <Attribute>
                <Name>SenderId</Name>
                <Value>195004372649</Value>
                </Attribute>
            </Message>
            </ReceiveMessageResult>
            <ResponseMetadata>
            <RequestId>
                b6633655-283d-45b4-aee4-4e84e0ae6afa
            </RequestId>
            </ResponseMetadata>
        </ReceiveMessageResponse>"#,
        )
        .with_request_checker(|request: &SignedRequest| {
            assert_eq!("POST", request.method);
            assert_eq!("/", request.path);
            if let Some(SignedRequestPayload::Buffer(ref buffer)) = request.payload {
                let params: Params = serde_urlencoded::from_bytes(buffer).unwrap();
                assert_eq!(
                    params.get("Action"),
                    Some(&Some("ReceiveMessage".to_owned()))
                );
                assert_eq!(
                    params.get("MaxNumberOfMessages"),
                    Some(&Some("1".to_owned()))
                );
                assert_eq!(params.get("VisibilityTimeout"), Some(&Some("2".to_owned())));
                assert_eq!(params.get("WaitTimeSeconds"), Some(&Some("3".to_owned())));
                assert_eq!(params.get("Integer"), None);
            } else {
                panic!("Unexpected request.payload: {:?}", request.payload);
            }
        });

    let request = ReceiveMessageRequest {
        max_number_of_messages: Some(1),
        queue_url: "foo".to_owned(),
        visibility_timeout: Some(2),
        wait_time_seconds: Some(3),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let _result = client.receive_message(request).await.unwrap();
}

#[tokio::test]
async fn test_parse_queue_does_not_exist_error() {
    let mock = MockRequestDispatcher::with_status(400).with_body(
        r#"<?xml version="1.0"?>
        <ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
            <Error>
                <Type>Sender</Type>
                AWS.SimpleQueueService.NonExistentQueue
                <Message>The specified queue does not exist for this wsdl version.</Message>
                <Detail/>
            </Error>
            <RequestId>8f8f9957-c0d9-536a-9ca6-ca7483be06ad</RequestId>
        </ErrorResponse>"#,
    );

    let request = GetQueueUrlRequest {
        queue_name: "no-such-queue".to_owned(),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let result = client.get_queue_url(request).await;
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(
        RusotoError::Service(GetQueueUrlError::QueueDoesNotExist(
            "The specified queue does not exist for this wsdl version.".to_owned()
        )),
        err
    );
}
<commit_msg>Add a test of infinite loop reproduction.<commit_after>extern crate rusoto_mock;

use crate::generated::{
    GetQueueUrlError, GetQueueUrlRequest, MessageAttributeValue, ReceiveMessageRequest,
    SendMessageRequest, Sqs, SqsClient,
};
use std::collections::HashMap;

use self::rusoto_mock::*;
use rusoto_core::param::Params;
use rusoto_core::signature::SignedRequest;
use rusoto_core::signature::SignedRequestPayload;
use rusoto_core::{Region, RusotoError};
use serde_urlencoded;

#[tokio::test]
async fn should_serialize_map_parameters_in_request_body() {
    let mock = MockRequestDispatcher::with_status(200)
        .with_body(
            r#"<?xml version="1.0" encoding="UTF-8"?>
        <SendMessageResponse>
            <SendMessageResult>
                <MD5OfMessageBody>
                    fafb00f5732ab283681e124bf8747ed1
                </MD5OfMessageBody>
                <MD5OfMessageAttributes>
            3ae8f24a165a8cedc005670c81a27295
                </MD5OfMessageAttributes>
                <MessageId>
                    5fea7756-0ea4-451a-a703-a558b933e274
                </MessageId>
            </SendMessageResult>
            <ResponseMetadata>
                <RequestId>
                    27daac76-34dd-47df-bd01-1f6e873584a0
                </RequestId>
            </ResponseMetadata>
        </SendMessageResponse>"#,
        )
        .with_request_checker(|request: &SignedRequest| {
            println!("{:#?}", request.params);

            assert_eq!("POST", request.method);
            assert_eq!("/", request.path);
            if let Some(SignedRequestPayload::Buffer(ref buffer)) = request.payload {
                let params: Params = serde_urlencoded::from_bytes(buffer).unwrap();
                assert_eq!(
                    Some(&Some("test_attribute_name".to_owned())),
                    params.get("MessageAttribute.1.Name")
                );
                assert_eq!(
                    Some(&Some("test_attribute_value".to_owned())),
                    params.get("MessageAttribute.1.Value.StringValue")
                );
                assert_eq!(
                    Some(&Some("String".to_owned())),
                    params.get("MessageAttribute.1.Value.DataType")
                );
            } else {
                panic!("Unexpected request.payload: {:?}", request.payload);
            }
        });

    let mut message_attributes = HashMap::new();

    message_attributes.insert(
        "test_attribute_name".to_owned(),
        MessageAttributeValue {
            string_value: Some("test_attribute_value".to_owned()),
            data_type: "String".to_owned(),
            ..Default::default()
        },
    );
    let request = SendMessageRequest {
        message_body: "foo".to_owned(),
        queue_url: "bar".to_owned(),
        message_attributes: Some(message_attributes),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let _result = client.send_message(request).await.unwrap();
}

#[tokio::test]
async fn should_fix_issue_323() {
    let mock = MockRequestDispatcher::with_status(200)
        .with_body(
            r#"<?xml version="1.0" encoding="UTF-8"?>
        <ReceiveMessageResponse>
            <ReceiveMessageResult>
            <Message>
                <MessageId>
                5fea7756-0ea4-451a-a703-a558b933e274
                </MessageId>
                <ReceiptHandle>
                MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+Cw
                Lj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QE
                auMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=
                </ReceiptHandle>
                <MD5OfBody>
                fafb00f5732ab283681e124bf8747ed1
                </MD5OfBody>
                This is a test message
                <Attribute>
                <Name>SenderId</Name>
                <Value>195004372649</Value>
                </Attribute>
            </Message>
            </ReceiveMessageResult>
            <ResponseMetadata>
            <RequestId>
                b6633655-283d-45b4-aee4-4e84e0ae6afa
            </RequestId>
            </ResponseMetadata>
        </ReceiveMessageResponse>"#,
        )
        .with_request_checker(|request: &SignedRequest| {
            assert_eq!("POST", request.method);
            assert_eq!("/", request.path);
            if let Some(SignedRequestPayload::Buffer(ref buffer)) = request.payload {
                let params: Params = serde_urlencoded::from_bytes(buffer).unwrap();
                assert_eq!(
                    params.get("Action"),
                    Some(&Some("ReceiveMessage".to_owned()))
                );
                assert_eq!(
                    params.get("MaxNumberOfMessages"),
                    Some(&Some("1".to_owned()))
                );
                assert_eq!(params.get("VisibilityTimeout"), Some(&Some("2".to_owned())));
                assert_eq!(params.get("WaitTimeSeconds"), Some(&Some("3".to_owned())));
                assert_eq!(params.get("Integer"), None);
            } else {
                panic!("Unexpected request.payload: {:?}", request.payload);
            }
        });

    let request = ReceiveMessageRequest {
        max_number_of_messages: Some(1),
        queue_url: "foo".to_owned(),
        visibility_timeout: Some(2),
        wait_time_seconds: Some(3),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let _result = client.receive_message(request).await.unwrap();
}

#[tokio::test]
async fn test_parse_queue_does_not_exist_error() {
    let mock = MockRequestDispatcher::with_status(400).with_body(
        r#"<?xml version="1.0"?>
        <ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
            <Error>
                <Type>Sender</Type>
                AWS.SimpleQueueService.NonExistentQueue
                <Message>The specified queue does not exist for this wsdl version.</Message>
                <Detail/>
            </Error>
            <RequestId>8f8f9957-c0d9-536a-9ca6-ca7483be06ad</RequestId>
        </ErrorResponse>"#,
    );

    let request = GetQueueUrlRequest {
        queue_name: "no-such-queue".to_owned(),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let result = client.get_queue_url(request).await;
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(
        RusotoError::Service(GetQueueUrlError::QueueDoesNotExist(
            "The specified queue does not exist for this wsdl version.".to_owned()
        )),
        err
    );
}

#[tokio::test]
async fn should_deserialize_map_parameters_in_response_body() {
    let mock = MockRequestDispatcher::with_status(200)
        .with_body(
            r#"<?xml version="1.0" encoding="UTF-8"?>
        <ReceiveMessageResponse>
            <ReceiveMessageResult>
            <Message>
                <MessageId>
                    5fea7756-0ea4-451a-a703-a558b933e274
                </MessageId>
                <ReceiptHandle>
                    MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+Cw
                    Lj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QE
                    auMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=
                </ReceiptHandle>
                <MD5OfBody>
                    fafb00f5732ab283681e124bf8747ed1
                </MD5OfBody>
                This is a test message
                <MessageAttribute>
                    <Name>test_attribute_name</Name>
                    <Value>
                        <DataType>String</DataType>
                        <StringValue>test_attribute_value</StringValue>
                    </Value>
                </MessageAttribute>
            </Message>
            </ReceiveMessageResult>
            <ResponseMetadata>
            <RequestId>
                b6633655-283d-45b4-aee4-4e84e0ae6afa
            </RequestId>
            </ResponseMetadata>
        </ReceiveMessageResponse>"#,
        );

    let request = ReceiveMessageRequest {
        queue_url: "foo".to_owned(),
        ..Default::default()
    };

    let client = SqsClient::new_with(mock, MockCredentialsProvider, Region::UsEast1);
    let result = client.receive_message(request).await;
    assert!(result.is_ok());

    let mut messages = result.unwrap().messages.unwrap();
    assert_eq!(1, messages.len());

    let message = messages.pop().unwrap();
    let mut message_attributes = HashMap::new();
    message_attributes.insert(
        "test_attribute_name".to_owned(),
        MessageAttributeValue {
            string_value: Some("test_attribute_value".to_owned()),
            data_type: "String".to_owned(),
            ..Default::default()
        },
    );

    assert_eq!(
        message_attributes,
        message.message_attributes.unwrap(),
    );
}<|endoftext|>


<commit_before>use std::collections::HashMap;

use lazy_static::lazy_static;
use maplit::hashmap;
use specs::{ReadStorage, System, WriteStorage};

use crate::combat::components::{Command, Direction, Intent, MoveCommand, Velocity, WalkingState};

pub const STEP_LEFT: [i32; 4] = [-25, -3, -23, -4];
pub const STEP_RIGHT: [i32; 4] = [25, 3, 23, 4];
pub const STEP_UP: [i32; 4] = [-8, -2, -9, -2];
pub const STEP_DOWN: [i32; 4] = [2, 9, 2, 9];
pub const NO_STEP: [i32; 4] = [0, 0, 0, 0];

lazy_static! {
    static ref move_to_step: HashMap<MoveCommand, (&'static [i32; 4], &'static [i32; 4])> = hashmap!{
        MoveCommand::TryMoveUp => (&NO_STEP, &STEP_UP),
        MoveCommand::TryMoveDown => (&NO_STEP, &STEP_DOWN),
        MoveCommand::TryMoveLeft => (&STEP_LEFT, &NO_STEP),
        MoveCommand::TryMoveRight => (&STEP_RIGHT, &NO_STEP),
        MoveCommand::TryMoveLeftUp => (&STEP_LEFT, &STEP_UP),
        MoveCommand::TryMoveRightUp => (&STEP_RIGHT, &STEP_UP),
        MoveCommand::TryMoveLeftDown => (&STEP_LEFT, &STEP_DOWN),
        MoveCommand::TryMoveRightDown => (&STEP_RIGHT, &STEP_DOWN),
    };
}

pub struct VelocitySystem;

impl<'a> System<'a> for VelocitySystem {
    type SystemData = (
        ReadStorage<'a, Intent>,
        WriteStorage<'a, Velocity>,
        WriteStorage<'a, WalkingState>,
    );

    fn run(&mut self, (intent, mut velocity, mut walking_state): Self::SystemData) {
        use specs::Join;

        for (intent, velocity, walking_state) in (&intent, &mut velocity, &mut walking_state).join()
        {
            match intent.command {
                Command::Move(m) => {
                    let step_vector = move_to_step[&m];
                    let step = ((walking_state.step + 1) % 4);
                    velocity.x = step_vector.0[step as usize];
                    velocity.y = step_vector.1[step as usize];
                    walking_state.step = step;
                    match m {
                        MoveCommand::TryMoveLeft
                        | MoveCommand::TryMoveLeftUp
                        | MoveCommand::TryMoveLeftDown => walking_state.direction = Direction::Left,
                        MoveCommand::TryMoveRight
                        | MoveCommand::TryMoveRightUp
                        | MoveCommand::TryMoveRightDown => {
                            walking_state.direction = Direction::Right
                        }
                        _ => (),
                    }
                }
                _ => {
                    velocity.x = 0;
                    velocity.y = 0;
                }
            }
        }
    }
}
<commit_msg>Rust: fix y step<commit_after>use std::collections::HashMap;

use lazy_static::lazy_static;
use maplit::hashmap;
use specs::{ReadStorage, System, WriteStorage};

use crate::combat::components::{Command, Direction, Intent, MoveCommand, Velocity, WalkingState};

pub const STEP_LEFT: [i32; 4] = [-25, -3, -23, -4];
pub const STEP_RIGHT: [i32; 4] = [25, 3, 23, 4];
pub const STEP_UP: [i32; 4] = [-2, -9, -2, -9];
pub const STEP_DOWN: [i32; 4] = [8, 2, 9, 2];
pub const NO_STEP: [i32; 4] = [0, 0, 0, 0];

lazy_static! {
    static ref move_to_step: HashMap<MoveCommand, (&'static [i32; 4], &'static [i32; 4])> = hashmap!{
        MoveCommand::TryMoveUp => (&NO_STEP, &STEP_UP),
        MoveCommand::TryMoveDown => (&NO_STEP, &STEP_DOWN),
        MoveCommand::TryMoveLeft => (&STEP_LEFT, &NO_STEP),
        MoveCommand::TryMoveRight => (&STEP_RIGHT, &NO_STEP),
        MoveCommand::TryMoveLeftUp => (&STEP_LEFT, &STEP_UP),
        MoveCommand::TryMoveRightUp => (&STEP_RIGHT, &STEP_UP),
        MoveCommand::TryMoveLeftDown => (&STEP_LEFT, &STEP_DOWN),
        MoveCommand::TryMoveRightDown => (&STEP_RIGHT, &STEP_DOWN),
    };
}

pub struct VelocitySystem;

impl<'a> System<'a> for VelocitySystem {
    type SystemData = (
        ReadStorage<'a, Intent>,
        WriteStorage<'a, Velocity>,
        WriteStorage<'a, WalkingState>,
    );

    fn run(&mut self, (intent, mut velocity, mut walking_state): Self::SystemData) {
        use specs::Join;

        for (intent, velocity, walking_state) in (&intent, &mut velocity, &mut walking_state).join()
        {
            match intent.command {
                Command::Move(m) => {
                    let step_vector = move_to_step[&m];
                    let step = ((walking_state.step + 1) % 4);
                    velocity.x = step_vector.0[step as usize];
                    velocity.y = step_vector.1[step as usize];
                    walking_state.step = step;
                    match m {
                        MoveCommand::TryMoveLeft
                        | MoveCommand::TryMoveLeftUp
                        | MoveCommand::TryMoveLeftDown => walking_state.direction = Direction::Left,
                        MoveCommand::TryMoveRight
                        | MoveCommand::TryMoveRightUp
                        | MoveCommand::TryMoveRightDown => {
                            walking_state.direction = Direction::Right
                        }
                        _ => (),
                    }
                }
                _ => {
                    velocity.x = 0;
                    velocity.y = 0;
                }
            }
        }
    }
}
<|endoftext|>