messagebird_async/sms/
recipient.rs

1use super::*;
2
3// requires manual Serialize/Deserialize impl
4#[derive(Copy, Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
5#[serde(rename = "msisdn")]
6pub struct Msisdn(u64);
7
8impl Deref for Msisdn {
9    type Target = u64;
10    fn deref(&self) -> &Self::Target {
11        &self.0
12    }
13}
14
15/// Mobile Subscriber Integrated Services Digital Network Number
16///
17/// A worldwide unique phone number. This does not require a `+` or `00` prefix before the country code.
18impl Msisdn {
19    pub fn new(raw: u64) -> Result<Self, MessageBirdError> {
20        if raw != 0 {
21            Ok(Msisdn(raw))
22        } else {
23            Err(MessageBirdError::TypeError {
24                msg: format!("Invalid phone number: {}", raw),
25            })
26        }
27    }
28
29    /// convert from u64
30    ///
31    /// TODO use TryFrom as soon as stabilized
32    pub fn try_from(raw: u64) -> Result<Self, MessageBirdError> {
33        Msisdn::new(raw)
34    }
35}
36
37impl FromStr for Msisdn {
38    type Err = MessageBirdError;
39    fn from_str(s: &str) -> Result<Self, Self::Err> {
40        serde_plain::from_str::<Self>(s).map_err(|_e| MessageBirdError::ParseError)
41    }
42}
43
44impl ToString for Msisdn {
45    fn to_string(&self) -> String {
46        serde_plain::to_string(self).unwrap()
47    }
48}
49
50/// Deliver Status of a SMS message
51#[derive(Copy, Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
52#[serde(rename_all = "snake_case")]
53pub enum Status {
54    /// not defined by the spec (you should never see this)
55    Unknown,
56    /// tracked in message birds system, but not delivered yet
57    Scheduled,
58    /// Sent, but not on the device just yet
59    Sent,
60    /// TODO
61    Buffered,
62    /// Delivery completed
63    Delivered,
64    /// SMS did not get delivered to the recipient, usually happens after 48 hours
65    Expired,
66    /// TODO not sure about the difference to `Expired`
67    DeliveryFailed,
68}
69
70impl Status {
71    pub fn as_str(&self) -> &str {
72        match self {
73            Status::Scheduled => "scheduled",
74            Status::Sent => "sent",
75            Status::Buffered => "buffered",
76            Status::Delivered => "delivered",
77            Status::Expired => "expired",
78            Status::DeliveryFailed => "delivery_failed",
79            _ => "invalid",
80        }
81    }
82}
83
84impl FromStr for Status {
85    type Err = MessageBirdError;
86    fn from_str(s: &str) -> Result<Self, Self::Err> {
87        serde_plain::from_str::<Self>(s).map_err(|_e| MessageBirdError::ParseError)
88    }
89}
90
91impl ToString for Status {
92    fn to_string(&self) -> String {
93        serde_plain::to_string(self).unwrap()
94    }
95}
96
97/// Recipient
98///
99/// Definition of a recepient, used for querying the status of a SMS.
100/// Contains the deliver status of a message as well as the time of posting
101/// the SMS to the MessageBird API.
102#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
103#[serde(rename_all = "snake_case")]
104pub struct Recipient {
105    #[serde(rename = "recipient")]
106    msisdn: Msisdn,
107    #[serde(rename = "status")]
108    status: Option<Status>,
109    #[serde(rename = "statusDatetime")]
110    status_datetime: Option<DateTime>,
111}
112
113impl Recipient {
114    pub fn new(number: u64) -> Self {
115        Self {
116            msisdn: Msisdn(number),
117            status: None,
118            status_datetime: None,
119        }
120    }
121}
122
123impl From<u64> for Recipient {
124    fn from(raw: u64) -> Self {
125        Recipient::new(raw)
126    }
127}
128
129impl FromStr for Recipient {
130    type Err = MessageBirdError;
131    fn from_str(s: &str) -> Result<Self, Self::Err> {
132        let s = s.replace('"', "");
133        s.parse::<u64>()
134            .and_then(|x: u64| Ok(Recipient::from(x)))
135            .map_err(|e| {
136                debug!("{:?}", e);
137                MessageBirdError::ParseError
138            })
139    }
140}
141
142#[cfg(test)]
143mod test {
144    use super::*;
145
146    serde_roundtrip!(recipient_serde, Recipient, Recipient::new(1234512345));
147
148    static RAW_1: &str = r#"{
149"recipient": 23747,
150"status": "delivery_failed",
151"statusDatetime" : "2016-05-03T14:26:57+00:00"
152}"#;
153    deser_roundtrip!(recipient_sample1_deser, Recipient, RAW_1);
154
155    //only one or the other can work at the same time, since serialize can only work one way at a time
156    //     static RAW_2: &str = r#"{
157    // "recipient": 23747,
158    // }"#;
159    //deser_roundtrip!(recipient_sample3_deser, Recipient, RAW_2);
160
161    static RAW_3: &str = r#"{
162    "recipient": 23747,
163    "status": null,
164    "statusDatetime" : null
165    }"#;
166
167    deser_roundtrip!(recipient_sample2_deser, Recipient, RAW_3);
168}