1#[derive(serde::Serialize)]
5pub struct Message {
6 da: String,
7 ud: String,
8 #[serde(skip_serializing_if = "Option::is_none")]
9 limit: Option<u8>,
10 #[serde(skip_serializing_if = "Option::is_none")]
11 costcentre: Option<String>,
12 #[serde(skip_serializing_if = "Option::is_none")]
13 private: Option<bool>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 oa: Option<String>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 udh: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 srr: Option<String>,
20}
21
22impl Message {
23 pub fn builder() -> MessageBuilder {
25 MessageBuilder {
26 ..MessageBuilder::default()
27 }
28 }
29}
30
31#[derive(Default, Debug)]
33pub struct MessageBuilder {
34 da: Option<String>,
35 ud: Option<String>,
36 limit: Option<u8>,
37 costcentre: Option<String>,
38 private: Option<bool>,
39 oa: Option<String>,
40 udh: Option<String>,
41 srr: Option<String>,
42}
43
44impl MessageBuilder {
45 pub fn build(self) -> Message {
47 Message {
48 da: self
49 .da
50 .expect("Cannot build sms without destination, `da`."),
51 ud: self.ud.expect("Cannot build sms without message, `ud`."),
52 limit: self.limit,
53 costcentre: self.costcentre,
54 private: self.private,
55 oa: self.oa,
56 udh: self.udh,
57 srr: self.srr,
58 }
59 }
60
61 pub fn da(mut self, da: impl Into<String>) -> Self {
69 self.da = Some(da.into());
70 self
71 }
72
73 pub fn destination(self, destination: impl Into<String>) -> Self {
77 self.da(destination)
78 }
79
80 pub fn ud(mut self, ud: impl Into<String>) -> Self {
86 self.ud = Some(ud.into());
87 self
88 }
89
90 pub fn message(self, message: impl Into<String>) -> Self {
94 self.ud(message)
95 }
96
97 pub fn limit(mut self, limit: u8) -> Self {
102 self.limit = Some(limit);
103 self
104 }
105
106 pub fn costcentre(mut self, costcentre: impl Into<String>) -> Self {
111 self.costcentre = Some(costcentre.into());
112 self
113 }
114
115 pub fn private(mut self, private: bool) -> Self {
120 self.private = Some(private);
121 self
122 }
123
124 pub fn oa(mut self, oa: impl Into<String>) -> Self {
129 self.oa = Some(oa.into());
130 self
131 }
132
133 pub fn udh(mut self, udh: impl Into<String>) -> Self {
137 self.udh = Some(udh.into());
138 self
139 }
140
141 pub fn srr(mut self, srr: impl Into<String>) -> Self {
145 self.srr = Some(srr.into());
146 self
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[test]
155 fn builder_default_all_none() {
156 let mb = Message::builder();
157 assert_eq!(mb.da, None);
158 assert_eq!(mb.ud, None);
159 assert_eq!(mb.limit, None);
160 assert_eq!(mb.costcentre, None);
161 assert_eq!(mb.private, None);
162 assert_eq!(mb.oa, None);
163 assert_eq!(mb.udh, None);
164 assert_eq!(mb.srr, None);
165 }
166
167 #[test]
168 fn basic_builder_setters_work() {
169 let mb = Message::builder().da("123");
170 assert_eq!(mb.da, Some(String::from("123")));
171
172 let mb = Message::builder().ud("123");
173 assert_eq!(mb.ud, Some(String::from("123")));
174 assert_eq!(mb.da, None);
175
176 let mb = Message::builder().limit(1);
177 assert_eq!(mb.limit, Some(1));
178 assert_eq!(mb.ud, None);
179
180 let mb = Message::builder().costcentre("123");
181 assert_eq!(mb.costcentre, Some(String::from("123")));
182 assert_eq!(mb.limit, None);
183
184 let mb = Message::builder().private(true);
185 assert_eq!(mb.private, Some(true));
186 assert_eq!(mb.costcentre, None);
187
188 let mb = Message::builder().oa("123");
189 assert_eq!(mb.oa, Some(String::from("123")));
190 assert_eq!(mb.private, None);
191
192 let mb = Message::builder().udh("123");
193 assert_eq!(mb.udh, Some(String::from("123")));
194 assert_eq!(mb.oa, None);
195
196 let mb = Message::builder().srr("123");
197 assert_eq!(mb.srr, Some(String::from("123")));
198 assert_eq!(mb.udh, None);
199 }
200
201 #[test]
202 fn basic_builder_works() {
203 let message = Message::builder().da("123").ud("456").build();
204 assert_eq!(message.da, "123");
205 assert_eq!(message.ud, "456");
206 }
207
208 #[test]
209 fn sugar_builder_works() {
210 let message = Message::builder().destination("123").message("456").build();
211 assert_eq!(message.da, "123");
212 assert_eq!(message.ud, "456");
213 }
214
215 #[test]
216 fn basic_builder_order_doesnt_matter() {
217 let message1 = Message::builder().da("123").ud("456").build();
218 let message2 = Message::builder().ud("456").da("123").build();
219 assert_eq!(message1.da, message2.da);
220 assert_eq!(message1.ud, message2.ud);
221 }
222
223 #[test]
224 fn sugar_or_basic_builder_doesnt_matter() {
225 let message1 = Message::builder().da("123").message("456").build();
226 let message2 = Message::builder().destination("123").ud("456").build();
227 assert_eq!(message1.da, message2.da);
228 assert_eq!(message1.ud, message2.ud);
229 }
230
231 #[test]
232 #[should_panic]
233 fn build_without_da_fails() {
234 Message::builder().ud("123").build();
235 }
236
237 #[test]
238 #[should_panic]
239 fn build_without_ud_fails() {
240 Message::builder().da("123").build();
241 }
242}