Skip to main content

zulip_api/message/
content_type.rs

1use serde::{Deserialize, Serialize};
2
3use crate::error::Error;
4use crate::result::Result;
5
6/// Represents the content type of a Zulip message.
7#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
8pub enum ContentType {
9    #[serde(rename = "text/html")]
10    Html,
11    #[serde(rename = "text/x-markdown")]
12    Markdown,
13}
14
15impl ContentType {
16    /// Represents the string value of the HTML [ContentType].
17    pub const HTML: &str = "text/html";
18    /// Represents the string value of the Markdown [ContentType].
19    pub const MARKDOWN: &str = "text/x-markdown";
20
21    /// Creates a new [ContentType].
22    pub const fn new() -> Self {
23        Self::Html
24    }
25
26    /// Gets the [ContentType] string representation.
27    pub const fn as_str(&self) -> &'static str {
28        match self {
29            Self::Html => Self::HTML,
30            Self::Markdown => Self::MARKDOWN,
31        }
32    }
33
34    /// Attempts to convert a string into a [ContentType].
35    pub fn try_from_str(val: &str) -> Result<Self> {
36        match val.to_lowercase().as_str() {
37            Self::HTML => Ok(Self::Html),
38            Self::MARKDOWN => Ok(Self::Markdown),
39            s => Err(Error::invalid_field(
40                "content_type",
41                s,
42                format!("{} | {}", Self::HTML, Self::MARKDOWN),
43            )),
44        }
45    }
46}
47
48impl Default for ContentType {
49    fn default() -> Self {
50        Self::new()
51    }
52}
53
54impl From<ContentType> for &'static str {
55    fn from(val: ContentType) -> Self {
56        val.as_str()
57    }
58}
59
60impl From<ContentType> for String {
61    fn from(val: ContentType) -> Self {
62        val.as_str().to_string()
63    }
64}
65
66impl TryFrom<&str> for ContentType {
67    type Error = Error;
68
69    fn try_from(val: &str) -> Result<Self> {
70        Self::try_from_str(val)
71    }
72}
73
74impl TryFrom<&String> for ContentType {
75    type Error = Error;
76
77    fn try_from(val: &String) -> Result<Self> {
78        Self::try_from_str(val.as_str())
79    }
80}
81
82impl TryFrom<String> for ContentType {
83    type Error = Error;
84
85    fn try_from(val: String) -> Result<Self> {
86        Self::try_from_str(val.as_str())
87    }
88}
89
90impl std::fmt::Display for ContentType {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        write!(f, "{}", self.as_str())
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn test_content_type() {
102        [
103            (ContentType::Html, ContentType::HTML),
104            (ContentType::Markdown, ContentType::MARKDOWN),
105        ]
106        .into_iter()
107        .for_each(|(ct_ty, ct_ty_str)| {
108            let ct_ty_json = format!(r#""{ct_ty_str}""#);
109
110            assert_eq!(ct_ty.as_str(), ct_ty_str);
111            assert_eq!(ContentType::try_from(ct_ty_str), Ok(ct_ty));
112            assert_eq!(ContentType::try_from(ct_ty_str.to_string()), Ok(ct_ty));
113
114            assert_eq!(serde_json::to_string(&ct_ty).unwrap(), ct_ty_json);
115            assert_eq!(
116                serde_json::from_str::<ContentType>(&ct_ty_json).unwrap(),
117                ct_ty
118            );
119        });
120    }
121}