Add Response struct and tests
This commit is contained in:
parent
399d567c62
commit
62eeb9d627
2 changed files with 97 additions and 14 deletions
15
src/lib.rs
15
src/lib.rs
|
@ -1,16 +1,3 @@
|
||||||
|
pub mod response;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
|
||||||
pub fn add(left: usize, right: usize) -> usize {
|
|
||||||
left + right
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
96
src/response.rs
Normal file
96
src/response.rs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue