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