Skip to main content

zulip_api/message/response/
result.rs

1use serde::{Deserialize, Serialize};
2use zeroize::Zeroize;
3
4use crate::error::Error;
5use crate::result::Result;
6
7/// Represents the `result` field returned in Zulip API responses.
8#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize, Zeroize)]
9#[serde(rename_all = "lowercase")]
10pub enum ApiResult {
11    Success,
12    Error,
13}
14
15impl ApiResult {
16    /// Represents the string value of a success result.
17    pub const SUCCESS: &str = "success";
18    /// Represents the string value of an error result.
19    pub const ERROR: &str = "error";
20
21    /// Creates a new [ApiResult].
22    pub const fn new() -> Self {
23        Self::Success
24    }
25
26    /// Gets the string representation of the [ApiResult].
27    pub const fn as_str(&self) -> &'static str {
28        match self {
29            Self::Success => Self::SUCCESS,
30            Self::Error => Self::ERROR,
31        }
32    }
33
34    /// Attempts to convert a string into an [ApiResult].
35    pub fn try_from_str<S: Into<String>>(val: S) -> Result<Self> {
36        match val.into().to_lowercase().as_str() {
37            Self::SUCCESS => Ok(Self::Success),
38            Self::ERROR => Ok(Self::Error),
39            s => Err(Error::io_other(format!("invalid ApiResult: {s}"))),
40        }
41    }
42}
43
44impl Default for ApiResult {
45    fn default() -> Self {
46        Self::new()
47    }
48}
49
50impl From<ApiResult> for &'static str {
51    fn from(val: ApiResult) -> Self {
52        val.as_str()
53    }
54}
55
56impl From<ApiResult> for String {
57    fn from(val: ApiResult) -> Self {
58        val.as_str().to_string()
59    }
60}
61
62impl TryFrom<&str> for ApiResult {
63    type Error = Error;
64
65    fn try_from(val: &str) -> Result<Self> {
66        Self::try_from_str(val)
67    }
68}
69
70impl TryFrom<String> for ApiResult {
71    type Error = Error;
72
73    fn try_from(val: String) -> Result<Self> {
74        Self::try_from_str(val.as_str())
75    }
76}
77
78impl std::fmt::Display for ApiResult {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        write!(f, "{}", self.as_str())
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn test_api_result() {
90        [ApiResult::Success, ApiResult::Error]
91            .into_iter()
92            .zip([ApiResult::SUCCESS, ApiResult::ERROR])
93            .for_each(|(res, res_str)| {
94                let res_json = format!(r#""{res}""#);
95                assert_eq!(res.as_str(), res_str);
96
97                assert_eq!(<&str>::from(res), res_str);
98                assert_eq!(String::from(res), res_str.to_string());
99
100                assert_eq!(ApiResult::try_from_str(res_str), Ok(res));
101                assert_eq!(ApiResult::try_from(res_str), Ok(res));
102                assert_eq!(ApiResult::try_from(res_str.to_string()), Ok(res));
103
104                assert_eq!(serde_json::to_string(&res).unwrap(), res_json);
105                assert_eq!(serde_json::from_str::<ApiResult>(&res_json).unwrap(), res);
106            });
107    }
108}