<commit_before>extern crate serde_json;

use indy::api::ErrorCode;
use indy::api::non_secrets::*;

use utils::callback::CallbackUtils;
use utils::wallet::WalletUtils;
use utils::constants::POOL;
use utils::test::TestUtils;
use utils::types::WalletRecord;

use std::ffi::CString;
use std::ptr::null;
use std::sync::{Once, ONCE_INIT};
use std::collections::HashMap;

pub const SEARCH_COMMON_WALLET: &'static str = "SEARCH_COMMON_WALLET";
pub const TYPE: &'static str = "TestType";
pub const TYPE_2: &'static str = "TestType2";
pub const ID: &'static str = "RecordId";
pub const ID_2: &'static str = "RecordId2";
pub const ID_3: &'static str = "RecordId3";
pub const ID_4: &'static str = "RecordId4";
pub const ID_5: &'static str = "RecordId5";
pub const VALUE: &'static str = "RecordValue";
pub const VALUE_2: &'static str = "RecordValue2";
pub const VALUE_3: &'static str = "RecordValue3";
pub const VALUE_4: &'static str = "RecordValue4";
pub const VALUE_5: &'static str = "RecordValue5";
pub const QUERY_EMPTY: &'static str = r#"{}"#;
pub const OPTIONS_EMPTY: &'static str = r#"{}"#;
pub const OPTIONS_ID_TYPE_VALUE: &'static str = r#"{"retrieveType":true, "retrieveValue":true, "retrieveTags":false}"#;
pub const OPTIONS_FULL: &'static str = r#"{"retrieveType":true, "retrieveValue":true, "retrieveTags":true, "retrieveTotalCount":true}"#;
pub const TAGS_EMPTY: &'static str = r#"{}"#;
pub const TAGS: &'static str = r#"{"tagName1":"str1","~tagName2":"5","~tagName3":"8"}"#;
pub const TAGS_2: &'static str = r#"{"tagName1":"str2","~tagName2":"pre_str3","~tagName3":"2"}"#;
pub const TAGS_3: &'static str = r#"{"tagName1":"str1","tagName2":"str2","tagName3":"str3"}"#;
pub const TAGS_4: &'static str = r#"{"tagName1":"somestr","~tagName2":"4","~tagName3":"5"}"#;
pub const TAGS_5: &'static str = r#"{"tagName1":"prefix_str2","~tagName2":"str3","~tagName3":"6"}"#;

pub struct NonSecretsUtils {}

impl NonSecretsUtils {
    pub fn add_wallet_record(wallet_handle: i32, type_: &str, id: &str, value: &str, tags_json: Option<&str>) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let value = CString::new(value).unwrap();
        let tags_json_str = tags_json.map(|s| CString::new(s).unwrap()).unwrap_or(CString::new("").unwrap());

