summaryrefslogtreecommitdiff
path: root/src/status.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/status.rs')
-rw-r--r--src/status.rs83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/status.rs b/src/status.rs
new file mode 100644
index 0000000..14f5ca3
--- /dev/null
+++ b/src/status.rs
@@ -0,0 +1,83 @@
+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<String>) -> 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<String>) -> Result<Self, HTTPError> {
+ 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::<u16>() 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<T> From<($type, T)> for Status
+ where
+ T: Into<String>
+ {
+ 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");