Skip to main content

zulip_api/filter/
operator.rs

1use serde::{Deserialize, Serialize};
2
3/// Represents a filter operator used for searching and getting messages.
4#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
5#[serde(rename_all = "snake_case")]
6pub enum Operator {
7    Channel,
8    Channels,
9    Stream,
10    Streams,
11    Topic,
12    Dm,
13    #[serde(rename = "dm-including")]
14    DmIncluding,
15    Sender,
16    Has,
17    Is,
18    #[serde(rename = "-is")]
19    NotIs,
20    Near,
21}
22
23impl Operator {
24    /// Represents the string value of the channel [Operator].
25    pub const CHANNEL: &str = "channel";
26    /// Represents the string value of the channels [Operator].
27    pub const CHANNELS: &str = "channels";
28    /// Represents the string value of the stream [Operator].
29    pub const STREAM: &str = "stream";
30    /// Represents the string value of the streams [Operator].
31    pub const STREAMS: &str = "streams";
32    /// Represents the string value of the topic [Operator].
33    pub const TOPIC: &str = "topic";
34    /// Represents the string value of the dm [Operator].
35    pub const DM: &str = "dm";
36    /// Represents the string value of the dm-including [Operator].
37    pub const DM_INCLUDING: &str = "dm-including";
38    /// Represents the string value of the sender [Operator].
39    pub const SENDER: &str = "sender";
40    /// Represents the string value of the has [Operator].
41    pub const HAS: &str = "has";
42    /// Represents the string value of the is [Operator].
43    pub const IS: &str = "is";
44    /// Represents the string value of the not-is [Operator].
45    pub const NOT_IS: &str = "-is";
46    /// Represents the string value of the near [Operator].
47    pub const NEAR: &str = "near";
48
49    /// Creates a new [Operator].
50    pub const fn new() -> Self {
51        Self::Channel
52    }
53
54    /// Gets the [Operator] string representation.
55    pub const fn as_str(&self) -> &'static str {
56        match self {
57            Self::Channel => Self::CHANNEL,
58            Self::Channels => Self::CHANNELS,
59            Self::Stream => Self::STREAM,
60            Self::Streams => Self::STREAMS,
61            Self::Topic => Self::TOPIC,
62            Self::Dm => Self::DM,
63            Self::DmIncluding => Self::DM_INCLUDING,
64            Self::Sender => Self::SENDER,
65            Self::Has => Self::HAS,
66            Self::Is => Self::IS,
67            Self::NotIs => Self::NOT_IS,
68            Self::Near => Self::NEAR,
69        }
70    }
71}
72
73impl Default for Operator {
74    fn default() -> Self {
75        Self::new()
76    }
77}
78
79impl From<Operator> for &'static str {
80    fn from(val: Operator) -> Self {
81        val.as_str()
82    }
83}
84
85impl From<Operator> for String {
86    fn from(val: Operator) -> Self {
87        val.as_str().to_string()
88    }
89}
90
91impl std::fmt::Display for Operator {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        write!(f, "{}", self.as_str())
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    #[test]
102    fn test_filter_operator() {
103        [
104            Operator::Channel,
105            Operator::Channels,
106            Operator::Stream,
107            Operator::Streams,
108            Operator::Topic,
109            Operator::Dm,
110            Operator::DmIncluding,
111            Operator::Sender,
112            Operator::Has,
113            Operator::Is,
114            Operator::NotIs,
115            Operator::Near,
116        ]
117        .into_iter()
118        .for_each(|op| {
119            let op_json = format!(r#""{op}""#);
120
121            assert_eq!(serde_json::to_string(&op).unwrap(), op_json);
122            assert_eq!(serde_json::from_str::<Operator>(&op_json).unwrap(), op);
123        });
124    }
125}