use crate::wire::{WireContact, WireDeliveredEmail, WireSendResponseData}; /// Successful send result. #[derive(Clone, Debug, PartialEq, Eq)] pub struct SendResponse { deliveries: Vec, timestamp: String, } impl SendResponse { pub fn deliveries(&self) -> &[Delivery] { &self.deliveries } pub fn timestamp(&self) -> &str { &self.timestamp } } impl From for SendResponse { fn from(value: WireSendResponseData) -> Self { Self { deliveries: value.emails.into_iter().map(Delivery::from).collect(), timestamp: value.timestamp, } } } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Delivery { contact: Contact, id: String, } impl Delivery { pub fn contact(&self) -> &Contact { &self.contact } pub fn id(&self) -> &str { &self.id } } impl From for Delivery { fn from(value: WireDeliveredEmail) -> Self { Self { contact: Contact::from(value.contact), id: value.email, } } } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Contact { id: String, email: String, } impl Contact { pub fn id(&self) -> &str { &self.id } pub fn email(&self) -> &str { &self.email } } impl From for Contact { fn from(value: WireContact) -> Self { Self { id: value.id, email: value.email, } } } #[cfg(test)] mod tests { use super::*; use crate::wire::WireSendResponse; use serde_json::json; #[test] fn deserializes_success_response_into_domain_types() { let response = serde_json::from_value::(json!({ "success": true, "data": { "emails": [ { "contact": { "id": "cnt_abc123", "email": "user@example.com" }, "email": "ac32f08e-c6b9-45d3-9824-a73dff1e3bbf" } ], "timestamp": "2025-01-15T10:30:00.000Z" } })) .unwrap(); let response = SendResponse::from(response.data); assert_eq!(response.deliveries().len(), 1); assert_eq!( response.deliveries()[0].contact().email(), "user@example.com" ); assert_eq!( response.deliveries()[0].id(), "ac32f08e-c6b9-45d3-9824-a73dff1e3bbf" ); } }