1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub struct TimeSlot {
19 pub emails: Vec<String>,
21
22 pub start_time: i64,
24
25 pub end_time: i64,
27}
28
29impl TimeSlot {
30 pub fn new(emails: Vec<String>, start_time: i64, end_time: i64) -> Self {
32 Self {
33 emails,
34 start_time,
35 end_time,
36 }
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
57pub struct AvailabilityResponse {
58 pub time_slots: Vec<TimeSlot>,
60}
61
62impl AvailabilityResponse {
63 pub fn new(time_slots: Vec<TimeSlot>) -> Self {
65 Self { time_slots }
66 }
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
83pub struct AvailabilityRequest {
84 pub emails: Vec<String>,
86
87 pub duration_minutes: u32,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
93 pub interval_minutes: Option<u32>,
94
95 pub start_time: i64,
97
98 pub end_time: i64,
100}
101
102impl AvailabilityRequest {
103 pub fn builder() -> AvailabilityRequestBuilder {
105 AvailabilityRequestBuilder {
106 emails: Vec::new(),
107 duration_minutes: None,
108 interval_minutes: None,
109 start_time: None,
110 end_time: None,
111 }
112 }
113
114 pub fn new(emails: Vec<String>, duration_minutes: u32, start_time: i64, end_time: i64) -> Self {
116 Self {
117 emails,
118 duration_minutes,
119 interval_minutes: None,
120 start_time,
121 end_time,
122 }
123 }
124}
125
126#[derive(Debug, Clone)]
128pub struct AvailabilityRequestBuilder {
129 emails: Vec<String>,
130 duration_minutes: Option<u32>,
131 interval_minutes: Option<u32>,
132 start_time: Option<i64>,
133 end_time: Option<i64>,
134}
135
136impl AvailabilityRequestBuilder {
137 pub fn email(mut self, email: impl Into<String>) -> Self {
139 self.emails.push(email.into());
140 self
141 }
142
143 pub fn emails(mut self, emails: Vec<String>) -> Self {
145 self.emails.extend(emails);
146 self
147 }
148
149 pub fn duration_minutes(mut self, duration: u32) -> Self {
151 self.duration_minutes = Some(duration);
152 self
153 }
154
155 pub fn interval_minutes(mut self, interval: u32) -> Self {
157 self.interval_minutes = Some(interval);
158 self
159 }
160
161 pub fn start_time(mut self, start_time: i64) -> Self {
163 self.start_time = Some(start_time);
164 self
165 }
166
167 pub fn end_time(mut self, end_time: i64) -> Self {
169 self.end_time = Some(end_time);
170 self
171 }
172
173 pub fn build(self) -> AvailabilityRequest {
179 AvailabilityRequest {
180 emails: if self.emails.is_empty() {
181 panic!("At least one email address is required")
182 } else {
183 self.emails
184 },
185 duration_minutes: self.duration_minutes.expect("duration_minutes is required"),
186 interval_minutes: self.interval_minutes,
187 start_time: self.start_time.expect("start_time is required"),
188 end_time: self.end_time.expect("end_time is required"),
189 }
190 }
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196
197 #[test]
198 fn test_time_slot_creation() {
199 let slot = TimeSlot::new(vec!["user@example.com".to_string()], 1234567890, 1234571490);
200
201 assert_eq!(slot.emails.len(), 1);
202 assert_eq!(slot.emails[0], "user@example.com");
203 assert_eq!(slot.start_time, 1234567890);
204 assert_eq!(slot.end_time, 1234571490);
205 }
206
207 #[test]
208 fn test_time_slot_serialization() {
209 let slot = TimeSlot::new(vec!["user@example.com".to_string()], 1234567890, 1234571490);
210
211 let json = serde_json::to_string(&slot).unwrap();
212 assert!(json.contains("user@example.com"));
213 assert!(json.contains("1234567890"));
214 assert!(json.contains("1234571490"));
215
216 let deserialized: TimeSlot = serde_json::from_str(&json).unwrap();
217 assert_eq!(deserialized, slot);
218 }
219
220 #[test]
221 fn test_availability_response_creation() {
222 let slots = vec![TimeSlot::new(
223 vec!["user@example.com".to_string()],
224 1234567890,
225 1234571490,
226 )];
227
228 let response = AvailabilityResponse::new(slots.clone());
229 assert_eq!(response.time_slots.len(), 1);
230 assert_eq!(response.time_slots[0], slots[0]);
231 }
232
233 #[test]
234 fn test_availability_response_serialization() {
235 let response = AvailabilityResponse::new(vec![TimeSlot::new(
236 vec!["user@example.com".to_string()],
237 1234567890,
238 1234571490,
239 )]);
240
241 let json = serde_json::to_string(&response).unwrap();
242 assert!(json.contains("user@example.com"));
243
244 let deserialized: AvailabilityResponse = serde_json::from_str(&json).unwrap();
245 assert_eq!(deserialized, response);
246 }
247
248 #[test]
249 fn test_availability_request_new() {
250 let request = AvailabilityRequest::new(
251 vec!["user@example.com".to_string()],
252 30,
253 1234567890,
254 1234654290,
255 );
256
257 assert_eq!(request.emails.len(), 1);
258 assert_eq!(request.emails[0], "user@example.com");
259 assert_eq!(request.duration_minutes, 30);
260 assert_eq!(request.start_time, 1234567890);
261 assert_eq!(request.end_time, 1234654290);
262 assert_eq!(request.interval_minutes, None);
263 }
264
265 #[test]
266 fn test_availability_request_builder_single_email() {
267 let request = AvailabilityRequest::builder()
268 .email("user@example.com")
269 .duration_minutes(30)
270 .start_time(1234567890)
271 .end_time(1234654290)
272 .build();
273
274 assert_eq!(request.emails.len(), 1);
275 assert_eq!(request.emails[0], "user@example.com");
276 assert_eq!(request.duration_minutes, 30);
277 }
278
279 #[test]
280 fn test_availability_request_builder_multiple_emails() {
281 let request = AvailabilityRequest::builder()
282 .email("user1@example.com")
283 .email("user2@example.com")
284 .duration_minutes(45)
285 .interval_minutes(15)
286 .start_time(1234567890)
287 .end_time(1234654290)
288 .build();
289
290 assert_eq!(request.emails.len(), 2);
291 assert_eq!(request.duration_minutes, 45);
292 assert_eq!(request.interval_minutes, Some(15));
293 }
294
295 #[test]
296 fn test_availability_request_builder_with_emails_vec() {
297 let emails = vec![
298 "user1@example.com".to_string(),
299 "user2@example.com".to_string(),
300 ];
301
302 let request = AvailabilityRequest::builder()
303 .emails(emails)
304 .duration_minutes(60)
305 .start_time(1234567890)
306 .end_time(1234654290)
307 .build();
308
309 assert_eq!(request.emails.len(), 2);
310 assert_eq!(request.duration_minutes, 60);
311 }
312
313 #[test]
314 #[should_panic(expected = "At least one email address is required")]
315 fn test_availability_request_builder_no_emails() {
316 AvailabilityRequest::builder()
317 .duration_minutes(30)
318 .start_time(1234567890)
319 .end_time(1234654290)
320 .build();
321 }
322
323 #[test]
324 #[should_panic(expected = "duration_minutes is required")]
325 fn test_availability_request_builder_no_duration() {
326 AvailabilityRequest::builder()
327 .email("user@example.com")
328 .start_time(1234567890)
329 .end_time(1234654290)
330 .build();
331 }
332
333 #[test]
334 #[should_panic(expected = "start_time is required")]
335 fn test_availability_request_builder_no_start_time() {
336 AvailabilityRequest::builder()
337 .email("user@example.com")
338 .duration_minutes(30)
339 .end_time(1234654290)
340 .build();
341 }
342
343 #[test]
344 fn test_availability_request_serialization() {
345 let request = AvailabilityRequest::builder()
346 .email("user@example.com")
347 .duration_minutes(30)
348 .interval_minutes(15)
349 .start_time(1234567890)
350 .end_time(1234654290)
351 .build();
352
353 let json = serde_json::to_string(&request).unwrap();
354 assert!(json.contains("user@example.com"));
355 assert!(json.contains("30"));
356 assert!(json.contains("15"));
357
358 let deserialized: AvailabilityRequest = serde_json::from_str(&json).unwrap();
359 assert_eq!(deserialized, request);
360 }
361
362 #[test]
363 fn test_availability_request_serialization_no_interval() {
364 let request = AvailabilityRequest::new(
365 vec!["user@example.com".to_string()],
366 30,
367 1234567890,
368 1234654290,
369 );
370
371 let json = serde_json::to_string(&request).unwrap();
372 assert!(!json.contains("interval_minutes"));
374
375 let deserialized: AvailabilityRequest = serde_json::from_str(&json).unwrap();
376 assert_eq!(deserialized, request);
377 }
378}