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
use serde::{Deserialize, Serialize};
use crate::{field_access, impl_cow, impl_default, impl_display};
/// Represents a the edit history of a message returned by the Zulip API server.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct EditHistory {
#[serde(skip_serializing_if = "Option::is_none")]
prev_content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
prev_rendered_content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
prev_stream: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
prev_topic: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
stream: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
timestamp: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
topic: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
user_id: Option<u64>,
}
impl EditHistory {
/// Creates a new [EditHistory].
pub const fn new() -> Self {
Self {
prev_content: None,
prev_rendered_content: None,
prev_stream: None,
prev_topic: None,
stream: None,
timestamp: None,
topic: None,
user_id: None,
}
}
}
field_access! {
EditHistory {
/// Only present if message's content was edited.
///
/// The content of the message immediately prior to this edit event.
prev_content: option_cow_deref { str, String },
/// Only present if message's content was edited.
///
/// The rendered HTML representation of `prev_content`.
///
/// See [Markdown message formatting](https://zulip.com/api/message-formatting) for details on Zulip's HTML format.
prev_rendered_content: option_cow_deref { str, String },
/// Only present if message's topic was edited.
///
/// The topic of the message immediately prior to this edit event.
///
/// **Changes**: New in Zulip 5.0 (feature level 118).
/// Previously, this field was called `prev_subject`;
/// clients are recommended to rename `prev_subject` to
/// `prev_topic` if present for compatibility with older Zulip servers.
prev_topic: option_cow_deref { str, String },
/// Only present if message's channel was edited.
///
/// The ID of the channel containing the message
/// immediately after this edit event.
///
/// **Changes**: New in Zulip 5.0 (feature level 118).
stream: option_cow_deref { str, String },
/// Only present if message's topic was edited.
///
/// The topic of the message immediately after this edit event.
///
/// **Changes**: New in Zulip 5.0 (feature level 118).
topic: option_cow_deref { str, String },
}
}
field_access! {
EditHistory {
/// Only present if message's channel was edited.
///
/// The channel ID of the message immediately prior to this edit event.
///
/// **Changes**: New in Zulip 3.0 (feature level 1).
prev_stream: option { u64 },
/// The UNIX timestamp for the edit.
timestamp: option { u64 },
/// The ID of the user that made the edit.
///
/// Will be `null` only for edit history events predating March 2017.
///
/// Clients can display edit history events where this
/// is `null` as modified by either the sender (for content
/// edits) or an unknown user (for topic edits).
user_id: option { u64 },
}
}
impl_cow!(EditHistory);
impl_default!(EditHistory);
impl_display!(EditHistory);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_edit_history_minimal() {
let user_id = 42;
let timestamp = 468460800;
let edit_history = EditHistory::new()
.with_user_id(user_id)
.with_timestamp(timestamp);
let edit_history_json = edit_history.to_string();
assert_eq!(edit_history.timestamp(), Some(timestamp));
assert_eq!(edit_history.user_id(), Some(user_id));
assert_eq!(
serde_json::to_string(&edit_history).unwrap(),
edit_history_json
);
assert_eq!(
serde_json::from_str::<EditHistory>(&edit_history_json).unwrap(),
edit_history
);
}
#[test]
fn test_edit_history_full() {
let user_id = 42;
let timestamp = 468460800;
let prev_content = "prev content";
let prev_rendered_content = "prev rendered content";
let prev_stream = 1;
let prev_topic = "prev topic";
let stream = "stream";
let topic = "topic";
let edit_history = EditHistory::new()
.with_user_id(user_id)
.with_timestamp(timestamp)
.with_prev_content(prev_content)
.with_prev_rendered_content(prev_rendered_content)
.with_prev_stream(prev_stream)
.with_prev_topic(prev_topic)
.with_stream(stream)
.with_topic(topic);
let edit_history_json = edit_history.to_string();
assert_eq!(edit_history.timestamp(), Some(timestamp));
assert_eq!(edit_history.user_id(), Some(user_id));
assert_eq!(edit_history.prev_content(), Some(prev_content));
assert_eq!(
edit_history.prev_rendered_content(),
Some(prev_rendered_content)
);
assert_eq!(edit_history.prev_stream(), Some(prev_stream));
assert_eq!(edit_history.prev_topic(), Some(prev_topic));
assert_eq!(edit_history.stream(), Some(stream));
assert_eq!(edit_history.topic(), Some(topic));
assert_eq!(
serde_json::to_string(&edit_history).unwrap(),
edit_history_json
);
assert_eq!(
serde_json::from_str::<EditHistory>(&edit_history_json).unwrap(),
edit_history
);
}
}