Skip to main content

zulip_api/message/
cross_realm_bot.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{field_access, impl_default, impl_display, BotType, ProfileData, Role};
4
5/// Represents the `Cross-realm bot` field of the response to a `Register` Zulip API request.
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 CrossRealmBot {
30    #[serde(skip_serializing_if = "Option::is_none")]
31    user_id: Option<u64>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    delivery_email: Option<String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    email: Option<String>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    full_name: Option<String>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    date_joined: Option<String>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    is_active: Option<bool>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    is_owner: Option<bool>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    is_admin: Option<bool>,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    is_guest: Option<bool>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    is_bot: Option<bool>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    bot_type: Option<BotType>,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    bot_owner_id: Option<u64>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    role: Option<Role>,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    timezone: Option<String>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    avatar_url: Option<String>,
60    #[serde(skip_serializing_if = "Option::is_none")]
61    avatar_version: Option<u64>,
62    #[serde(skip_serializing_if = "Option::is_none")]
63    profile_data: Option<ProfileData>,
64    #[serde(skip_serializing_if = "Option::is_none")]
65    is_system_bot: Option<bool>,
66}
67
68impl CrossRealmBot {
69    /// Creates a new [CrossRealmBot].
70    pub const fn new() -> Self {
71        CrossRealmBot {
72            user_id: None,
73            delivery_email: None,
74            email: None,
75            full_name: None,
76            date_joined: None,
77            is_active: None,
78            is_owner: None,
79            is_admin: None,
80            is_guest: None,
81            is_bot: None,
82            bot_type: None,
83            bot_owner_id: None,
84            role: None,
85            timezone: None,
86            avatar_url: None,
87            avatar_version: None,
88            profile_data: None,
89            is_system_bot: None,
90        }
91    }
92}
93
94field_access! {
95    CrossRealmBot {
96        /// The unique ID of the user.
97        user_id: option { u64 },
98        /// A boolean specifying whether the user account has been deactivated.
99        is_active: option { bool },
100        /// A boolean specifying whether the user is an organization owner.
101        is_owner: option { bool },
102        /// A boolean specifying whether the user is an organization administrator.
103        is_admin: option { bool },
104        /// A boolean specifying whether the user is a guest user.
105        is_guest: option { bool },
106        /// A boolean specifying whether the user is a bot or full account.
107        is_bot: option { bool },
108        /// An integer describing the type of bot.
109        bot_type: option { BotType },
110        /// If the user is a bot (i.e. `is_bot` is true), then `bot_owner_id`
111        /// is the user ID of the bot's owner (usually, whoever created the bot).
112        ///
113        /// Will be `null` for legacy bots that do not have an owner.
114        ///
115        /// **Changes**: New in Zulip 3.0 (feature level 1). In previous
116        /// versions, there was a `bot_owner` field containing the email
117        /// address of the bot's owner.
118        bot_owner_id: option { u64 },
119        /// [Organization-level role](https://zulip.com/api/roles-and-permissions) of the user.
120        role: option { Role },
121        /// Version for the user's avatar. Used for cache-busting requests
122        /// for the user's avatar. Clients generally shouldn't need to use this;
123        /// most avatar URLs sent by Zulip will already end with `?v={avatar_version}`.
124        avatar_version: option { u64 },
125        /// Whether the user is a system bot.
126        ///
127        /// System bots are special bot user accounts that are managed by the system, rather than the organization's administrators.
128        ///
129        /// **Changes**: This field was called `is_cross_realm_bot` before Zulip 5.0 (feature level 83).
130        is_system_bot: option { bool },
131    }
132}
133
134field_access! {
135    CrossRealmBot {
136        /// The user's real email address. This value will be `null` if you cannot
137        /// access user's real email address. For bot users, this field is always
138        /// set to the real email of the bot, because bot users always have
139        /// `email_address_visibility` set to everyone.
140        ///
141        /// **Changes**: Prior to Zulip 7.0 (feature level 163), this field was
142        /// present only when `email_address_visibility` was restricted and you had
143        /// access to the user's real email. As of this feature level, this field
144        /// is always present, including the case when `email_address_visibility`
145        /// is set to everyone (and therefore not restricted).
146        delivery_email: option_cow_deref { str, String },
147        /// The Zulip API email address of the user or bot.
148
149        /// If you do not have permission to view the email address of the target user,
150        /// this will be a fake email address that is usable for the Zulip API but nothing else.
151        email: option_cow_deref { str, String },
152        /// Full name of the user or bot, used for all display purposes.
153        full_name: option_cow_deref { str, String },
154        /// The time the user account was created.
155        date_joined: option_cow_deref { str, String },
156        /// The IANA identifier of the user's [profile time zone](https://zulip.com/help/change-your-timezone),
157        /// which is used primarily to display the user's local time to other users.
158        timezone: option_cow_deref { str, String },
159        /// URL for the user's avatar.
160        avatar_url: option_cow_deref { str, String },
161    }
162}
163
164field_access! {
165    CrossRealmBot {
166        /// A dictionary containing the updated custom profile field data for the user.
167        profile_data: option_cow_ref { ProfileData },
168    }
169}
170
171impl_default!(CrossRealmBot);
172impl_display!(CrossRealmBot);
173
174#[cfg(test)]
175mod tests {
176    use super::*;
177
178    #[test]
179    fn test_cross_realm_bot() {
180        let user_id = 1;
181        let delivery_email = "test-delivery@example.com";
182        let email = "test@example.com";
183        let full_name = "full name";
184        let date_joined = "2001/01/01";
185        let is_active = true;
186        let is_owner = false;
187        let is_admin = true;
188        let is_guest = false;
189        let is_bot = true;
190        let bot_type = BotType::new();
191        let bot_owner_id = 2;
192        let role = Role::new();
193        let timezone = "UTC";
194        let avatar_url = "https://example.com/avatar";
195        let avatar_version = 3;
196        let profile_data = ProfileData::new();
197        let is_system_bot = false;
198
199        let bot = CrossRealmBot::new()
200            .with_user_id(user_id)
201            .with_delivery_email(delivery_email)
202            .with_email(email)
203            .with_full_name(full_name)
204            .with_date_joined(date_joined)
205            .with_is_active(is_active)
206            .with_is_owner(is_owner)
207            .with_is_admin(is_admin)
208            .with_is_guest(is_guest)
209            .with_is_bot(is_bot)
210            .with_bot_type(bot_type)
211            .with_bot_owner_id(bot_owner_id)
212            .with_role(role)
213            .with_timezone(timezone)
214            .with_avatar_url(avatar_url)
215            .with_avatar_version(avatar_version)
216            .with_profile_data(&profile_data)
217            .with_is_system_bot(is_system_bot);
218        let bot_json = bot.to_string();
219
220        assert_eq!(serde_json::to_string(&bot).unwrap(), bot_json);
221        assert_eq!(
222            serde_json::from_str::<CrossRealmBot>(&bot_json).unwrap(),
223            bot
224        );
225
226        assert_eq!(bot.user_id(), Some(user_id));
227        assert_eq!(bot.delivery_email(), Some(delivery_email));
228        assert_eq!(bot.email(), Some(email));
229        assert_eq!(bot.full_name(), Some(full_name));
230        assert_eq!(bot.date_joined(), Some(date_joined));
231        assert_eq!(bot.is_active(), Some(is_active));
232        assert_eq!(bot.is_owner(), Some(is_owner));
233        assert_eq!(bot.is_admin(), Some(is_admin));
234        assert_eq!(bot.is_guest(), Some(is_guest));
235        assert_eq!(bot.is_bot(), Some(is_bot));
236        assert_eq!(bot.bot_type(), Some(bot_type));
237        assert_eq!(bot.bot_owner_id(), Some(bot_owner_id));
238        assert_eq!(bot.role(), Some(role));
239        assert_eq!(bot.timezone(), Some(timezone));
240        assert_eq!(bot.avatar_url(), Some(avatar_url));
241        assert_eq!(bot.avatar_version(), Some(avatar_version));
242        assert_eq!(bot.profile_data(), Some(&profile_data));
243        assert_eq!(bot.is_system_bot(), Some(is_system_bot));
244    }
245}