<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    CreateTokenAuth, CreateTokenResponse, ExportKey, ExportKeyResponse, ListKeys, ListKeysResponse,
    ListPoliciesResponse, ReadKey, ReadKeyResponse, ReadKeys, ReadSecretData, ReadSecretListData,
    ReadSecretListResponse, ReadSecretMetadata, ReadSecretResponse, RenewTokenAuth,
    RenewTokenResponse, SealStatusResponse, Signature, SignatureResponse,
};
use libra_types::proptest_types::arb_json_value;
use proptest::prelude::*;
use serde_json::Value;
use ureq::Response;

const MAX_COLLECTION_SIZE: usize = 100;

// This generates an arbitrary generic response returned by vault for various API calls.
prop_compose! {
    pub fn arb_generic_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        value in arb_json_value(),
    ) -> Response {
        let value =
            serde_json::to_string::<Value>(&value).unwrap();
        Response::new(status, &status_text, &value)
    }
}

// This generates an arbitrary policy list response returned by vault.
prop_compose! {
    pub fn arb_policy_list_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        policies in prop::collection::vec(any::<String>(), 0..MAX_COLLECTION_SIZE)
    ) -> Response {
        let policy_list = ListPoliciesResponse {
            policies,
        };
        let policy_list =
            serde_json::to_string::<ListPoliciesResponse>(&policy_list).unwrap();
        Response::new(status, &status_text, &policy_list)
    }
}

// This generates an arbitrary secret list response returned by vault.
prop_compose! {
    pub fn arb_secret_list_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::vec(any::<String>(), 0..MAX_COLLECTION_SIZE),
    ) -> Response {
        let data = ReadSecretListData {
            keys,
        };
        let read_secret_list_response = ReadSecretListResponse {
            data
        };

        let read_secret_list_response =
            serde_json::to_string::<ReadSecretListResponse>(&read_secret_list_response).unwrap();
        Response::new(status, &status_text, &read_secret_list_response)
    }
}

// This generates an arbitrary secret read response returned by vault, as well as an arbitrary pair
// of input strings for the secret and key.
prop_compose! {
    pub fn arb_secret_read_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        data in prop::collection::btree_map(any::<String>(), any::<String>(), 0..MAX_COLLECTION_SIZE),
        created_time in any::<String>(),
        version in any::<u32>(),
        secret in any::<String>(),
        key in any::<String>(),
    ) -> (Response, String, String) {
        let metadata = ReadSecretMetadata {
            created_time,
            version,
        };
        let data = ReadSecretData {
            data,
            metadata,
        };
        let read_secret_response = ReadSecretResponse {
            data
        };

        let read_secret_response =
            serde_json::to_string::<ReadSecretResponse>(&read_secret_response).unwrap();
        let read_secret_response = Response::new(status, &status_text, &read_secret_response);

        (read_secret_response, secret, key)
    }
}

// This generates an arbitrary token create response returned by vault.
prop_compose! {
    pub fn arb_token_create_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        client_token in any::<String>(),
    ) -> Response {
    let auth = CreateTokenAuth {
        client_token,
    };
    let create_token_response = CreateTokenResponse {
        auth,
     };

     let create_token_response =
            serde_json::to_string::<CreateTokenResponse>(&create_token_response).unwrap();
     Response::new(status, &status_text, &create_token_response)
    }
}

// This generates an arbitrary token renew response returned by vault.
prop_compose! {
    pub fn arb_token_renew_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        lease_duration in any::<u32>(),
    ) -> Response {
    let auth = RenewTokenAuth {
        lease_duration,
    };
    let renew_token_response = RenewTokenResponse {
        auth,
     };

     let renew_token_response =
            serde_json::to_string::<RenewTokenResponse>(&renew_token_response).unwrap();
     Response::new(status, &status_text, &renew_token_response)
    }
}

// This generates an arbitrary transit create response returned by vault, as well as an arbitrary
// string name.
prop_compose! {
    pub fn arb_transit_create_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        value in arb_json_value(),
        name in any::<String>(),
    ) -> (Response, String) {
        let value =
            serde_json::to_string::<Value>(&value).unwrap();
        let create_key_response = Response::new(status, &status_text, &value);

        (create_key_response, name)
    }
}

// This generates an arbitrary transit export response returned by vault, as well as an arbitrary
// string name and version.
prop_compose! {
    pub fn arb_transit_export_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::btree_map(any::<u32>(), any::<String>(), 0..MAX_COLLECTION_SIZE),
        name in any::<String>(),
        key_name in any::<String>(),
        version in any::<Option<u32>>(),
    ) -> (Response, String, Option<u32>) {
        let data = ExportKey {
            name,
            keys,
        };
        let export_key_response = ExportKeyResponse {
            data,
        };

        let export_key_response =
            serde_json::to_string::<ExportKeyResponse>(&export_key_response).unwrap();
        let export_key_response = Response::new(status, &status_text, &export_key_response);

        (export_key_response, key_name, version)
    }
}

// This generates an arbitrary transit list response returned by vault.
prop_compose! {
    pub fn arb_transit_list_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::vec(any::<String>(), 0..MAX_COLLECTION_SIZE),
    ) -> Response {
        let data = ListKeys {
            keys,
        };
        let list_keys_response = ListKeysResponse {
            data,
        };
        let list_keys_response =
            serde_json::to_string::<ListKeysResponse>(&list_keys_response).unwrap();
        Response::new(status, &status_text, &list_keys_response)
    }
}

// This generates an arbitrary read key struct.
prop_compose! {
    pub fn arb_transit_read_key(
    )(
        creation_time in any::<String>(),
        public_key in any::<String>(),
    ) -> ReadKey {
        ReadKey {
            creation_time,
            public_key
        }
    }
}

// This generates an arbitrary transit read response returned by vault, as well as an arbitrary
// string name.
prop_compose! {
    pub fn arb_transit_read_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::btree_map(any::<u32>(), arb_transit_read_key(), 0..MAX_COLLECTION_SIZE),
        name in any::<String>(),
        key_type in any::<String>(),
        key_name in any::<String>(),
    ) -> (Response, String) {
        let data = ReadKeys {
            keys,
            name,
            key_type,
        };
        let read_key_response = ReadKeyResponse {
            data,
        };

        let read_key_response =
            serde_json::to_string::<ReadKeyResponse>(&read_key_response).unwrap();
        let read_key_response = Response::new(status, &status_text, &read_key_response);

        (read_key_response, key_name)
    }
}

// This generates an arbitrary transit sign response returned by vault.
prop_compose! {
    pub fn arb_transit_sign_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        signature in any::<String>(),
    ) -> Response {
        let data = Signature {
            signature,
        };
        let signature_response = SignatureResponse {
            data,
        };
        let signature_response =
            serde_json::to_string::<SignatureResponse>(&signature_response).unwrap();
        Response::new(status, &status_text, &signature_response)
    }
}

// This generates an arbitrary unsealed response returned by vault.
prop_compose! {
    pub fn arb_unsealed_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        sealed in any::<bool>(),
    ) -> Response {
        let sealed_status_response = SealStatusResponse {
            sealed,
        };
        let sealed_status_response =
            serde_json::to_string::<SealStatusResponse>(&sealed_status_response).unwrap();
        Response::new(status, &status_text, &sealed_status_response)
    }
}

// Note: these tests ensure that the various fuzzers are maintained (i.e., not broken
// at some time in the future and only discovered when a fuzz test fails).
#[cfg(test)]
mod tests {
    use crate::{
        fuzzing::{
            arb_generic_response, arb_policy_list_response, arb_secret_list_response,
            arb_secret_read_response, arb_token_create_response, arb_token_renew_response,
            arb_transit_create_response, arb_transit_export_response, arb_transit_list_response,
            arb_transit_read_response, arb_transit_sign_response, arb_unsealed_response,
        },
        process_generic_response, process_policy_list_response, process_policy_read_response,
        process_secret_list_response, process_secret_read_response, process_token_create_response,
        process_token_renew_response, process_transit_create_response,
        process_transit_export_response, process_transit_list_response,
        process_transit_read_response, process_transit_restore_response,
        process_transit_sign_response, process_unsealed_response,
    };
    use proptest::prelude::*;

    proptest! {
        #![proptest_config(ProptestConfig::with_cases(10))]

        #[test]
        fn process_generic_response_proptest(input in arb_generic_response()) {
            let _ = process_generic_response(input);
        }

        #[test]
        fn process_policy_read_response_proptest(input in arb_generic_response()) {
            let _ = process_policy_read_response(input);
        }

        #[test]
        fn process_policy_list_response_proptest(input in arb_policy_list_response()) {
            let _ = process_policy_list_response(input);
        }

        #[test]
        fn process_secret_list_response_proptest(input in arb_secret_list_response()) {
            let _ = process_secret_list_response(input);
        }

        #[test]
        fn process_secret_read_response_proptest((response, secret, key) in arb_secret_read_response()) {
            let _ = process_secret_read_response(&secret, &key, response);
        }

        #[test]
        fn process_token_create_response_proptest(input in arb_token_create_response()) {
            let _ = process_token_create_response(input);
        }

        #[test]
        fn process_token_renew_response_proptest(input in arb_token_renew_response()) {
            let _ = process_token_renew_response(input);
        }

        #[test]
        fn process_transit_create_response_proptest((response, name) in arb_transit_create_response()) {
            let _ = process_transit_create_response(&name, response);
        }

        #[test]
        fn process_transit_export_response_proptest((response, name, version) in arb_transit_export_response()) {
            let _ = process_transit_export_response(&name, version, response);
        }

        #[test]
        fn process_transit_list_response_proptest(response in arb_transit_list_response()) {
            let _ = process_transit_list_response(response);
        }

        #[test]
        fn process_transit_read_response_proptest((response, name) in arb_transit_read_response()) {
            let _ = process_transit_read_response(&name, response);
        }

        #[test]
        fn process_transit_restore_response_proptest(input in arb_generic_response()) {
            let _ = process_transit_restore_response(input);
        }

        #[test]
        fn process_transit_sign_response_proptest(input in arb_transit_sign_response()) {
            let _ = process_transit_sign_response(input);
        }

        #[test]
        fn process_unsealed_response_proptest(input in arb_unsealed_response()) {
            let _ = process_unsealed_response(input);
        }
    }
}
<commit_msg>[Fuzzing] Clean up vault fuzzing tests and arbitrary functions.<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    CreateTokenAuth, CreateTokenResponse, ExportKey, ExportKeyResponse, ListKeys, ListKeysResponse,
    ListPoliciesResponse, ReadKey, ReadKeyResponse, ReadKeys, ReadSecretData, ReadSecretListData,
    ReadSecretListResponse, ReadSecretMetadata, ReadSecretResponse, RenewTokenAuth,
    RenewTokenResponse, SealStatusResponse, Signature, SignatureResponse,
};
use libra_types::proptest_types::arb_json_value;
use proptest::prelude::*;
use serde_json::Value;
use ureq::Response;

const MAX_COLLECTION_SIZE: usize = 100;

// This generates an arbitrary generic response returned by vault for various API calls.
prop_compose! {
    pub fn arb_generic_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        value in arb_json_value(),
    ) -> Response {
        let value =
            serde_json::to_string::<Value>(&value).unwrap();
        Response::new(status, &status_text, &value)
    }
}

