From 6d66bf9664457bf5c97138f4b9030c184d59efd1 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 22 May 2023 10:25:49 -0400 Subject: [PATCH] Finish Request struct trait impl's; TODO: write tests --- src/request.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/request.rs b/src/request.rs index 7e7efc1..21210da 100644 --- a/src/request.rs +++ b/src/request.rs @@ -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 for ParseRequestError { + fn from(value: ParseHostError) -> Self { + Self::ParseHostError(value) + } +} + +impl FromStr for Request { + type Err = ParseRequestError; + + fn from_str(s: &str) -> Result { + 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) + } + } +}