use std::borrow::Cow; use crate::{parse::TryParse, error::HTTPError}; pub struct Status(u16, Cow<'static, str>); impl Status { pub fn new(code: u16, msg: impl Into) -> Self { Self(code, Cow::Owned(msg.into())) } pub fn code(&self) -> u16 { self.0 } pub fn msg(&self) -> &str { self.1.as_ref() } } impl ToString for Status { fn to_string(&self) -> String { if self.1.len() < 1 { format!("{}", self.0) } else { format!("{} {}", self.0, self.1) } } } impl TryParse for Status { fn try_parse(s: impl Into) -> Result { let s = s.into(); let mut parts = s.split(" "); let Some(code_str) = parts.next() else { return Err(HTTPError::InvalidStatus(s)) }; let Ok(code) = code_str.parse::() else { return Err(HTTPError::InvalidStatus(s)) }; let msg: String = parts.collect(); Ok(Self::new(code, msg)) } } impl PartialEq for Status { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } macro_rules! status_from { ($type:ty) => { impl From<$type> for Status { fn from(value: $type) -> Self { Self(value as u16, Cow::Owned(String::new())) } } impl From<($type, T)> for Status where T: Into { fn from(value: ($type, T)) -> Self { Self(value.0 as u16, Cow::Owned(value.1.into())) } } }; } status_from!(u8); status_from!(u16); status_from!(u32); status_from!(u64); status_from!(u128); macro_rules! status { ($name:ident, $code:literal, $msg:literal) => { pub const $name: Status = Status($code, Cow::Borrowed($msg)); }; } status!(SUCCESS, 200, "Ok");