        let err =
            indy_add_wallet_record(command_handle,
                                   wallet_handle,
                                   type_.as_ptr(),
                                   id.as_ptr(),
                                   value.as_ptr(),
                                   if tags_json.is_some() { tags_json_str.as_ptr() } else { null() },
                                   cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn update_wallet_record_value(wallet_handle: i32, type_: &str, id: &str, value: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let value = CString::new(value).unwrap();

        let err =
            indy_update_wallet_record_value(command_handle,
                                            wallet_handle,
                                            type_.as_ptr(),
                                            id.as_ptr(),
                                            value.as_ptr(),
                                            cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn update_wallet_record_tags(wallet_handle: i32, type_: &str, id: &str, tags_json: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let tags_json = CString::new(tags_json).unwrap();

        let err =
            indy_update_wallet_record_tags(command_handle,
                                           wallet_handle,
                                           type_.as_ptr(),
                                           id.as_ptr(),
                                           tags_json.as_ptr(),
                                           cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn add_wallet_record_tags(wallet_handle: i32, type_: &str, id: &str, tags_json: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let tags_json = CString::new(tags_json).unwrap();

        let err =
            indy_add_wallet_record_tags(command_handle,
                                        wallet_handle,
                                        type_.as_ptr(),
                                        id.as_ptr(),
                                        tags_json.as_ptr(),
                                        cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn delete_wallet_record_tags(wallet_handle: i32, type_: &str, id: &str, tag_names_json: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let tag_names_json = CString::new(tag_names_json).unwrap();

        let err =
            indy_delete_wallet_record_tags(command_handle,
                                           wallet_handle,
                                           type_.as_ptr(),
                                           id.as_ptr(),
                                           tag_names_json.as_ptr(),
                                           cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn delete_wallet_record(wallet_handle: i32, type_: &str, id: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();

        let err =
            indy_delete_wallet_record(command_handle,
                                      wallet_handle,
                                      type_.as_ptr(),
                                      id.as_ptr(),
                                      cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn get_wallet_record(wallet_handle: i32, type_: &str, id: &str, options_json: &str) -> Result<String, ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec_string();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let options_json = CString::new(options_json).unwrap();

        let err =
            indy_get_wallet_record(command_handle,
                                   wallet_handle,
                                   type_.as_ptr(),
                                   id.as_ptr(),
                                   options_json.as_ptr(),
                                   cb);

        super::results::result_to_string(err, receiver)
    }

    pub fn open_wallet_search(wallet_handle: i32, type_: &str, query_json: &str, options_json: &str) -> Result<i32, ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec_i32();

        let type_ = CString::new(type_).unwrap();
        let query_json = CString::new(query_json).unwrap();
        let options_json = CString::new(options_json).unwrap();

        let err =
            indy_open_wallet_search(command_handle,
                                    wallet_handle,
                                    type_.as_ptr(),
                                    query_json.as_ptr(),
                                    options_json.as_ptr(),
                                    cb);

        super::results::result_to_int(err, receiver)
    }

    pub fn fetch_wallet_search_next_records(wallet_handle: i32, wallet_search_handle: i32, count: usize) -> Result<String, ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec_string();

        let err =
            indy_fetch_wallet_search_next_records(command_handle,
                                                  wallet_handle,
                                                  wallet_search_handle,
                                                  count,
                                                  cb);

        super::results::result_to_string(err, receiver)
    }

    pub fn close_wallet_search(wallet_search_handle: i32) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let err =
            indy_close_wallet_search(command_handle,
                                     wallet_search_handle,
                                     cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn tags_1() -> HashMap<String, String> {
        serde_json::from_str(TAGS).unwrap()
    }

    pub fn tags_2() -> HashMap<String, String> {
        serde_json::from_str(TAGS_2).unwrap()
    }

    pub fn tags_3() -> HashMap<String, String> {
        serde_json::from_str(TAGS_3).unwrap()
    }

    pub fn tags_4() -> HashMap<String, String> {
        serde_json::from_str(TAGS_4).unwrap()
    }

    pub fn tags_5() -> HashMap<String, String> {
        serde_json::from_str(TAGS_5).unwrap()
    }

    pub fn record_1() -> WalletRecord {
        WalletRecord { id: ID.to_string(), type_: None, value: Some(VALUE.to_string()), tags: Some(NonSecretsUtils::tags_1()) }
    }

    pub fn record_2() -> WalletRecord {
        WalletRecord { id: ID_2.to_string(), type_: None, value: Some(VALUE_2.to_string()), tags: Some(NonSecretsUtils::tags_2()) }
    }

    pub fn record_3() -> WalletRecord {
        WalletRecord { id: ID_3.to_string(), type_: None, value: Some(VALUE_3.to_string()), tags: Some(NonSecretsUtils::tags_3()) }
    }

    pub fn record_4() -> WalletRecord {
        WalletRecord { id: ID_4.to_string(), type_: None, value: Some(VALUE_4.to_string()), tags: Some(NonSecretsUtils::tags_4()) }
    }

    pub fn record_5() -> WalletRecord {
        WalletRecord { id: ID_5.to_string(), type_: None, value: Some(VALUE_5.to_string()), tags: Some(NonSecretsUtils::tags_5()) }
    }

    pub fn populate_wallet_for_search() {
        lazy_static! {
                    static ref COMMON_WALLET_INIT: Once = ONCE_INIT;

                }

        COMMON_WALLET_INIT.call_once(|| {
            TestUtils::cleanup_storage();

            //1. Create and Open wallet
            WalletUtils::create_wallet(POOL, SEARCH_COMMON_WALLET, None, None, None).unwrap();
            let wallet_handle = WalletUtils::open_wallet(SEARCH_COMMON_WALLET, None, None).unwrap();

            let record_1 = NonSecretsUtils::record_1();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_1.id,
                                               &record_1.value.clone().unwrap(),
                                               Some(TAGS)).unwrap();

            let record_2 = NonSecretsUtils::record_2();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_2.id,
                                               &record_2.value.clone().unwrap(),
                                               Some(TAGS_2)).unwrap();

            let record_3 = NonSecretsUtils::record_3();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_3.id,
                                               &record_3.value.clone().unwrap(),
                                               Some(TAGS_3)).unwrap();

            let record_4 = NonSecretsUtils::record_4();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_4.id,
                                               &record_4.value.clone().unwrap(),
                                               Some(TAGS_4)).unwrap();

            let record_5 = NonSecretsUtils::record_5();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_5.id,
                                               &record_5.value.clone().unwrap(),
                                               Some(TAGS_5)).unwrap();

            WalletUtils::close_wallet(wallet_handle).unwrap();
        });
    }
}<commit_msg>Fixed tests which request type<commit_after>extern crate serde_json;

use indy::api::ErrorCode;
use indy::api::non_secrets::*;

use utils::callback::CallbackUtils;
use utils::wallet::WalletUtils;
use utils::constants::POOL;
use utils::test::TestUtils;
use utils::types::WalletRecord;

use std::ffi::CString;
use std::ptr::null;
use std::sync::{Once, ONCE_INIT};
use std::collections::HashMap;

pub const SEARCH_COMMON_WALLET: &'static str = "SEARCH_COMMON_WALLET";
pub const TYPE: &'static str = "TestType";
pub const TYPE_2: &'static str = "TestType2";
pub const ID: &'static str = "RecordId";
pub const ID_2: &'static str = "RecordId2";
pub const ID_3: &'static str = "RecordId3";
pub const ID_4: &'static str = "RecordId4";
pub const ID_5: &'static str = "RecordId5";
pub const VALUE: &'static str = "RecordValue";
pub const VALUE_2: &'static str = "RecordValue2";
pub const VALUE_3: &'static str = "RecordValue3";
pub const VALUE_4: &'static str = "RecordValue4";
pub const VALUE_5: &'static str = "RecordValue5";
pub const QUERY_EMPTY: &'static str = r#"{}"#;
pub const OPTIONS_EMPTY: &'static str = r#"{}"#;
pub const OPTIONS_ID_TYPE_VALUE: &'static str = r#"{"retrieveType":true, "retrieveValue":true, "retrieveTags":false}"#;
pub const OPTIONS_FULL: &'static str = r#"{"retrieveType":true, "retrieveValue":true, "retrieveTags":true, "retrieveTotalCount":true}"#;
pub const TAGS_EMPTY: &'static str = r#"{}"#;
pub const TAGS: &'static str = r#"{"tagName1":"str1","~tagName2":"5","~tagName3":"8"}"#;
pub const TAGS_2: &'static str = r#"{"tagName1":"str2","~tagName2":"pre_str3","~tagName3":"2"}"#;
pub const TAGS_3: &'static str = r#"{"tagName1":"str1","tagName2":"str2","tagName3":"str3"}"#;
pub const TAGS_4: &'static str = r#"{"tagName1":"somestr","~tagName2":"4","~tagName3":"5"}"#;
pub const TAGS_5: &'static str = r#"{"tagName1":"prefix_str2","~tagName2":"str3","~tagName3":"6"}"#;

pub struct NonSecretsUtils {}

impl NonSecretsUtils {
    pub fn add_wallet_record(wallet_handle: i32, type_: &str, id: &str, value: &str, tags_json: Option<&str>) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let value = CString::new(value).unwrap();
        let tags_json_str = tags_json.map(|s| CString::new(s).unwrap()).unwrap_or(CString::new("").unwrap());

        let err =
            indy_add_wallet_record(command_handle,
                                   wallet_handle,
                                   type_.as_ptr(),
                                   id.as_ptr(),
                                   value.as_ptr(),
                                   if tags_json.is_some() { tags_json_str.as_ptr() } else { null() },
                                   cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn update_wallet_record_value(wallet_handle: i32, type_: &str, id: &str, value: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let value = CString::new(value).unwrap();

        let err =
            indy_update_wallet_record_value(command_handle,
                                            wallet_handle,
                                            type_.as_ptr(),
                                            id.as_ptr(),
                                            value.as_ptr(),
                                            cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn update_wallet_record_tags(wallet_handle: i32, type_: &str, id: &str, tags_json: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let tags_json = CString::new(tags_json).unwrap();

        let err =
            indy_update_wallet_record_tags(command_handle,
                                           wallet_handle,
                                           type_.as_ptr(),
                                           id.as_ptr(),
                                           tags_json.as_ptr(),
                                           cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn add_wallet_record_tags(wallet_handle: i32, type_: &str, id: &str, tags_json: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let tags_json = CString::new(tags_json).unwrap();

        let err =
            indy_add_wallet_record_tags(command_handle,
                                        wallet_handle,
                                        type_.as_ptr(),
                                        id.as_ptr(),
                                        tags_json.as_ptr(),
                                        cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn delete_wallet_record_tags(wallet_handle: i32, type_: &str, id: &str, tag_names_json: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let tag_names_json = CString::new(tag_names_json).unwrap();

        let err =
            indy_delete_wallet_record_tags(command_handle,
                                           wallet_handle,
                                           type_.as_ptr(),
                                           id.as_ptr(),
                                           tag_names_json.as_ptr(),
                                           cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn delete_wallet_record(wallet_handle: i32, type_: &str, id: &str) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();

        let err =
            indy_delete_wallet_record(command_handle,
                                      wallet_handle,
                                      type_.as_ptr(),
                                      id.as_ptr(),
                                      cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn get_wallet_record(wallet_handle: i32, type_: &str, id: &str, options_json: &str) -> Result<String, ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec_string();

        let type_ = CString::new(type_).unwrap();
        let id = CString::new(id).unwrap();
        let options_json = CString::new(options_json).unwrap();

        let err =
            indy_get_wallet_record(command_handle,
                                   wallet_handle,
                                   type_.as_ptr(),
                                   id.as_ptr(),
                                   options_json.as_ptr(),
                                   cb);

        super::results::result_to_string(err, receiver)
    }

    pub fn open_wallet_search(wallet_handle: i32, type_: &str, query_json: &str, options_json: &str) -> Result<i32, ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec_i32();

        let type_ = CString::new(type_).unwrap();
        let query_json = CString::new(query_json).unwrap();
        let options_json = CString::new(options_json).unwrap();

        let err =
            indy_open_wallet_search(command_handle,
                                    wallet_handle,
                                    type_.as_ptr(),
                                    query_json.as_ptr(),
                                    options_json.as_ptr(),
                                    cb);

        super::results::result_to_int(err, receiver)
    }

    pub fn fetch_wallet_search_next_records(wallet_handle: i32, wallet_search_handle: i32, count: usize) -> Result<String, ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec_string();

        let err =
            indy_fetch_wallet_search_next_records(command_handle,
                                                  wallet_handle,
                                                  wallet_search_handle,
                                                  count,
                                                  cb);

        super::results::result_to_string(err, receiver)
    }

    pub fn close_wallet_search(wallet_search_handle: i32) -> Result<(), ErrorCode> {
        let (receiver, command_handle, cb) = CallbackUtils::_closure_to_cb_ec();

        let err =
            indy_close_wallet_search(command_handle,
                                     wallet_search_handle,
                                     cb);

        super::results::result_to_empty(err, receiver)
    }

    pub fn tags_1() -> HashMap<String, String> {
        serde_json::from_str(TAGS).unwrap()
    }

    pub fn tags_2() -> HashMap<String, String> {
        serde_json::from_str(TAGS_2).unwrap()
    }

    pub fn tags_3() -> HashMap<String, String> {
        serde_json::from_str(TAGS_3).unwrap()
    }

    pub fn tags_4() -> HashMap<String, String> {
        serde_json::from_str(TAGS_4).unwrap()
    }

    pub fn tags_5() -> HashMap<String, String> {
        serde_json::from_str(TAGS_5).unwrap()
    }

    pub fn record_1() -> WalletRecord {
        WalletRecord { id: ID.to_string(), type_: Some(TYPE.to_string()), value: Some(VALUE.to_string()), tags: Some(NonSecretsUtils::tags_1()) }
    }

    pub fn record_2() -> WalletRecord {
        WalletRecord { id: ID_2.to_string(), type_: Some(TYPE.to_string()), value: Some(VALUE_2.to_string()), tags: Some(NonSecretsUtils::tags_2()) }
    }

    pub fn record_3() -> WalletRecord {
        WalletRecord { id: ID_3.to_string(), type_: Some(TYPE.to_string()), value: Some(VALUE_3.to_string()), tags: Some(NonSecretsUtils::tags_3()) }
    }

    pub fn record_4() -> WalletRecord {
        WalletRecord { id: ID_4.to_string(), type_: Some(TYPE.to_string()), value: Some(VALUE_4.to_string()), tags: Some(NonSecretsUtils::tags_4()) }
    }

    pub fn record_5() -> WalletRecord {
        WalletRecord { id: ID_5.to_string(), type_: Some(TYPE.to_string()), value: Some(VALUE_5.to_string()), tags: Some(NonSecretsUtils::tags_5()) }
    }

    pub fn populate_wallet_for_search() {
        lazy_static! {
                    static ref COMMON_WALLET_INIT: Once = ONCE_INIT;

                }

        COMMON_WALLET_INIT.call_once(|| {
            TestUtils::cleanup_storage();

            //1. Create and Open wallet
            WalletUtils::create_wallet(POOL, SEARCH_COMMON_WALLET, None, None, None).unwrap();
            let wallet_handle = WalletUtils::open_wallet(SEARCH_COMMON_WALLET, None, None).unwrap();

            let record_1 = NonSecretsUtils::record_1();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_1.id,
                                               &record_1.value.clone().unwrap(),
                                               Some(TAGS)).unwrap();

            let record_2 = NonSecretsUtils::record_2();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_2.id,
                                               &record_2.value.clone().unwrap(),
                                               Some(TAGS_2)).unwrap();

            let record_3 = NonSecretsUtils::record_3();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_3.id,
                                               &record_3.value.clone().unwrap(),
                                               Some(TAGS_3)).unwrap();

            let record_4 = NonSecretsUtils::record_4();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_4.id,
                                               &record_4.value.clone().unwrap(),
                                               Some(TAGS_4)).unwrap();

            let record_5 = NonSecretsUtils::record_5();
            NonSecretsUtils::add_wallet_record(wallet_handle,
                                               TYPE,
                                               &record_5.id,
                                               &record_5.value.clone().unwrap(),
                                               Some(TAGS_5)).unwrap();

            WalletUtils::close_wallet(wallet_handle).unwrap();
        });
    }
}<|endoftext|>


<commit_before>use std::io::Write;
use std::fmt::Display;
use serde::ser::{self, Impossible, Serialize};
use error::Error;

pub fn serialize<W: Write, S: Serialize>(value: S, writer: W) -> Result<(), Error> {
    let mut ser = Serializer::new(writer);
    value.serialize(&mut ser)
}

/// An XML Serializer.
pub struct Serializer<W>
    where W: Write
{
    writer: W,
}

impl<W> Serializer<W>
    where W: Write
{
    pub fn new(writer: W) -> Self {
        Self { writer: writer }
    }

    fn write_primitive<P: Display>(&mut self, primitive: P) -> Result<(), Error> {
        write!(self.writer, "{}", primitive)
            .map(|_| ())
            .map_err(|e| e.into())
    }

    fn write_wrapped<S: Serialize>(&mut self, tag: &str, value: S) -> Result<(), Error> {
        write!(self.writer, "<{}>", tag)?;
        value.serialize(&mut *self)?;
        write!(self.writer, "</{}>", tag)?;
        Ok(())
    }
}

#[allow(unused_variables)]
impl<'w, W> ser::Serializer for &'w mut Serializer<W>
    where W: Write
{
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
    type SerializeMap = Map<'w, W>;
    type SerializeStruct = Struct<'w, W>;
    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;

    fn serialize_bool(mut self, v: bool) -> Result<Self::Ok, Self::Error> {
        if v {
            write!(self.writer, "true")?;
        } else {
            write!(self.writer, "false")?;
        }

        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(value)
    }

    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
        // TODO: I imagine you'd want to use base64 here.
        // Not sure how to roundtrip effectively though...
        Err(Error::UnsupportedOperation("serialize_bytes".to_string()))
    }

    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
        self.serialize_none()
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
        self.write_wrapped(name, ())
    }

    fn serialize_unit_variant(self,
                              name: &'static str,
                              variant_index: usize,
                              variant: &'static str)
                              -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_unit_variant".to_string()))
    }

    fn serialize_newtype_struct<T: ?Sized + Serialize>(self,
                                                       name: &'static str,
                                                       value: &T)
                                                       -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_newtype_struct".to_string()))
    }

    fn serialize_newtype_variant<T: ?Sized + Serialize>(self,
                                                        name: &'static str,
                                                        variant_index: usize,
                                                        variant: &'static str,
                                                        value: &T)
                                                        -> Result<Self::Ok, Self::Error> {
        self.write_wrapped(name, value)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        // TODO: Figure out how to constrain the things written to only be composites
        Err(Error::UnsupportedOperation("serialize_seq".to_string()))
    }

    fn serialize_seq_fixed_size(self, size: usize) -> Result<Self::SerializeSeq, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_seq_fixed_size".to_string()))
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple".to_string()))
    }

    fn serialize_tuple_struct(self,
                              name: &'static str,
                              len: usize)
                              -> Result<Self::SerializeTupleStruct, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_struct".to_string()))
    }

    fn serialize_tuple_variant(self,
                               name: &'static str,
                               variant_index: usize,
                               variant: &'static str,
                               len: usize)
                               -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_variant".to_string()))
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Ok(Map { parent: self })
    }

    fn serialize_struct(self,
                        name: &'static str,
                        len: usize)
                        -> Result<Self::SerializeStruct, Self::Error> {
        write!(self.writer, "<{}>", name)?;
        Ok(Struct {
               parent: self,
               name: name,
           })
    }

    fn serialize_struct_variant(self,
                                name: &'static str,
                                variant_index: usize,
                                variant: &'static str,
                                len: usize)
                                -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(Error::UnsupportedOperation("Result".to_string()))
    }
}

