<commit_before>extern crate rust_base58;
extern crate serde_json;
extern crate serde;
extern crate rmp_serde;

use settings;
use utils::httpclient;
use utils::error;
use messages::{MsgType, GeneralMessage, Bundled, bundle_for_agency};

#[derive(Clone, Serialize, Debug, PartialEq, PartialOrd)]
#[serde(rename_all = "camelCase")]
struct GetMessagesPayload{
    #[serde(rename = "@type")]
    msg_type: MsgType,
    #[serde(rename = "excludePayload")]
    exclude_payload: String,
    uids: String,
    #[serde(rename = "statusCodes")]
    status_code: String,
}

#[derive(Serialize, Debug, PartialEq, PartialOrd, Clone)]
#[serde(rename_all = "camelCase")]
pub struct GetMessages {
    #[serde(rename = "to")]
    to_did: String,
    agent_payload: String,
    #[serde(skip_serializing, default)]
    payload: GetMessagesPayload,
    #[serde(skip_serializing, default)]
    to_vk: String,
    #[serde(skip_serializing, default)]
    validate_rc: u32,
}

impl GetMessages{

    pub fn create() -> GetMessages {
        GetMessages {
            to_did: String::new(),
            to_vk: String::new(),
            payload: GetMessagesPayload{
                msg_type: MsgType { name: "GET_MSGS".to_string(), ver: "1.0".to_string(), },
                uids: String::new(),
                status_code: String::new(),
                exclude_payload: "Y".to_string(),
            },
            agent_payload: String::new(),
            validate_rc: error::SUCCESS.code_num,
        }
    }

    pub fn msg_type(&mut self, msg: &str) -> &mut Self{
        //Todo: validate msg??
        self.payload.msg_type.name = msg.to_string();
        self
    }

    pub fn uid(&mut self, uid: &str) -> &mut Self{
        //Todo: validate msg_uid??
        self.payload.uids = uid.to_string();
        self
    }

    pub fn status_code(&mut self, code: &str) -> &mut Self {
        //Todo: validate that it can be parsed to number??
        self.payload.status_code = code.to_string();
        self
    }

    pub fn include_edge_payload(&mut self, payload: &str) -> &mut Self {
        //todo: is this a json value, String??
        self.payload.exclude_payload = payload.to_string();
        self
    }

}

//Todo: Every GeneralMessage extension, duplicates code
impl GeneralMessage for GetMessages{
    type Msg = GetMessages;

    fn set_to_did(&mut self, to_did: String){
        self.to_did = to_did;
    }
    fn set_validate_rc(&mut self, rc: u32){
        self.validate_rc = rc;
    }

    fn serialize_message(&mut self) -> Result<String, u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }
        self.agent_payload = json!(self.payload).to_string();
        Ok(json!(self).to_string())
    }

    fn send(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/route", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let json_msg = self.serialize_message()?;

        match httpclient::post(&json_msg, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => Ok(response),
        }
    }

    fn set_to_vk(&mut self, to_vk: String){ self.to_vk = to_vk; }

    fn to_post(&self) -> Result<Vec<u8>,u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }

        let msg = Bundled::create(self.payload.clone()).encode()?;

        bundle_for_agency(msg, self.to_did.as_ref())
    }

    fn send_enc(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/route", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let data = match self.to_post() {
            Ok(x) => x,
            Err(x) => return Err(x),
        };

        match httpclient::post_u8(&data, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => parse_get_messages_response(&response),
        }
    }
}

fn parse_get_messages_response(response: &Vec<u8>) -> Result<String, u32> {
    Ok(String::new().to_owned())
}

#[derive(Clone, Serialize, Debug, PartialEq, PartialOrd)]
#[serde(rename_all = "camelCase")]
struct SendMessagePayload{
    #[serde(rename = "type")]
    msg_type: String,
    #[serde(rename = "msgType")]
    message: String,
    uid: String,
    status_code: String,
    edge_agent_payload: String,
    ref_msg_id: String,
}

#[derive(Serialize, Debug, PartialEq, PartialOrd, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SendMessage {
    #[serde(rename = "to")]
    to_did: String,
    agent_payload: String,
    #[serde(skip_serializing, default)]
    payload: SendMessagePayload,
    #[serde(skip_serializing, default)]
    to_vk: String,
    #[serde(skip_serializing, default)]
    validate_rc: u32,
    #[serde(rename = "refMsgId")]
    ref_msg_id: String,
    status_code: String,
}

impl SendMessage{

    pub fn create() -> SendMessage {
        SendMessage {
            to_did: String::new(),
            to_vk: String::new(),
            payload: SendMessagePayload{
                msg_type: "SEND_MSG".to_string(),
                message: String::new(),
                uid: String::new(),
                status_code: String::new(),
                edge_agent_payload: String::new(),
                ref_msg_id: String::new(),
            },
            agent_payload: String::new(),
            validate_rc: error::SUCCESS.code_num,
            ref_msg_id: String::new(),
            status_code: String::new(),
        }
    }

    pub fn msg_type(&mut self, msg: &str) -> &mut Self{
        //Todo: validate msg??
        self.payload.message = msg.to_string();
        self
    }

    pub fn uid(&mut self, uid: &str) -> &mut Self{
        //Todo: validate msg_uid??
        self.payload.uid = uid.to_string();
        self
    }

    pub fn status_code(&mut self, code: &str) -> &mut Self {
        //Todo: validate that it can be parsed to number??
        self.payload.status_code = code.to_string();
        self
    }

    pub fn edge_agent_payload(&mut self, payload: &str) -> &mut Self {
        //todo: is this a json value, String??
        self.payload.edge_agent_payload = payload.to_string();
        self
    }

    pub fn ref_msg_id(&mut self, id: &str) -> &mut Self {
        self.payload.ref_msg_id = String::from(id);
        self
    }

}

//Todo: Every GeneralMessage extension, duplicates code
impl GeneralMessage for SendMessage{
    type Msg = SendMessage;

    fn set_to_did(&mut self, to_did: String){
        self.to_did = to_did;
    }
    fn set_validate_rc(&mut self, rc: u32){
        self.validate_rc = rc;
    }

    fn serialize_message(&mut self) -> Result<String, u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }
        self.agent_payload = json!(self.payload).to_string();
        Ok(json!(self).to_string())
    }

    fn send(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/route", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let json_msg = self.serialize_message()?;
        match httpclient::post(&json_msg, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => Ok(response),
        }
    }

    fn set_to_vk(&mut self, to_vk: String){ self.to_vk = to_vk; }

    fn to_post(&self) -> Result<Vec<u8>, u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }

        let msg = Bundled::create(self.payload.clone()).encode()?;

        bundle_for_agency(msg, self.to_did.as_ref())
    }

    fn send_enc(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/msg", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let data = match self.to_post() {
            Ok(x) => x,
            Err(x) => return Err(x),
        };

        match httpclient::post_u8(&data, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => parse_send_message_response(&response),
        }
    }
}

fn parse_send_message_response(response: &Vec<u8>) -> Result<String, u32> {
    Ok(String::new().to_owned())
}

#[cfg(test)]
mod tests {
    use super::*;
    use messages::{get_messages, send_message};

    #[test]
    fn test_get_messages_set_values_and_serialize(){
        let to_did = "8XFh8yBzrpJQmNyZzgoTqB";
        let uid = "123";
        let status_code = "0";
        let payload = "Some Data";
        let msg_type = "message";
        let msg = match get_messages()
            .to(&to_did)
            .uid(&uid)
            .status_code(&status_code)
            .serialize_message(){
            Ok(x) => x.to_string(),
            Err(y) => {
             println!("Had error during message build: {}", y);
                String::from("error")
            }
        };
        assert_eq!(msg, "{\"agentPayload\":\"\
        {\\\"@type\\\":\
        {\\\"name\\\":\\\"GET_MSGS\\\",\
        \\\"ver\\\":\\\"1.0\\\"},\
        \\\"excludePayload\\\":\\\"Y\\\",\
        \\\"statusCodes\\\":\\\"0\\\",\
        \\\"uids\\\":\\\"123\\\"}\",\
        \"to\":\"8XFh8yBzrpJQmNyZzgoTqB\"}");
    }

    #[test]
    fn test_get_messages_set_invalid_did_errors_at_serialize(){
        let to_did = "A";
        let uid = "123";
        let status_code = "0";
        let payload = "Some Data";
        let mut msg = get_messages()
            .to(&to_did)
            .uid(&uid)
            .status_code(&status_code)
            .include_edge_payload(&payload).clone();

        match msg.serialize_message(){
            Ok(_) => panic!("should have had did error"),
            Err(x) => assert_eq!(x, error::INVALID_DID.code_num)
        }
    }

