dory/src/response.rs

106 lines
2.7 KiB
Rust
Raw Normal View History

2023-05-22 01:29:03 -04:00
use std::{fmt, str::FromStr, num::ParseIntError};
use crate::status::{Status, StatusError};
#[derive(Clone, Debug, PartialEq)]
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)
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ParseResponseError {
TooLong,
ParseInt(ParseIntError),
StatusError,
Malformed,
}
impl fmt::Display for ParseResponseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::TooLong => write!(f, "ParseResponseError: too long"),
Self::ParseInt(e) => write!(f, "ParseResponseError: {e}"),
Self::StatusError => write!(f, "ParseResponseError: Invalid Status"),
Self::Malformed => write!(f, "ParseResponseError: Malformed"),
}
}
}
impl std::error::Error for ParseResponseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::ParseInt(e) => Some(e),
_ => None,
}
}
}
impl From<ParseIntError> for ParseResponseError {
fn from(value: ParseIntError) -> Self {
Self::ParseInt(value)
}
}
impl From<StatusError> for ParseResponseError {
fn from(_value: StatusError) -> Self {
Self::StatusError
}
}
impl FromStr for Response {
type Err = ParseResponseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() > 2048 {
return Err(ParseResponseError::TooLong);
}
if !s.ends_with("\r\n") {
return Err(ParseResponseError::Malformed);
}
let Some((status, meta)) = s.split_once(' ') else {
return Err(ParseResponseError::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(ParseResponseError::Malformed));
}
#[test]
fn parse_badint() {
let response = "twenty message deliverred\r\n".parse::<Response>();
match response {
Err(ParseResponseError::ParseInt(_)) => {},
_ => panic!(),
}
}
2023-05-22 01:29:03 -04:00
}