/// An implementation of SerializeStruct for serializing to XML.
pub struct Struct<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
    name: &'w str,
}

impl<'w, W> ser::SerializeStruct for Struct<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized + Serialize>(&mut self,
                                              key: &'static str,
                                              value: &T)
                                              -> Result<(), Self::Error> {
        write!(self.parent.writer, "<{}>", key)?;
        value.serialize(&mut *self.parent)?;
        write!(self.parent.writer, "</{}>", key)?;
        Ok(())
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        write!(self.parent.writer, "</{}>", self.name).map_err(|e| e.into())
    }
}

/// An implementation of SerializeMap for serializing to XML.
pub struct Map<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
}

impl<'w, W> ser::SerializeMap for Map<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<(), Self::Error> {
        panic!("impossible to serialize the key on its own, please use serialize_entry()")
    }

    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
        value.serialize(&mut *self.parent)
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>(&mut self,
                                                                     key: &K,
                                                                     value: &V)
                                                                     -> Result<(), Self::Error> {
        // TODO: Is it possible to ensure our key is never a composite type?
        // Anything which isn't a "primitive" would lead to malformed XML here...
        write!(self.parent.writer, "<")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;

        value.serialize(&mut *self.parent)?;

        write!(self.parent.writer, "</")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde::Serializer as SerSerializer;
    use serde::ser::{SerializeMap, SerializeStruct};

    #[test]
    fn test_serialize_bool() {
        let inputs = vec![(true, "true"), (false, "false")];

        for (src, should_be) in inputs {
            let mut buffer = Vec::new();

            {
                let mut ser = Serializer::new(&mut buffer);
                ser.serialize_bool(src).unwrap();
            }

            let got = String::from_utf8(buffer).unwrap();
            assert_eq!(got, should_be);
        }
    }

    #[test]
    fn test_start_serialize_struct() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let _ = ser.serialize_struct("foo", 0).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>");
    }

    #[test]
    fn test_serialize_struct_field() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut struct_ser = Struct {
                parent: &mut ser,
                name: "baz",
            };
            struct_ser.serialize_field("foo", "bar").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>bar</foo>");
    }

    #[test]
    fn test_serialize_struct() {
        #[derive(Serialize)]
        struct Person {
            name: String,
            age: u32,
        }

        let bob = Person {
            name: "Bob".to_string(),
            age: 42,
        };
        let should_be = "<Person><name>Bob</name><age>42</age></Person>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            bob.serialize(&mut ser).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }

    #[test]
    fn test_serialize_map_entries() {
        let should_be = "<name>Bob</name><age>5</age>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut map = Map { parent: &mut ser };
            map.serialize_entry("name", "Bob").unwrap();
            map.serialize_entry("age", "5").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }

    #[test]
    fn test_serialize_enum() {
        #[derive(Serialize)]
        enum Node {
            Boolean(bool),
            Number(f64),
            String(String),
        }

        let mut buffer = Vec::new();
        let should_be = "<Boolean>true</Boolean>";

        {
            let mut ser = Serializer::new(&mut buffer);
            let node = Node::Boolean(true);
            node.serialize(&mut ser).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }
}
<commit_msg>Added documentation to the generic serialize method<commit_after>use std::io::Write;
use std::fmt::Display;
use serde::ser::{self, Impossible, Serialize};
use error::Error;

/// A convenience method for serializing some object to a buffer.
///
/// You'll almost always want to use this over any of the other things in the
/// `serde_xml_rs::serialize` module.
///
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// # extern crate serde;
/// # extern crate serde_xml_rs;
/// # use serde_xml_rs::serialize;
/// #[derive(Serialize)]
/// struct Person {
///   name: String,
///   age: u32,
/// }
///
/// # fn main() {
/// let mut buffer = Vec::new();
/// let joe = Person {name: "Joe".to_string(), age: 42};
///
/// serialize(&joe, &mut buffer).unwrap();
///
/// let serialized = String::from_utf8(buffer).unwrap();
/// println!("{}", serialized);
/// # }
/// ```
pub fn serialize<W: Write, S: Serialize>(value: S, writer: W) -> Result<(), Error> {
    let mut ser = Serializer::new(writer);
    value.serialize(&mut ser)
}

/// An XML Serializer.
pub struct Serializer<W>
    where W: Write
{
    writer: W,
}

impl<W> Serializer<W>
    where W: Write
{
    pub fn new(writer: W) -> Self {
        Self { writer: writer }
    }

    fn write_primitive<P: Display>(&mut self, primitive: P) -> Result<(), Error> {
        write!(self.writer, "{}", primitive)
            .map(|_| ())
            .map_err(|e| e.into())
    }

    fn write_wrapped<S: Serialize>(&mut self, tag: &str, value: S) -> Result<(), Error> {
        write!(self.writer, "<{}>", tag)?;
        value.serialize(&mut *self)?;
        write!(self.writer, "</{}>", tag)?;
        Ok(())
    }
}

#[allow(unused_variables)]
impl<'w, W> ser::Serializer for &'w mut Serializer<W>
    where W: Write
{
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
    type SerializeMap = Map<'w, W>;
    type SerializeStruct = Struct<'w, W>;
    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;

    fn serialize_bool(mut self, v: bool) -> Result<Self::Ok, Self::Error> {
        if v {
            write!(self.writer, "true")?;
        } else {
            write!(self.writer, "false")?;
        }

        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(value)
    }

    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
        // TODO: I imagine you'd want to use base64 here.
        // Not sure how to roundtrip effectively though...
        Err(Error::UnsupportedOperation("serialize_bytes".to_string()))
    }

    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
        self.serialize_none()
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
        self.write_wrapped(name, ())
    }

    fn serialize_unit_variant(self,
                              name: &'static str,
                              variant_index: usize,
                              variant: &'static str)
                              -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_unit_variant".to_string()))
    }

    fn serialize_newtype_struct<T: ?Sized + Serialize>(self,
                                                       name: &'static str,
                                                       value: &T)
                                                       -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_newtype_struct".to_string()))
    }

    fn serialize_newtype_variant<T: ?Sized + Serialize>(self,
                                                        name: &'static str,
                                                        variant_index: usize,
                                                        variant: &'static str,
                                                        value: &T)
                                                        -> Result<Self::Ok, Self::Error> {
        self.write_wrapped(name, value)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        // TODO: Figure out how to constrain the things written to only be composites
        Err(Error::UnsupportedOperation("serialize_seq".to_string()))
    }

    fn serialize_seq_fixed_size(self, size: usize) -> Result<Self::SerializeSeq, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_seq_fixed_size".to_string()))
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple".to_string()))
    }

    fn serialize_tuple_struct(self,
                              name: &'static str,
                              len: usize)
                              -> Result<Self::SerializeTupleStruct, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_struct".to_string()))
    }

    fn serialize_tuple_variant(self,
                               name: &'static str,
                               variant_index: usize,
                               variant: &'static str,
                               len: usize)
                               -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_variant".to_string()))
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Ok(Map { parent: self })
    }

    fn serialize_struct(self,
                        name: &'static str,
                        len: usize)
                        -> Result<Self::SerializeStruct, Self::Error> {
        write!(self.writer, "<{}>", name)?;
        Ok(Struct {
               parent: self,
               name: name,
           })
    }

    fn serialize_struct_variant(self,
                                name: &'static str,
                                variant_index: usize,
                                variant: &'static str,
                                len: usize)
                                -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(Error::UnsupportedOperation("Result".to_string()))
    }
}

