/
payload.rs
225 lines (188 loc) · 6.99 KB
/
payload.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
use std::collections::BTreeMap;
use rustc_serialize::json::{Json, ToJson};
pub struct Payload {
/// The standard APNS payload data.
pub aps: APS,
/// Custom data to be handled by the app.
pub custom: Option<CustomData>,
}
pub struct CustomData {
/// The JSON root key for app specific custom data.
pub key: String,
/// The custom data.
pub body: Json,
}
impl Payload {
pub fn new<S>(alert: APSAlert, sound: S, badge: Option<u32>, category: Option<String>,
custom_data: Option<CustomData>) -> Payload
where S: Into<String>
{
Payload {
aps: APS {
alert: Some(alert),
badge: badge,
sound: Some(sound.into()),
content_available: None,
category: category,
mutable_content: false,
},
custom: custom_data,
}
}
pub fn new_mutable<S>(alert: APSLocalizedAlert, sound: S, badge: Option<u32>, category: Option<String>,
custom_data: Option<CustomData>) -> Payload
where S: Into<String>
{
Payload {
aps: APS {
alert: Some(APSAlert::Localized(alert)),
badge: badge,
sound: Some(sound.into()),
content_available: None,
category: category,
mutable_content: true,
},
custom: custom_data,
}
}
pub fn new_silent_notification(custom_data: Option<CustomData>) -> Payload {
Payload {
aps: APS {
alert: None,
badge: None,
sound: None,
content_available: Some(1),
category: None,
mutable_content: false,
},
custom: custom_data,
}
}
pub fn to_string(&self) -> String {
self.to_json().to_string()
}
pub fn len(&self) -> usize {
self.to_string().len()
}
}
impl ToJson for Payload {
fn to_json(&self) -> Json {
let mut d = BTreeMap::new();
d.insert("aps".to_string(), self.aps.to_json());
if let Some(ref custom) = self.custom {
d.insert(custom.key.to_string(), custom.body.clone());
}
Json::Object(d)
}
}
/// The APS can contain one or more properties that specify the following user notification types:
/// - an alert message to display to the user
/// - a number to badge the app icon with
/// - a sound to play
pub struct APS {
/// If this property is included, the system displays a standard alert or a banner,
/// based on the user’s setting.
pub alert: Option<APSAlert>,
/// The number to display as the badge of the app icon.
pub badge: Option<u32>,
/// The name of a sound file in the app bundle or in the Library/Sounds folder of
/// the app’s data container.
pub sound: Option<String>,
/// Provide this key with a value of 1 to indicate that new content is available.
pub content_available: Option<u32>,
/// Provide this key with a string value that represents the identifier property.
pub category: Option<String>,
/// Can the client modify the alert before showing it to the user
pub mutable_content: bool,
}
impl ToJson for APS {
fn to_json(&self) -> Json {
let mut d = BTreeMap::new();
match self.alert {
Some(APSAlert::Plain(ref s)) => {
d.insert("alert".to_string(), s.to_json());
}
Some(APSAlert::Localized(ref l)) => {
d.insert("alert".to_string(), l.to_json());
}
None => {}
};
if let Some(ref badge) = self.badge {
d.insert("badge".to_string(), badge.to_json());
}
if let Some(ref sound) = self.sound {
d.insert("sound".to_string(), sound.to_json());
}
if let Some(ref content_available) = self.content_available {
d.insert("content-available".to_string(), content_available.to_json());
}
if let Some(ref category) = self.category {
d.insert("category".to_string(), category.to_json());
}
if self.mutable_content {
d.insert("mutable-content".to_string(), 1.to_json());
}
Json::Object(d)
}
}
/// Can specify a string or a dictionary as the value of alert.
pub enum APSAlert {
Plain(String),
Localized(APSLocalizedAlert),
}
/// Child properties of the alert property.
pub struct APSLocalizedAlert {
/// A short string describing the purpose of the notification
pub title: String,
/// The text of the alert message.
pub body: String,
/// The key to a title string in the Localizable.strings file for the current localization.
pub title_loc_key: Option<String>,
/// Variable string values to appear in place of the format specifiers in title-loc-key.
pub title_loc_args: Option<Vec<String>>,
/// If a string is specified, the system displays an alert that includes the Close and View buttons.
pub action_loc_key: Option<String>,
/// A key to an alert-message string in a Localizable.strings file for the current localization.
pub loc_key: Option<String>,
/// Variable string values to appear in place of the format specifiers in loc-key.
pub loc_args: Option<Vec<String>>,
/// The filename of an image file in the app bundle.
/// The image is used as the launch image when users tap the action button or move the action slider.
pub launch_image: Option<String>,
}
impl ToJson for APSLocalizedAlert {
fn to_json(&self) -> Json {
let mut d = BTreeMap::new();
d.insert("title".to_string(), self.title.to_json());
d.insert("body".to_string(), self.body.to_json());
if let Some(ref title_loc_key) = self.title_loc_key {
d.insert("title-loc-key".to_string(), title_loc_key.to_json());
} else {
d.insert("title-loc-key".to_string(), Json::Null);
}
if let Some(ref title_loc_args) = self.title_loc_args {
d.insert("title-loc-args".to_string(), title_loc_args.to_json());
} else {
d.insert("title-loc-args".to_string(), Json::Null);
}
if let Some(ref action_loc_key) = self.action_loc_key {
d.insert("action-loc-key".to_string(), action_loc_key.to_json());
} else {
d.insert("action-loc-key".to_string(), Json::Null);
}
if let Some(ref loc_key) = self.loc_key {
d.insert("loc-key".to_string(), loc_key.to_json());
} else {
d.insert("loc-key".to_string(), Json::Null);
}
if let Some(ref loc_args) = self.loc_args {
d.insert("loc-args".to_string(), loc_args.to_json());
} else {
d.insert("loc-args".to_string(), Json::Null);
}
if let Some(ref launch_image) = self.launch_image {
d.insert("launch-image".to_string(), launch_image.to_json());
}
Json::Object(d)
}
}