// This generates an arbitrary policy list response returned by vault.
prop_compose! {
    pub fn arb_policy_list_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        policies in prop::collection::vec(any::<String>(), 0..MAX_COLLECTION_SIZE)
    ) -> Response {
        let policy_list = ListPoliciesResponse {
            policies,
        };

        let policy_list =
            serde_json::to_string::<ListPoliciesResponse>(&policy_list).unwrap();
        Response::new(status, &status_text, &policy_list)
    }
}

// This generates an arbitrary secret list response returned by vault.
prop_compose! {
    pub fn arb_secret_list_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::vec(any::<String>(), 0..MAX_COLLECTION_SIZE),
    ) -> Response {
        let data = ReadSecretListData {
            keys,
        };
        let read_secret_list_response = ReadSecretListResponse {
            data
        };

        let read_secret_list_response =
            serde_json::to_string::<ReadSecretListResponse>(&read_secret_list_response).unwrap();
        Response::new(status, &status_text, &read_secret_list_response)
    }
}

// This generates an arbitrary secret read response returned by vault, as well as an arbitrary pair
// of input strings for the secret and key.
prop_compose! {
    pub fn arb_secret_read_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        data in prop::collection::btree_map(any::<String>(), any::<String>(), 0..MAX_COLLECTION_SIZE),
        created_time in any::<String>(),
        version in any::<u32>(),
        secret in any::<String>(),
        key in any::<String>(),
    ) -> (Response, String, String) {
        let metadata = ReadSecretMetadata {
            created_time,
            version,
        };
        let data = ReadSecretData {
            data,
            metadata,
        };
        let read_secret_response = ReadSecretResponse {
            data
        };

        let read_secret_response =
            serde_json::to_string::<ReadSecretResponse>(&read_secret_response).unwrap();
        let read_secret_response = Response::new(status, &status_text, &read_secret_response);

        (read_secret_response, secret, key)
    }
}

// This generates an arbitrary token create response returned by vault.
prop_compose! {
    pub fn arb_token_create_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        client_token in any::<String>(),
    ) -> Response {
    let auth = CreateTokenAuth {
        client_token,
    };
    let create_token_response = CreateTokenResponse {
        auth,
     };

     let create_token_response =
            serde_json::to_string::<CreateTokenResponse>(&create_token_response).unwrap();
     Response::new(status, &status_text, &create_token_response)
    }
}

// This generates an arbitrary token renew response returned by vault.
prop_compose! {
    pub fn arb_token_renew_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        lease_duration in any::<u32>(),
    ) -> Response {
    let auth = RenewTokenAuth {
        lease_duration,
    };
    let renew_token_response = RenewTokenResponse {
        auth,
     };

     let renew_token_response =
            serde_json::to_string::<RenewTokenResponse>(&renew_token_response).unwrap();
     Response::new(status, &status_text, &renew_token_response)
    }
}

// This generates an arbitrary transit create response returned by vault, as well as an arbitrary
// string name.
prop_compose! {
    pub fn arb_transit_create_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        value in arb_json_value(),
        name in any::<String>(),
    ) -> (Response, String) {
        let value =
            serde_json::to_string::<Value>(&value).unwrap();
        let create_key_response = Response::new(status, &status_text, &value);

        (create_key_response, name)
    }
}

// This generates an arbitrary transit export response returned by vault, as well as an arbitrary
// string name and version.
prop_compose! {
    pub fn arb_transit_export_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::btree_map(any::<u32>(), any::<String>(), 0..MAX_COLLECTION_SIZE),
        name in any::<String>(),
        key_name in any::<String>(),
        version in any::<Option<u32>>(),
    ) -> (Response, String, Option<u32>) {
        let data = ExportKey {
            name,
            keys,
        };
        let export_key_response = ExportKeyResponse {
            data,
        };

        let export_key_response =
            serde_json::to_string::<ExportKeyResponse>(&export_key_response).unwrap();
        let export_key_response = Response::new(status, &status_text, &export_key_response);

        (export_key_response, key_name, version)
    }
}

// This generates an arbitrary transit list response returned by vault.
prop_compose! {
    pub fn arb_transit_list_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::vec(any::<String>(), 0..MAX_COLLECTION_SIZE),
    ) -> Response {
        let data = ListKeys {
            keys,
        };
        let list_keys_response = ListKeysResponse {
            data,
        };

        let list_keys_response =
            serde_json::to_string::<ListKeysResponse>(&list_keys_response).unwrap();
        Response::new(status, &status_text, &list_keys_response)
    }
}

// This generates an arbitrary read key struct.
prop_compose! {
    pub fn arb_transit_read_key(
    )(
        creation_time in any::<String>(),
        public_key in any::<String>(),
    ) -> ReadKey {
        ReadKey {
            creation_time,
            public_key
        }
    }
}

// This generates an arbitrary transit read response returned by vault, as well as an arbitrary
// string name.
prop_compose! {
    pub fn arb_transit_read_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        keys in prop::collection::btree_map(any::<u32>(), arb_transit_read_key(), 0..MAX_COLLECTION_SIZE),
        name in any::<String>(),
        key_type in any::<String>(),
        key_name in any::<String>(),
    ) -> (Response, String) {
        let data = ReadKeys {
            keys,
            name,
            key_type,
        };
        let read_key_response = ReadKeyResponse {
            data,
        };

        let read_key_response =
            serde_json::to_string::<ReadKeyResponse>(&read_key_response).unwrap();
        let read_key_response = Response::new(status, &status_text, &read_key_response);

        (read_key_response, key_name)
    }
}

// This generates an arbitrary transit sign response returned by vault.
prop_compose! {
    pub fn arb_transit_sign_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        signature in any::<String>(),
    ) -> Response {
        let data = Signature {
            signature,
        };
        let signature_response = SignatureResponse {
            data,
        };

        let signature_response =
            serde_json::to_string::<SignatureResponse>(&signature_response).unwrap();
        Response::new(status, &status_text, &signature_response)
    }
}

// This generates an arbitrary unsealed response returned by vault.
prop_compose! {
    pub fn arb_unsealed_response(
    )(
        status in any::<u16>(),
        status_text in any::<String>(),
        sealed in any::<bool>(),
    ) -> Response {
        let sealed_status_response = SealStatusResponse {
            sealed,
        };

        let sealed_status_response =
            serde_json::to_string::<SealStatusResponse>(&sealed_status_response).unwrap();
        Response::new(status, &status_text, &sealed_status_response)
    }
}

// Note: these tests ensure that the various fuzzers are maintained (i.e., not broken
// at some time in the future and only discovered when a fuzz test fails).
#[cfg(test)]
mod tests {
    use crate::{
        fuzzing::{
            arb_generic_response, arb_policy_list_response, arb_secret_list_response,
            arb_secret_read_response, arb_token_create_response, arb_token_renew_response,
            arb_transit_create_response, arb_transit_export_response, arb_transit_list_response,
            arb_transit_read_response, arb_transit_sign_response, arb_unsealed_response,
        },
        process_generic_response, process_policy_list_response, process_policy_read_response,
        process_secret_list_response, process_secret_read_response, process_token_create_response,
        process_token_renew_response, process_transit_create_response,
        process_transit_export_response, process_transit_list_response,
        process_transit_read_response, process_transit_restore_response,
        process_transit_sign_response, process_unsealed_response,
    };
    use proptest::prelude::*;

    proptest! {
        #![proptest_config(ProptestConfig::with_cases(10))]

        #[test]
        fn process_generic_response_proptest(response in arb_generic_response()) {
            let _ = process_generic_response(response);
        }

        #[test]
        fn process_policy_read_response_proptest(response in arb_generic_response()) {
            let _ = process_policy_read_response(response);
        }

        #[test]
        fn process_policy_list_response_proptest(response in arb_policy_list_response()) {
            let _ = process_policy_list_response(response);
        }

        #[test]
        fn process_secret_list_response_proptest(response in arb_secret_list_response()) {
            let _ = process_secret_list_response(response);
        }

        #[test]
        fn process_secret_read_response_proptest((response, secret, key) in arb_secret_read_response()) {
            let _ = process_secret_read_response(&secret, &key, response);
        }

        #[test]
        fn process_token_create_response_proptest(response in arb_token_create_response()) {
            let _ = process_token_create_response(response);
        }

        #[test]
        fn process_token_renew_response_proptest(response in arb_token_renew_response()) {
            let _ = process_token_renew_response(response);
        }

        #[test]
        fn process_transit_create_response_proptest((response, name) in arb_transit_create_response()) {
            let _ = process_transit_create_response(&name, response);
        }

        #[test]
        fn process_transit_export_response_proptest((response, name, version) in arb_transit_export_response()) {
            let _ = process_transit_export_response(&name, version, response);
        }

        #[test]
        fn process_transit_list_response_proptest(response in arb_transit_list_response()) {
            let _ = process_transit_list_response(response);
        }

        #[test]
        fn process_transit_read_response_proptest((response, name) in arb_transit_read_response()) {
            let _ = process_transit_read_response(&name, response);
        }

        #[test]
        fn process_transit_restore_response_proptest(response in arb_generic_response()) {
            let _ = process_transit_restore_response(response);
        }

        #[test]
        fn process_transit_sign_response_proptest(response in arb_transit_sign_response()) {
            let _ = process_transit_sign_response(response);
        }

        #[test]
        fn process_unsealed_response_proptest(response in arb_unsealed_response()) {
            let _ = process_unsealed_response(response);
        }
    }
}
<|endoftext|>


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

use build::{Location, ScopeAuxiliaryVec};
use rustc::hir;
use rustc::mir::repr::*;
use rustc::mir::transform::MirSource;
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fnv::FnvHashMap;
use std::fmt::Display;
use std::fs;
use std::io::{self, Write};
use syntax::ast::NodeId;
use syntax::codemap::Span;

const INDENT: &'static str = "    ";
/// Alignment for lining up comments following MIR statements
const ALIGN: usize = 40;

/// If the session is properly configured, dumps a human-readable
/// representation of the mir into:
///
/// ```text
/// rustc.node<node_id>.<pass_name>.<disambiguator>
/// ```
///
/// Output from this function is controlled by passing `-Z dump-mir=<filter>`,
/// where `<filter>` takes the following forms:
///
/// - `all` -- dump MIR for all fns, all passes, all everything
/// - `substring1&substring2,...` -- `&`-separated list of substrings
///   that can appear in the pass-name or the `item_path_str` for the given
///   node-id. If any one of the substrings match, the data is dumped out.
pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          pass_name: &str,
                          disambiguator: &Display,
                          src: MirSource,
                          mir: &Mir<'tcx>,
                          auxiliary: Option<&ScopeAuxiliaryVec>) {
    let filters = match tcx.sess.opts.debugging_opts.dump_mir {
        None => return,
        Some(ref filters) => filters,
    };
    let node_id = src.item_id();
    let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
    let is_matched =
        filters.split("&")
               .any(|filter| {
                   filter == "all" ||
                       pass_name.contains(filter) ||
                       node_path.contains(filter)
               });
    if !is_matched {
        return;
    }

    let file_name = format!("rustc.node{}.{}.{}.mir",
                            node_id, pass_name, disambiguator);
    let _ = fs::File::create(&file_name).and_then(|mut file| {
        try!(writeln!(file, "// MIR for `{}`", node_path));
        try!(writeln!(file, "// node_id = {}", node_id));
        try!(writeln!(file, "// pass_name = {}", pass_name));
        try!(writeln!(file, "// disambiguator = {}", disambiguator));
        try!(writeln!(file, ""));
        try!(write_mir_fn(tcx, src, mir, &mut file, auxiliary));
        Ok(())
    });
}