/// An implementation of SerializeStruct for serializing to XML.
pub struct Struct<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
    name: &'w str,
}

impl<'w, W> ser::SerializeStruct for Struct<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized + Serialize>(&mut self,
                                              key: &'static str,
                                              value: &T)
                                              -> Result<(), Self::Error> {
        write!(self.parent.writer, "<{}>", key)?;
        value.serialize(&mut *self.parent)?;
        write!(self.parent.writer, "</{}>", key)?;
        Ok(())
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        write!(self.parent.writer, "</{}>", self.name).map_err(|e| e.into())
    }
}

/// An implementation of SerializeMap for serializing to XML.
pub struct Map<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
}

impl<'w, W> ser::SerializeMap for Map<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<(), Self::Error> {
        panic!("impossible to serialize the key on its own, please use serialize_entry()")
    }

    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
        value.serialize(&mut *self.parent)
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>(&mut self,
                                                                     key: &K,
                                                                     value: &V)
                                                                     -> Result<(), Self::Error> {
        // TODO: Is it possible to ensure our key is never a composite type?
        // Anything which isn't a "primitive" would lead to malformed XML here...
        write!(self.parent.writer, "<")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;

        value.serialize(&mut *self.parent)?;

        write!(self.parent.writer, "</")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde::Serializer as SerSerializer;
    use serde::ser::{SerializeMap, SerializeStruct};

    #[test]
    fn test_serialize_bool() {
        let inputs = vec![(true, "true"), (false, "false")];

        for (src, should_be) in inputs {
            let mut buffer = Vec::new();

            {
                let mut ser = Serializer::new(&mut buffer);
                ser.serialize_bool(src).unwrap();
            }

            let got = String::from_utf8(buffer).unwrap();
            assert_eq!(got, should_be);
        }
    }

    #[test]
    fn test_start_serialize_struct() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let _ = ser.serialize_struct("foo", 0).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>");
    }

    #[test]
    fn test_serialize_struct_field() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut struct_ser = Struct {
                parent: &mut ser,
                name: "baz",
            };
            struct_ser.serialize_field("foo", "bar").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>bar</foo>");
    }

    #[test]
    fn test_serialize_struct() {
        #[derive(Serialize)]
        struct Person {
            name: String,
            age: u32,
        }

        let bob = Person {
            name: "Bob".to_string(),
            age: 42,
        };
        let should_be = "<Person><name>Bob</name><age>42</age></Person>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            bob.serialize(&mut ser).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }

    #[test]
    fn test_serialize_map_entries() {
        let should_be = "<name>Bob</name><age>5</age>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut map = Map { parent: &mut ser };
            map.serialize_entry("name", "Bob").unwrap();
            map.serialize_entry("age", "5").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }

    #[test]
    fn test_serialize_enum() {
        #[derive(Serialize)]
        enum Node {
            Boolean(bool),
            Number(f64),
            String(String),
        }

        let mut buffer = Vec::new();
        let should_be = "<Boolean>true</Boolean>";

        {
            let mut ser = Serializer::new(&mut buffer);
            let node = Node::Boolean(true);
            node.serialize(&mut ser).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }
}
<|endoftext|>


<commit_before>pub mod foreign_items;
pub mod intrinsics;
pub mod tls;
pub mod dlsym;
pub mod env;

use rustc::{ty, mir};

use crate::*;

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    fn find_fn(
        &mut self,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx, Tag>],
        dest: Option<PlaceTy<'tcx, Tag>>,
        ret: Option<mir::BasicBlock>,
    ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
        let this = self.eval_context_mut();
        trace!("eval_fn_call: {:#?}, {:?}", instance, dest.map(|place| *place));

        // First, run the common hooks also supported by CTFE.
        if this.hook_fn(instance, args, dest)? {
            this.goto_block(ret)?;
            return Ok(None);
        }
        // There are some more lang items we want to hook that CTFE does not hook (yet).
        if this.tcx.lang_items().align_offset_fn() == Some(instance.def.def_id()) {

            let n = {
                let ptr = this.force_ptr(this.read_scalar(args[0])?.not_undef()?)?;
                let align = this.force_bits(
                    this.read_scalar(args[1])?.not_undef()?,
                    this.pointer_size()
                )? as usize;

                let stride = this.memory().get(ptr.alloc_id)?.align.bytes() as usize;
                // if the allocation alignment is at least the required alignment, we use the
                // libcore implementation
                if stride >= align {
                    ((stride + ptr.offset.bytes() as usize) as *const ())
                        .align_offset(align) as u128
                } else {
                    u128::max_value()
                }
            };

            let dest = dest.unwrap();
            let n = this.truncate(n, dest.layout);
            this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
            this.goto_block(ret)?;
            return Ok(None);
        }

        // Try to see if we can do something about foreign items.
        if this.tcx.is_foreign_item(instance.def_id()) {
            // An external function that we cannot find MIR for, but we can still run enough
            // of them to make miri viable.
            this.emulate_foreign_item(instance.def_id(), args, dest, ret)?;
            // `goto_block` already handled.
            return Ok(None);
        }

        // Otherwise, load the MIR.
        Ok(Some(this.load_mir(instance.def, None)?))
    }
}
<commit_msg>Add align_offset for integers<commit_after>pub mod foreign_items;
pub mod intrinsics;
pub mod tls;
pub mod dlsym;
pub mod env;

use rustc::{ty, mir};

use crate::*;

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    fn find_fn(
        &mut self,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx, Tag>],
        dest: Option<PlaceTy<'tcx, Tag>>,
        ret: Option<mir::BasicBlock>,
    ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
        let this = self.eval_context_mut();
        trace!("eval_fn_call: {:#?}, {:?}", instance, dest.map(|place| *place));

        // First, run the common hooks also supported by CTFE.
        if this.hook_fn(instance, args, dest)? {
            this.goto_block(ret)?;
            return Ok(None);
        }
        // There are some more lang items we want to hook that CTFE does not hook (yet).
        if this.tcx.lang_items().align_offset_fn() == Some(instance.def.def_id()) {
            let n = this.align_offset(args[0], args[1])?;
            let dest = dest.unwrap();
            let n = this.truncate(n, dest.layout);
            this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
            this.goto_block(ret)?;
            return Ok(None);
        }

        // Try to see if we can do something about foreign items.
        if this.tcx.is_foreign_item(instance.def_id()) {
            // An external function that we cannot find MIR for, but we can still run enough
            // of them to make miri viable.
            this.emulate_foreign_item(instance.def_id(), args, dest, ret)?;
            // `goto_block` already handled.
            return Ok(None);
        }

        // Otherwise, load the MIR.
        Ok(Some(this.load_mir(instance.def, None)?))
    }

    fn align_offset(
        &mut self,
        ptr_op: OpTy<'tcx, Tag>,
        align_op: OpTy<'tcx, Tag>
    ) -> InterpResult<'tcx, u128> {
        let this = self.eval_context_mut();

        let req_align = this.force_bits(
            this.read_scalar(align_op)?.not_undef()?,
            this.pointer_size()
        )? as usize;

        let ptr_scalar = this.read_scalar(ptr_op)?.not_undef()?;

        if let Scalar::Ptr(ptr) = ptr_scalar {
            let cur_align = this.memory().get(ptr.alloc_id)?.align.bytes() as usize;
            if cur_align < req_align {
                return Ok(u128::max_value());
            }
        }

        // if the allocation alignment is at least the required alignment or if the pointer is an
        // integer, we use the libcore implementation
        Ok(
            (this.force_bits(ptr_scalar, this.pointer_size())? as *const i8)
            .align_offset(req_align) as u128
        )
    }
}
<|endoftext|>


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

