dory/src/response/mod.rs

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!(),
}
}
}