71 lines
1.8 KiB
Rust
71 lines
1.8 KiB
Rust
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<Self, Self::Err> {
|
|
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::<Response>();
|
|
assert_eq!(response, Err(Error::Malformed));
|
|
}
|
|
|
|
#[test]
|
|
fn parse_badint() {
|
|
let response = "twenty message deliverred\r\n".parse::<Response>();
|
|
match response {
|
|
Err(Error::ParseInt(_)) => {}
|
|
_ => panic!(),
|
|
}
|
|
}
|
|
}
|