use rustc_target::abi::LayoutOf;
use rustc::{ty, ty::layout::HasDataLayout, mir};

use crate::{
    InterpResult, InterpError, StackPopCleanup,
    MPlaceTy, Scalar, Tag,
};

pub type TlsKey = u128;

#[derive(Copy, Clone, Debug)]
pub struct TlsEntry<'tcx> {
    /// The data for this key. None is used to represent NULL.
    /// (We normalize this early to avoid having to do a NULL-ptr-test each time we access the data.)
    /// Will eventually become a map from thread IDs to `Scalar`s, if we ever support more than one thread.
    pub(crate) data: Option<Scalar<Tag>>,
    pub(crate) dtor: Option<ty::Instance<'tcx>>,
}

#[derive(Debug)]
pub struct TlsData<'tcx> {
    /// The Key to use for the next thread-local allocation.
    pub(crate) next_key: TlsKey,

    /// pthreads-style thread-local storage.
    pub(crate) keys: BTreeMap<TlsKey, TlsEntry<'tcx>>,
}

impl<'tcx> Default for TlsData<'tcx> {
    fn default() -> Self {
        TlsData {
            next_key: 1, // start with 1 as we must not use 0 on Windows
            keys: Default::default(),
        }
    }
}

impl<'tcx> TlsData<'tcx> {
    pub fn create_tls_key(
        &mut self,
        dtor: Option<ty::Instance<'tcx>>,
    ) -> TlsKey {
        let new_key = self.next_key;
        self.next_key += 1;
        self.keys.insert(
            new_key,
            TlsEntry {
                data: None,
                dtor,
            },
        );
        trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
        new_key
    }

    pub fn delete_tls_key(&mut self, key: TlsKey) -> InterpResult<'tcx> {
        match self.keys.remove(&key) {
            Some(_) => {
                trace!("TLS key {} removed", key);
                Ok(())
            }
            None => err!(TlsOutOfBounds),
        }
    }

    pub fn load_tls(
        &mut self,
        key: TlsKey,
        cx: &impl HasDataLayout,
    ) -> InterpResult<'tcx, Scalar<Tag>> {
        match self.keys.get(&key) {
            Some(&TlsEntry { data, .. }) => {
                trace!("TLS key {} loaded: {:?}", key, data);
                Ok(data.unwrap_or_else(|| Scalar::ptr_null(cx).into()))
            }
            None => err!(TlsOutOfBounds),
        }
    }

    pub fn store_tls(&mut self, key: TlsKey, new_data: Option<Scalar<Tag>>) -> InterpResult<'tcx> {
        match self.keys.get_mut(&key) {
            Some(&mut TlsEntry { ref mut data, .. }) => {
                trace!("TLS key {} stored: {:?}", key, new_data);
                *data = new_data;
                Ok(())
            }
            None => err!(TlsOutOfBounds),
        }
    }

    /// Returns a dtor, its argument and its index, if one is supposed to run
    ///
    /// An optional destructor function may be associated with each key value.
    /// At thread exit, if a key value has a non-NULL destructor pointer,
    /// and the thread has a non-NULL value associated with that key,
    /// the value of the key is set to NULL, and then the function pointed
    /// to is called with the previously associated value as its sole argument.
    /// The order of destructor calls is unspecified if more than one destructor
    /// exists for a thread when it exits.
    ///
    /// If, after all the destructors have been called for all non-NULL values
    /// with associated destructors, there are still some non-NULL values with
    /// associated destructors, then the process is repeated.
    /// If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS} iterations of destructor
    /// calls for outstanding non-NULL values, there are still some non-NULL values
    /// with associated destructors, implementations may stop calling destructors,
    /// or they may continue calling destructors until no non-NULL values with
    /// associated destructors exist, even though this might result in an infinite loop.
    fn fetch_tls_dtor(
        &mut self,
        key: Option<TlsKey>,
        cx: &impl HasDataLayout,
    ) -> Option<(ty::Instance<'tcx>, Scalar<Tag>, TlsKey)> {
        use std::collections::Bound::*;

        let thread_local = &mut self.keys;
        let start = match key {
            Some(key) => Excluded(key),
            None => Unbounded,
        };
        for (&key, &mut TlsEntry { ref mut data, dtor }) in
            thread_local.range_mut((start, Unbounded))
        {
            if let Some(ref mut data) = *data {
                if let Some(dtor) = dtor {
                    let ret = Some((dtor, *data, key));
                    *data = Scalar::ptr_null(cx);
                    return ret;
                }
            }
        }
        None
    }
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    fn run_tls_dtors(&mut self) -> InterpResult<'tcx> {
        let this = self.eval_context_mut();
        let mut dtor = this.machine.tls.fetch_tls_dtor(None, &*this.tcx);
        // FIXME: replace loop by some structure that works with stepping
        while let Some((instance, ptr, key)) = dtor {
            trace!("Running TLS dtor {:?} on {:?}", instance, ptr);
            // TODO: Potentially, this has to support all the other possible instances?
            // See eval_fn_call in interpret/terminator/mod.rs
            let mir = this.load_mir(instance.def)?;
            let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into();
            this.push_stack_frame(
                instance,
                mir.span,
                mir,
                Some(ret_place),
                StackPopCleanup::None { cleanup: true },
            )?;
            let arg_local = this.frame().body.args_iter().next().ok_or_else(
                || InterpError::AbiViolation("TLS dtor does not take enough arguments.".to_owned()),
            )?;
            let dest = this.eval_place(&mir::Place::Base(mir::PlaceBase::Local(arg_local)))?;
            this.write_scalar(ptr, dest)?;

            // step until out of stackframes
            this.run()?;

            dtor = match this.machine.tls.fetch_tls_dtor(Some(key), &*this.tcx) {
                dtor @ Some(_) => dtor,
                None => this.machine.tls.fetch_tls_dtor(None, &*this.tcx),
            };
        }
        // FIXME: On a windows target, call `unsafe extern "system" fn on_tls_callback`.
        Ok(())
    }
}
<commit_msg>fix NULL in TLS dtors<commit_after>use std::collections::BTreeMap;

use rustc_target::abi::LayoutOf;
use rustc::{ty, ty::layout::HasDataLayout, mir};

use crate::{
    InterpResult, InterpError, StackPopCleanup,
    MPlaceTy, Scalar, Tag,
    HelpersEvalContextExt,
};

pub type TlsKey = u128;

#[derive(Copy, Clone, Debug)]
pub struct TlsEntry<'tcx> {
    /// The data for this key. None is used to represent NULL.
    /// (We normalize this early to avoid having to do a NULL-ptr-test each time we access the data.)
    /// Will eventually become a map from thread IDs to `Scalar`s, if we ever support more than one thread.
    pub(crate) data: Option<Scalar<Tag>>,
    pub(crate) dtor: Option<ty::Instance<'tcx>>,
}

#[derive(Debug)]
pub struct TlsData<'tcx> {
    /// The Key to use for the next thread-local allocation.
    pub(crate) next_key: TlsKey,

    /// pthreads-style thread-local storage.
    pub(crate) keys: BTreeMap<TlsKey, TlsEntry<'tcx>>,
}

impl<'tcx> Default for TlsData<'tcx> {
    fn default() -> Self {
        TlsData {
            next_key: 1, // start with 1 as we must not use 0 on Windows
            keys: Default::default(),
        }
    }
}

impl<'tcx> TlsData<'tcx> {
    pub fn create_tls_key(
        &mut self,
        dtor: Option<ty::Instance<'tcx>>,
    ) -> TlsKey {
        let new_key = self.next_key;
        self.next_key += 1;
        self.keys.insert(
            new_key,
            TlsEntry {
                data: None,
                dtor,
            },
        );
        trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
        new_key
    }