    #[test]
    fn test_send_message_set_values_and_serialize(){
        let to_did = "8XFh8yBzrpJQmNyZzgoTqB";
        let uid = "123";
        let status_code = "0";
        let payload = "Some Data";
        let msg_type = "message";
        let ref_msg_id = "6tZ5kQo";
        let msg = match send_message()
            .to(&to_did)
            .msg_type(&msg_type)
            .uid(&uid)
            .status_code(&status_code)
            .edge_agent_payload(&payload)
            .ref_msg_id(&ref_msg_id)
            .serialize_message(){
            Ok(x) => x.to_string(),
            Err(y) => {
             println!("Had error during message build: {}", y);
                String::from("error")
            }
        };
        assert_eq!(msg, "{\"agentPayload\":\
        \"{\\\"edgeAgentPayload\\\":\\\"Some Data\\\",\
            \\\"msgType\\\":\\\"message\\\",\
            \\\"refMsgId\\\":\\\"6tZ5kQo\\\",\
            \\\"statusCode\\\":\\\"0\\\",\
            \\\"type\\\":\\\"SEND_MSG\\\",\
            \\\"uid\\\":\\\"123\\\"}\",\
        \"refMsgId\":\"\",\
        \"statusCode\":\"\",\
        \"to\":\"8XFh8yBzrpJQmNyZzgoTqB\"}");
    }
}
<commit_msg>revert future changes to fix demo (#123)<commit_after>extern crate rust_base58;
extern crate serde_json;
extern crate serde;
extern crate rmp_serde;

use settings;
use utils::httpclient;
use utils::error;
use messages::{GeneralMessage, Bundled, bundle_for_agency};

#[derive(Clone, Serialize, Debug, PartialEq, PartialOrd)]
#[serde(rename_all = "camelCase")]
struct GetMessagesPayload{
    #[serde(rename = "type")]
    msg_type: String,
    #[serde(rename = "msgType")]
    message: String,
    uid: String,
    status_code: String,
    include_edge_payload: String,
}

#[derive(Serialize, Debug, PartialEq, PartialOrd, Clone)]
#[serde(rename_all = "camelCase")]
pub struct GetMessages {
    #[serde(rename = "to")]
    to_did: String,
    agent_payload: String,
    #[serde(skip_serializing, default)]
    payload: GetMessagesPayload,
    #[serde(skip_serializing, default)]
    to_vk: String,
    #[serde(skip_serializing, default)]
    validate_rc: u32,
}

impl GetMessages{

    pub fn create() -> GetMessages {
        GetMessages {
            to_did: String::new(),
            to_vk: String::new(),
            payload: GetMessagesPayload{
                msg_type: "GET_MSGS".to_string(),
                message: String::new(),
                uid: String::new(),
                status_code: String::new(),
                include_edge_payload: "Y".to_string(),
            },
            agent_payload: String::new(),
            validate_rc: error::SUCCESS.code_num,
        }
    }

    pub fn msg_type(&mut self, msg: &str) -> &mut Self{
        //Todo: validate msg??
        self.payload.msg_type = msg.to_string();
        self
    }

    pub fn uid(&mut self, uid: &str) -> &mut Self{
        //Todo: validate msg_uid??
        self.payload.uid = uid.to_string();
        self
    }

    pub fn status_code(&mut self, code: &str) -> &mut Self {
        //Todo: validate that it can be parsed to number??
        self.payload.status_code = code.to_string();
        self
    }

    pub fn include_edge_payload(&mut self, payload: &str) -> &mut Self {
        //todo: is this a json value, String??
        self.payload.include_edge_payload = payload.to_string();
        self
    }

}

//Todo: Every GeneralMessage extension, duplicates code
impl GeneralMessage for GetMessages{
    type Msg = GetMessages;

    fn set_to_did(&mut self, to_did: String){
        self.to_did = to_did;
    }
    fn set_validate_rc(&mut self, rc: u32){
        self.validate_rc = rc;
    }

    fn serialize_message(&mut self) -> Result<String, u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }
        self.agent_payload = json!(self.payload).to_string();
        Ok(json!(self).to_string())
    }

    fn send(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/route", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let json_msg = self.serialize_message()?;

        match httpclient::post(&json_msg, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => Ok(response),
        }
    }

    fn set_to_vk(&mut self, to_vk: String){ self.to_vk = to_vk; }

    fn to_post(&self) -> Result<Vec<u8>,u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }

        let msg = Bundled::create(self.payload.clone()).encode()?;

        bundle_for_agency(msg, self.to_did.as_ref())
    }

    fn send_enc(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/route", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let data = match self.to_post() {
            Ok(x) => x,
            Err(x) => return Err(x),
        };

        match httpclient::post_u8(&data, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => parse_get_messages_response(&response),
        }
    }
}

fn parse_get_messages_response(response: &Vec<u8>) -> Result<String, u32> {
    Ok(String::new().to_owned())
}

#[derive(Clone, Serialize, Debug, PartialEq, PartialOrd)]
#[serde(rename_all = "camelCase")]
struct SendMessagePayload{
    #[serde(rename = "type")]
    msg_type: String,
    #[serde(rename = "msgType")]
    message: String,
    uid: String,
    status_code: String,
    edge_agent_payload: String,
    ref_msg_id: String,
}

#[derive(Serialize, Debug, PartialEq, PartialOrd, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SendMessage {
    #[serde(rename = "to")]
    to_did: String,
    agent_payload: String,
    #[serde(skip_serializing, default)]
    payload: SendMessagePayload,
    #[serde(skip_serializing, default)]
    to_vk: String,
    #[serde(skip_serializing, default)]
    validate_rc: u32,
    #[serde(rename = "refMsgId")]
    ref_msg_id: String,
    status_code: String,
}

impl SendMessage{

    pub fn create() -> SendMessage {
        SendMessage {
            to_did: String::new(),
            to_vk: String::new(),
            payload: SendMessagePayload{
                msg_type: "SEND_MSG".to_string(),
                message: String::new(),
                uid: String::new(),
                status_code: String::new(),
                edge_agent_payload: String::new(),
                ref_msg_id: String::new(),
            },
            agent_payload: String::new(),
            validate_rc: error::SUCCESS.code_num,
            ref_msg_id: String::new(),
            status_code: String::new(),
        }
    }

    pub fn msg_type(&mut self, msg: &str) -> &mut Self{
        //Todo: validate msg??
        self.payload.message = msg.to_string();
        self
    }

    pub fn uid(&mut self, uid: &str) -> &mut Self{
        //Todo: validate msg_uid??
        self.payload.uid = uid.to_string();
        self
    }

    pub fn status_code(&mut self, code: &str) -> &mut Self {
        //Todo: validate that it can be parsed to number??
        self.payload.status_code = code.to_string();
        self
    }

    pub fn edge_agent_payload(&mut self, payload: &str) -> &mut Self {
        //todo: is this a json value, String??
        self.payload.edge_agent_payload = payload.to_string();
        self
    }

    pub fn ref_msg_id(&mut self, id: &str) -> &mut Self {
        self.payload.ref_msg_id = String::from(id);
        self
    }

}

//Todo: Every GeneralMessage extension, duplicates code
impl GeneralMessage for SendMessage{
    type Msg = SendMessage;

    fn set_to_did(&mut self, to_did: String){
        self.to_did = to_did;
    }
    fn set_validate_rc(&mut self, rc: u32){
        self.validate_rc = rc;
    }

    fn serialize_message(&mut self) -> Result<String, u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }
        self.agent_payload = json!(self.payload).to_string();
        Ok(json!(self).to_string())
    }

    fn send(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/route", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let json_msg = self.serialize_message()?;
        match httpclient::post(&json_msg, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => Ok(response),
        }
    }

    fn set_to_vk(&mut self, to_vk: String){ self.to_vk = to_vk; }

    fn to_post(&self) -> Result<Vec<u8>, u32> {
        if self.validate_rc != error::SUCCESS.code_num {
            return Err(self.validate_rc)
        }

        let msg = Bundled::create(self.payload.clone()).encode()?;

        bundle_for_agency(msg, self.to_did.as_ref())
    }

    fn send_enc(&mut self) -> Result<String, u32> {
        let url = format!("{}/agency/msg", settings::get_config_value(settings::CONFIG_AGENT_ENDPOINT).unwrap());

        let data = match self.to_post() {
            Ok(x) => x,
            Err(x) => return Err(x),
        };

        match httpclient::post_u8(&data, &url) {
            Err(_) => Err(error::POST_MSG_FAILURE.code_num),
            Ok(response) => parse_send_message_response(&response),
        }
    }
}

fn parse_send_message_response(response: &Vec<u8>) -> Result<String, u32> {
    Ok(String::new().to_owned())
}

#[cfg(test)]
mod tests {
    use super::*;
    use messages::{get_messages, send_message};

    #[test]
    fn test_get_messages_set_values_and_serialize(){
        let to_did = "8XFh8yBzrpJQmNyZzgoTqB";
        let uid = "123";
        let status_code = "0";
        let payload = "Some Data";
        let msg_type = "message";
        let msg = match get_messages()
            .to(&to_did)
            .uid(&uid)
            .status_code(&status_code)
            .serialize_message(){
            Ok(x) => x.to_string(),
            Err(y) => {
             println!("Had error during message build: {}", y);
                String::from("error")
            }
        };
        assert_eq!(msg,"{\"agentPayload\":\"{\\\"includeEdgePayload\\\":\\\"Y\\\",\\\"msgType\\\":\\\"\\\",\\\"statusCode\\\":\\\"0\\\",\\\"type\\\":\\\"GET_MSGS\\\",\\\"uid\\\":\\\"123\\\"}\",\"to\":\"8XFh8yBzrpJQmNyZzgoTqB\"}");
    }

    #[test]
    fn test_get_messages_set_invalid_did_errors_at_serialize(){
        let to_did = "A";
        let uid = "123";
        let status_code = "0";
        let payload = "Some Data";
        let mut msg = get_messages()
            .to(&to_did)
            .uid(&uid)
            .status_code(&status_code)
            .include_edge_payload(&payload).clone();

        match msg.serialize_message(){
            Ok(_) => panic!("should have had did error"),
            Err(x) => assert_eq!(x, error::INVALID_DID.code_num)
        }
    }

    #[test]
    fn test_send_message_set_values_and_serialize(){
        let to_did = "8XFh8yBzrpJQmNyZzgoTqB";
        let uid = "123";
        let status_code = "0";
        let payload = "Some Data";
        let msg_type = "message";
        let ref_msg_id = "6tZ5kQo";
        let msg = match send_message()
            .to(&to_did)
            .msg_type(&msg_type)
            .uid(&uid)
            .status_code(&status_code)
            .edge_agent_payload(&payload)
            .ref_msg_id(&ref_msg_id)
            .serialize_message(){
            Ok(x) => x.to_string(),
            Err(y) => {
             println!("Had error during message build: {}", y);
                String::from("error")
            }
        };
        assert_eq!(msg, "{\"agentPayload\":\
        \"{\\\"edgeAgentPayload\\\":\\\"Some Data\\\",\
            \\\"msgType\\\":\\\"message\\\",\
            \\\"refMsgId\\\":\\\"6tZ5kQo\\\",\
            \\\"statusCode\\\":\\\"0\\\",\
            \\\"type\\\":\\\"SEND_MSG\\\",\
            \\\"uid\\\":\\\"123\\\"}\",\
        \"refMsgId\":\"\",\
        \"statusCode\":\"\",\
        \"to\":\"8XFh8yBzrpJQmNyZzgoTqB\"}");
    }
}
<|endoftext|>


<commit_before>//! A channel for sending a single message between asynchronous tasks.

use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::error::Error;
use std::fmt;

use futures_core::{Future, Poll, Async};
use futures_core::task::{self, Waker};
use futures_core::never::Never;

use lock::Lock;

/// A future for a value that will be provided by another asynchronous task.
///
/// This is created by the [`channel`](channel) function.
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub struct Receiver<T> {
    inner: Arc<Inner<T>>,
}

/// A means of transmitting a single value to another task.
///
/// This is created by the [`channel`](channel) function.
#[derive(Debug)]
pub struct Sender<T> {
    inner: Arc<Inner<T>>,
}

/// Internal state of the `Receiver`/`Sender` pair above. This is all used as
/// the internal synchronization between the two for send/recv operations.
#[derive(Debug)]
struct Inner<T> {
    /// Indicates whether this oneshot is complete yet. This is filled in both
    /// by `Sender::drop` and by `Receiver::drop`, and both sides interpret it
    /// appropriately.
    ///
    /// For `Receiver`, if this is `true`, then it's guaranteed that `data` is
    /// unlocked and ready to be inspected.
    ///
    /// For `Sender` if this is `true` then the oneshot has gone away and it
    /// can return ready from `poll_cancel`.
    complete: AtomicBool,