/// Write out a human-readable textual representation for the given MIR.
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                         iter: I,
                                         w: &mut Write)
                                         -> io::Result<()>
    where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
{
    let mut first = true;
    for (&id, mir) in iter {
        if first {
            first = false;
        } else {
            // Put empty lines between all items
            writeln!(w, "")?;
        }

        let src = MirSource::from_node(tcx, id);
        write_mir_fn(tcx, src, mir, w, None)?;

        for (i, mir) in mir.promoted.iter().enumerate() {
            writeln!(w, "")?;
            write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?;
        }
    }
    Ok(())
}

enum Annotation {
    EnterScope(ScopeId),
    ExitScope(ScopeId),
}

fn scope_entry_exit_annotations(auxiliary: Option<&ScopeAuxiliaryVec>)
                                -> FnvHashMap<Location, Vec<Annotation>>
{
    // compute scope/entry exit annotations
    let mut annotations = FnvHashMap();
    if let Some(auxiliary) = auxiliary {
        for (index, auxiliary) in auxiliary.vec.iter().enumerate() {
            let scope_id = ScopeId::new(index);

            annotations.entry(auxiliary.dom)
                       .or_insert(vec![])
                       .push(Annotation::EnterScope(scope_id));

            for &loc in &auxiliary.postdoms {
                annotations.entry(loc)
                           .or_insert(vec![])
                           .push(Annotation::ExitScope(scope_id));
            }
        }
    }
    return annotations;
}

pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              src: MirSource,
                              mir: &Mir<'tcx>,
                              w: &mut Write,
                              auxiliary: Option<&ScopeAuxiliaryVec>)
                              -> io::Result<()> {
    let annotations = scope_entry_exit_annotations(auxiliary);
    write_mir_intro(tcx, src, mir, w)?;
    for block in mir.all_basic_blocks() {
        write_basic_block(tcx, block, mir, w, &annotations)?;
    }

    // construct a scope tree and write it out
    let mut scope_tree: FnvHashMap<Option<ScopeId>, Vec<ScopeId>> = FnvHashMap();
    for (index, scope_data) in mir.scopes.iter().enumerate() {
        scope_tree.entry(scope_data.parent_scope)
                  .or_insert(vec![])
                  .push(ScopeId::new(index));
    }

    writeln!(w, "{}scope tree:", INDENT)?;
    write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1, false)?;
    writeln!(w, "")?;

    writeln!(w, "}}")?;
    Ok(())
}

/// Write out a human-readable textual representation for the given basic block.
fn write_basic_block(tcx: TyCtxt,
                     block: BasicBlock,
                     mir: &Mir,
                     w: &mut Write,
                     annotations: &FnvHashMap<Location, Vec<Annotation>>)
                     -> io::Result<()> {
    let data = mir.basic_block_data(block);

    // Basic block label at the top.
    writeln!(w, "{}{:?}: {{", INDENT, block)?;

    // List of statements in the middle.
    let mut current_location = Location { block: block, statement_index: 0 };
    for statement in &data.statements {
        if let Some(ref annotations) = annotations.get(&current_location) {
            for annotation in annotations.iter() {
                match *annotation {
                    Annotation::EnterScope(id) =>
                        writeln!(w, "{0}{0}// Enter Scope({1})",
                                 INDENT, id.index())?,
                    Annotation::ExitScope(id) =>
                        writeln!(w, "{0}{0}// Exit Scope({1})",
                                 INDENT, id.index())?,
                }
            }
        }

        let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
        writeln!(w, "{0:1$} // {2}",
                 indented_mir,
                 ALIGN,
                 comment(tcx, statement.scope, statement.span))?;

        current_location.statement_index += 1;
    }

    // Terminator at the bottom.
    let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
    writeln!(w, "{0:1$} // {2}",
             indented_terminator,
             ALIGN,
             comment(tcx, data.terminator().scope, data.terminator().span))?;

    writeln!(w, "{}}}\n", INDENT)
}

fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String {
    format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
}

fn write_scope_tree(tcx: TyCtxt,
                    mir: &Mir,
                    auxiliary: Option<&ScopeAuxiliaryVec>,
                    scope_tree: &FnvHashMap<Option<ScopeId>, Vec<ScopeId>>,
                    w: &mut Write,
                    parent: Option<ScopeId>,
                    depth: usize,
                    same_line: bool)
                    -> io::Result<()> {
    let indent = if same_line {
        0
    } else {
        depth * INDENT.len()
    };

    let children = match scope_tree.get(&parent) {
        Some(childs) => childs,
        None => return Ok(()),
    };

    for (index, &child) in children.iter().enumerate() {
        if index == 0 && same_line {
            // We know we're going to output a scope, so prefix it with a space to separate it from
            // the previous scopes on this line
            write!(w, " ")?;
        }

        let data = &mir.scopes[child];
        assert_eq!(data.parent_scope, parent);
        write!(w, "{0:1$}{2}", "", indent, child.index())?;

        let indent = indent + INDENT.len();

        if let Some(auxiliary) = auxiliary {
            let extent = auxiliary[child].extent;
            let data = tcx.region_maps.code_extent_data(extent);
            writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?;
        }

        let child_count = scope_tree.get(&Some(child)).map(Vec::len).unwrap_or(0);
        if child_count < 2 {
            // Skip the braces when there's no or only a single subscope
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth, true)?;
        } else {
            // 2 or more child scopes? Put them in braces and on new lines.
            writeln!(w, " {{")?;
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth + 1, false)?;

            write!(w, "\n{0:1$}}}", "", depth * INDENT.len())?;
        }

        if !same_line && index + 1 < children.len() {
            writeln!(w, "")?;
        }
    }

    Ok(())
}

pub fn write_mir_named(tcx: &ty::TyCtxt, name: &str, mir: &Mir, w: &mut Write, auxiliary: Option<&ScopeAuxiliaryVec>)
-> io::Result<()> {

    let annotations = scope_entry_exit_annotations(auxiliary);
    write_mir_intro_named(tcx, name, mir, w)?;
    for block in mir.all_basic_blocks() {
        write_basic_block(tcx, block, mir, w, &annotations)?;
    }
    writeln!(w, "}}")
}

/// Write out a human-readable textual representation of the MIR's
/// `fn` type and the types of its local variables (both user-defined
/// bindings and compiler temporaries). Assumes the function
/// represented by `mir` is named `name`. Note: Generated output
/// introduces an open curly that needs to be closed.
pub fn write_mir_intro_named(tcx: &ty::TyCtxt, name: &str, mir: &Mir, w: &mut Write)
-> io::Result<()> {
    write_mir_fn_sig(tcx, name, mir, w)?;
    writeln!(w, " {{")?;
    write_mir_fn_decls(tcx, mir, w)
}

/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
/// local variables (both user-defined bindings and compiler temporaries).
fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             src: MirSource,
                             mir: &Mir,
                             w: &mut Write)
                             -> io::Result<()> {
    write_mir_sig(tcx, src, mir, w)?;
    writeln!(w, " {{")?;
    write_mir_decls(tcx, mir, w)
}

fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write)
                 -> io::Result<()>
{
    match src {
        MirSource::Fn(_) => write!(w, "fn")?,
        MirSource::Const(_) => write!(w, "const")?,
        MirSource::Static(_, hir::MutImmutable) => write!(w, "static")?,
        MirSource::Static(_, hir::MutMutable) => write!(w, "static mut")?,
        MirSource::Promoted(_, i) => write!(w, "promoted{} in", i)?
    }

    write!(w, " {}", tcx.node_path_str(src.item_id()))?;

    if let MirSource::Fn(_) = src {
        write!(w, "(")?;

        // fn argument types.
        for (i, arg) in mir.arg_decls.iter().enumerate() {
            if i > 0 {
                write!(w, ", ")?;
            }
            write!(w, "{:?}: {}", Lvalue::Arg(i as u32), arg.ty)?;
        }

        write!(w, ") -> ")?;

        // fn return type.
        match mir.return_ty {
            ty::FnOutput::FnConverging(ty) => write!(w, "{}", ty),
            ty::FnOutput::FnDiverging => write!(w, "!"),
        }
    } else {
        assert!(mir.arg_decls.is_empty());
        write!(w, ": {} =", mir.return_ty.unwrap())
    }
}

fn write_mir_decls(tcx: TyCtxt, mir: &Mir, w: &mut Write)
                   -> io::Result<()>
{
    // User variable types (including the user's name in a comment).
    for (i, var) in mir.var_decls.iter().enumerate() {
        let mut_str = if var.mutability == Mutability::Mut {
            "mut "
        } else {
            ""
        };

        let indented_var = format!("{}let {}{:?}: {};",
                                   INDENT,
                                   mut_str,
                                   Lvalue::Var(i as u32),
                                   var.ty);
        writeln!(w, "{0:1$} // \"{2}\" in {3}",
                 indented_var,
                 ALIGN,
                 var.name,
                 comment(tcx, var.scope, var.span))?;
    }

    // Compiler-introduced temporary types.
    for (i, temp) in mir.temp_decls.iter().enumerate() {
        writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?;
    }

    // Wrote any declaration? Add an empty line before the first block is printed.
    if !mir.var_decls.is_empty() || !mir.temp_decls.is_empty() {
        writeln!(w, "")?;
    }

    Ok(())
}
<commit_msg>One-line doc clarification for representation of unit type `()`.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use build::{Location, ScopeAuxiliaryVec};
use rustc::hir;
use rustc::mir::repr::*;
use rustc::mir::transform::MirSource;
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fnv::FnvHashMap;
use std::fmt::Display;
use std::fs;
use std::io::{self, Write};
use syntax::ast::NodeId;
use syntax::codemap::Span;

const INDENT: &'static str = "    ";
/// Alignment for lining up comments following MIR statements
const ALIGN: usize = 40;

/// If the session is properly configured, dumps a human-readable
/// representation of the mir into:
///
/// ```text
/// rustc.node<node_id>.<pass_name>.<disambiguator>
/// ```
///
/// Output from this function is controlled by passing `-Z dump-mir=<filter>`,
/// where `<filter>` takes the following forms:
///
/// - `all` -- dump MIR for all fns, all passes, all everything
/// - `substring1&substring2,...` -- `&`-separated list of substrings
///   that can appear in the pass-name or the `item_path_str` for the given
///   node-id. If any one of the substrings match, the data is dumped out.
pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          pass_name: &str,
                          disambiguator: &Display,
                          src: MirSource,
                          mir: &Mir<'tcx>,
                          auxiliary: Option<&ScopeAuxiliaryVec>) {
    let filters = match tcx.sess.opts.debugging_opts.dump_mir {
        None => return,
        Some(ref filters) => filters,
    };
    let node_id = src.item_id();
    let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
    let is_matched =
        filters.split("&")
               .any(|filter| {
                   filter == "all" ||
                       pass_name.contains(filter) ||
                       node_path.contains(filter)
               });
    if !is_matched {
        return;
    }

    let file_name = format!("rustc.node{}.{}.{}.mir",
                            node_id, pass_name, disambiguator);
    let _ = fs::File::create(&file_name).and_then(|mut file| {
        try!(writeln!(file, "// MIR for `{}`", node_path));
        try!(writeln!(file, "// node_id = {}", node_id));
        try!(writeln!(file, "// pass_name = {}", pass_name));
        try!(writeln!(file, "// disambiguator = {}", disambiguator));
        try!(writeln!(file, ""));
        try!(write_mir_fn(tcx, src, mir, &mut file, auxiliary));
        Ok(())
    });
}