    pub fn delete_tls_key(&mut self, key: TlsKey) -> InterpResult<'tcx> {
        match self.keys.remove(&key) {
            Some(_) => {
                trace!("TLS key {} removed", key);
                Ok(())
            }
            None => err!(TlsOutOfBounds),
        }
    }

    pub fn load_tls(
        &mut self,
        key: TlsKey,
        cx: &impl HasDataLayout,
    ) -> InterpResult<'tcx, Scalar<Tag>> {
        match self.keys.get(&key) {
            Some(&TlsEntry { data, .. }) => {
                trace!("TLS key {} loaded: {:?}", key, data);
                Ok(data.unwrap_or_else(|| Scalar::ptr_null(cx).into()))
            }
            None => err!(TlsOutOfBounds),
        }
    }

    pub fn store_tls(&mut self, key: TlsKey, new_data: Option<Scalar<Tag>>) -> InterpResult<'tcx> {
        match self.keys.get_mut(&key) {
            Some(&mut TlsEntry { ref mut data, .. }) => {
                trace!("TLS key {} stored: {:?}", key, new_data);
                *data = new_data;
                Ok(())
            }
            None => err!(TlsOutOfBounds),
        }
    }

    /// Returns a dtor, its argument and its index, if one is supposed to run
    ///
    /// An optional destructor function may be associated with each key value.
    /// At thread exit, if a key value has a non-NULL destructor pointer,
    /// and the thread has a non-NULL value associated with that key,
    /// the value of the key is set to NULL, and then the function pointed
    /// to is called with the previously associated value as its sole argument.
    /// The order of destructor calls is unspecified if more than one destructor
    /// exists for a thread when it exits.
    ///
    /// If, after all the destructors have been called for all non-NULL values
    /// with associated destructors, there are still some non-NULL values with
    /// associated destructors, then the process is repeated.
    /// If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS} iterations of destructor
    /// calls for outstanding non-NULL values, there are still some non-NULL values
    /// with associated destructors, implementations may stop calling destructors,
    /// or they may continue calling destructors until no non-NULL values with
    /// associated destructors exist, even though this might result in an infinite loop.
    fn fetch_tls_dtor(
        &mut self,
        key: Option<TlsKey>,
    ) -> Option<(ty::Instance<'tcx>, Scalar<Tag>, TlsKey)> {
        use std::collections::Bound::*;

        let thread_local = &mut self.keys;
        let start = match key {
            Some(key) => Excluded(key),
            None => Unbounded,
        };
        for (&key, &mut TlsEntry { ref mut data, dtor }) in
            thread_local.range_mut((start, Unbounded))
        {
            if let Some(data_scalar) = *data {
                if let Some(dtor) = dtor {
                    let ret = Some((dtor, data_scalar, key));
                    *data = None;
                    return ret;
                }
            }
        }
        None
    }
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    fn run_tls_dtors(&mut self) -> InterpResult<'tcx> {
        let this = self.eval_context_mut();
        let mut dtor = this.machine.tls.fetch_tls_dtor(None);
        // FIXME: replace loop by some structure that works with stepping
        while let Some((instance, ptr, key)) = dtor {
            trace!("Running TLS dtor {:?} on {:?}", instance, ptr);
            assert!(!this.is_null(ptr).unwrap(), "Data can't be NULL when dtor is called!");
            // TODO: Potentially, this has to support all the other possible instances?
            // See eval_fn_call in interpret/terminator/mod.rs
            let mir = this.load_mir(instance.def)?;
            let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into();
            this.push_stack_frame(
                instance,
                mir.span,
                mir,
                Some(ret_place),
                StackPopCleanup::None { cleanup: true },
            )?;
            let arg_local = this.frame().body.args_iter().next().ok_or_else(
                || InterpError::AbiViolation("TLS dtor does not take enough arguments.".to_owned()),
            )?;
            let dest = this.eval_place(&mir::Place::Base(mir::PlaceBase::Local(arg_local)))?;
            this.write_scalar(ptr, dest)?;

            // step until out of stackframes
            this.run()?;

            dtor = match this.machine.tls.fetch_tls_dtor(Some(key)) {
                dtor @ Some(_) => dtor,
                None => this.machine.tls.fetch_tls_dtor(None),
            };
        }
        // FIXME: On a windows target, call `unsafe extern "system" fn on_tls_callback`.
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::iter::repeat;
use std::collections::VecDeque;
use std::collections::BinaryHeap;
use std::cmp::Ordering;

fn max(a: u32, b: u32) -> u32 { if a > b { a } else { b } }

#[derive(Clone)]
struct Edge {
    vertex: u32,
    weight: f32,
}

impl Edge {
    pub fn new(vertex_: u32, weight_: f32) -> Edge {
        Edge{vertex: vertex_, weight: weight_,}
    }
}

impl Ord for Edge {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl Eq for Edge {}

//impl Eq for Edge {}

impl PartialOrd for Edge {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        (self.weight, self.vertex).partial_cmp(&(other.weight, other.vertex))
    }
}

impl PartialEq for Edge {
    fn eq(&self, other: &Self) -> bool {
        (self.weight, &self.vertex) == (other.weight, &other.vertex)
    }
}

struct Graph {
    nodes: Vec<Vec<Edge>>,
}

impl Graph {
    pub fn new() -> Graph { Graph{nodes: Vec::new(),} }

    pub fn add_edge(&mut self, src: u32, dst: u32, weight: f32) {
        let len = self.nodes.len();

        if (max(src, dst)) > len as u32 {
            let new_len = (max(src, dst) + 1) as usize;
            self.nodes.extend(repeat(Vec::new()).take(new_len - len))
        }
        self.nodes[src as usize].push(Edge::new(dst, weight));
    }
    pub fn bfs(&self, src: u32) {
        let mut queue: VecDeque<u32> = VecDeque::new();
        let len = self.nodes.len();
        let mut visited = vec!(false ; len);

        queue.push_front(src);

        while let Some(current) = queue.pop_back() {
            if !visited[current as usize] {
                println!("current: {}" , current);
                visited[current as usize] = true;
            } else { continue ; }

            for n in &self.nodes[current as usize] {
                let neighbor: u32 = n.vertex;
                queue.push_front(neighbor);
            }
        }
    }
    pub fn dfs(&self, src: u32) {
        let mut stack: Vec<u32> = Vec::new();
        let len = self.nodes.len() as usize;
        let mut visited = vec!(false ; len);

        stack.push(src);

        while let Some(current) = stack.pop() {
            if !visited[current as usize] {
                println!("current: {}" , current);
                visited[current as usize] = true;
            } else { continue ; }

            for n in &self.nodes[current as usize] {
                let neighbor: u32 = n.vertex;
                stack.push(neighbor);
            }
        }
    }

    pub fn dijkstra(&self, src: u32, dst: u32) {
      let mut dist: Vec<f32> = Vec::new();
      let mut prev: Vec<u32> = Vec::new();
      let mut q = BinaryHeap::new();
      const max_weight: f32 = std::f32::MAX;

      // init dist, prev table
      for i in 0..self.nodes.len() {
        dist.push(max_weight);
        prev.push(0);
      }

      // We're at `start`, with a zero cost
      dist[src as usize] = 0.0;
      q.push(Edge::new(src, dist[src as usize]));

      //while (!q.is_empty()) {
      while let Some(u) = q.pop() {
        //let u: Edge = el.unwrap();

        // loop for all edges connected to
        for v in self.nodes[u.vertex as usize].iter() {

          let alt: f32 = dist[u.vertex as usize] + v.weight; // accumulate shortest dist from source

          if (alt < dist[v.vertex as usize]) {
            dist[v.vertex as usize] = alt; // keep the shortest dist from src to v
            prev[v.vertex as usize] = u.vertex;

            q.push(Edge::new(v.vertex, dist[v.vertex as usize])); // Add unvisited v into the Q to be processed
          }
        }
      }

      let mut shortestPath: Vec<u32> = Vec::new();
      let mut curr: u32 = dst;

      shortestPath.push(curr);

      while (curr != src) {
        curr = prev[curr as usize];
        shortestPath.push(curr);
      }

      shortestPath.reverse();

      for v in shortestPath.iter() {
        println!("{}", v);
      }
    }
}

fn main() {
    let mut g1 = Graph::new();
    g1.add_edge(0, 1, 1.0);
    g1.add_edge(0, 2, 4.0);
    g1.add_edge(1, 0, 1.0);
    g1.add_edge(1, 2, 2.0);
    g1.add_edge(1, 3, 6.0);
    g1.add_edge(2, 0, 4.0);
    g1.add_edge(2, 1, 2.0);
    g1.add_edge(2, 3, 3.0);
    g1.add_edge(3, 1, 6.0);
    g1.add_edge(3, 2, 3.0);

    g1.bfs(3);

    println!("\n");

    g1.dfs(3);

    g1.dijkstra(0, 2);
}<commit_msg>formatted code<commit_after>use std::iter::repeat;
use std::collections::VecDeque;
use std::collections::BinaryHeap;
use std::cmp::Ordering;

fn max(a: u32, b: u32) -> u32 { if a > b { a } else { b } }

#[derive(Clone)]
struct Edge {
    vertex: u32,
    weight: f32,
}

impl Edge {
    pub fn new(vertex_: u32, weight_: f32) -> Edge {
        Edge{vertex: vertex_, weight: weight_,}
    }
}

impl Ord for Edge {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl Eq for Edge {}

impl PartialOrd for Edge {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        (self.weight, self.vertex).partial_cmp(&(other.weight, other.vertex))
    }
}

impl PartialEq for Edge {
    fn eq(&self, other: &Self) -> bool {
        (self.weight, &self.vertex) == (other.weight, &other.vertex)
    }
}

struct Graph {
    nodes: Vec<Vec<Edge>>,
}

impl Graph {
    pub fn new() -> Graph { Graph{nodes: Vec::new(),} }

    pub fn add_edge(&mut self, src: u32, dst: u32, weight: f32) {
        let len = self.nodes.len();

        if (max(src, dst)) > len as u32 {
            let new_len = (max(src, dst) + 1) as usize;
            self.nodes.extend(repeat(Vec::new()).take(new_len - len))
        }
        self.nodes[src as usize].push(Edge::new(dst, weight));
    }
    pub fn bfs(&self, src: u32) {
        let mut queue: VecDeque<u32> = VecDeque::new();
        let len = self.nodes.len();
        let mut visited = vec!(false ; len);

        queue.push_front(src);

        while let Some(current) = queue.pop_back() {
            if !visited[current as usize] {
                println!("current: {}" , current);
                visited[current as usize] = true;
            } else { continue ; }

            for n in &self.nodes[current as usize] {
                let neighbor: u32 = n.vertex;
                queue.push_front(neighbor);
            }
        }
    }
    pub fn dfs(&self, src: u32) {
        let mut stack: Vec<u32> = Vec::new();
        let len = self.nodes.len() as usize;
        let mut visited = vec!(false ; len);

        stack.push(src);

        while let Some(current) = stack.pop() {
            if !visited[current as usize] {
                println!("current: {}" , current);
                visited[current as usize] = true;
            } else { continue ; }

            for n in &self.nodes[current as usize] {
                let neighbor: u32 = n.vertex;
                stack.push(neighbor);
            }
        }
    }

