use serde::{Deserialize, Serialize};
use crate::error::Error;
use crate::result::Result;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub enum ContentType {
#[serde(rename = "text/html")]
Html,
#[serde(rename = "text/x-markdown")]
Markdown,
}
impl ContentType {
pub const HTML: &str = "text/html";
pub const MARKDOWN: &str = "text/x-markdown";
pub const fn new() -> Self {
Self::Html
}
pub const fn as_str(&self) -> &'static str {
match self {
Self::Html => Self::HTML,
Self::Markdown => Self::MARKDOWN,
}
}
pub fn try_from_str(val: &str) -> Result<Self> {
match val.to_lowercase().as_str() {
Self::HTML => Ok(Self::Html),
Self::MARKDOWN => Ok(Self::Markdown),
s => Err(Error::invalid_field(
"content_type",
s,
format!("{} | {}", Self::HTML, Self::MARKDOWN),
)),
}
}
}
impl Default for ContentType {
fn default() -> Self {
Self::new()
}
}
impl From<ContentType> for &'static str {
fn from(val: ContentType) -> Self {
val.as_str()
}
}
impl From<ContentType> for String {
fn from(val: ContentType) -> Self {
val.as_str().to_string()
}
}
impl TryFrom<&str> for ContentType {
type Error = Error;
fn try_from(val: &str) -> Result<Self> {
Self::try_from_str(val)
}
}
impl TryFrom<&String> for ContentType {
type Error = Error;
fn try_from(val: &String) -> Result<Self> {
Self::try_from_str(val.as_str())
}
}
impl TryFrom<String> for ContentType {
type Error = Error;
fn try_from(val: String) -> Result<Self> {
Self::try_from_str(val.as_str())
}
}
impl std::fmt::Display for ContentType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_content_type() {
[
(ContentType::Html, ContentType::HTML),
(ContentType::Markdown, ContentType::MARKDOWN),
]
.into_iter()
.for_each(|(ct_ty, ct_ty_str)| {
let ct_ty_json = format!(r#""{ct_ty_str}""#);
assert_eq!(ct_ty.as_str(), ct_ty_str);
assert_eq!(ContentType::try_from(ct_ty_str), Ok(ct_ty));
assert_eq!(ContentType::try_from(ct_ty_str.to_string()), Ok(ct_ty));
assert_eq!(serde_json::to_string(&ct_ty).unwrap(), ct_ty_json);
assert_eq!(
serde_json::from_str::<ContentType>(&ct_ty_json).unwrap(),
ct_ty
);
});
}
}