use crate::prelude::Status; use std::{fmt, str::FromStr}; mod error; pub use error::Error; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Sent from the receiving server back to the sending server pub struct Response { pub status: Status, pub meta: String, } impl fmt::Display for Response { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} {}\r\n", u8::from(self.status.clone()), self.meta) } } impl FromStr for Response { type Err = Error; fn from_str(s: &str) -> Result { if s.len() > 2048 { return Err(Error::TooLong); } if !s.ends_with("\r\n") { return Err(Error::Malformed); } let Some((status, meta)) = s.split_once(' ') else { return Err(Error::Malformed); }; let status: u8 = status.parse()?; let status: Status = status.try_into()?; Ok(Self { status, meta: meta.trim_end().to_string(), }) } } #[cfg(test)] mod tests { use super::*; #[test] fn parse_success() { let response: Response = "20 message delivered\r\n".parse().unwrap(); assert_eq!(response.status, Status::Success); assert_eq!(response.meta.as_str(), "message delivered"); } #[test] fn parse_badend() { let response = "20 message delivered\n".parse::(); assert_eq!(response, Err(Error::Malformed)); } #[test] fn parse_badint() { let response = "twenty message deliverred\r\n".parse::(); match response { Err(Error::ParseInt(_)) => {} _ => panic!(), } } }