/// Write out a human-readable textual representation for the given MIR.
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                         iter: I,
                                         w: &mut Write)
                                         -> io::Result<()>
    where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
{
    let mut first = true;
    for (&id, mir) in iter {
        if first {
            first = false;
        } else {
            // Put empty lines between all items
            writeln!(w, "")?;
        }

        let src = MirSource::from_node(tcx, id);
        write_mir_fn(tcx, src, mir, w, None)?;

        for (i, mir) in mir.promoted.iter().enumerate() {
            writeln!(w, "")?;
            write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?;
        }
    }
    Ok(())
}

enum Annotation {
    EnterScope(ScopeId),
    ExitScope(ScopeId),
}

fn scope_entry_exit_annotations(auxiliary: Option<&ScopeAuxiliaryVec>)
                                -> FnvHashMap<Location, Vec<Annotation>>
{
    // compute scope/entry exit annotations
    let mut annotations = FnvHashMap();
    if let Some(auxiliary) = auxiliary {
        for (index, auxiliary) in auxiliary.vec.iter().enumerate() {
            let scope_id = ScopeId::new(index);

            annotations.entry(auxiliary.dom)
                       .or_insert(vec![])
                       .push(Annotation::EnterScope(scope_id));

            for &loc in &auxiliary.postdoms {
                annotations.entry(loc)
                           .or_insert(vec![])
                           .push(Annotation::ExitScope(scope_id));
            }
        }
    }
    return annotations;
}

pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              src: MirSource,
                              mir: &Mir<'tcx>,
                              w: &mut Write,
                              auxiliary: Option<&ScopeAuxiliaryVec>)
                              -> io::Result<()> {
    let annotations = scope_entry_exit_annotations(auxiliary);
    write_mir_intro(tcx, src, mir, w)?;
    for block in mir.all_basic_blocks() {
        write_basic_block(tcx, block, mir, w, &annotations)?;
    }

    // construct a scope tree and write it out
    let mut scope_tree: FnvHashMap<Option<ScopeId>, Vec<ScopeId>> = FnvHashMap();
    for (index, scope_data) in mir.scopes.iter().enumerate() {
        scope_tree.entry(scope_data.parent_scope)
                  .or_insert(vec![])
                  .push(ScopeId::new(index));
    }

    writeln!(w, "{}scope tree:", INDENT)?;
    write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1, false)?;
    writeln!(w, "")?;

    writeln!(w, "}}")?;
    Ok(())
}

/// Write out a human-readable textual representation for the given basic block.
fn write_basic_block(tcx: TyCtxt,
                     block: BasicBlock,
                     mir: &Mir,
                     w: &mut Write,
                     annotations: &FnvHashMap<Location, Vec<Annotation>>)
                     -> io::Result<()> {
    let data = mir.basic_block_data(block);

    // Basic block label at the top.
    writeln!(w, "{}{:?}: {{", INDENT, block)?;

    // List of statements in the middle.
    let mut current_location = Location { block: block, statement_index: 0 };
    for statement in &data.statements {
        if let Some(ref annotations) = annotations.get(&current_location) {
            for annotation in annotations.iter() {
                match *annotation {
                    Annotation::EnterScope(id) =>
                        writeln!(w, "{0}{0}// Enter Scope({1})",
                                 INDENT, id.index())?,
                    Annotation::ExitScope(id) =>
                        writeln!(w, "{0}{0}// Exit Scope({1})",
                                 INDENT, id.index())?,
                }
            }
        }

        let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
        writeln!(w, "{0:1$} // {2}",
                 indented_mir,
                 ALIGN,
                 comment(tcx, statement.scope, statement.span))?;

        current_location.statement_index += 1;
    }

    // Terminator at the bottom.
    let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
    writeln!(w, "{0:1$} // {2}",
             indented_terminator,
             ALIGN,
             comment(tcx, data.terminator().scope, data.terminator().span))?;

    writeln!(w, "{}}}\n", INDENT)
}

fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String {
    format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
}

fn write_scope_tree(tcx: TyCtxt,
                    mir: &Mir,
                    auxiliary: Option<&ScopeAuxiliaryVec>,
                    scope_tree: &FnvHashMap<Option<ScopeId>, Vec<ScopeId>>,
                    w: &mut Write,
                    parent: Option<ScopeId>,
                    depth: usize,
                    same_line: bool)
                    -> io::Result<()> {
    let indent = if same_line {
        0
    } else {
        depth * INDENT.len()
    };

    let children = match scope_tree.get(&parent) {
        Some(childs) => childs,
        None => return Ok(()),
    };

    for (index, &child) in children.iter().enumerate() {
        if index == 0 && same_line {
            // We know we're going to output a scope, so prefix it with a space to separate it from
            // the previous scopes on this line
            write!(w, " ")?;
        }

        let data = &mir.scopes[child];
        assert_eq!(data.parent_scope, parent);
        write!(w, "{0:1$}{2}", "", indent, child.index())?;

        let indent = indent + INDENT.len();

        if let Some(auxiliary) = auxiliary {
            let extent = auxiliary[child].extent;
            let data = tcx.region_maps.code_extent_data(extent);
            writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?;
        }

        let child_count = scope_tree.get(&Some(child)).map(Vec::len).unwrap_or(0);
        if child_count < 2 {
            // Skip the braces when there's no or only a single subscope
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth, true)?;
        } else {
            // 2 or more child scopes? Put them in braces and on new lines.
            writeln!(w, " {{")?;
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth + 1, false)?;

            write!(w, "\n{0:1$}}}", "", depth * INDENT.len())?;
        }

        if !same_line && index + 1 < children.len() {
            writeln!(w, "")?;
        }
    }

    Ok(())
}

/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
/// local variables (both user-defined bindings and compiler temporaries).
fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             src: MirSource,
                             mir: &Mir,
                             w: &mut Write)
                             -> io::Result<()> {
    write_mir_sig(tcx, src, mir, w)?;
    writeln!(w, " {{")?;
    write_mir_decls(tcx, mir, w)
}

fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write)
                 -> io::Result<()>
{
    match src {
        MirSource::Fn(_) => write!(w, "fn")?,
        MirSource::Const(_) => write!(w, "const")?,
        MirSource::Static(_, hir::MutImmutable) => write!(w, "static")?,
        MirSource::Static(_, hir::MutMutable) => write!(w, "static mut")?,
        MirSource::Promoted(_, i) => write!(w, "promoted{} in", i)?
    }

    write!(w, " {}", tcx.node_path_str(src.item_id()))?;

    if let MirSource::Fn(_) = src {
        write!(w, "(")?;

        // fn argument types.
        for (i, arg) in mir.arg_decls.iter().enumerate() {
            if i > 0 {
                write!(w, ", ")?;
            }
            write!(w, "{:?}: {}", Lvalue::Arg(i as u32), arg.ty)?;
        }

        write!(w, ") -> ")?;

        // fn return type.
        match mir.return_ty {
            ty::FnOutput::FnConverging(ty) => write!(w, "{}", ty),
            ty::FnOutput::FnDiverging => write!(w, "!"),
        }
    } else {
        assert!(mir.arg_decls.is_empty());
        write!(w, ": {} =", mir.return_ty.unwrap())
    }
}

fn write_mir_decls(tcx: TyCtxt, mir: &Mir, w: &mut Write)
                   -> io::Result<()>
{
    // User variable types (including the user's name in a comment).
    for (i, var) in mir.var_decls.iter().enumerate() {
        let mut_str = if var.mutability == Mutability::Mut {
            "mut "
        } else {
            ""
        };

        let indented_var = format!("{}let {}{:?}: {};",
                                   INDENT,
                                   mut_str,
                                   Lvalue::Var(i as u32),
                                   var.ty);
        writeln!(w, "{0:1$} // \"{2}\" in {3}",
                 indented_var,
                 ALIGN,
                 var.name,
                 comment(tcx, var.scope, var.span))?;
    }

    // Compiler-introduced temporary types.
    for (i, temp) in mir.temp_decls.iter().enumerate() {
        writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?;
    }

    // Wrote any declaration? Add an empty line before the first block is printed.
    if !mir.var_decls.is_empty() || !mir.temp_decls.is_empty() {
        writeln!(w, "")?;
    }

    Ok(())
}
<|endoftext|>


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

//! Some stuff used by rustc that doesn't have many dependencies
//!
//! Originally extracted from rustc::back, which was nominally the
//! compiler 'backend', though LLVM is rustc's backend, so rustc_target
//! is really just odds-and-ends relating to code gen and linking.
//! This crate mostly exists to make rustc smaller, so we might put
//! more 'stuff' here in the future.  It does not have a dependency on
//! LLVM.

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(slice_patterns)]

#[macro_use]
extern crate bitflags;
extern crate serialize;
#[macro_use] extern crate log;

extern crate serialize as rustc_serialize; // used by deriving

// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
#[allow(unused_extern_crates)]
extern crate rustc_cratesio_shim;

pub mod abi;
pub mod spec;
<commit_msg>[nll] librustc_target: enable feature(nll) for bootstrap<commit_after>// Copyright 2012-2013 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.

//! Some stuff used by rustc that doesn't have many dependencies
//!
//! Originally extracted from rustc::back, which was nominally the
//! compiler 'backend', though LLVM is rustc's backend, so rustc_target
//! is really just odds-and-ends relating to code gen and linking.
//! This crate mostly exists to make rustc smaller, so we might put
//! more 'stuff' here in the future.  It does not have a dependency on
//! LLVM.

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(box_syntax)]
#![feature(const_fn)]
#![cfg_attr(not(stage0), feature(nll))]
#![feature(slice_patterns)]

#[macro_use]
extern crate bitflags;
extern crate serialize;
#[macro_use] extern crate log;

extern crate serialize as rustc_serialize; // used by deriving

// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
#[allow(unused_extern_crates)]
extern crate rustc_cratesio_shim;

pub mod abi;
pub mod spec;
<|endoftext|>


<commit_before>// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gcc;
extern crate cmake;
extern crate pkg_config;

use std::path::Path;
use std::process::Command;

const GRPC_VERSION: &'static str = "1.2.5";
const ZLIB_VERSION: &'static str = "1.2.8";
const BORINGSSL_GIT_HASH: &'static str = "78684e5b222645828ca302e56b40b9daff2b2d27";

fn wget(url: &str, out: &str) -> Result<(), String> {
    Command::new("wget").args(&["-q", "-c", "-O", out, url])
        .status()
        .map_err(|err| format!("wget execute failed: {}", err))
        .and_then(|status| {
            if status.success() {
                Ok(())
            } else {
                Err(format!("wget exit with {}", status))
            }
        })
}

fn tar_xf(file: &str) -> Result<(), String> {
    Command::new("tar").args(&["zxf", file])
        .status()
        .map_err(|err| format!("tar execute failed: {}", err))
        .and_then(|status| {
            if status.success() {
                Ok(())
            } else {
                Err(format!("tar exit with {}", status))
            }
        })
}