    /// The actual data being transferred as part of this `Receiver`. This is
    /// filled in by `Sender::complete` and read by `Receiver::poll`.
    ///
    /// Note that this is protected by `Lock`, but it is in theory safe to
    /// replace with an `UnsafeCell` as it's actually protected by `complete`
    /// above. I wouldn't recommend doing this, however, unless someone is
    /// supremely confident in the various atomic orderings here and there.
    data: Lock<Option<T>>,

    /// Field to store the task which is blocked in `Receiver::poll`.
    ///
    /// This is filled in when a oneshot is polled but not ready yet. Note that
    /// the `Lock` here, unlike in `data` above, is important to resolve races.
    /// Both the `Receiver` and the `Sender` halves understand that if they
    /// can't acquire the lock then some important interference is happening.
    rx_task: Lock<Option<Waker>>,

    /// Like `rx_task` above, except for the task blocked in
    /// `Sender::poll_cancel`. Additionally, `Lock` cannot be `UnsafeCell`.
    tx_task: Lock<Option<Waker>>,
}

/// Creates a new one-shot channel for sending values across asynchronous tasks.
///
/// This function is similar to Rust's channel constructor found in the standard library.
/// Two halves are returned, the first of which is a `Sender` handle, used to
/// signal the end of a computation and provide its value. The second half is a
/// `Receiver` which implements the `Future` trait, resolving to the value that
/// was given to the `Sender` handle.
///
/// Each half can be separately owned and sent across tasks.
///
/// # Examples
///
/// ```
/// extern crate futures;
/// extern crate futures_channel;
///
/// use std::thread;
///
/// use futures_channel::oneshot;
/// use futures::*;
///
/// fn main() {
///     let (p, c) = oneshot::channel::<i32>();
///
/// # let t =
///     thread::spawn(|| {
///         let future = c.map(|i| {
///             println!("got: {}", i);
///         });
///         // ...
/// # return future;
///     });
///
///     p.send(3).unwrap();
/// # t.join().unwrap();
/// }
/// ```
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    let inner = Arc::new(Inner::new());
    let receiver = Receiver {
        inner: inner.clone(),
    };
    let sender = Sender {
        inner: inner,
    };
    (sender, receiver)
}

impl<T> Inner<T> {
    fn new() -> Inner<T> {
        Inner {
            complete: AtomicBool::new(false),
            data: Lock::new(None),
            rx_task: Lock::new(None),
            tx_task: Lock::new(None),
        }
    }

    fn send(&self, t: T) -> Result<(), T> {
        if self.complete.load(SeqCst) {
            return Err(t)
        }

        // Note that this lock acquisition may fail if the receiver
        // is closed and sets the `complete` flag to true, whereupon
        // the receiver may call `poll()`.
        if let Some(mut slot) = self.data.try_lock() {
            assert!(slot.is_none());
            *slot = Some(t);
            drop(slot);

            // If the receiver called `close()` between the check at the
            // start of the function, and the lock being released, then
            // the receiver may not be around to receive it, so try to
            // pull it back out.
            if self.complete.load(SeqCst) {
                // If lock acquisition fails, then receiver is actually
                // receiving it, so we're good.
                if let Some(mut slot) = self.data.try_lock() {
                    if let Some(t) = slot.take() {
                        return Err(t);
                    }
                }
            }
            Ok(())
        } else {
            // Must have been closed
            Err(t)
        }
    }

    fn poll_cancel(&self, cx: &mut task::Context) -> Poll<(), Never> {
        // Fast path up first, just read the flag and see if our other half is
        // gone. This flag is set both in our destructor and the oneshot
        // destructor, but our destructor hasn't run yet so if it's set then the
        // oneshot is gone.
        if self.complete.load(SeqCst) {
            return Ok(Async::Ready(()))
        }

        // If our other half is not gone then we need to park our current task
        // and move it into the `notify_cancel` slot to get notified when it's
        // actually gone.
        //
        // If `try_lock` fails, then the `Receiver` is in the process of using
        // it, so we can deduce that it's now in the process of going away and
        // hence we're canceled. If it succeeds then we just store our handle.
        //
        // Crucially we then check `oneshot_gone` *again* before we return.
        // While we were storing our handle inside `notify_cancel` the `Receiver`
        // may have been dropped. The first thing it does is set the flag, and
        // if it fails to acquire the lock it assumes that we'll see the flag
        // later on. So... we then try to see the flag later on!
        let handle = cx.waker().clone();
        match self.tx_task.try_lock() {
            Some(mut p) => *p = Some(handle),
            None => return Ok(Async::Ready(())),
        }
        if self.complete.load(SeqCst) {
            Ok(Async::Ready(()))
        } else {
            Ok(Async::Pending)
        }
    }

    fn is_canceled(&self) -> bool {
        self.complete.load(SeqCst)
    }

    fn drop_tx(&self) {
        // Flag that we're a completed `Sender` and try to wake up a receiver.
        // Whether or not we actually stored any data will get picked up and
        // translated to either an item or cancellation.
        //
        // Note that if we fail to acquire the `rx_task` lock then that means
        // we're in one of two situations:
        //
        // 1. The receiver is trying to block in `poll`
        // 2. The receiver is being dropped
        //
        // In the first case it'll check the `complete` flag after it's done
        // blocking to see if it succeeded. In the latter case we don't need to
        // wake up anyone anyway. So in both cases it's ok to ignore the `None`
        // case of `try_lock` and bail out.
        //
        // The first case crucially depends on `Lock` using `SeqCst` ordering
        // under the hood. If it instead used `Release` / `Acquire` ordering,
        // then it would not necessarily synchronize with `inner.complete`
        // and deadlock might be possible, as was observed in
        // https://github.com/rust-lang-nursery/futures-rs/pull/219.
        self.complete.store(true, SeqCst);
        if let Some(mut slot) = self.rx_task.try_lock() {
            if let Some(task) = slot.take() {
                drop(slot);
                task.wake();
            }
        }
    }

    fn close_rx(&self) {
        // Flag our completion and then attempt to wake up the sender if it's
        // blocked. See comments in `drop` below for more info
        self.complete.store(true, SeqCst);
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }

    fn recv(&self, cx: &mut task::Context) -> Poll<T, Canceled> {
        let mut done = false;

        // Check to see if some data has arrived. If it hasn't then we need to
        // block our task.
        //
        // Note that the acquisition of the `rx_task` lock might fail below, but
        // the only situation where this can happen is during `Sender::drop`
        // when we are indeed completed already. If that's happening then we
        // know we're completed so keep going.
        if self.complete.load(SeqCst) {
            done = true;
        } else {
            let task = cx.waker().clone();
            match self.rx_task.try_lock() {
                Some(mut slot) => *slot = Some(task),
                None => done = true,
            }
        }

        // If we're `done` via one of the paths above, then look at the data and
        // figure out what the answer is. If, however, we stored `rx_task`
        // successfully above we need to check again if we're completed in case
        // a message was sent while `rx_task` was locked and couldn't notify us
        // otherwise.
        //
        // If we're not done, and we're not complete, though, then we've
        // successfully blocked our task and we return `Pending`.
        if done || self.complete.load(SeqCst) {
            // If taking the lock fails, the sender will realise that the we're
            // `done` when it checks the `complete` flag on the way out, and will
            // treat the send as a failure.
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(data.into());
                }
            }
            Err(Canceled)
        } else {
            Ok(Async::Pending)
        }
    }

    fn drop_rx(&self) {
        // Indicate to the `Sender` that we're done, so any future calls to
        // `poll_cancel` are weeded out.
        self.complete.store(true, SeqCst);

        // If we've blocked a task then there's no need for it to stick around,
        // so we need to drop it. If this lock acquisition fails, though, then
        // it's just because our `Sender` is trying to take the task, so we
        // let them take care of that.
        if let Some(mut slot) = self.rx_task.try_lock() {
            let task = slot.take();
            drop(slot);
            drop(task);
        }

        // Finally, if our `Sender` wants to get notified of us going away, it
        // would have stored something in `tx_task`. Here we try to peel that
        // out and unpark it.
        //
        // Note that the `try_lock` here may fail, but only if the `Sender` is
        // in the process of filling in the task. If that happens then we
        // already flagged `complete` and they'll pick that up above.
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }
}

impl<T> Sender<T> {
    /// Completes this oneshot with a successful result.
    ///
    /// This function will consume `self` and indicate to the other end, the
    /// [`Receiver`](Receiver), that the value provided is the result of the
    /// computation this represents.
    ///
    /// If the value is successfully enqueued for the remote end to receive,
    /// then `Ok(())` is returned. If the receiving end was dropped before
    /// this function was called, however, then `Err` is returned with the value
    /// provided.
    pub fn send(self, t: T) -> Result<(), T> {
        self.inner.send(t)
    }

    /// Polls this `Sender` half to detect whether its associated
    /// [`Receiver`](Receiver) with has been dropped.
    ///
    /// # Return values
    ///
    /// If `Ok(Ready)` is returnd then the associated `Receiver` has been dropped,
    /// which means any work required for sending should be cancelled.
    ///
    /// If `Ok(Pending)` is returned then the associated `Receiver` is still
    /// alive and may be able to receive a message if sent. The current task,
    /// however, is scheduled to receive a notification if the corresponding
    /// `Receiver` goes away.
    pub fn poll_cancel(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
        self.inner.poll_cancel(cx)
    }

    /// Tests to see whether this `Sender`'s corresponding `Receiver`
    /// has been dropped.
    ///
    /// Unlike [`poll_cancel`](Sender::poll_cancel), this function does not
    /// enqueue a task for wakeup upon cancellation, but merely reports the
    /// current state, which may be subject to concurrent modification.
    pub fn is_canceled(&self) -> bool {
        self.inner.is_canceled()
    }
}

impl<T> Drop for Sender<T> {
    fn drop(&mut self) {
        self.inner.drop_tx()
    }
}

/// Error returned from a [`Receiver`](Receiver) when the corresponding
/// [`Sender`](Sender) is dropped.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Canceled;

impl fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "oneshot canceled")
    }
}

impl Error for Canceled {
    fn description(&self) -> &str {
        "oneshot canceled"
    }
}

impl<T> Receiver<T> {
    /// Gracefully close this receiver, preventing any subsequent attempts to
    /// send to it.
    ///
    /// Any `send` operation which happens after this method returns is
    /// guaranteed to fail. After calling this method, you can use
    /// [`Receiver::poll`](Receiver::poll) to determine whether a message had
    /// previously been sent.
    pub fn close(&mut self) {
        self.inner.close_rx()
    }
}

impl<T> Future for Receiver<T> {
    type Item = T;
    type Error = Canceled;

    fn poll(&mut self, cx: &mut task::Context) -> Poll<T, Canceled> {
        self.inner.recv(cx)
    }
}

impl<T> Drop for Receiver<T> {
    fn drop(&mut self) {
        self.inner.drop_rx()
    }
}
<commit_msg>Add `oneshot::Receiver::try_recv`.<commit_after>//! A channel for sending a single message between asynchronous tasks.

