Skip to main content

zulip_api/message/
bot.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{field_access, BotService, BotType};
4
5/// Represents a Zulip bot.
6///
7/// Modified from `openapi-generator-cli` output:
8///
9/// ```shell,no_build,no_run
10/// $ openapi-generator-cli generate -g rust -i ./zerver/openapi/zulip.yaml -o zulip-openapi --skip-validate-spec
11/// ```
12///
13/// ```text
14/// /*
15/// * Zulip REST API
16/// *
17/// * Powerful open source group chat
18/// *
19/// * The version of the OpenAPI document: 1.0.0
20/// *
21/// * Generated by: https://openapi-generator.tech
22/// */
23/// ```
24///
25/// See [zerver/openapi/zulip.yaml](https://github.com/zulip/zulip/blob/main/zerver/openapi/zulip.yaml) for the original OpenAPI configuration.
26///
27/// Configuration slightly modified to work with the Rust generator of [`openapi-generator-cli`](https://openapi-generator.tech).
28#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
29pub struct Bot {
30    #[serde(skip_serializing_if = "Option::is_none")]
31    user_id: Option<u64>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    full_name: Option<String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    api_key: Option<String>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    default_sending_stream: Option<String>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    default_events_register_stream: Option<String>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    default_all_public_streams: Option<bool>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    avatar_url: Option<String>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    owner_id: Option<u64>,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    services: Option<Vec<BotService>>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    email: Option<String>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    bot_type: Option<BotType>,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    is_active: Option<bool>,
54}
55
56impl Bot {
57    /// Creates a new [Bot].
58    pub const fn new() -> Bot {
59        Bot {
60            user_id: None,
61            full_name: None,
62            api_key: None,
63            default_sending_stream: None,
64            default_events_register_stream: None,
65            default_all_public_streams: None,
66            avatar_url: None,
67            owner_id: None,
68            services: None,
69            email: None,
70            bot_type: None,
71            is_active: None,
72        }
73    }
74}
75
76field_access! {
77    Bot {
78        /// The user ID of the bot.
79        user_id: option { u64 },
80        /// Whether the bot can send messages to all channels by default.
81        default_all_public_streams: option { bool },
82        /// The user ID of the bot's owner.
83        ///
84        /// If `null`, the bot has no owner.
85        owner_id: option { u64 },
86        /// An integer describing the type of bot.
87        bot_type: option { BotType },
88        /// A boolean describing whether the user account has been deactivated.
89        is_active: option { bool },
90    }
91}
92
93field_access! {
94    Bot {
95        /// The full name of the bot.
96        full_name: option_cow_deref { str, String },
97        /// The API key of the bot which it uses to make API requests.
98        api_key: option_cow_deref { str, String },
99        /// The default sending channel of the bot. If `null`, the bot doesn't have a default sending channel.
100        default_sending_stream: option_cow_deref { str, String },
101        /// The default channel for which the bot receives events/register data.
102        /// If `null`, the bot doesn't have such a default channel.
103        default_events_register_stream: option_cow_deref { str, String },
104        /// The URL of the bot's avatar.
105        avatar_url: option_cow_deref { str, String },
106        /// An array containing extra configuration fields only relevant for
107        /// outgoing webhook bots and embedded bots. This is always a single-element
108        /// array.
109        ///
110        /// We consider this part of the Zulip API to be unstable; it is used only
111        /// for UI elements for administering bots and is likely to change.
112        services: option_cow_deref { [BotService], Vec<BotService> },
113        /// The email of the bot.
114        email: option_cow_deref { str, String },
115    }
116}
117
118impl Default for Bot {
119    fn default() -> Self {
120        Self::new()
121    }
122}
123
124impl std::fmt::Display for Bot {
125    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126        serde_json::to_string(self)
127            .map_err(|_| std::fmt::Error)
128            .and_then(|s| write!(f, "{s}"))
129    }
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_bot() {
138        let user_id = 1;
139        let full_name = "test_full_name";
140        let api_key = "test_api_key";
141        let default_sending_stream = "test_default_sending_stream";
142        let default_events_register_stream = "test_default_events_register_stream";
143        let default_all_public_streams = true;
144        let avatar_url = "https://test.avatar.url";
145        let owner_id = 2;
146        let services = [BotService::new()];
147        let email = "test@example.com";
148        let bot_type = BotType::new();
149        let is_active = true;
150
151        let bot = Bot::new()
152            .with_user_id(user_id)
153            .with_full_name(full_name)
154            .with_api_key(api_key)
155            .with_default_sending_stream(default_sending_stream)
156            .with_default_events_register_stream(default_events_register_stream)
157            .with_default_all_public_streams(default_all_public_streams)
158            .with_avatar_url(avatar_url)
159            .with_owner_id(owner_id)
160            .with_services(services.as_ref())
161            .with_email(email)
162            .with_bot_type(bot_type)
163            .with_is_active(is_active);
164        let bot_json = bot.to_string();
165
166        assert_eq!(serde_json::to_string(&bot).unwrap(), bot_json);
167        assert_eq!(serde_json::from_str::<Bot>(&bot_json).unwrap(), bot);
168
169        assert_eq!(bot.user_id(), Some(user_id));
170        assert_eq!(bot.full_name(), Some(full_name));
171        assert_eq!(bot.api_key(), Some(api_key));
172        assert_eq!(bot.default_sending_stream(), Some(default_sending_stream));
173        assert_eq!(
174            bot.default_events_register_stream(),
175            Some(default_events_register_stream)
176        );
177        assert_eq!(
178            bot.default_all_public_streams(),
179            Some(default_all_public_streams)
180        );
181        assert_eq!(bot.avatar_url(), Some(avatar_url));
182        assert_eq!(bot.owner_id(), Some(owner_id));
183        assert_eq!(bot.services(), Some(services.as_ref()));
184        assert_eq!(bot.email(), Some(email));
185        assert_eq!(bot.bot_type(), Some(bot_type));
186        assert_eq!(bot.is_active(), Some(is_active));
187    }
188}