fn build_or_link_grpc(cc: &mut gcc::Config) {
    if Ok(lib) = pkg_config::Config::new().atleast_version("1.2.5").statik(true).probe("grpc_unsecure") {
        for inc_path in &lib.include_paths {
            cc.include(inc_path);
        }
        return;

    }

    if !Path::new(&format!("grpc-{}", GRPC_VERSION)).exists() {
        wget(&format!("https://github.com/grpc/grpc/archive/v{}.tar.gz", GRPC_VERSION),
             "grpc.tar.gz")
            .and_then(|_| tar_xf("grpc.tar.gz"))
            .unwrap();
    }

    if !Path::new(&format!("zlib-{}", ZLIB_VERSION)).exists() {
        wget(&format!("https://github.com/madler/zlib/archive/v{}.tar.gz", ZLIB_VERSION),
             "zlib.tar.gz")
            .and_then(|_| tar_xf("zlib.tar.gz"))
            .unwrap();
    }

    if !Path::new(&format!("boringssl-{}", BORINGSSL_GIT_HASH)).exists() {
        wget(&format!("https://github.com/google/boringssl/archive/{}.tar.gz", BORINGSSL_GIT_HASH),
             "boringssl.tar.gz")
            .and_then(|_| tar_xf("boringssl.tar.gz"))
            .unwrap();
    }

    let dst = cmake::Config::new(format!("zlib-{}", ZLIB_VERSION))
        .build();

    println!("cargo:rustc-link-search=native={}/lib", dst.display());

    let dst = cmake::Config::new("grpc-1.2.5")
        .define("ZLIB_ROOT_DIR", format!("../zlib-{}", ZLIB_VERSION)) // relative to grpc dir
        .define("BORINGSSL_ROOT_DIR", format!("../boringssl-{}", BORINGSSL_GIT_HASH))
        .build_target("grpc_unsecure")
        .build();

    cc.include("grpc/include");

    println!("cargo:rustc-link-search=native={}/build", dst.display());
    println!("cargo:rustc-link-search=native={}/build/third_party/zlib", dst.display());

    println!("cargo:rustc-link-lib=static=z");
    println!("cargo:rustc-link-lib=static=gpr");
    println!("cargo:rustc-link-lib=static=grpc_unsecure");
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    let mut cc = gcc::Config::new();

    build_or_link_grpc(&mut cc);

    cc.file("grpc_wrap.c")
        .flag("-fPIC")
        .flag("-O2")
        .compile("libgrpc_wrap.a");
}
<commit_msg>*: fix typo<commit_after>// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gcc;
extern crate cmake;
extern crate pkg_config;

use std::path::Path;
use std::process::Command;

const GRPC_VERSION: &'static str = "1.2.5";
const ZLIB_VERSION: &'static str = "1.2.8";
const BORINGSSL_GIT_HASH: &'static str = "78684e5b222645828ca302e56b40b9daff2b2d27";

fn wget(url: &str, out: &str) -> Result<(), String> {
    Command::new("wget").args(&["-q", "-c", "-O", out, url])
        .status()
        .map_err(|err| format!("wget execute failed: {}", err))
        .and_then(|status| {
            if status.success() {
                Ok(())
            } else {
                Err(format!("wget exit with {}", status))
            }
        })
}

fn tar_xf(file: &str) -> Result<(), String> {
    Command::new("tar").args(&["zxf", file])
        .status()
        .map_err(|err| format!("tar execute failed: {}", err))
        .and_then(|status| {
            if status.success() {
                Ok(())
            } else {
                Err(format!("tar exit with {}", status))
            }
        })
}

fn build_or_link_grpc(cc: &mut gcc::Config) {
    if let Ok(lib) = pkg_config::Config::new().atleast_version("1.2.5").statik(true).probe("grpc_unsecure") {
        for inc_path in &lib.include_paths {
            cc.include(inc_path);
        }
        return;

    }

    if !Path::new(&format!("grpc-{}", GRPC_VERSION)).exists() {
        wget(&format!("https://github.com/grpc/grpc/archive/v{}.tar.gz", GRPC_VERSION),
             "grpc.tar.gz")
            .and_then(|_| tar_xf("grpc.tar.gz"))
            .unwrap();
    }

    if !Path::new(&format!("zlib-{}", ZLIB_VERSION)).exists() {
        wget(&format!("https://github.com/madler/zlib/archive/v{}.tar.gz", ZLIB_VERSION),
             "zlib.tar.gz")
            .and_then(|_| tar_xf("zlib.tar.gz"))
            .unwrap();
    }

    if !Path::new(&format!("boringssl-{}", BORINGSSL_GIT_HASH)).exists() {
        wget(&format!("https://github.com/google/boringssl/archive/{}.tar.gz", BORINGSSL_GIT_HASH),
             "boringssl.tar.gz")
            .and_then(|_| tar_xf("boringssl.tar.gz"))
            .unwrap();
    }

    let dst = cmake::Config::new(format!("zlib-{}", ZLIB_VERSION))
        .build();

    println!("cargo:rustc-link-search=native={}/lib", dst.display());

    let dst = cmake::Config::new("grpc-1.2.5")
        .define("ZLIB_ROOT_DIR", format!("../zlib-{}", ZLIB_VERSION)) // relative to grpc dir
        .define("BORINGSSL_ROOT_DIR", format!("../boringssl-{}", BORINGSSL_GIT_HASH))
        .build_target("grpc_unsecure")
        .build();

    cc.include("grpc/include");

    println!("cargo:rustc-link-search=native={}/build", dst.display());
    println!("cargo:rustc-link-search=native={}/build/third_party/zlib", dst.display());

    println!("cargo:rustc-link-lib=static=z");
    println!("cargo:rustc-link-lib=static=gpr");
    println!("cargo:rustc-link-lib=static=grpc_unsecure");
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    let mut cc = gcc::Config::new();

    build_or_link_grpc(&mut cc);

    cc.file("grpc_wrap.c")
        .flag("-fPIC")
        .flag("-O2")
        .compile("libgrpc_wrap.a");
}
<|endoftext|>


<commit_before>extern crate ratelimit_meter;

use ratelimit_meter::{GCRA, Threadsafe, Limiter, Decider, Decision};
use std::thread;

#[test]
fn simple_operation() {
    let mut lim = Limiter::new()
        .capacity(5)
        .weight(1)
        .build::<Threadsafe<GCRA>>()
        .unwrap();
    assert_eq!(Decision::Yes, lim.check());
}

#[test]
fn actual_threadsafety() {
    let lim = Limiter::new()
        .capacity(5)
        .weight(1)
        .build::<Threadsafe<GCRA>>()
        .unwrap();
    let mut children = vec![];
    for _i in 0..20 {
        let mut lim = lim.clone();
        children.push(thread::spawn(move || {
            lim.check();
        }));
    }
    for child in children {
        child.join().unwrap();
    }
}
<commit_msg>Test that the threaded rate-limiter is actually doing its work<commit_after>extern crate ratelimit_meter;

use ratelimit_meter::{GCRA, Threadsafe, Limiter, Decider, Decision};
use std::thread;
use std::time::{Instant, Duration};

#[test]
fn simple_operation() {
    let mut lim = Limiter::new()
        .capacity(5)
        .weight(1)
        .build::<Threadsafe<GCRA>>()
        .unwrap();
    assert_eq!(Decision::Yes, lim.check());
}

#[test]
fn actual_threadsafety() {
    let mut lim = Limiter::new()
        .capacity(20)
        .weight(1)
        .build::<Threadsafe<GCRA>>()
        .unwrap();
    let now = Instant::now();
    let ms = Duration::from_millis(1);
    let mut children = vec![];

    lim.test_and_update(now);
    for _i in 0..20 {
        let mut lim = lim.clone();
        children.push(thread::spawn(move || {
            lim.test_and_update(now);
        }));
    }
    for child in children {
        child.join().unwrap();
    }
    assert!(!lim.test_and_update(now).is_compliant());
    assert_eq!(Decision::Yes, lim.test_and_update(now+ms*1000));
}
<|endoftext|>


<commit_before>! version = 2.0

+ invalid\trigger
- Test

+ my email address is *
- <set email=<star>>I will remember your e-mail is <get email>.

+ what is my email
- Your email address is <get email>.

+ comment ça va
- Je vais très bien, merci.

+ mon prénom est *
- <set name=<formal>>Je suis enchantée de faire votre connaissance.
<commit_msg>Update unicode.rs<commit_after>! version = 2.0

+ invalid\trigger
- Test

+ my email address is *
- <set email=<star>>I will remember your e-mail is <get email>.

+ what is my email
- Your email address is <get email>.

+ comment ça va
- Je vais très bien, merci.

+ mon prénom est *
- <set name=<formal>>Je suis enchantée de faire votre connaissance.

+ il y a quoi au cinéma
- Testing
<|endoftext|>


<commit_before>use std::ascii::AsciiExt;
use std::cmp::min;

pub fn compute_matches<'a>(choices: &[&'a str], query: &str) -> Vec<&'a str> {
    struct ScoredChoice<'a> {
        score: f64,
        choice: &'a str,
    };
    let mut ret = Vec::new();
    for choice in choices.iter() {
        let score = score(&choice, query);
        if score > 0_f64 {
            ret.push(ScoredChoice{ score: score, choice: &choice });
        }
    }
    ret.sort_by(|x, y| y.score.partial_cmp(&x.score).unwrap());
    ret.iter().map(|s| s.choice).collect()
}

#[allow(dead_code)]
fn get_slice_indices(length: usize, workers: usize, idx: usize) -> (usize, usize) {
    let lb = (length as f64 / workers as f64) * idx as f64;
    let ub = (length as f64 / workers as f64) * (idx + 1) as f64;
    (lb as usize, ub as usize)
}

#[test]
fn get_slice_indices_test() {
    assert_eq!(get_slice_indices(100, 1, 0), (0, 100));

    assert_eq!(get_slice_indices(100, 2, 1), (50, 100));
    assert_eq!(get_slice_indices(100, 2, 0), (0, 50));

    assert_eq!(get_slice_indices(100, 3, 0), (0, 33));
    assert_eq!(get_slice_indices(100, 3, 1), (33, 66));
    assert_eq!(get_slice_indices(100, 3, 2), (66, 100));

    assert_eq!(get_slice_indices(100, 4, 0), (0, 25));
    assert_eq!(get_slice_indices(100, 4, 1), (25, 50));
    assert_eq!(get_slice_indices(100, 4, 2), (50, 75));
    assert_eq!(get_slice_indices(100, 4, 3), (75, 100));

    assert_eq!(get_slice_indices(12, 12, 11), (11, 12));
    assert_eq!(get_slice_indices(12, 12, 0), (0, 1));

    assert_eq!(get_slice_indices(1, 2, 0), (0, 0));
    assert_eq!(get_slice_indices(1, 2, 1), (0, 1));
}

fn score(choice: &str, query: &str) -> f64 {
    if query.len() == 0 {
        return 1.0;
    }
    if choice.len() == 0 {
        return 0.0;
    }

    let query = query.to_ascii_lowercase();
    let choice = choice.to_ascii_lowercase();

    match compute_match_length(&choice, &query) {
        None => return 0.0,
        Some(match_length) => {
            let score = query.len() as f64 / match_length as f64;
            return score as f64 / choice.len() as f64;
        }
    }
}