use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::error::Error;
use std::fmt;

use futures_core::{Future, Poll, Async};
use futures_core::task::{self, Waker};
use futures_core::never::Never;

use lock::Lock;

/// A future for a value that will be provided by another asynchronous task.
///
/// This is created by the [`channel`](channel) function.
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub struct Receiver<T> {
    inner: Arc<Inner<T>>,
}

/// A means of transmitting a single value to another task.
///
/// This is created by the [`channel`](channel) function.
#[derive(Debug)]
pub struct Sender<T> {
    inner: Arc<Inner<T>>,
}

/// Internal state of the `Receiver`/`Sender` pair above. This is all used as
/// the internal synchronization between the two for send/recv operations.
#[derive(Debug)]
struct Inner<T> {
    /// Indicates whether this oneshot is complete yet. This is filled in both
    /// by `Sender::drop` and by `Receiver::drop`, and both sides interpret it
    /// appropriately.
    ///
    /// For `Receiver`, if this is `true`, then it's guaranteed that `data` is
    /// unlocked and ready to be inspected.
    ///
    /// For `Sender` if this is `true` then the oneshot has gone away and it
    /// can return ready from `poll_cancel`.
    complete: AtomicBool,

    /// The actual data being transferred as part of this `Receiver`. This is
    /// filled in by `Sender::complete` and read by `Receiver::poll`.
    ///
    /// Note that this is protected by `Lock`, but it is in theory safe to
    /// replace with an `UnsafeCell` as it's actually protected by `complete`
    /// above. I wouldn't recommend doing this, however, unless someone is
    /// supremely confident in the various atomic orderings here and there.
    data: Lock<Option<T>>,

    /// Field to store the task which is blocked in `Receiver::poll`.
    ///
    /// This is filled in when a oneshot is polled but not ready yet. Note that
    /// the `Lock` here, unlike in `data` above, is important to resolve races.
    /// Both the `Receiver` and the `Sender` halves understand that if they
    /// can't acquire the lock then some important interference is happening.
    rx_task: Lock<Option<Waker>>,

    /// Like `rx_task` above, except for the task blocked in
    /// `Sender::poll_cancel`. Additionally, `Lock` cannot be `UnsafeCell`.
    tx_task: Lock<Option<Waker>>,
}

/// Creates a new one-shot channel for sending values across asynchronous tasks.
///
/// This function is similar to Rust's channel constructor found in the standard library.
/// Two halves are returned, the first of which is a `Sender` handle, used to
/// signal the end of a computation and provide its value. The second half is a
/// `Receiver` which implements the `Future` trait, resolving to the value that
/// was given to the `Sender` handle.
///
/// Each half can be separately owned and sent across tasks.
///
/// # Examples
///
/// ```
/// extern crate futures;
/// extern crate futures_channel;
///
/// use std::thread;
///
/// use futures_channel::oneshot;
/// use futures::*;
///
/// fn main() {
///     let (p, c) = oneshot::channel::<i32>();
///
/// # let t =
///     thread::spawn(|| {
///         let future = c.map(|i| {
///             println!("got: {}", i);
///         });
///         // ...
/// # return future;
///     });
///
///     p.send(3).unwrap();
/// # t.join().unwrap();
/// }
/// ```
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    let inner = Arc::new(Inner::new());
    let receiver = Receiver {
        inner: inner.clone(),
    };
    let sender = Sender {
        inner: inner,
    };
    (sender, receiver)
}

impl<T> Inner<T> {
    fn new() -> Inner<T> {
        Inner {
            complete: AtomicBool::new(false),
            data: Lock::new(None),
            rx_task: Lock::new(None),
            tx_task: Lock::new(None),
        }
    }

    fn send(&self, t: T) -> Result<(), T> {
        if self.complete.load(SeqCst) {
            return Err(t)
        }

        // Note that this lock acquisition may fail if the receiver
        // is closed and sets the `complete` flag to true, whereupon
        // the receiver may call `poll()`.
        if let Some(mut slot) = self.data.try_lock() {
            assert!(slot.is_none());
            *slot = Some(t);
            drop(slot);

            // If the receiver called `close()` between the check at the
            // start of the function, and the lock being released, then
            // the receiver may not be around to receive it, so try to
            // pull it back out.
            if self.complete.load(SeqCst) {
                // If lock acquisition fails, then receiver is actually
                // receiving it, so we're good.
                if let Some(mut slot) = self.data.try_lock() {
                    if let Some(t) = slot.take() {
                        return Err(t);
                    }
                }
            }
            Ok(())
        } else {
            // Must have been closed
            Err(t)
        }
    }

    fn poll_cancel(&self, cx: &mut task::Context) -> Poll<(), Never> {
        // Fast path up first, just read the flag and see if our other half is
        // gone. This flag is set both in our destructor and the oneshot
        // destructor, but our destructor hasn't run yet so if it's set then the
        // oneshot is gone.
        if self.complete.load(SeqCst) {
            return Ok(Async::Ready(()))
        }

        // If our other half is not gone then we need to park our current task
        // and move it into the `notify_cancel` slot to get notified when it's
        // actually gone.
        //
        // If `try_lock` fails, then the `Receiver` is in the process of using
        // it, so we can deduce that it's now in the process of going away and
        // hence we're canceled. If it succeeds then we just store our handle.
        //
        // Crucially we then check `oneshot_gone` *again* before we return.
        // While we were storing our handle inside `notify_cancel` the `Receiver`
        // may have been dropped. The first thing it does is set the flag, and
        // if it fails to acquire the lock it assumes that we'll see the flag
        // later on. So... we then try to see the flag later on!
        let handle = cx.waker().clone();
        match self.tx_task.try_lock() {
            Some(mut p) => *p = Some(handle),
            None => return Ok(Async::Ready(())),
        }
        if self.complete.load(SeqCst) {
            Ok(Async::Ready(()))
        } else {
            Ok(Async::Pending)
        }
    }

    fn is_canceled(&self) -> bool {
        self.complete.load(SeqCst)
    }

    fn drop_tx(&self) {
        // Flag that we're a completed `Sender` and try to wake up a receiver.
        // Whether or not we actually stored any data will get picked up and
        // translated to either an item or cancellation.
        //
        // Note that if we fail to acquire the `rx_task` lock then that means
        // we're in one of two situations:
        //
        // 1. The receiver is trying to block in `poll`
        // 2. The receiver is being dropped
        //
        // In the first case it'll check the `complete` flag after it's done
        // blocking to see if it succeeded. In the latter case we don't need to
        // wake up anyone anyway. So in both cases it's ok to ignore the `None`
        // case of `try_lock` and bail out.
        //
        // The first case crucially depends on `Lock` using `SeqCst` ordering
        // under the hood. If it instead used `Release` / `Acquire` ordering,
        // then it would not necessarily synchronize with `inner.complete`
        // and deadlock might be possible, as was observed in
        // https://github.com/rust-lang-nursery/futures-rs/pull/219.
        self.complete.store(true, SeqCst);
        if let Some(mut slot) = self.rx_task.try_lock() {
            if let Some(task) = slot.take() {
                drop(slot);
                task.wake();
            }
        }
    }

    fn close_rx(&self) {
        // Flag our completion and then attempt to wake up the sender if it's
        // blocked. See comments in `drop` below for more info
        self.complete.store(true, SeqCst);
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }

    fn try_recv(&self) -> Result<Option<T>, Canceled> {
        // If we're complete, either `::close_rx` or `::drop_tx` was called.
        // We can assume a successful send if data is present.
        if self.complete.load(SeqCst) {
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(Some(data.into()));
                }
            }
            // Should there be a different error value or a panic in the case
            // where `self.data.try_lock() == None`?
            Err(Canceled)
        } else {
            Ok(None)
        }
    }

    fn recv(&self, cx: &mut task::Context) -> Poll<T, Canceled> {
        let mut done = false;

        // Check to see if some data has arrived. If it hasn't then we need to
        // block our task.
        //
        // Note that the acquisition of the `rx_task` lock might fail below, but
        // the only situation where this can happen is during `Sender::drop`
        // when we are indeed completed already. If that's happening then we
        // know we're completed so keep going.
        if self.complete.load(SeqCst) {
            done = true;
        } else {
            let task = cx.waker().clone();
            match self.rx_task.try_lock() {
                Some(mut slot) => *slot = Some(task),
                None => done = true,
            }
        }

        // If we're `done` via one of the paths above, then look at the data and
        // figure out what the answer is. If, however, we stored `rx_task`
        // successfully above we need to check again if we're completed in case
        // a message was sent while `rx_task` was locked and couldn't notify us
        // otherwise.
        //
        // If we're not done, and we're not complete, though, then we've
        // successfully blocked our task and we return `Pending`.
        if done || self.complete.load(SeqCst) {
            // If taking the lock fails, the sender will realise that the we're
            // `done` when it checks the `complete` flag on the way out, and will
            // treat the send as a failure.
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(data.into());
                }
            }
            Err(Canceled)
        } else {
            Ok(Async::Pending)
        }
    }

    fn drop_rx(&self) {
        // Indicate to the `Sender` that we're done, so any future calls to
        // `poll_cancel` are weeded out.
        self.complete.store(true, SeqCst);

        // If we've blocked a task then there's no need for it to stick around,
        // so we need to drop it. If this lock acquisition fails, though, then
        // it's just because our `Sender` is trying to take the task, so we
        // let them take care of that.
        if let Some(mut slot) = self.rx_task.try_lock() {
            let task = slot.take();
            drop(slot);
            drop(task);
        }

        // Finally, if our `Sender` wants to get notified of us going away, it
        // would have stored something in `tx_task`. Here we try to peel that
        // out and unpark it.
        //
        // Note that the `try_lock` here may fail, but only if the `Sender` is
        // in the process of filling in the task. If that happens then we
        // already flagged `complete` and they'll pick that up above.
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }
}

impl<T> Sender<T> {
    /// Completes this oneshot with a successful result.
    ///
    /// This function will consume `self` and indicate to the other end, the
    /// [`Receiver`](Receiver), that the value provided is the result of the
    /// computation this represents.
    ///
    /// If the value is successfully enqueued for the remote end to receive,
    /// then `Ok(())` is returned. If the receiving end was dropped before
    /// this function was called, however, then `Err` is returned with the value
    /// provided.
    pub fn send(self, t: T) -> Result<(), T> {
        self.inner.send(t)
    }

    /// Polls this `Sender` half to detect whether its associated
    /// [`Receiver`](Receiver) with has been dropped.
    ///
    /// # Return values
    ///
    /// If `Ok(Ready)` is returned then the associated `Receiver` has been
    /// dropped, which means any work required for sending should be canceled.
    ///
    /// If `Ok(Pending)` is returned then the associated `Receiver` is still
    /// alive and may be able to receive a message if sent. The current task,
    /// however, is scheduled to receive a notification if the corresponding
    /// `Receiver` goes away.
    pub fn poll_cancel(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
        self.inner.poll_cancel(cx)
    }

