twilio_rust 0.1.0

An async client library for Twilio based on hyper
Documentation
extern crate hyper;

use ::{Client, ToUrlEncoded};
use url::{form_urlencoded, Url};
use chrono::prelude::*;
use serde_helper;
use hyper::{Method, Request};
use hyper::header::{ContentType, ContentLength};
use futures::Future;

pub struct Messages<'a> {
    client: &'a Client,
}

#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum MessageStatus {
    Accepted,
    Queued,
    Sending,
    Sent,
    Failed,
    Delivered,
    Undelivered,
    Receiving,
    Received,
}

#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum MessageDirection {
    Inbound,
    OutboundApi,
    OutboundCall,
    OutboundReply,
}


#[derive(Deserialize)]
pub struct Message {
    pub sid: String,
    pub account_sid: String,
    pub messaging_service_sid: Option<String>,
    pub from: String,
    pub to: String,
    pub body: String,
    #[serde(deserialize_with = "serde_helper::deserialize_str_to_u32")] pub num_segments: Option<u32>,
    pub status: MessageStatus,
    pub error_code: Option<String>,
    pub error_message: Option<String>,
    pub direction: MessageDirection,
    pub price: Option<String>,
    pub price_unit: Option<String>,
    #[serde(deserialize_with = "serde_helper::deserialize_rfc2822")] pub date_created: Option<DateTime<Utc>>,
    #[serde(deserialize_with = "serde_helper::deserialize_rfc2822")] pub date_updated: Option<DateTime<Utc>>,
    #[serde(deserialize_with = "serde_helper::deserialize_rfc2822")] pub date_sent: Option<DateTime<Utc>>,
}

#[derive(Copy, Clone)]
pub enum MessageBody<'a> {
    SMS(&'a str),
    MMS(&'a Url),
}

#[derive(Copy, Clone)]
pub enum MessageFrom<'a> {
    From(&'a str),
    MessagingServiceSid(&'a str),
}

pub struct OutboundMessage<'a> {
    to: &'a str,
    from: MessageFrom<'a>,
    body: MessageBody<'a>,
    status_callback: Option<&'a Url>,
    application_sid: Option<&'a str>,
    max_price: Option<&'a str>,
    provide_feedback: bool,
    validity_period: Option<u32>,
}

pub struct OutboundMessageBuilder<'a> {
    to: &'a str,
    from: MessageFrom<'a>,
    body: MessageBody<'a>,
    status_callback: Option<&'a Url>,
    application_sid: Option<&'a str>,
    max_price: Option<&'a str>,
    provide_feedback: bool,
    validity_period: Option<u32>,
}

impl<'a> OutboundMessageBuilder<'a> {
    pub fn new_sms(from: MessageFrom<'a>, to: &'a str, body: &'a str) -> OutboundMessageBuilder<'a> {
        OutboundMessageBuilder {
            from,
            to,
            body: MessageBody::SMS(body),
            status_callback: None,
            application_sid: None,
            max_price: None,
            provide_feedback: false,
            validity_period: None,
        }
    }

    pub fn new_mms(from: MessageFrom<'a>, to: &'a str, body: &'a Url) -> OutboundMessageBuilder<'a> {
        OutboundMessageBuilder {
            from,
            to,
            body: MessageBody::MMS(body),
            status_callback: None,
            application_sid: None,
            max_price: None,
            provide_feedback: false,
            validity_period: None,
        }
    }

    pub fn with_status_callback(&mut self, url: &'a Url) -> &mut Self {
        self.status_callback = Some(url);
        self
    }

    pub fn with_application_sid(&mut self, application_sid: &'a str) -> &mut Self {
        self.application_sid = Some(application_sid);
        self
    }

    pub fn with_max_price(&mut self, max_price: &'a str) -> &mut Self {
        self.max_price = Some(max_price);
        self
    }

    pub fn with_provide_feedback(&mut self, provide_feedback: bool) -> &mut Self {
        self.provide_feedback = provide_feedback;
        self
    }

    pub fn with_validity_period(&mut self, validity_period: u32) -> &mut Self {
        self.validity_period = Some(validity_period);
        self
    }

    pub fn build(&self) -> OutboundMessage<'a> {
        OutboundMessage {
            from: self.from,
            to: self.to,
            body: self.body,
            status_callback: self.status_callback,
            application_sid: self.application_sid,
            max_price: self.max_price,
            provide_feedback: self.provide_feedback,
            validity_period: self.validity_period,
        }
    }
}

impl<'a> ToUrlEncoded for OutboundMessage<'a> {

    fn to_url_encoded(&self) -> String {
        let mut encoder = form_urlencoded::Serializer::new(String::new());
        encoder.append_pair("To", self.to);

        let (name, value) = match self.from {
            MessageFrom::From(x) => ("From", x),
            MessageFrom::MessagingServiceSid(x) => ("MessagingServiceSid", x),
        };

        encoder.append_pair(name, value);

        let (name, value) = match self.body {
            MessageBody::SMS(x) => ("Body", x),
            MessageBody::MMS(x) => ("MediaUrl", x.as_str()),
        };

        encoder.append_pair(name, value);

        if let Some(url) = self.status_callback {
            encoder.append_pair("StatusCallback", url.as_str());
        }

        if let Some(application_sid) = self.application_sid {
            encoder.append_pair("ApplicationSid", application_sid);
        }

        if let Some(max_price) = self.max_price {
            encoder.append_pair("MaxPrice", max_price);
        }

        if self.provide_feedback {
            encoder.append_pair("ProvideFeedback", "true");
        }

        if let Some(validity_period) = self.validity_period {
            encoder.append_pair("ValidityPeriod", &validity_period.to_string());
        }


        encoder.finish()
    }
}

impl<'a> Messages<'a> {

    pub fn new(client: &'a Client) -> Messages {
        Messages { client }
    }

    pub fn send_message(&self, message: &'a OutboundMessage) -> Box<Future<Item = Message, Error = ::TwilioError>> {
        let encoded_params = message.to_url_encoded();
        let uri = format!(
            "{}/2010-04-01/Accounts/{}/Messages.json",
            ::BASE_URI,
            self.client.account_sid).parse().unwrap();
        let mut req = Request::new(Method::Post, uri);
        req.headers_mut().set(ContentType::form_url_encoded());
        req.headers_mut().set(ContentLength(encoded_params.len() as u64));
        req.set_body(encoded_params.into_bytes());
        self.client.make_req(req)
    }
}