fn compute_match_length(string: &str, chars: &str) -> Option<usize> {
    let first_char = chars.char_at(0);
    let rest = &chars[1..chars.len()];
    let indices = find_char_in_string(string, first_char);

    let mut current_min = None;
    for i in indices.iter() {
        let last_index = find_end_of_match(string, rest, *i);
        if last_index.is_some() {
            let idx = last_index.unwrap() - *i + 1;
            if current_min.is_some() {
                let cm = min(current_min.unwrap(), idx);
                current_min = Some(cm);
            } else {
                current_min = Some(idx)
            }
        }
    }
    return current_min;
}

fn find_char_in_string(string: &str, char: char) -> Vec<usize> {
    let mut indices = Vec::new();
    let mut i = 0;
    for c in string.chars() {
        if c == char {
            indices.push(i);
        }
        i = i + 1;
    }
    return indices;
}

fn find_end_of_match(string: &str, rest_of_query: &str, first_index: usize) -> Option<usize> {
    let mut last_index = first_index + 1;
    let chars_in_string = string.chars().collect::<Vec<_>>().len();
    for c in rest_of_query.chars() {
        let current_substring = string.slice_chars(last_index, chars_in_string);
        match current_substring.find(c) {
            None => return None,
            Some(ref i) => {
                last_index += *i + 1;
            }
        }
    }
    return Some(last_index - 1);
}

#[test]
fn find_end_of_match_test() {
    assert_eq!(find_end_of_match("a", "a", 0), None);
    assert_eq!(find_end_of_match("ba", "a", 1), None);
    assert_eq!(find_end_of_match("aaa", "aa", 0), Some(2));
    assert_eq!(find_end_of_match("aaa", "b", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "this is a match", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "his is a match", 0), Some(19));
    assert_eq!(find_end_of_match("./rust/x86_64-apple-darwin/test/run-pass/process-spawn-with-unicode-params-πЯ音æ∞/child.stage2-x86_64-apple-darwin", "ust", 2), Some(5));
}

#[test]
fn basic_scoring() {
    assert_eq!(score("", "a"), 0.0);
    assert_eq!(score("a", ""), 1.0);
    assert_eq!(score("short", "longer"), 0.0);
    assert_eq!(score("a", "b"), 0.0);
    assert_eq!(score("ab", "ac"), 0.0);

    assert!(score("a", "a") > 0.0);
    assert!(score("ab", "a") > 0.0);
    assert!(score("ba", "a") > 0.0);
    assert!(score("bab", "a") > 0.0);
    assert!(score("babababab", "aaaa") > 0.0);

    assert_eq!(score("a", "a"), 1_f64 / "a".len() as f64);
    assert_eq!(score("ab", "ab"), 0.5);
    assert_eq!(score("a long string", "a long string"), 1_f64 / "a long string".len() as f64);
    assert_eq!(score("spec/search_spec.rb", "sear"), 1_f64 / "spec/search_spec.rb".len() as f64);
}

#[test]
fn character_matching() {
    assert!(score("/! symbols $^", "/!$^") > 0.0);

    assert_eq!(score("a", "A"), 1.0);
    assert_eq!(score("A", "a"), 1.0);

    assert_eq!(score("a", "aa"), 0.0);
}

#[test]
fn match_equality() {
    assert!(score("selecta.gemspec", "asp") > score("algorithm4_spec.rb", "asp"));
    assert!(score("README.md", "em") > score("benchmark.rb", "em"));
    assert!(score("search.rb", "sear") > score("spec/search_spec.rb", "sear"));

    assert!(score("fbb", "fbb") > score("foo bar baz", "fbb"));
    assert!(score("foo", "foo") > score("longer foo", "foo"));
    assert!(score("foo", "foo") > score("foo longer", "foo"));
    assert!(score("1/2/3/4", "1/2/3") > score("1/9/2/3/4", "1/2/3"));

    assert!(score("long 12 long", "12") > score("1 long 2", "12"));

    assert_eq!(score("121padding2", "12"), 1.0 / "121padding2".len() as f64);
    assert_eq!(score("1padding212", "12"), 1.0 / "1padding212".len() as f64);
}
<commit_msg>Use slice_shift_char<commit_after>use std::ascii::AsciiExt;
use std::cmp::min;

pub fn compute_matches<'a>(choices: &[&'a str], query: &str) -> Vec<&'a str> {
    struct ScoredChoice<'a> {
        score: f64,
        choice: &'a str,
    };
    let mut ret = Vec::new();
    for choice in choices.iter() {
        let score = score(&choice, query);
        if score > 0_f64 {
            ret.push(ScoredChoice{ score: score, choice: &choice });
        }
    }
    ret.sort_by(|x, y| y.score.partial_cmp(&x.score).unwrap());
    ret.iter().map(|s| s.choice).collect()
}

#[allow(dead_code)]
fn get_slice_indices(length: usize, workers: usize, idx: usize) -> (usize, usize) {
    let lb = (length as f64 / workers as f64) * idx as f64;
    let ub = (length as f64 / workers as f64) * (idx + 1) as f64;
    (lb as usize, ub as usize)
}

#[test]
fn get_slice_indices_test() {
    assert_eq!(get_slice_indices(100, 1, 0), (0, 100));

    assert_eq!(get_slice_indices(100, 2, 1), (50, 100));
    assert_eq!(get_slice_indices(100, 2, 0), (0, 50));

    assert_eq!(get_slice_indices(100, 3, 0), (0, 33));
    assert_eq!(get_slice_indices(100, 3, 1), (33, 66));
    assert_eq!(get_slice_indices(100, 3, 2), (66, 100));

    assert_eq!(get_slice_indices(100, 4, 0), (0, 25));
    assert_eq!(get_slice_indices(100, 4, 1), (25, 50));
    assert_eq!(get_slice_indices(100, 4, 2), (50, 75));
    assert_eq!(get_slice_indices(100, 4, 3), (75, 100));

    assert_eq!(get_slice_indices(12, 12, 11), (11, 12));
    assert_eq!(get_slice_indices(12, 12, 0), (0, 1));

    assert_eq!(get_slice_indices(1, 2, 0), (0, 0));
    assert_eq!(get_slice_indices(1, 2, 1), (0, 1));
}

fn score(choice: &str, query: &str) -> f64 {
    if query.len() == 0 {
        return 1.0;
    }
    if choice.len() == 0 {
        return 0.0;
    }

    let query = query.to_ascii_lowercase();
    let choice = choice.to_ascii_lowercase();

    match compute_match_length(&choice, &query) {
        None => return 0.0,
        Some(match_length) => {
            let score = query.len() as f64 / match_length as f64;
            return score as f64 / choice.len() as f64;
        }
    }
}

fn compute_match_length(string: &str, chars: &str) -> Option<usize> {
    let (first_char, rest) = match chars.slice_shift_char() {
        Some((f, r)) => (f, r),
        None => return None,
    };
    let indices = find_char_in_string(string, first_char);

    let mut current_min = None;
    for i in indices.iter() {
        let last_index = find_end_of_match(string, rest, *i);
        if last_index.is_some() {
            let idx = last_index.unwrap() - *i + 1;
            if current_min.is_some() {
                let cm = min(current_min.unwrap(), idx);
                current_min = Some(cm);
            } else {
                current_min = Some(idx)
            }
        }
    }
    return current_min;
}

fn find_char_in_string(string: &str, char: char) -> Vec<usize> {
    let mut indices = Vec::new();
    let mut i = 0;
    for c in string.chars() {
        if c == char {
            indices.push(i);
        }
        i = i + 1;
    }
    return indices;
}

fn find_end_of_match(string: &str, rest_of_query: &str, first_index: usize) -> Option<usize> {
    let mut last_index = first_index + 1;
    let chars_in_string = string.chars().collect::<Vec<_>>().len();
    for c in rest_of_query.chars() {
        let current_substring = string.slice_chars(last_index, chars_in_string);
        match current_substring.find(c) {
            None => return None,
            Some(ref i) => {
                last_index += *i + 1;
            }
        }
    }
    return Some(last_index - 1);
}

#[test]
fn find_end_of_match_test() {
    assert_eq!(find_end_of_match("a", "a", 0), None);
    assert_eq!(find_end_of_match("ba", "a", 1), None);
    assert_eq!(find_end_of_match("aaa", "aa", 0), Some(2));
    assert_eq!(find_end_of_match("aaa", "b", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "this is a match", 0), None);
    assert_eq!(find_end_of_match("this is a long match", "his is a match", 0), Some(19));
    assert_eq!(find_end_of_match("./rust/x86_64-apple-darwin/test/run-pass/process-spawn-with-unicode-params-πЯ音æ∞/child.stage2-x86_64-apple-darwin", "ust", 2), Some(5));
}

#[test]
fn basic_scoring() {
    assert_eq!(score("", "a"), 0.0);
    assert_eq!(score("a", ""), 1.0);
    assert_eq!(score("short", "longer"), 0.0);
    assert_eq!(score("a", "b"), 0.0);
    assert_eq!(score("ab", "ac"), 0.0);

    assert!(score("a", "a") > 0.0);
    assert!(score("ab", "a") > 0.0);
    assert!(score("ba", "a") > 0.0);
    assert!(score("bab", "a") > 0.0);
    assert!(score("babababab", "aaaa") > 0.0);

    assert_eq!(score("a", "a"), 1_f64 / "a".len() as f64);
    assert_eq!(score("ab", "ab"), 0.5);
    assert_eq!(score("a long string", "a long string"), 1_f64 / "a long string".len() as f64);
    assert_eq!(score("spec/search_spec.rb", "sear"), 1_f64 / "spec/search_spec.rb".len() as f64);
}

#[test]
fn character_matching() {
    assert!(score("/! symbols $^", "/!$^") > 0.0);

    assert_eq!(score("a", "A"), 1.0);
    assert_eq!(score("A", "a"), 1.0);

    assert_eq!(score("a", "aa"), 0.0);
}

#[test]
fn match_equality() {
    assert!(score("selecta.gemspec", "asp") > score("algorithm4_spec.rb", "asp"));
    assert!(score("README.md", "em") > score("benchmark.rb", "em"));
    assert!(score("search.rb", "sear") > score("spec/search_spec.rb", "sear"));

    assert!(score("fbb", "fbb") > score("foo bar baz", "fbb"));
    assert!(score("foo", "foo") > score("longer foo", "foo"));
    assert!(score("foo", "foo") > score("foo longer", "foo"));
    assert!(score("1/2/3/4", "1/2/3") > score("1/9/2/3/4", "1/2/3"));

    assert!(score("long 12 long", "12") > score("1 long 2", "12"));

    assert_eq!(score("121padding2", "12"), 1.0 / "121padding2".len() as f64);
    assert_eq!(score("1padding212", "12"), 1.0 / "1padding212".len() as f64);
}
<|endoftext|>


<commit_before>// Copyright 2013 The Num-rs Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use algebra::{Field, CommutativeRing};