    /// Tests to see whether this `Sender`'s corresponding `Receiver`
    /// has been dropped.
    ///
    /// Unlike [`poll_cancel`](Sender::poll_cancel), this function does not
    /// enqueue a task for wakeup upon cancellation, but merely reports the
    /// current state, which may be subject to concurrent modification.
    pub fn is_canceled(&self) -> bool {
        self.inner.is_canceled()
    }
}

impl<T> Drop for Sender<T> {
    fn drop(&mut self) {
        self.inner.drop_tx()
    }
}

/// Error returned from a [`Receiver`](Receiver) when the corresponding
/// [`Sender`](Sender) is dropped.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Canceled;

impl fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "oneshot canceled")
    }
}

impl Error for Canceled {
    fn description(&self) -> &str {
        "oneshot canceled"
    }
}

impl<T> Receiver<T> {
    /// Gracefully close this receiver, preventing any subsequent attempts to
    /// send to it.
    ///
    /// Any `send` operation which happens after this method returns is
    /// guaranteed to fail. After calling this method, you can use
    /// [`Receiver::poll`](Receiver::poll) to determine whether a message had
    /// previously been sent.
    pub fn close(&mut self) {
        self.inner.close_rx()
    }

    /// Attempts to receive a message outside of the context of a task.
    ///
    /// Useful when a [`Context`](Context) is not available such as within a
    /// `Drop` impl.
    ///
    /// Does not schedule a task wakeup or have any other side effects.
    ///
    /// A return value of `None` must be considered immediately stale (out of
    /// date) unless [`::close`](Receiver::close) has been called first.
    ///
    /// Returns an error if the sender was dropped.
    pub fn try_recv(&mut self) -> Result<Option<T>, Canceled> {
        self.inner.try_recv()
    }
}

impl<T> Future for Receiver<T> {
    type Item = T;
    type Error = Canceled;

    fn poll(&mut self, cx: &mut task::Context) -> Poll<T, Canceled> {
        self.inner.recv(cx)
    }
}

impl<T> Drop for Receiver<T> {
    fn drop(&mut self) {
        self.inner.drop_rx()
    }
}
<|endoftext|>


<commit_before>mod autoio;
mod batch;
mod bios;
mod content;
mod contest;
mod dce;
mod diff;
mod ev;
mod evr;
mod feedback;
mod make;
mod ppf;
mod ps;
mod rusage;
mod score;
mod submission;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<commit_msg>Make turingarena sub-modules public<commit_after>pub mod autoio;
pub mod batch;
pub mod bios;
pub mod content;
pub mod contest;
pub mod dce;
pub mod diff;
pub mod ev;
pub mod evr;
pub mod feedback;
pub mod make;
pub mod ppf;
pub mod ps;
pub mod rusage;
pub mod score;
pub mod submission;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::fs::File;
use std::path::{ Path, PathBuf };

use download;
use extract;
use verify;
use find_package;
use find_package::Package;

fn _install_package(package: &Package, path: &Path) -> Result<bool, String> {
    let mut download_path = PathBuf::new();
        download_path.push(path);
        download_path.push(format!("download/{}", package.name));

    if !download_path.exists() {
        download::download_file(&package.url, download_path.as_path())?;

        let target = match File::open(download_path.as_path()) {
            Ok(x) => x,
            Err(why) => return Err(format!("{}", why))
        };

        if verify::verify_file_crc32(&target) != package.crc32 {
            fs::remove_file(download_path.as_path())
                .ok()
                .expect(
                    &format!(
                        "Failed to remove file: {}",
                        download_path.as_path().to_str().unwrap_or("Invalid File")
                    )
                );
            return Err(String::from("The downloaded file is corrupted.\nwiz will delete the file now."))
        }
    }

    let mut tar_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("download/{}.tar", package.name));

    if !tar_path.exists() {
        extract::extract_gz(download_path.as_path(), tar_path.as_path())?;
    }

    let mut install_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("install/{}", package.name));

    if !install_path.exists() {
        extract::extract_tar(tar_path.as_path(), install_path.as_path())?;
    } else {
        return Ok(false)
    }

    return Ok(true)
}

pub fn install_package(name: &str, path: &Path) -> Result<bool, String> {
    let package = find_package::select_package(name, path)?;
    for dep in &package.dependencies {
        install_package(&dep.name, path)?;
    }
    return _install_package(&package, path)
}<commit_msg>Newline.<commit_after>use std::fs;
use std::fs::File;
use std::path::{ Path, PathBuf };

use download;
use extract;
use verify;
use find_package;
use find_package::Package;

fn _install_package(package: &Package, path: &Path) -> Result<bool, String> {
    let mut download_path = PathBuf::new();
        download_path.push(path);
        download_path.push(format!("download/{}", package.name));

    if !download_path.exists() {
        download::download_file(&package.url, download_path.as_path())?;

        let target = match File::open(download_path.as_path()) {
            Ok(x) => x,
            Err(why) => return Err(format!("{}", why))
        };

        if verify::verify_file_crc32(&target) != package.crc32 {
            fs::remove_file(download_path.as_path())
                .ok()
                .expect(
                    &format!(
                        "Failed to remove file: {}",
                        download_path.as_path().to_str().unwrap_or("Invalid File")
                    )
                );
            return Err(String::from("The downloaded file is corrupted.\nwiz will delete the file now."))
        }
    }

    let mut tar_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("download/{}.tar", package.name));

    if !tar_path.exists() {
        extract::extract_gz(download_path.as_path(), tar_path.as_path())?;
    }

    let mut install_path = PathBuf::new();
        tar_path.push(path);
        tar_path.push(format!("install/{}", package.name));

    if !install_path.exists() {
        extract::extract_tar(tar_path.as_path(), install_path.as_path())?;
    } else {
        return Ok(false)
    }

    return Ok(true)
}

pub fn install_package(name: &str, path: &Path) -> Result<bool, String> {
    let package = find_package::select_package(name, path)?;
    for dep in &package.dependencies {
        install_package(&dep.name, path)?;
    }
    return _install_package(&package, path)
}
<|endoftext|>


<commit_before>#![feature(option_expect_none, option_unwrap_none)]
//! Test that panic locations for `#[track_caller]` functions in std have the correct
//! location reported.

use std::sync::atomic::{AtomicUsize, Ordering};

static HOOK_COUNT: AtomicUsize = AtomicUsize::new(0);

fn main() {
    // inspect the `PanicInfo` we receive to ensure the right file is the source
    std::panic::set_hook(Box::new(|info| {
        HOOK_COUNT.fetch_add(1, Ordering::Relaxed);
        let actual = info.location().unwrap();
        if actual.file() != file!() {
            eprintln!("expected a location in the test file, found {:?}", actual);
            panic!();
        }
    }));

    fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) {
        std::panic::catch_unwind(f).unwrap_err();
    }

    let nope: Option<()> = None;
    assert_panicked(|| nope.unwrap());
    assert_panicked(|| nope.expect(""));

    let yep: Option<()> = Some(());
    assert_panicked(|| yep.unwrap_none());
    assert_panicked(|| yep.expect_none(""));

    let oops: Result<(), ()> = Err(());
    assert_panicked(|| oops.unwrap());
    assert_panicked(|| oops.expect(""));

    let fine: Result<(), ()> = Ok(());
    assert_panicked(|| fine.unwrap_err());
    assert_panicked(|| fine.expect_err(""));

    // Cleanup: reset to default hook.
    drop(std::panic::take_hook());

    assert_eq!(HOOK_COUNT.load(Ordering::Relaxed), 8);
}
<commit_msg>Unwind panicking does not currently work on Windows<commit_after>// ignore-windows: Unwind panicking does not currently work on Windows
#![feature(option_expect_none, option_unwrap_none)]
//! Test that panic locations for `#[track_caller]` functions in std have the correct
//! location reported.

use std::sync::atomic::{AtomicUsize, Ordering};

static HOOK_COUNT: AtomicUsize = AtomicUsize::new(0);

fn main() {
    // inspect the `PanicInfo` we receive to ensure the right file is the source
    std::panic::set_hook(Box::new(|info| {
        HOOK_COUNT.fetch_add(1, Ordering::Relaxed);
        let actual = info.location().unwrap();
        if actual.file() != file!() {
            eprintln!("expected a location in the test file, found {:?}", actual);
            panic!();
        }
    }));

    fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) {
        std::panic::catch_unwind(f).unwrap_err();
    }

    let nope: Option<()> = None;
    assert_panicked(|| nope.unwrap());
    assert_panicked(|| nope.expect(""));

    let yep: Option<()> = Some(());
    assert_panicked(|| yep.unwrap_none());
    assert_panicked(|| yep.expect_none(""));

    let oops: Result<(), ()> = Err(());
    assert_panicked(|| oops.unwrap());
    assert_panicked(|| oops.expect(""));

    let fine: Result<(), ()> = Ok(());
    assert_panicked(|| fine.unwrap_err());
    assert_panicked(|| fine.expect_err(""));

    // Cleanup: reset to default hook.
    drop(std::panic::take_hook());

    assert_eq!(HOOK_COUNT.load(Ordering::Relaxed), 8);
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::{Command, Output};
use walkdir::{DirEntry, WalkDirIterator};

fn announce(banner: &str) {
    let mut line = String::new();
    for _ in 0..banner.len() {
        line.push('-');
    }
    println!("{}", line);
    println!("{}", banner);
    println!("{}", line);
}