    pub fn dijkstra(&self, src: u32, dst: u32) {
      let mut dist: Vec<f32> = Vec::new();
      let mut prev: Vec<u32> = Vec::new();
      let mut q = BinaryHeap::new();
      const max_weight: f32 = std::f32::MAX;

      // init dist, prev table
      for i in 0..self.nodes.len() {
        dist.push(max_weight);
        prev.push(0);
      }

      // We're at `start`, with a zero cost
      dist[src as usize] = 0.0;
      q.push(Edge::new(src, dist[src as usize]));

      //while (!q.is_empty()) {
      while let Some(u) = q.pop() {
        //let u: Edge = el.unwrap();

        // loop for all edges connected to
        for v in self.nodes[u.vertex as usize].iter() {

          let alt: f32 = dist[u.vertex as usize] + v.weight; // accumulate shortest dist from source

          if (alt < dist[v.vertex as usize]) {
            dist[v.vertex as usize] = alt; // keep the shortest dist from src to v
            prev[v.vertex as usize] = u.vertex;

            q.push(Edge::new(v.vertex, dist[v.vertex as usize])); // Add unvisited v into the Q to be processed
          }
        }
      }

      let mut shortestPath: Vec<u32> = Vec::new();
      let mut curr: u32 = dst;

      shortestPath.push(curr);

      while (curr != src) {
        curr = prev[curr as usize];
        shortestPath.push(curr);
      }

      shortestPath.reverse();

      for v in shortestPath.iter() {
        println!("{}", v);
      }
    }
}

fn main() {
    let mut g1 = Graph::new();
    g1.add_edge(0, 1, 1.0);
    g1.add_edge(0, 2, 4.0);
    g1.add_edge(1, 0, 1.0);
    g1.add_edge(1, 2, 2.0);
    g1.add_edge(1, 3, 6.0);
    g1.add_edge(2, 0, 4.0);
    g1.add_edge(2, 1, 2.0);
    g1.add_edge(2, 3, 3.0);
    g1.add_edge(3, 1, 6.0);
    g1.add_edge(3, 2, 3.0);

    g1.bfs(3);

    println!("\n");

    g1.dfs(3);

    g1.dijkstra(0, 2);
}<|endoftext|>


<commit_before>use crate::ops::Try;
use crate::iter::LoopState;

/// An iterator able to yield elements from both ends.
///
/// Something that implements `DoubleEndedIterator` has one extra capability
/// over something that implements [`Iterator`]: the ability to also take
/// `Item`s from the back, as well as the front.
///
/// It is important to note that both back and forth work on the same range,
/// and do not cross: iteration is over when they meet in the middle.
///
/// In a similar fashion to the [`Iterator`] protocol, once a
/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again
/// may or may not ever return `Some` again. `next()` and `next_back()` are
/// interchangeable for this purpose.
///
/// [`Iterator`]: trait.Iterator.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let numbers = vec![1, 2, 3, 4, 5, 6];
///
/// let mut iter = numbers.iter();
///
/// assert_eq!(Some(&1), iter.next());
/// assert_eq!(Some(&6), iter.next_back());
/// assert_eq!(Some(&5), iter.next_back());
/// assert_eq!(Some(&2), iter.next());
/// assert_eq!(Some(&3), iter.next());
/// assert_eq!(Some(&4), iter.next());
/// assert_eq!(None, iter.next());
/// assert_eq!(None, iter.next_back());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait DoubleEndedIterator: Iterator {
    /// Removes and returns an element from the end of the iterator.
    ///
    /// Returns `None` when there are no more elements.
    ///
    /// The [trait-level] docs contain more details.
    ///
    /// [trait-level]: trait.DoubleEndedIterator.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let numbers = vec![1, 2, 3, 4, 5, 6];
    ///
    /// let mut iter = numbers.iter();
    ///
    /// assert_eq!(Some(&1), iter.next());
    /// assert_eq!(Some(&6), iter.next_back());
    /// assert_eq!(Some(&5), iter.next_back());
    /// assert_eq!(Some(&2), iter.next());
    /// assert_eq!(Some(&3), iter.next());
    /// assert_eq!(Some(&4), iter.next());
    /// assert_eq!(None, iter.next());
    /// assert_eq!(None, iter.next_back());
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn next_back(&mut self) -> Option<Self::Item>;

    /// Returns the `n`th element from the end of the iterator.
    ///
    /// This is essentially the reversed version of [`nth`]. Although like most indexing
    /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro
    /// the end, `nth_back(1)` the second, and so on.
    ///
    /// Note that all elements between the end and the returned element will be
    /// consumed, including the returned element. This also means that calling
    /// `nth_back(0)` multiple times on the same iterator will return different
    /// elements.
    ///
    /// `nth_back()` will return [`None`] if `n` is greater than or equal to the length of the
    /// iterator.
    ///
    /// [`None`]: ../../std/option/enum.Option.html#variant.None
    /// [`nth`]: ../../std/iter/trait.Iterator.html#method.nth
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    /// assert_eq!(a.iter().nth_back(2), Some(&1));
    /// ```
    ///
    /// Calling `nth_back()` multiple times doesn't rewind the iterator:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// let mut iter = a.iter();
    ///
    /// assert_eq!(iter.nth_back(1), Some(&2));
    /// assert_eq!(iter.nth_back(1), None);
    /// ```
    ///
    /// Returning `None` if there are less than `n + 1` elements:
    ///
    /// ```
    /// let a = [1, 2, 3];
    /// assert_eq!(a.iter().nth_back(10), None);
    /// ```
    #[inline]
    #[stable(feature = "iter_nth_back", since = "1.37.0")]
    fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
        for x in self.rev() {
            if n == 0 { return Some(x) }
            n -= 1;
        }
        None
    }

    /// This is the reverse version of [`try_fold()`]: it takes elements
    /// starting from the back of the iterator.
    ///
    /// [`try_fold()`]: trait.Iterator.html#method.try_fold
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = ["1", "2", "3"];
    /// let sum = a.iter()
    ///     .map(|&s| s.parse::<i32>())
    ///     .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
    /// assert_eq!(sum, Ok(6));
    /// ```
    ///
    /// Short-circuiting:
    ///
    /// ```
    /// let a = ["1", "rust", "3"];
    /// let mut it = a.iter();
    /// let sum = it
    ///     .by_ref()
    ///     .map(|&s| s.parse::<i32>())
    ///     .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
    /// assert!(sum.is_err());
    ///
    /// // Because it short-circuited, the remaining elements are still
    /// // available through the iterator.
    /// assert_eq!(it.next_back(), Some(&"1"));
    /// ```
    #[inline]
    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> R,
        R: Try<Ok=B>
    {
        let mut accum = init;
        while let Some(x) = self.next_back() {
            accum = f(accum, x)?;
        }
        Try::from_ok(accum)
    }

    /// An iterator method that reduces the iterator's elements to a single,
    /// final value, starting from the back.
    ///
    /// This is the reverse version of [`fold()`]: it takes elements starting from
    /// the back of the iterator.
    ///
    /// `rfold()` takes two arguments: an initial value, and a closure with two
    /// arguments: an 'accumulator', and an element. The closure returns the value that
    /// the accumulator should have for the next iteration.
    ///
    /// The initial value is the value the accumulator will have on the first
    /// call.
    ///
    /// After applying this closure to every element of the iterator, `rfold()`
    /// returns the accumulator.
    ///
    /// This operation is sometimes called 'reduce' or 'inject'.
    ///
    /// Folding is useful whenever you have a collection of something, and want
    /// to produce a single value from it.
    ///
    /// [`fold()`]: trait.Iterator.html#method.fold
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// // the sum of all of the elements of a
    /// let sum = a.iter()
    ///            .rfold(0, |acc, &x| acc + x);
    ///
    /// assert_eq!(sum, 6);
    /// ```
    ///
    /// This example builds a string, starting with an initial value
    /// and continuing with each element from the back until the front:
    ///
    /// ```
    /// let numbers = [1, 2, 3, 4, 5];
    ///
    /// let zero = "0".to_string();
    ///
    /// let result = numbers.iter().rfold(zero, |acc, &x| {
    ///     format!("({} + {})", x, acc)
    /// });
    ///
    /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
    /// ```
    #[inline]
    #[stable(feature = "iter_rfold", since = "1.27.0")]
    fn rfold<B, F>(mut self, accum: B, f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        #[inline]
        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
            move |acc, x| Ok(f(acc, x))
        }

        self.try_rfold(accum, ok(f)).unwrap()
    }

    /// Searches for an element of an iterator from the back that satisfies a predicate.
    ///
    /// `rfind()` takes a closure that returns `true` or `false`. It applies
    /// this closure to each element of the iterator, starting at the end, and if any
    /// of them return `true`, then `rfind()` returns [`Some(element)`]. If they all return
    /// `false`, it returns [`None`].
    ///
    /// `rfind()` is short-circuiting; in other words, it will stop processing
    /// as soon as the closure returns `true`.
    ///
    /// Because `rfind()` takes a reference, and many iterators iterate over
    /// references, this leads to a possibly confusing situation where the
    /// argument is a double reference. You can see this effect in the
    /// examples below, with `&&x`.
    ///
    /// [`Some(element)`]: ../../std/option/enum.Option.html#variant.Some
    /// [`None`]: ../../std/option/enum.Option.html#variant.None
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2));
    ///
    /// assert_eq!(a.iter().rfind(|&&x| x == 5), None);
    /// ```
    ///
    /// Stopping at the first `true`:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// let mut iter = a.iter();
    ///
    /// assert_eq!(iter.rfind(|&&x| x == 2), Some(&2));
    ///
    /// // we can still use `iter`, as there are more elements.
    /// assert_eq!(iter.next_back(), Some(&1));
    /// ```
    #[inline]
    #[stable(feature = "iter_rfind", since = "1.27.0")]
    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool
    {
        #[inline]
        fn check<T>(
            mut predicate: impl FnMut(&T) -> bool,
        ) -> impl FnMut((), T) -> LoopState<(), T> {
            move |(), x| {
                if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
            }
        }

        self.try_rfold((), check(predicate)).break_value()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
    fn next_back(&mut self) -> Option<I::Item> {
        (**self).next_back()
    }
    fn nth_back(&mut self, n: usize) -> Option<I::Item> {
        (**self).nth_back(n)
    }
}
<commit_msg>Rollup merge of #63615 - jens1o:patch-1, r=jonas-schievink<commit_after>use crate::ops::Try;
use crate::iter::LoopState;