/// A number that can be written without a fractional or decimal component.
///
/// # Handling of Division and Modulus
///
/// The most interesting part of this trait is the support for different
/// interpretations of integer division and modulus for discrete numbers. This
/// topic is discussed in greater depth in Daan Leijen's
/// _[Division and Modulus for Computer Scientists]
/// (http://legacy.cs.uu.nl/daan/download/papers/divmodnote-letter.pdf)_.
trait Integral
    : Eq + Ord
    + CommutativeRing {
    /// Truncated division satisfying:
    ///
    /// ~~~
    /// t_div(a, b) = trunc(a / b)              ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of division adopted by the ISO C99 standard for the `/`
    /// operator, and is usually more efficient than `f_div` due to better
    /// support on processors.
    fn t_div(a: &Self, b: &Self) -> Self;

    /// The remainder after truncated division satisfying:
    ///
    /// ~~~
    /// t_mod(a, b) = a - (b * t_div(a, b))     ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of modulus adopted by the ISO C99 standard for the `%`
    /// operator, and is usually more efficient than `f_mod` due to better
    /// support on processors.
    fn t_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `t_div` and `t_mod` simultaneously.
    fn t_div_mod(a: &Self, b: &Self) -> (Self, Self);

    /// Floored division satisfying:
    ///
    /// ~~~
    /// f_div(a, b) = ⌊a / b⌋                   ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    fn f_div(a: &Self, b: &Self) -> Self;

    /// The remainder after floored division satisfying:
    ///
    /// ~~~
    /// f_mod(a, b) = a - (b * f_div(a, b))     ∀ a, b where b ≠ 0
    /// ~~~
    fn f_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `f_div` and `f_mod` simultaneously.
    fn f_div_mod(a: &Self, b: &Self) -> (Self, Self);

    /// Greatest Common Divisor
    fn gcd(&self) -> Self;

    /// Lowest Common Multiple
    fn lcm(&self) -> Self;
}

#[inline]
pub fn t_div<T: Integral>(a: &T, b: &T) -> T {
    Integral::t_div(a, b)
}

#[inline]
pub fn t_mod<T: Integral>(a: &T, b: &T) -> T {
    Integral::t_mod(a, b)
}

#[inline]
pub fn t_div_mod<T: Integral>(a: &T, b: &T) -> (T, T) {
    Integral::t_div_mod(a, b)
}

#[inline]
pub fn f_div<T: Integral>(a: &T, b: &T) -> T {
    Integral::f_div(a, b)
}

#[inline]
pub fn f_mod<T: Integral>(a: &T, b: &T) -> T {
    Integral::f_mod(a, b)
}

#[inline]
pub fn f_div_mod<T: Integral>(a: &T, b: &T) -> (T, T) {
    Integral::f_div_mod(a, b)
}

trait Real
    : Eq + Ord
    + Field {
}

impl Real for f32  {}
impl Real for f64  {}
<commit_msg>Fix gcd and lcm method parameters<commit_after>// Copyright 2013 The Num-rs Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use algebra::{Field, CommutativeRing};

/// A number that can be written without a fractional or decimal component.
///
/// # Handling of Division and Modulus
///
/// The most interesting part of this trait is the support for different
/// interpretations of integer division and modulus for discrete numbers. This
/// topic is discussed in greater depth in Daan Leijen's
/// _[Division and Modulus for Computer Scientists]
/// (http://legacy.cs.uu.nl/daan/download/papers/divmodnote-letter.pdf)_.
trait Integral
    : Eq + Ord
    + CommutativeRing {
    /// Truncated division satisfying:
    ///
    /// ~~~
    /// t_div(a, b) = trunc(a / b)              ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of division adopted by the ISO C99 standard for the `/`
    /// operator, and is usually more efficient than `f_div` due to better
    /// support on processors.
    fn t_div(a: &Self, b: &Self) -> Self;

    /// The remainder after truncated division satisfying:
    ///
    /// ~~~
    /// t_mod(a, b) = a - (b * t_div(a, b))     ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of modulus adopted by the ISO C99 standard for the `%`
    /// operator, and is usually more efficient than `f_mod` due to better
    /// support on processors.
    fn t_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `t_div` and `t_mod` simultaneously.
    fn t_div_mod(a: &Self, b: &Self) -> (Self, Self);

    /// Floored division satisfying:
    ///
    /// ~~~
    /// f_div(a, b) = ⌊a / b⌋                   ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    fn f_div(a: &Self, b: &Self) -> Self;

    /// The remainder after floored division satisfying:
    ///
    /// ~~~
    /// f_mod(a, b) = a - (b * f_div(a, b))     ∀ a, b where b ≠ 0
    /// ~~~
    fn f_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `f_div` and `f_mod` simultaneously.
    fn f_div_mod(a: &Self, b: &Self) -> (Self, Self);

    /// Greatest Common Divisor (GCD)
    fn gcd(a: &Self, b: &Self) -> Self;

    /// Lowest Common Multiple (LCM)
    fn lcm(a: &Self, b: &Self) -> Self;
}

#[inline]
pub fn t_div<T: Integral>(a: &T, b: &T) -> T {
    Integral::t_div(a, b)
}

#[inline]
pub fn t_mod<T: Integral>(a: &T, b: &T) -> T {
    Integral::t_mod(a, b)
}

#[inline]
pub fn t_div_mod<T: Integral>(a: &T, b: &T) -> (T, T) {
    Integral::t_div_mod(a, b)
}

#[inline]
pub fn f_div<T: Integral>(a: &T, b: &T) -> T {
    Integral::f_div(a, b)
}

#[inline]
pub fn f_mod<T: Integral>(a: &T, b: &T) -> T {
    Integral::f_mod(a, b)
}

#[inline]
pub fn f_div_mod<T: Integral>(a: &T, b: &T) -> (T, T) {
    Integral::f_div_mod(a, b)
}

trait Real
    : Eq + Ord
    + Field {
}

impl Real for f32  {}
impl Real for f64  {}
<|endoftext|>


<commit_before>// The code below is based on the fallback `memrchr` implementation from the respective crate.
//
// We use this mainly to skip repeated `/`. If there is only one slash, `memrnchr` performs the same
// as a naive version (e.g. `rposition`). However, it is much faster in pathological cases.

#[cfg(target_pointer_width = "32")]
const USIZE_BYTES: usize = 4;
#[cfg(target_pointer_width = "64")]
const USIZE_BYTES: usize = 8;

// Returns the byte offset of the last byte that is NOT equal to the given one.
#[inline(always)]
pub fn memrnchr(x: u8, text: &[u8]) -> Option<usize> {
  // Scan for a single byte value by reading two `usize` words at a time.
  //
  // Split `text` in three parts
  // - unaligned tail, after the last word aligned address in text
  // - body, scan by 2 words at a time
  // - the first remaining bytes, < 2 word size
  let len = text.len();
  let ptr = text.as_ptr();

  // search to an aligned boundary
  let end_align = (ptr as usize + len) & (USIZE_BYTES - 1);
  let mut offset;
  if end_align > 0 {
    offset = if end_align >= len { 0 } else { len - end_align };
    let pos = text[offset..].iter().rposition(|elt| *elt != x);
    if let Some(index) = pos {
      return Some(offset + index);
    }
  } else {
    offset = len;
  }

  // search the body of the text
  let repeated_x = repeat_byte(x);

  while offset >= 2 * USIZE_BYTES {
    debug_assert_eq!((ptr as usize + offset) % USIZE_BYTES, 0);
    unsafe {
      let u = *(ptr.offset(offset as isize - 2 * USIZE_BYTES as isize) as *const usize);
      let v = *(ptr.offset(offset as isize - USIZE_BYTES as isize) as *const usize);

      // break if there is no matching byte
      if u & repeated_x != usize::max_value() || v & repeated_x != usize::max_value() {
        break;
      }
    }
    offset -= 2 * USIZE_BYTES;
  }

  // find the byte before the point the body loop stopped
  text[..offset].iter().rposition(|elt| *elt != x)
}

#[cfg(target_pointer_width = "32")]
#[inline]
fn repeat_byte(b: u8) -> usize {
  let mut rep = (b as usize) << 8 | b as usize;
  rep = rep << 16 | rep;
  rep
}

#[cfg(target_pointer_width = "64")]
#[inline]
fn repeat_byte(b: u8) -> usize {
  let mut rep = (b as usize) << 8 | b as usize;
  rep = rep << 16 | rep;
  rep = rep << 32 | rep;
  rep
}
<commit_msg>Use size_of::<usize>() instead of cfg constants<commit_after>// The code below is based on the fallback `memrchr` implementation from the respective crate.
//
// We use this mainly to skip repeated `/`. If there is only one slash, `memrnchr` performs the same
// as a naive version (e.g. `rposition`). However, it is much faster in pathological cases.

use std::mem::size_of;

// Returns the byte offset of the last byte that is NOT equal to the given one.
#[inline(always)]
pub fn memrnchr(x: u8, text: &[u8]) -> Option<usize> {
  // Scan for a single byte value by reading two `usize` words at a time.
  //
  // Split `text` in three parts
  // - unaligned tail, after the last word aligned address in text
  // - body, scan by 2 words at a time
  // - the first remaining bytes, < 2 word size
  let len = text.len();
  let ptr = text.as_ptr();

  // search to an aligned boundary
  let end_align = (ptr as usize + len) & (size_of::<usize>() - 1);
  let mut offset;
  if end_align > 0 {
    offset = if end_align >= len { 0 } else { len - end_align };
    if let Some(index) = memrnchr_naive(x, &text[offset..]) {
      return Some(offset + index);
    }
  } else {
    offset = len;
  }

  // search the body of the text
  let repeated_x = repeat_byte(x);
  while offset >= 2 * size_of::<usize>() {
    debug_assert_eq!((ptr as usize + offset) % size_of::<usize>(), 0);
    unsafe {
      let u = *(ptr.offset(offset as isize - 2 * size_of::<usize>() as isize) as *const usize);
      let v = *(ptr.offset(offset as isize - size_of::<usize>() as isize) as *const usize);
      if u & repeated_x != usize::max_value() || v & repeated_x != usize::max_value() {
        break;
      }
    }
    offset -= 2 * size_of::<usize>();
  }

  // find the byte before the point the body loop stopped
  memrnchr_naive(x, &text[..offset])
}

#[inline(always)]
fn memrnchr_naive(x: u8, text: &[u8]) -> Option<usize> {
  text.iter().rposition(|c| *c != x)
}

#[cfg(target_pointer_width = "32")]
#[inline]
fn repeat_byte(b: u8) -> usize {
  let mut rep = (b as usize) << 8 | b as usize;
  rep = rep << 16 | rep;
  rep
}