fn print_ident(buf: Vec<u8>) {
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn display_path(path: &PathBuf) {
    path.file_name()
        .and_then(|p| p.to_str())
        .map(|p| println!("{}:", p));
}

fn report_output(output: Output) {
    if output.status.success() {
        print_ident(output.stdout);
    } else {
        print_ident(output.stderr);
    }
    println!("");
}

const CARGO: &'static str = "cargo";
const MIN_DEPTH: usize = 1;
const MAX_DEPTH: usize = 1;

fn main() {
    let mut cmd = Command::new(CARGO);
    let mut banner = String::from("Executing ") + CARGO;

    for arg in env::args().skip(2) {
        cmd.arg(OsString::from(&arg));
        banner = banner + " " + &arg;
    }

    announce(&banner);

    let is_crate = |e: &DirEntry| e.path().join("Cargo.toml").exists();
    let to_path_buf = |e: DirEntry| e.path().to_path_buf();
    let execute = move |p| cmd.current_dir(p).output().map(report_output);

    let cwd = env::current_dir().unwrap();
    walkdir::WalkDir::new(cwd)
        .min_depth(MIN_DEPTH)
        .max_depth(MAX_DEPTH)
        .into_iter()
        .filter_entry(is_crate)
        .filter_map(|e| e.ok())
        .map(to_path_buf)
        .inspect(display_path)
        .map(execute)
        .last();
}
<commit_msg>Document the .last() use<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::{Command, Output};
use walkdir::{DirEntry, WalkDirIterator};

fn announce(banner: &str) {
    let mut line = String::new();
    for _ in 0..banner.len() {
        line.push('-');
    }
    println!("{}", line);
    println!("{}", banner);
    println!("{}", line);
}

fn print_ident(buf: Vec<u8>) {
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn display_path(path: &PathBuf) {
    path.file_name()
        .and_then(|p| p.to_str())
        .map(|p| println!("{}:", p));
}

fn report_output(output: Output) {
    if output.status.success() {
        print_ident(output.stdout);
    } else {
        print_ident(output.stderr);
    }
    println!("");
}

const CARGO: &'static str = "cargo";
const MIN_DEPTH: usize = 1;
const MAX_DEPTH: usize = 1;

fn main() {
    let mut cmd = Command::new(CARGO);
    let mut banner = String::from("Executing ") + CARGO;

    for arg in env::args().skip(2) {
        cmd.arg(OsString::from(&arg));
        banner = banner + " " + &arg;
    }

    announce(&banner);

    let is_crate = |e: &DirEntry| e.path().join("Cargo.toml").exists();
    let to_path_buf = |e: DirEntry| e.path().to_path_buf();
    let execute = move |p| cmd.current_dir(p).output().map(report_output);

    let cwd = env::current_dir().unwrap();
    walkdir::WalkDir::new(cwd)
        .min_depth(MIN_DEPTH)
        .max_depth(MAX_DEPTH)
        .into_iter()
        .filter_entry(is_crate)
        .filter_map(|e| e.ok())
        .map(to_path_buf)
        .inspect(display_path)
        .map(execute)
        .last(); // XXX Non-idiomatic perhaps, but gets the job done. May need to revisit later.
}
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary move<commit_after><|endoftext|>


<commit_before><commit_msg>add subzones<commit_after><|endoftext|>


<commit_before><commit_msg>Aftermath from various attempts to close stdin.<commit_after><|endoftext|>


<commit_before><commit_msg>Added additional functions from visa and AgMD2<commit_after><|endoftext|>


<commit_before><commit_msg>More progress with arrays<commit_after><|endoftext|>


<commit_before><commit_msg>Minor fix<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unused #[macro_use]<commit_after><|endoftext|>


<commit_before><commit_msg>Check if VISUAL is set before checking EDITOR<commit_after><|endoftext|>


<commit_before><commit_msg>Re-align spotty with librespot to simplify updates.<commit_after><|endoftext|>


<commit_before>// For reference on linking to C++ functions, see https://github.com/rust-lang/rust/issues/5853#issuecomment-44365672

#[cfg(target_family = "windows")]
#[allow(non_snake_case)]
mod Platform {
    pub mod Details {
        #[link(name = "vccorlib")]
        #[cfg(target_arch="x86_64")]
        extern "C" {
            // This generates invalid program output causing a crash when this function is called. See https://github.com/rust-lang/rust/issues/23216 for details.
            #[link_name = "?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z"]
            pub fn GetCmdArguments(argc : *mut ::libc::c_int) -> *const *const ::libc::wchar_t;
        }

        #[link(name = "vccorlib")]
        #[cfg(target_arch = "x86")]
        extern "C" {
            // This generates invalid program output causing a crash when this function is called. See https://github.com/rust-lang/rust/issues/23216 for details.
            #[link_name = "?GetCmdArguments@Details@Platform@@YAPAPA_WPAH@Z"]
            pub fn GetCmdArguments(argc : *mut ::libc::c_int) -> *const *const ::libc::wchar_t;
        }
    }
}

pub fn get_command_arguments(argc : ::libc::c_int) -> (&'static [* const ::libc::wchar_t], usize) {
    let mut argc = argc;
    let argv = unsafe { Platform::Details::GetCmdArguments(&mut argc) };
    ( unsafe { ::std::slice::from_raw_parts(argv, argc as usize) }, argc as usize)
}

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

    #[test]
    fn test_get_command_arguments() {
        let (argv, argc) = get_command_arguments(0);
        assert!(argc == 1);
        for i in 0..argc {
            let argument : &[::libc::wchar_t] = unsafe { ::std::slice::from_raw_parts(argv[i], ::libc::wcslen(argv[i]) as usize) };
            // println!("Foo: {}", argument)
            // assert!(argument[0] == 'C' as u16)
        }
    }
}<commit_msg>Make get_command_arguments present a pure Rust return<commit_after>// For reference on linking to C++ functions, see https://github.com/rust-lang/rust/issues/5853#issuecomment-44365672

#[cfg(target_family = "windows")]
#[allow(non_snake_case)]
mod Platform {
    pub mod Details {
        #[link(name = "vccorlib")]
        #[cfg(target_arch="x86_64")]
        extern "C" {
            // This generates invalid program output causing a crash when this function is called. See https://github.com/rust-lang/rust/issues/23216 for details.
            #[link_name = "?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z"]
            pub fn GetCmdArguments(argc : *mut ::libc::c_int) -> *const *const ::libc::wchar_t;
        }

        #[link(name = "vccorlib")]
        #[cfg(target_arch = "x86")]
        extern "C" {
            // This generates invalid program output causing a crash when this function is called. See https://github.com/rust-lang/rust/issues/23216 for details.
            #[link_name = "?GetCmdArguments@Details@Platform@@YAPAPA_WPAH@Z"]
            pub fn GetCmdArguments(argc : *mut ::libc::c_int) -> *const *const ::libc::wchar_t;
        }
    }
}

pub fn get_command_arguments(argc : ::libc::c_int) -> Vec<String> {
    let mut argc = argc;
    let argv = unsafe { Platform::Details::GetCmdArguments(&mut argc) };
    let mut arguments : Vec<String> = Vec::with_capacity(argc as usize);
    /*
    // How do I make this code work?
    for arg in unsafe { ::std::slice::from_raw_parts(argv, argc as usize) }.into_iter() {
        let argument : &[::libc::wchar_t] = unsafe { ::std::slice::from_raw_parts(arg, ::libc::wcslen(arg) as usize) };
        arguments.push(String::from_utf16(unsafe { ::std::mem::transmute(argument) } ).unwrap())
    }
    */
    let args = unsafe { ::std::slice::from_raw_parts(argv, argc as usize) };
    for i in 0..args.len() {
        let argument : &[::libc::wchar_t] = unsafe { ::std::slice::from_raw_parts(args[i], ::libc::wcslen(args[i]) as usize) };
        arguments.push(String::from_utf16(unsafe { ::std::mem::transmute(argument) } ).unwrap())
    }
    arguments
}

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

    #[test]
    fn test_get_command_arguments() {
        let arguments = get_command_arguments(0);
        assert!(arguments.len() == 1);
        for argv in arguments {
            println!("{}", argv)
        }
    }
}<|endoftext|>


<commit_before>#![feature(staged_api)]
#![feature(test)]
#![unstable(feature = "test", issue = "0")]

extern crate test;

pub use test::*;

pub fn custom_api() {
}
<commit_msg>Use issue = "none" instead of "0"<commit_after>#![feature(staged_api)]
#![feature(test)]
#![unstable(feature = "test", issue = "none")]

extern crate test;

pub use test::*;

pub fn custom_api() {
}
<|endoftext|>


<commit_before><commit_msg>minor.<commit_after><|endoftext|>


<commit_before><commit_msg>add content to tombstone<commit_after><|endoftext|>


<commit_before>//! Apps should not need to concern themselves with this module.
//!
//! Crates which add new types which allow numeric operators should implement these traits to
//! specify what the output is for a given right hand side

/// Represents SQL types which can be added.
///
/// Similar to `std::ops::Add`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Add`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only have one other SQL type added
/// to it. The reason for this is that when the right side is a Rust value which would be sent as a
/// bind parameter, we need to know which type to use.
pub trait Add {
    /// The SQL type which can be added to this one
    type Rhs;
    /// The SQL type of the result of adding `Rhs` to `Self`
    type Output;
}

/// Represents SQL types which can be subtracted.
///
/// Similar to `std::ops::Sub`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Sub`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only have one other SQL type
/// subtracted from it. The reason for this is that when the right side is a Rust value which would
/// be sent as a bind parameter, we need to know which type to use.
pub trait Sub {
    /// The SQL type which can be subtracted from this one
    type Rhs;
    /// The SQL type of the result of subtracting `Rhs` from `Self`
    type Output;
}

/// Represents SQL types which can be multiplied.
///
/// Similar to `std::ops::Mul`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Mul`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only have one other SQL type
/// multiplied with it. The reason for this is that when the right side is a Rust value which
/// would be sent as a bind parameter, we need to know which type to use.
pub trait Mul {
    /// The SQL type which this can be multiplied by
    type Rhs;
    /// The SQL type of the result of multiplying `Self` by `Rhs`
    type Output;
}

/// Represents SQL types which can be divided.
///
/// Similar to `std::ops::Div`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Div`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only be divided by one other SQL
/// type. The reason for this is that when the right side is a Rust value which would be sent as a
/// bind parameter, we need to know which type to use.
pub trait Div {
    /// The SQL type which this one can be divided by
    type Rhs;
    /// The SQL type of the result of dividing `Self` by `Rhs`
    type Output;
}

macro_rules! numeric_type {
    ($($tpe: ident),*) => {
        $(
        impl Add for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Add for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Sub for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Sub for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Mul for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Mul for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Div for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Div for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }
        )*
    }
}

numeric_type!(SmallInt, Integer, BigInt, Float, Double, Numeric);

macro_rules! interval_type {
    ($($tpe: ident),*) => {
        $(
        impl Add for super::$tpe {
            type Rhs = super::Interval;
            type Output = super::$tpe;
        }

        impl Add for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::Interval>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Sub for super::$tpe {
            type Rhs = super::Interval;
            type Output = super::$tpe;
        }

        impl Sub for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::Interval>;
            type Output = super::Nullable<super::$tpe>;
        }
        )*
    }
}

interval_type!(Date, Timestamp);
<commit_msg>Postgres: {Date, Timestamp} + Interval = Timestamp<commit_after>//! Apps should not need to concern themselves with this module.
//!
//! Crates which add new types which allow numeric operators should implement these traits to
//! specify what the output is for a given right hand side

/// Represents SQL types which can be added.
///
/// Similar to `std::ops::Add`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Add`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only have one other SQL type added
/// to it. The reason for this is that when the right side is a Rust value which would be sent as a
/// bind parameter, we need to know which type to use.
pub trait Add {
    /// The SQL type which can be added to this one
    type Rhs;
    /// The SQL type of the result of adding `Rhs` to `Self`
    type Output;
}

/// Represents SQL types which can be subtracted.
///
/// Similar to `std::ops::Sub`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Sub`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only have one other SQL type
/// subtracted from it. The reason for this is that when the right side is a Rust value which would
/// be sent as a bind parameter, we need to know which type to use.
pub trait Sub {
    /// The SQL type which can be subtracted from this one
    type Rhs;
    /// The SQL type of the result of subtracting `Rhs` from `Self`
    type Output;
}

/// Represents SQL types which can be multiplied.
///
/// Similar to `std::ops::Mul`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Mul`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only have one other SQL type
/// multiplied with it. The reason for this is that when the right side is a Rust value which
/// would be sent as a bind parameter, we need to know which type to use.
pub trait Mul {
    /// The SQL type which this can be multiplied by
    type Rhs;
    /// The SQL type of the result of multiplying `Self` by `Rhs`
    type Output;
}

/// Represents SQL types which can be divided.
///
/// Similar to `std::ops::Div`, but this only includes information about the SQL types that will
/// result from the operation. Unlike `std::ops::Div`, the right side is an associated type rather
/// than a type parameter. This means that a given SQL type can only be divided by one other SQL
/// type. The reason for this is that when the right side is a Rust value which would be sent as a
/// bind parameter, we need to know which type to use.
pub trait Div {
    /// The SQL type which this one can be divided by
    type Rhs;
    /// The SQL type of the result of dividing `Self` by `Rhs`
    type Output;
}

macro_rules! numeric_type {
    ($($tpe: ident),*) => {
        $(
        impl Add for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Add for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Sub for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Sub for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Mul for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Mul for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }

        impl Div for super::$tpe {
            type Rhs = super::$tpe;
            type Output = super::$tpe;
        }

        impl Div for super::Nullable<super::$tpe> {
            type Rhs = super::Nullable<super::$tpe>;
            type Output = super::Nullable<super::$tpe>;
        }
        )*
    }
}

numeric_type!(SmallInt, Integer, BigInt, Float, Double, Numeric);

impl Add for super::Date {
    type Rhs = super::Interval;
    type Output = super::Timestamp;
}

impl Add for super::Nullable<super::Date> {
    type Rhs = super::Nullable<super::Interval>;
    type Output = super::Nullable<super::Timestamp>;
}

impl Sub for super::Date {
    type Rhs = super::Interval;
    type Output = super::Timestamp;
}

impl Sub for super::Nullable<super::Date> {
    type Rhs = super::Nullable<super::Interval>;
    type Output = super::Nullable<super::Timestamp>;
}

impl Add for super::Timestamp {
    type Rhs = super::Interval;
    type Output = super::Timestamp;
}

impl Add for super::Nullable<super::Timestamp> {
    type Rhs = super::Nullable<super::Interval>;
    type Output = super::Nullable<super::Timestamp>;
}

impl Sub for super::Timestamp {
    type Rhs = super::Interval;
    type Output = super::Timestamp;
}

impl Sub for super::Nullable<super::Timestamp> {
    type Rhs = super::Nullable<super::Interval>;
    type Output = super::Nullable<super::Timestamp>;
}
<|endoftext|>


<commit_before>/*
Basic interval implementation and other common functions/data structures
 */
#![feature(float_extras)]

// External libraries
use std::cmp::{PartialOrd, Ordering, PartialEq, Ord};
use std::f64::{NEG_INFINITY, INFINITY};

// Internal libraries
extern crate gr;
use gr::GI;

// Datatypes
pub type Flt = f64;
pub static INF:  Flt = INFINITY;
pub static NINF: Flt = NEG_INFINITY;

#[macro_export]
macro_rules! max {
    ($x:expr) => {{ $x }};
    ($x:expr, $($y:expr),* ) => {{
        let mut max = $x;
        $(
            max = if max > $y {max} else {$y};
        )*
            max
    }}
}

#[macro_export]
macro_rules! min {
    ($x:expr) => {{ $x }};
    ( $x:expr, $($y:expr),*) => {{
        let mut min = $x;
        $(
            min = if min < $y {min} else {$y};
        )*
            min
    }}
}

// Evolutionary algo
#[derive(Debug, Copy, Clone)]
pub struct Parameters {
    pub population:usize,
    pub selection: usize,
    pub elitism:   usize,
    pub mutation:    Flt,
    pub crossover:   Flt,
    pub seed:        u32,
}
// Evolutionary algo end

// Quple
// Data structure for insertion of a box into a priority queue
#[derive(Clone)]
pub struct Quple {
    pub p: Flt,
    pub pf: u32,
    pub data: Vec<GI>,
    pub fdata: GI
}

// Allow ordering of Quples
impl PartialEq for Quple {
    fn eq(&self, other: &Quple) -> bool {
        if self.pf == other.pf &&
            self.p == other.p {
                return true;
            }
        return false;
    }
}

impl Eq for Quple { }

impl PartialOrd for Quple {
    fn partial_cmp(&self, other: &Quple) -> Option<Ordering> {
        // This element is greater than the other element
        if self.pf < other.pf {
            return Some(Ordering::Greater);
        }
        else if self.pf == other.pf {
            return self.p.partial_cmp(&other.p);
        }
        else {
            return Some(Ordering::Less);
        }
    }
}

impl Ord for Quple {
    fn cmp(&self, other: &Quple) -> Ordering {
        if self.pf < other.pf {
            return Ordering::Greater;
        }
        else if self.pf == other.pf {
            if self.p > other.p {
                return Ordering::Greater;
            }
            else if self.p == other.p {
                return Ordering::Equal;
            }
            else {
                return Ordering::Less;
            }
        }
        else {
            return Ordering::Less;
        }
    }
}
// End Quple ordering.
// End Quple

pub fn eps_tol(fx: GI, est: f64, e_f: f64, e_f_r: f64) -> bool {
    (fx.upper() - est).abs() <= e_f_r*est +  e_f
}
<commit_msg>Added a function to print domains<commit_after>/*
Basic interval implementation and other common functions/data structures
 */
#![feature(float_extras)]

// External libraries
use std::cmp::{PartialOrd, Ordering, PartialEq, Ord};
use std::f64::{NEG_INFINITY, INFINITY};

// Internal libraries
extern crate gr;
use gr::GI;

// Datatypes
pub type Flt = f64;
pub static INF:  Flt = INFINITY;
pub static NINF: Flt = NEG_INFINITY;

#[macro_export]
macro_rules! max {
    ($x:expr) => {{ $x }};
    ($x:expr, $($y:expr),* ) => {{
        let mut max = $x;
        $(
            max = if max > $y {max} else {$y};
        )*
            max
    }}
}

#[macro_export]
macro_rules! min {
    ($x:expr) => {{ $x }};
    ( $x:expr, $($y:expr),*) => {{
        let mut min = $x;
        $(
            min = if min < $y {min} else {$y};
        )*
            min
    }}
}

// Evolutionary algo
#[derive(Debug, Copy, Clone)]
pub struct Parameters {
    pub population:usize,
    pub selection: usize,
    pub elitism:   usize,
    pub mutation:    Flt,
    pub crossover:   Flt,
    pub seed:        u32,
}
// Evolutionary algo end

// Quple
// Data structure for insertion of a box into a priority queue
#[derive(Clone)]
pub struct Quple {
    pub p: Flt,
    pub pf: u32,
    pub data: Vec<GI>,
    pub fdata: GI
}

// Allow ordering of Quples
impl PartialEq for Quple {
    fn eq(&self, other: &Quple) -> bool {
        if self.pf == other.pf &&
            self.p == other.p {
                return true;
            }
        return false;
    }
}

impl Eq for Quple { }

impl PartialOrd for Quple {
    fn partial_cmp(&self, other: &Quple) -> Option<Ordering> {
        // This element is greater than the other element
        if self.pf < other.pf {
            return Some(Ordering::Greater);
        }
        else if self.pf == other.pf {
            return self.p.partial_cmp(&other.p);
        }
        else {
            return Some(Ordering::Less);
        }
    }
}

impl Ord for Quple {
    fn cmp(&self, other: &Quple) -> Ordering {
        if self.pf < other.pf {
            return Ordering::Greater;
        }
        else if self.pf == other.pf {
            if self.p > other.p {
                return Ordering::Greater;
            }
            else if self.p == other.p {
                return Ordering::Equal;
            }
            else {
                return Ordering::Less;
            }
        }
        else {
            return Ordering::Less;
        }
    }
}
// End Quple ordering.
// End Quple

pub fn eps_tol(fx: GI, est: f64, e_f: f64, e_f_r: f64) -> bool {
    (fx.upper() - est).abs() <= e_f_r*est +  e_f
}

fn printerval(input: &Vec<GI>) -> () {
    print!("[");
    for i in 0..input.len() {
        print!("{}", input[i].to_string());
        if i < input.len() - 1 {
            print!(", ");
        }
    }
    println!("]");
}
<|endoftext|>


<commit_before>/*
    Copyright 2017-2018 Andrew Medworth <github@medworth.org.uk>

    This file is part of Dots-and-Boxes Engine.

    Dots-and-Boxes Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Dots-and-Boxes Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Dots-and-Boxes Engine.  If not, see <http://www.gnu.org/licenses/>.
*/
use game::{Position, Side};

pub fn p50_top() -> Position {
    let mut pos = Position::new_game(5, 2);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(1, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Right);
    for i in 0..5 {
        pos.make_move(i, 1, Side::Bottom);
    }
    pos
}

pub fn p50_bottomleft() -> Position {
    let mut pos = Position::new_game(3, 2);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(2, 0, Side::Top);
    pos.make_move(2, 0, Side::Right);
    pos.make_move(2, 1, Side::Right);
    pos.make_move(1, 0, Side::Bottom);
    pos
}

pub fn p50_bottomright() -> Position {
    let mut pos = Position::new_game(2, 2);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(0, 1, Side::Left);
    pos
}

pub fn p50() -> Position {
    let mut pos = Position::new_game(5, 4);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(1, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Right);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(0, 1, Side::Bottom);
    pos.make_move(1, 1, Side::Bottom);
    pos.make_move(2, 1, Side::Bottom);
    pos.make_move(3, 1, Side::Bottom);
    pos.make_move(4, 1, Side::Bottom);
    pos.make_move(1, 2, Side::Bottom);
    pos.make_move(2, 2, Side::Right);
    pos.make_move(2, 3, Side::Right);
    pos
}

pub fn icelandic_game(width: usize, height: usize) -> Position {
    let mut pos = Position::new_game(width, height);
    for y in 0..height {
        pos.make_move(0, y, Side::Left);
    }
    for x in 0..width {
        pos.make_move(x, 0, Side::Top);
    }
    pos
}

// Construct a position consisting of a given number of equally-sized chains.
pub fn multi_chains(chain_size: usize, chain_count: usize) -> Position {
    let mut pos = Position::new_game(chain_size, chain_count);
    for x in 0..chain_size {
        pos.make_move(x, 0, Side::Top);
        for y in 0..chain_count {
            pos.make_move(x, y, Side::Bottom);
        }
    }
    pos
}
// Create a position consisting of a single horizontal chain of a given length.
pub fn make_chain(length: usize) -> Position {
    multi_chains(length, 1)
}