/// An iterator able to yield elements from both ends.
///
/// Something that implements `DoubleEndedIterator` has one extra capability
/// over something that implements [`Iterator`]: the ability to also take
/// `Item`s from the back, as well as the front.
///
/// It is important to note that both back and forth work on the same range,
/// and do not cross: iteration is over when they meet in the middle.
///
/// In a similar fashion to the [`Iterator`] protocol, once a
/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again
/// may or may not ever return `Some` again. `next()` and `next_back()` are
/// interchangeable for this purpose.
///
/// [`Iterator`]: trait.Iterator.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let numbers = vec![1, 2, 3, 4, 5, 6];
///
/// let mut iter = numbers.iter();
///
/// assert_eq!(Some(&1), iter.next());
/// assert_eq!(Some(&6), iter.next_back());
/// assert_eq!(Some(&5), iter.next_back());
/// assert_eq!(Some(&2), iter.next());
/// assert_eq!(Some(&3), iter.next());
/// assert_eq!(Some(&4), iter.next());
/// assert_eq!(None, iter.next());
/// assert_eq!(None, iter.next_back());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait DoubleEndedIterator: Iterator {
    /// Removes and returns an element from the end of the iterator.
    ///
    /// Returns `None` when there are no more elements.
    ///
    /// The [trait-level] docs contain more details.
    ///
    /// [trait-level]: trait.DoubleEndedIterator.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let numbers = vec![1, 2, 3, 4, 5, 6];
    ///
    /// let mut iter = numbers.iter();
    ///
    /// assert_eq!(Some(&1), iter.next());
    /// assert_eq!(Some(&6), iter.next_back());
    /// assert_eq!(Some(&5), iter.next_back());
    /// assert_eq!(Some(&2), iter.next());
    /// assert_eq!(Some(&3), iter.next());
    /// assert_eq!(Some(&4), iter.next());
    /// assert_eq!(None, iter.next());
    /// assert_eq!(None, iter.next_back());
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn next_back(&mut self) -> Option<Self::Item>;

    /// Returns the `n`th element from the end of the iterator.
    ///
    /// This is essentially the reversed version of [`nth`]. Although like most indexing
    /// operations, the count starts from zero, so `nth_back(0)` returns the first value from
    /// the end, `nth_back(1)` the second, and so on.
    ///
    /// Note that all elements between the end and the returned element will be
    /// consumed, including the returned element. This also means that calling
    /// `nth_back(0)` multiple times on the same iterator will return different
    /// elements.
    ///
    /// `nth_back()` will return [`None`] if `n` is greater than or equal to the length of the
    /// iterator.
    ///
    /// [`None`]: ../../std/option/enum.Option.html#variant.None
    /// [`nth`]: ../../std/iter/trait.Iterator.html#method.nth
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    /// assert_eq!(a.iter().nth_back(2), Some(&1));
    /// ```
    ///
    /// Calling `nth_back()` multiple times doesn't rewind the iterator:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// let mut iter = a.iter();
    ///
    /// assert_eq!(iter.nth_back(1), Some(&2));
    /// assert_eq!(iter.nth_back(1), None);
    /// ```
    ///
    /// Returning `None` if there are less than `n + 1` elements:
    ///
    /// ```
    /// let a = [1, 2, 3];
    /// assert_eq!(a.iter().nth_back(10), None);
    /// ```
    #[inline]
    #[stable(feature = "iter_nth_back", since = "1.37.0")]
    fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
        for x in self.rev() {
            if n == 0 { return Some(x) }
            n -= 1;
        }
        None
    }

    /// This is the reverse version of [`try_fold()`]: it takes elements
    /// starting from the back of the iterator.
    ///
    /// [`try_fold()`]: trait.Iterator.html#method.try_fold
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = ["1", "2", "3"];
    /// let sum = a.iter()
    ///     .map(|&s| s.parse::<i32>())
    ///     .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
    /// assert_eq!(sum, Ok(6));
    /// ```
    ///
    /// Short-circuiting:
    ///
    /// ```
    /// let a = ["1", "rust", "3"];
    /// let mut it = a.iter();
    /// let sum = it
    ///     .by_ref()
    ///     .map(|&s| s.parse::<i32>())
    ///     .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
    /// assert!(sum.is_err());
    ///
    /// // Because it short-circuited, the remaining elements are still
    /// // available through the iterator.
    /// assert_eq!(it.next_back(), Some(&"1"));
    /// ```
    #[inline]
    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> R,
        R: Try<Ok=B>
    {
        let mut accum = init;
        while let Some(x) = self.next_back() {
            accum = f(accum, x)?;
        }
        Try::from_ok(accum)
    }

    /// An iterator method that reduces the iterator's elements to a single,
    /// final value, starting from the back.
    ///
    /// This is the reverse version of [`fold()`]: it takes elements starting from
    /// the back of the iterator.
    ///
    /// `rfold()` takes two arguments: an initial value, and a closure with two
    /// arguments: an 'accumulator', and an element. The closure returns the value that
    /// the accumulator should have for the next iteration.
    ///
    /// The initial value is the value the accumulator will have on the first
    /// call.
    ///
    /// After applying this closure to every element of the iterator, `rfold()`
    /// returns the accumulator.
    ///
    /// This operation is sometimes called 'reduce' or 'inject'.
    ///
    /// Folding is useful whenever you have a collection of something, and want
    /// to produce a single value from it.
    ///
    /// [`fold()`]: trait.Iterator.html#method.fold
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// // the sum of all of the elements of a
    /// let sum = a.iter()
    ///            .rfold(0, |acc, &x| acc + x);
    ///
    /// assert_eq!(sum, 6);
    /// ```
    ///
    /// This example builds a string, starting with an initial value
    /// and continuing with each element from the back until the front:
    ///
    /// ```
    /// let numbers = [1, 2, 3, 4, 5];
    ///
    /// let zero = "0".to_string();
    ///
    /// let result = numbers.iter().rfold(zero, |acc, &x| {
    ///     format!("({} + {})", x, acc)
    /// });
    ///
    /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
    /// ```
    #[inline]
    #[stable(feature = "iter_rfold", since = "1.27.0")]
    fn rfold<B, F>(mut self, accum: B, f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        #[inline]
        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
            move |acc, x| Ok(f(acc, x))
        }

        self.try_rfold(accum, ok(f)).unwrap()
    }

    /// Searches for an element of an iterator from the back that satisfies a predicate.
    ///
    /// `rfind()` takes a closure that returns `true` or `false`. It applies
    /// this closure to each element of the iterator, starting at the end, and if any
    /// of them return `true`, then `rfind()` returns [`Some(element)`]. If they all return
    /// `false`, it returns [`None`].
    ///
    /// `rfind()` is short-circuiting; in other words, it will stop processing
    /// as soon as the closure returns `true`.
    ///
    /// Because `rfind()` takes a reference, and many iterators iterate over
    /// references, this leads to a possibly confusing situation where the
    /// argument is a double reference. You can see this effect in the
    /// examples below, with `&&x`.
    ///
    /// [`Some(element)`]: ../../std/option/enum.Option.html#variant.Some
    /// [`None`]: ../../std/option/enum.Option.html#variant.None
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2));
    ///
    /// assert_eq!(a.iter().rfind(|&&x| x == 5), None);
    /// ```
    ///
    /// Stopping at the first `true`:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// let mut iter = a.iter();
    ///
    /// assert_eq!(iter.rfind(|&&x| x == 2), Some(&2));
    ///
    /// // we can still use `iter`, as there are more elements.
    /// assert_eq!(iter.next_back(), Some(&1));
    /// ```
    #[inline]
    #[stable(feature = "iter_rfind", since = "1.27.0")]
    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool
    {
        #[inline]
        fn check<T>(
            mut predicate: impl FnMut(&T) -> bool,
        ) -> impl FnMut((), T) -> LoopState<(), T> {
            move |(), x| {
                if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
            }
        }

        self.try_rfold((), check(predicate)).break_value()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
    fn next_back(&mut self) -> Option<I::Item> {
        (**self).next_back()
    }
    fn nth_back(&mut self, n: usize) -> Option<I::Item> {
        (**self).nth_back(n)
    }
}
<|endoftext|>