Finish Request struct trait impl's; TODO: write tests

This commit is contained in:
Nathan Fisher 2023-05-22 10:25:49 -04:00
parent 30f78990b1
commit 6d66bf9664

View file

@ -13,3 +13,59 @@ impl fmt::Display for Request {
write!(f, "misfin://{}@{} {}\r\n", self.user, self.host, self.message)
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ParseRequestError {
MissingSeparator,
EmptyUser,
EmptyHost,
EmptyMessage,
Malformed,
ParseHostError(ParseHostError),
}
impl fmt::Display for ParseRequestError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ParseHostError(e) => write!(f, "{e}"),
_ => write!(f, "{self:?}")
}
}
}
impl std::error::Error for ParseRequestError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::ParseHostError(e) => Some(e),
_ => None,
}
}
}
impl From<ParseHostError> for ParseRequestError {
fn from(value: ParseHostError) -> Self {
Self::ParseHostError(value)
}
}
impl FromStr for Request {
type Err = ParseRequestError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if !s.ends_with("\r\n") {
return Err(ParseRequestError::Malformed);
}
if let Some((user, message)) = s.split_once(' ') {
let message = message.trim_end().to_string();
if let Some((user, host)) = user.rsplit_once('@') {
let host = host.parse()?;
let user = user.to_string();
Ok(Request { user, host, message })
} else {
Err(ParseRequestError::MissingSeparator)
}
} else {
Err(ParseRequestError::MissingSeparator)
}
}
}