// Create a position consisting of two horizontal chains of a given length.
pub fn double_chain(length: usize) -> Position {
    multi_chains(length, 2)
}

// Create a position consisting of two loops of a given width.
pub fn double_loop(width: usize) -> Position {
    let mut pos = Position::new_game(width, 4);
    for i in 0..width {
        pos.make_move(i, 0, Side::Top);
        pos.make_move(i, 1, Side::Bottom);
        pos.make_move(i, 3, Side::Bottom);
    }
    for i in 0..4 {
        pos.make_move(0, i, Side::Left);
        pos.make_move(width-1, i, Side::Right);
    }
    for i in 1..width-1 {
        pos.make_move(i, 0, Side::Bottom);
        pos.make_move(i, 2, Side::Bottom);
    }
    pos
}

// Create Exercise 3.1 from Berlekamp's book
pub fn ex3p1() -> Position {
    let mut pos = Position::new_game(3, 3);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(1, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Bottom);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(0, 1, Side::Right);
    pos.make_move(0, 2, Side::Right);
    pos.make_move(1, 2, Side::Bottom);
    pos.make_move(2, 2, Side::Right);
    pos
}

// Create Exercise 3.12 from Berlekamp's book
pub fn ex3p12() -> Position {
    let mut pos = Position::new_game(5, 5);
    for i in 0..5 {
        pos.make_move(i, 0, Side::Top);
    }
    pos.make_move(0, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Right);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(1, 1, Side::Bottom);
    pos.make_move(1, 1, Side::Right);
    pos.make_move(2, 1, Side::Right);
    pos.make_move(3, 1, Side::Bottom);
    pos.make_move(4, 1, Side::Bottom);
    pos.make_move(0, 2, Side::Right);
    pos.make_move(0, 2, Side::Bottom);
    pos.make_move(2, 2, Side::Right);
    pos.make_move(2, 2, Side::Bottom);
    pos.make_move(4, 2, Side::Right);
    pos.make_move(0, 3, Side::Right);
    pos.make_move(2, 3, Side::Bottom);
    pos.make_move(3, 3, Side::Bottom);
    pos.make_move(3, 3, Side::Right);
    pos.make_move(4, 3, Side::Right);
    pos.make_move(0, 4, Side::Right);
    pos.make_move(1, 4, Side::Right);
    pos.make_move(3, 4, Side::Bottom);
    pos.make_move(4, 4, Side::Bottom);
    pos.make_move(4, 4, Side::Right);
    pos
}

// Create Exercise 6.2 from Berlekamp's book
pub fn ex6p2() -> Position {
    let mut pos = Position::new_game(3, 2);
    for x in 0..3 {
        pos.make_move(x, 0, Side::Top);
    }
    for y in 0..2 {
        pos.make_move(2, y, Side::Right);
    }
    pos.make_move(1, 0, Side::Bottom);
    pos
}

// Create Exercise 7.2 from Berlekamp's book
pub fn ex7p2() -> Position {
    let mut pos = Position::new_game(5, 5);
    pos.make_move(0, 0, Side::Right);
    pos.make_move(1, 0, Side::Right);
    pos.make_move(3, 0, Side::Right);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(0, 1, Side::Right);
    pos.make_move(3, 1, Side::Right);
    pos.make_move(1, 1, Side::Bottom);
    pos.make_move(2, 1, Side::Bottom);
    pos.make_move(3, 1, Side::Bottom);
    pos.make_move(0, 2, Side::Bottom);
    pos.make_move(0, 2, Side::Right);
    pos.make_move(2, 2, Side::Bottom);
    pos.make_move(3, 2, Side::Right);
    pos.make_move(4, 2, Side::Right);
    pos.make_move(1, 3, Side::Right);
    pos.make_move(3, 3, Side::Right);
    pos.make_move(3, 3, Side::Bottom);
    pos.make_move(1, 4, Side::Right);
    pos.make_move(2, 4, Side::Right);
    pos
}<commit_msg>Add comments<commit_after>/*
    Copyright 2017-2019 Andrew Medworth <github@medworth.org.uk>

    This file is part of Dots-and-Boxes Engine.

    Dots-and-Boxes Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Dots-and-Boxes Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Dots-and-Boxes Engine.  If not, see <http://www.gnu.org/licenses/>.
*/
use game::{Position, Side};

// Top of example from page 50 of Berlekamp's book
pub fn p50_top() -> Position {
    let mut pos = Position::new_game(5, 2);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(1, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Right);
    for i in 0..5 {
        pos.make_move(i, 1, Side::Bottom);
    }
    pos
}

// Bottom-left of example from page 50 of Berlekamp's book
pub fn p50_bottomleft() -> Position {
    let mut pos = Position::new_game(3, 2);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(2, 0, Side::Top);
    pos.make_move(2, 0, Side::Right);
    pos.make_move(2, 1, Side::Right);
    pos.make_move(1, 0, Side::Bottom);
    pos
}

// Bottom-right of example from page 50 of Berlekamp's book
pub fn p50_bottomright() -> Position {
    let mut pos = Position::new_game(2, 2);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(0, 1, Side::Left);
    pos
}

// Example from page 50 of Berlekamp's book
pub fn p50() -> Position {
    let mut pos = Position::new_game(5, 4);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(1, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Bottom);
    pos.make_move(3, 0, Side::Right);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(0, 1, Side::Bottom);
    pos.make_move(1, 1, Side::Bottom);
    pos.make_move(2, 1, Side::Bottom);
    pos.make_move(3, 1, Side::Bottom);
    pos.make_move(4, 1, Side::Bottom);
    pos.make_move(1, 2, Side::Bottom);
    pos.make_move(2, 2, Side::Right);
    pos.make_move(2, 3, Side::Right);
    pos
}

pub fn icelandic_game(width: usize, height: usize) -> Position {
    let mut pos = Position::new_game(width, height);
    for y in 0..height {
        pos.make_move(0, y, Side::Left);
    }
    for x in 0..width {
        pos.make_move(x, 0, Side::Top);
    }
    pos
}

// Construct a position consisting of a given number of equally-sized chains.
pub fn multi_chains(chain_size: usize, chain_count: usize) -> Position {
    let mut pos = Position::new_game(chain_size, chain_count);
    for x in 0..chain_size {
        pos.make_move(x, 0, Side::Top);
        for y in 0..chain_count {
            pos.make_move(x, y, Side::Bottom);
        }
    }
    pos
}
// Create a position consisting of a single horizontal chain of a given length.
pub fn make_chain(length: usize) -> Position {
    multi_chains(length, 1)
}

// Create a position consisting of two horizontal chains of a given length.
pub fn double_chain(length: usize) -> Position {
    multi_chains(length, 2)
}

// Create a position consisting of two loops of a given width.
pub fn double_loop(width: usize) -> Position {
    let mut pos = Position::new_game(width, 4);
    for i in 0..width {
        pos.make_move(i, 0, Side::Top);
        pos.make_move(i, 1, Side::Bottom);
        pos.make_move(i, 3, Side::Bottom);
    }
    for i in 0..4 {
        pos.make_move(0, i, Side::Left);
        pos.make_move(width-1, i, Side::Right);
    }
    for i in 1..width-1 {
        pos.make_move(i, 0, Side::Bottom);
        pos.make_move(i, 2, Side::Bottom);
    }
    pos
}

// Create Exercise 3.1 from Berlekamp's book
pub fn ex3p1() -> Position {
    let mut pos = Position::new_game(3, 3);
    pos.make_move(0, 0, Side::Top);
    pos.make_move(0, 0, Side::Left);
    pos.make_move(1, 0, Side::Top);
    pos.make_move(1, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Bottom);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(0, 1, Side::Right);
    pos.make_move(0, 2, Side::Right);
    pos.make_move(1, 2, Side::Bottom);
    pos.make_move(2, 2, Side::Right);
    pos
}

// Create Exercise 3.12 from Berlekamp's book
pub fn ex3p12() -> Position {
    let mut pos = Position::new_game(5, 5);
    for i in 0..5 {
        pos.make_move(i, 0, Side::Top);
    }
    pos.make_move(0, 0, Side::Bottom);
    pos.make_move(2, 0, Side::Right);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(1, 1, Side::Bottom);
    pos.make_move(1, 1, Side::Right);
    pos.make_move(2, 1, Side::Right);
    pos.make_move(3, 1, Side::Bottom);
    pos.make_move(4, 1, Side::Bottom);
    pos.make_move(0, 2, Side::Right);
    pos.make_move(0, 2, Side::Bottom);
    pos.make_move(2, 2, Side::Right);
    pos.make_move(2, 2, Side::Bottom);
    pos.make_move(4, 2, Side::Right);
    pos.make_move(0, 3, Side::Right);
    pos.make_move(2, 3, Side::Bottom);
    pos.make_move(3, 3, Side::Bottom);
    pos.make_move(3, 3, Side::Right);
    pos.make_move(4, 3, Side::Right);
    pos.make_move(0, 4, Side::Right);
    pos.make_move(1, 4, Side::Right);
    pos.make_move(3, 4, Side::Bottom);
    pos.make_move(4, 4, Side::Bottom);
    pos.make_move(4, 4, Side::Right);
    pos
}

// Create Exercise 6.2 from Berlekamp's book
pub fn ex6p2() -> Position {
    let mut pos = Position::new_game(3, 2);
    for x in 0..3 {
        pos.make_move(x, 0, Side::Top);
    }
    for y in 0..2 {
        pos.make_move(2, y, Side::Right);
    }
    pos.make_move(1, 0, Side::Bottom);
    pos
}

// Create Exercise 7.2 from Berlekamp's book
pub fn ex7p2() -> Position {
    let mut pos = Position::new_game(5, 5);
    pos.make_move(0, 0, Side::Right);
    pos.make_move(1, 0, Side::Right);
    pos.make_move(3, 0, Side::Right);
    pos.make_move(0, 1, Side::Left);
    pos.make_move(0, 1, Side::Right);
    pos.make_move(3, 1, Side::Right);
    pos.make_move(1, 1, Side::Bottom);
    pos.make_move(2, 1, Side::Bottom);
    pos.make_move(3, 1, Side::Bottom);
    pos.make_move(0, 2, Side::Bottom);
    pos.make_move(0, 2, Side::Right);
    pos.make_move(2, 2, Side::Bottom);
    pos.make_move(3, 2, Side::Right);
    pos.make_move(4, 2, Side::Right);
    pos.make_move(1, 3, Side::Right);
    pos.make_move(3, 3, Side::Right);
    pos.make_move(3, 3, Side::Bottom);
    pos.make_move(1, 4, Side::Right);
    pos.make_move(2, 4, Side::Right);
    pos
}
<|endoftext|>