zulip-api 0.0.8

Client library for interacting with the Zulip API
Documentation
use serde::{Deserialize, Serialize};

use crate::{field_access, impl_default, impl_display};

/// Represents a `snapshot` object with the values of a message after an edit.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct MessageHistory {
    topic: String,
    prev_topic: Option<String>,
    stream: Option<u64>,
    prev_stream: Option<u64>,
    content: String,
    rendered_content: String,
    prev_content: Option<String>,
    prev_rendered_content: Option<String>,
    user_id: Option<u64>,
    content_html_diff: Option<String>,
    timestamp: u64,
}

impl MessageHistory {
    /// Creates a new [MessageHistory].
    pub const fn new() -> Self {
        Self {
            topic: String::new(),
            prev_topic: None,
            stream: None,
            prev_stream: None,
            content: String::new(),
            rendered_content: String::new(),
            prev_content: None,
            prev_rendered_content: None,
            user_id: None,
            content_html_diff: None,
            timestamp: 0,
        }
    }
}

field_access! {
    MessageHistory {
        /// The topic of the message immediately after this edit event.
        topic: cow { str },
        /// The raw [Zulip-flavored Markdown](https://zulip.com/help/format-your-message-using-markdown) content of the message
        /// immediately after this edit event.
        content: cow { str },
        /// The rendered HTML representation of `content`.
        ///
        /// See [Markdown message formatting](https://zulip.com/api/message-formatting) for details on Zulip's HTML format.
        rendered_content: cow { str },
    }
}

field_access! {
    MessageHistory {
        /// Only present if message's topic was edited.
        ///
        /// The topic of the message immediately
        /// prior to this edit event.
        prev_topic: option_cow_deref { str, String },
        /// Only present if message's content was edited.
        ///
        /// The raw [Zulip-flavored Markdown](https://zulip.com/help/format-your-message-using-markdown) 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 content was edited.
        ///
        /// An HTML diff between this version of the message
        /// and the previous one.
        content_html_diff: option_cow_deref { str, String },
    }
}

field_access! {
    MessageHistory {
        /// 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 { u64 },
        /// Only present if message's channel was edited.
        ///
        /// The ID of the channel containing the message immediately
        /// prior to this edit event.
        ///
        /// **Changes**: New in Zulip 3.0 (feature level 1).
        prev_stream: 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 },
    }
}

field_access! {
    MessageHistory {
        /// The UNIX timestamp for this edit.
        timestamp: u64,
    }
}

impl_default!(MessageHistory);
impl_display!(MessageHistory);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_message_history() {
        let topic = "test_topic";
        let prev_topic = "test_prev_topic";
        let stream = 1;
        let prev_stream = 2;
        let content = "test content";
        let rendered_content = "<p>test content</p>";
        let prev_content = "test prev content";
        let prev_rendered_content = "<p>test prev content</p>";
        let user_id = 3;
        let content_html_diff = "<p>test content html diff</p>";
        let timestamp = 4;

        let history = MessageHistory::new()
            .with_topic(topic)
            .with_prev_topic(prev_topic)
            .with_stream(stream)
            .with_prev_stream(prev_stream)
            .with_content(content)
            .with_rendered_content(rendered_content)
            .with_prev_content(prev_content)
            .with_prev_rendered_content(prev_rendered_content)
            .with_user_id(user_id)
            .with_content_html_diff(content_html_diff)
            .with_timestamp(timestamp);
        let history_json = history.to_string();

        assert_eq!(serde_json::to_string(&history).unwrap(), history_json);
        assert_eq!(
            serde_json::from_str::<MessageHistory>(&history_json).unwrap(),
            history
        );

        assert_eq!(history.topic(), topic);
        assert_eq!(history.prev_topic(), Some(prev_topic));
        assert_eq!(history.stream(), Some(stream));
        assert_eq!(history.prev_stream(), Some(prev_stream));
        assert_eq!(history.content(), content);
        assert_eq!(history.rendered_content(), rendered_content);
        assert_eq!(history.prev_content(), Some(prev_content));
        assert_eq!(history.prev_rendered_content(), Some(prev_rendered_content));
        assert_eq!(history.user_id(), Some(user_id));
        assert_eq!(history.content_html_diff(), Some(content_html_diff));
        assert_eq!(history.timestamp(), timestamp);
    }
}