#[cfg(target_pointer_width = "64")]
#[inline]
fn repeat_byte(b: u8) -> usize {
  let mut rep = (b as usize) << 8 | b as usize;
  rep = rep << 16 | rep;
  rep = rep << 32 | rep;
  rep
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use num::BigUint;

use Construct;
use Data;
use Count;
use Of;
use ToIndex;
use ToPos;
use Zero;

/// Dimension is natural number, position is (a, b).
/// Represents all directional pairs that has not same element for `a` and `b`.
pub struct NeqPair<T = Data>(PhantomData<T>);

impl<T> Construct for NeqPair<T> {
    fn new() -> NeqPair<T> { NeqPair(PhantomData) }
}

impl Count<usize> for NeqPair<Data> {
    type N = usize;
    fn count(&self, dim: &usize) -> usize { dim * (dim - 1) }
}

impl Count<BigUint> for NeqPair<Data> {
    type N = BigUint;
    fn count(&self, dim: &BigUint) -> BigUint {
        let _1: BigUint = 1usize.into();
        dim * (dim - _1)
    }
}

impl<T, U> Count<U> for NeqPair<Of<T>>
    where
        T: Construct + Count<U>,
        NeqPair: Count<<T as Count<U>>::N, N = <T as Count<U>>::N>
{
    type N = <T as Count<U>>::N;
    fn count(&self, dim: &U) -> Self::N {
        let of: T = Construct::new();
        let data: NeqPair<Data> = Construct::new();
        data.count(&of.count(dim))
    }
}

impl Zero<usize, (usize, usize)> for NeqPair<Data> {
    fn zero(&self, _dim: &usize) -> (usize, usize) { (0, 0) }
}

impl<T, U, V>
Zero<U, (V, V)> for NeqPair<Of<T>>
    where
        T: Construct + Zero<U, V>
{
    fn zero(&self, dim: &U) -> (V, V) {
        let of: T = Construct::new();
        (of.zero(dim), of.zero(dim))
    }
}

impl ToIndex<usize, (usize, usize)>
for NeqPair<Data> {
    fn to_index(&self, dim: &usize, &(a, b): &(usize, usize)) -> usize {
        use Pair;

        let pair: Pair<Data> = Construct::new();
        if a < b {
            pair.to_index(dim, &(a, b)) * 2
        } else {
            pair.to_index(dim, &(b, a)) * 2 + 1
        }
    }
}

impl<T, U, V>
ToIndex<U, (V, V)> for NeqPair<Of<T>>
    where
        T: Construct + ToIndex<U, V> + Count<U, N = usize>
{
    fn to_index(
        &self,
        dim: &U,
        &(ref min, ref max): &(V, V)
    ) -> usize {
        let of: T = Construct::new();
        let data: NeqPair<Data> = Construct::new();
        let min = of.to_index(dim, min);
        let max = of.to_index(dim, max);
        data.to_index(&self.count(dim), &(min, max))
    }
}

impl ToPos<usize, (usize, usize)> for NeqPair<Data> {
    fn to_pos(&self, dim: &usize, index: usize, pos: &mut (usize, usize)) {
        use Pair;

        let pair: Pair<Data> = Construct::new();
        if index % 2 == 0 {
            pair.to_pos(dim, index / 2, pos);
        } else {
            pair.to_pos(dim, (index - 1) / 2, pos);
            let tmp = pos.1;
            pos.1 = pos.0;
            pos.0 = tmp;
        }
    }
}

impl<T, U, V>
ToPos<U, (V, V)> for NeqPair<Of<T>>
    where
        T: Construct + Count<U, N = usize> + ToPos<U, V>
{
    fn to_pos(
        &self,
        dim: &U,
        index: usize,
        &mut (ref mut min, ref mut max): &mut (V, V)
    ) {
        let of: T = Construct::new();
        let data: NeqPair<Data> = Construct::new();
        let count = of.count(dim);
        let mut pair = (0, 0);
        data.to_pos(&count, index, &mut pair);
        let (pair_min, pair_max) = pair;
        of.to_pos(dim, pair_min, min);
        of.to_pos(dim, pair_max, max);
    }
}

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

    #[test]
    fn features() {
        is_complete::<NeqPair, usize, (usize, usize)>();
        is_complete::<NeqPair<Of<NeqPair>>, usize,
            ((usize, usize), (usize, usize))>();
    }

    #[test]
    fn data() {
        let x: NeqPair = Construct::new();
        let ref dim = 4;
        assert_eq!(x.count(dim), 12);
        assert_eq!(x.to_index(dim, &(0, 1)), 0);
        assert_eq!(x.to_index(dim, &(1, 0)), 1);
        assert_eq!(x.to_index(dim, &(0, 2)), 2);
        assert_eq!(x.to_index(dim, &(2, 0)), 3);
        assert_eq!(x.to_index(dim, &(1, 2)), 4);
        assert_eq!(x.to_index(dim, &(2, 1)), 5);
        assert_eq!(x.to_index(dim, &(0, 3)), 6);
        let mut new_pos = (0, 0);
        x.to_pos(dim, 6, &mut new_pos);
        assert_eq!(new_pos, (0, 3));
        x.to_pos(dim, 5, &mut new_pos);
        assert_eq!(new_pos, (2, 1));
    }

    #[test]
    fn of() {
        let x: NeqPair<Of<DimensionN>> = Construct::new();
        let ref dim = vec![2, 2];
        assert_eq!(x.count(dim), 12);
        assert_eq!(x.to_index(dim, &(vec![0, 0], vec![1, 0])), 0);
        assert_eq!(x.to_index(dim, &(vec![0, 0], vec![0, 1])), 2);
        assert_eq!(x.to_index(dim, &(vec![1, 0], vec![0, 1])), 4);
        assert_eq!(x.to_index(dim, &(vec![0, 0], vec![1, 1])), 6);
        assert_eq!(x.to_index(dim, &(vec![1, 0], vec![1, 1])), 8);
        assert_eq!(x.to_index(dim, &(vec![0, 1], vec![1, 1])), 10);
        let mut pos = (Vec::new(), Vec::new());
        for i in 0..6 {
            x.to_pos(dim, i, &mut pos);
            // println!("{} {}", &min[], &max[]);
        }
        x.to_pos(dim, 10, &mut pos);
        assert_eq!(&pos.0, &[0, 1]);
        assert_eq!(&pos.1, &[1, 1]);
    }
}
<commit_msg>Impl `Zero<BigUint, (BigUint, BigUint)>` for `NeqPair`<commit_after>use std::marker::PhantomData;

use num::BigUint;

use Construct;
use Data;
use Count;
use Of;
use ToIndex;
use ToPos;
use Zero;

/// Dimension is natural number, position is (a, b).
/// Represents all directional pairs that has not same element for `a` and `b`.
pub struct NeqPair<T = Data>(PhantomData<T>);

impl<T> Construct for NeqPair<T> {
    fn new() -> NeqPair<T> { NeqPair(PhantomData) }
}

impl Count<usize> for NeqPair<Data> {
    type N = usize;
    fn count(&self, dim: &usize) -> usize { dim * (dim - 1) }
}

impl Count<BigUint> for NeqPair<Data> {
    type N = BigUint;
    fn count(&self, dim: &BigUint) -> BigUint {
        let _1: BigUint = 1usize.into();
        dim * (dim - _1)
    }
}

impl<T, U> Count<U> for NeqPair<Of<T>>
    where
        T: Construct + Count<U>,
        NeqPair: Count<<T as Count<U>>::N, N = <T as Count<U>>::N>
{
    type N = <T as Count<U>>::N;
    fn count(&self, dim: &U) -> Self::N {
        let of: T = Construct::new();
        let data: NeqPair<Data> = Construct::new();
        data.count(&of.count(dim))
    }
}

impl Zero<usize, (usize, usize)> for NeqPair<Data> {
    fn zero(&self, _dim: &usize) -> (usize, usize) { (0, 0) }
}

impl Zero<BigUint, (BigUint, BigUint)> for NeqPair<Data> {
    fn zero(&self, _dim: &BigUint) -> (BigUint, BigUint) { (0usize.into(), 0usize.into()) }
}

impl<T, U, V>
Zero<U, (V, V)> for NeqPair<Of<T>>
    where
        T: Construct + Zero<U, V>
{
    fn zero(&self, dim: &U) -> (V, V) {
        let of: T = Construct::new();
        (of.zero(dim), of.zero(dim))
    }
}

impl ToIndex<usize, (usize, usize)>
for NeqPair<Data> {
    fn to_index(&self, dim: &usize, &(a, b): &(usize, usize)) -> usize {
        use Pair;

        let pair: Pair<Data> = Construct::new();
        if a < b {
            pair.to_index(dim, &(a, b)) * 2
        } else {
            pair.to_index(dim, &(b, a)) * 2 + 1
        }
    }
}

impl<T, U, V>
ToIndex<U, (V, V)> for NeqPair<Of<T>>
    where
        T: Construct + ToIndex<U, V> + Count<U, N = usize>
{
    fn to_index(
        &self,
        dim: &U,
        &(ref min, ref max): &(V, V)
    ) -> usize {
        let of: T = Construct::new();
        let data: NeqPair<Data> = Construct::new();
        let min = of.to_index(dim, min);
        let max = of.to_index(dim, max);
        data.to_index(&self.count(dim), &(min, max))
    }
}

impl ToPos<usize, (usize, usize)> for NeqPair<Data> {
    fn to_pos(&self, dim: &usize, index: usize, pos: &mut (usize, usize)) {
        use Pair;

        let pair: Pair<Data> = Construct::new();
        if index % 2 == 0 {
            pair.to_pos(dim, index / 2, pos);
        } else {
            pair.to_pos(dim, (index - 1) / 2, pos);
            let tmp = pos.1;
            pos.1 = pos.0;
            pos.0 = tmp;
        }
    }
}

impl<T, U, V>
ToPos<U, (V, V)> for NeqPair<Of<T>>
    where
        T: Construct + Count<U, N = usize> + ToPos<U, V>
{
    fn to_pos(
        &self,
        dim: &U,
        index: usize,
        &mut (ref mut min, ref mut max): &mut (V, V)
    ) {
        let of: T = Construct::new();
        let data: NeqPair<Data> = Construct::new();
        let count = of.count(dim);
        let mut pair = (0, 0);
        data.to_pos(&count, index, &mut pair);
        let (pair_min, pair_max) = pair;
        of.to_pos(dim, pair_min, min);
        of.to_pos(dim, pair_max, max);
    }
}

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

    #[test]
    fn features() {
        is_complete::<NeqPair, usize, (usize, usize)>();
        is_complete::<NeqPair<Of<NeqPair>>, usize,
            ((usize, usize), (usize, usize))>();
    }

    #[test]
    fn data() {
        let x: NeqPair = Construct::new();
        let ref dim = 4;
        assert_eq!(x.count(dim), 12);
        assert_eq!(x.to_index(dim, &(0, 1)), 0);
        assert_eq!(x.to_index(dim, &(1, 0)), 1);
        assert_eq!(x.to_index(dim, &(0, 2)), 2);
        assert_eq!(x.to_index(dim, &(2, 0)), 3);
        assert_eq!(x.to_index(dim, &(1, 2)), 4);
        assert_eq!(x.to_index(dim, &(2, 1)), 5);
        assert_eq!(x.to_index(dim, &(0, 3)), 6);
        let mut new_pos = (0, 0);
        x.to_pos(dim, 6, &mut new_pos);
        assert_eq!(new_pos, (0, 3));
        x.to_pos(dim, 5, &mut new_pos);
        assert_eq!(new_pos, (2, 1));
    }

    #[test]
    fn of() {
        let x: NeqPair<Of<DimensionN>> = Construct::new();
        let ref dim = vec![2, 2];
        assert_eq!(x.count(dim), 12);
        assert_eq!(x.to_index(dim, &(vec![0, 0], vec![1, 0])), 0);
        assert_eq!(x.to_index(dim, &(vec![0, 0], vec![0, 1])), 2);
        assert_eq!(x.to_index(dim, &(vec![1, 0], vec![0, 1])), 4);
        assert_eq!(x.to_index(dim, &(vec![0, 0], vec![1, 1])), 6);
        assert_eq!(x.to_index(dim, &(vec![1, 0], vec![1, 1])), 8);
        assert_eq!(x.to_index(dim, &(vec![0, 1], vec![1, 1])), 10);
        let mut pos = (Vec::new(), Vec::new());
        for i in 0..6 {
            x.to_pos(dim, i, &mut pos);
            // println!("{} {}", &min[], &max[]);
        }
        x.to_pos(dim, 10, &mut pos);
        assert_eq!(&pos.0, &[0, 1]);
        assert_eq!(&pos.1, &[1, 1]);
    }
}
<|endoftext|>