zulip_rs 0.2.0

Rust library to access the Zulip API
Documentation
use serde::{Deserialize, Serialize, Serializer};

#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "result")]
pub enum SendMessageResponse {
    #[serde(rename = "success")]
    Success { id: i64, msg: String },
    #[serde(rename = "error")]
    Error {
        code: String,
        msg: String,
        stream: Option<String>,
    },
}

#[derive(Serialize, Debug)]
#[serde(tag = "type")]
pub enum SendMessageRequest {
    #[serde(rename = "stream")]
    Stream {
        to: String,
        topic: String,
        content: String,
    },
    #[serde(rename = "private")]
    Private { to: String, content: String },
}

#[derive(Serialize, Debug)]
pub struct GetMessagesRequest {
    pub anchor: Option<Anchor>,
    pub num_before: i64,
    pub num_after: i64,
    #[serde(skip_serializing)]
    pub narrow: Option<Vec<Narrow>>,
}

impl GetMessagesRequest {
    pub fn new(num_before: i64, num_after: i64) -> Self {
        Self {
            anchor: Some(Anchor::Newest),
            num_before,
            num_after,
            narrow: None,
        }
    }
    pub fn anchor(&mut self, anchor: Anchor) -> &mut Self {
        self.anchor = Some(anchor);
        self
    }
    pub fn narrow(&mut self, narrow: Vec<Narrow>) -> &mut Self {
        self.narrow = Some(narrow);
        self
    }
}

#[derive(Debug)]
pub enum Anchor {
    Newest,
    Oldest,
    FirstUnread,
    MessageID(i64),
}

impl Serialize for Anchor {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Anchor::Newest => serializer.serialize_str("newest"),
            Anchor::Oldest => serializer.serialize_str("oldest"),
            Anchor::FirstUnread => serializer.serialize_str("first_unread"),
            Anchor::MessageID(i) => serializer.serialize_i64(*i),
        }
    }
}

#[derive(Serialize, Debug)]
pub struct Narrow {
    pub operand: String,
    pub operator: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct GetMessagesResponse {
    msg: String,
    result: String,
    anchor: i64,
    found_newest: bool,
    found_oldest: Option<bool>,
    found_anchor: bool,
    history_limited: Option<bool>,
    messages: Vec<ReceivedMessage>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct ReceivedMessage {
    avatar_url: String,
    client: String,
    content: String,
    content_type: String,
    display_recipient: DisplayRecipient,
    id: i64,
    is_me_message: bool,
    reactions: Vec<Reaction>,
    recipient_id: i64,
    sender_email: String,
    sender_full_name: String,
    sender_id: i64,
    sender_realm_str: String,
    stream_id: Option<i64>,
    subject: String,
    topic_links: Vec<String>,
    submessages: Vec<String>,
    timestamp: i64,
    r#type: String,
    flags: Vec<String>,
    last_edit_timestamp: Option<i64>,
    match_content: Option<String>,
    match_subject: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum DisplayRecipient {
    Stream(String),
    PrivateMessage(Vec<DisplayRecipientPrivateMessage>),
}

#[derive(Serialize, Deserialize, Debug)]
pub struct DisplayRecipientPrivateMessage {
    id: i64,
    email: String,
    full_name: String,
    is_mirror_dummy: bool,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Reaction {
    emoji_code: String,
    emoji_name: String,
    reaction_type: String,
    user_id: i64,
}

#[derive(Deserialize, Debug)]
#[serde(tag = "result")]
#[serde(rename_all = "camelCase")]
pub enum DeleteMessageResponse {
    Success,
    Error(DeleteMessageError),
}

#[derive(Deserialize, Debug)]
pub struct DeleteMessageError {
    code: String,
    msg: String,
}

#[derive(Serialize, Debug)]
pub struct EditMessageRequest {
    #[serde(skip_serializing)]
    pub(crate) message_id: i64,
    topic: Option<String>,
    propagate_mode: PropagateMode,
    send_notification_to_old_thread: bool,
    send_notification_to_new_thread: bool,
    content: Option<String>,
    stream_id: Option<i64>,
}

impl EditMessageRequest {
    pub fn new(message_id: i64) -> Self {
        Self {
            message_id,
            topic: None,
            propagate_mode: PropagateMode::ChangeOne,
            send_notification_to_new_thread: true,
            send_notification_to_old_thread: true,
            content: None,
            stream_id: None,
        }
    }
    pub fn topic(&mut self, topic: &str) -> &mut Self {
        self.topic = Some(topic.to_string());
        self
    }
    pub fn propagate_mode(&mut self, propagate_mode: PropagateMode) -> &mut Self {
        self.propagate_mode = propagate_mode;
        self
    }
    pub fn send_notification_to_old_thread(&mut self, is_send: bool) -> &mut Self {
        self.send_notification_to_old_thread = is_send;
        self
    }
    pub fn send_notification_to_new_thread(&mut self, is_send: bool) -> &mut Self {
        self.send_notification_to_new_thread = is_send;
        self
    }
    pub fn content(&mut self, content: &str) -> &mut Self {
        self.content = Some(content.to_string());
        self
    }
    pub fn stream_id(&mut self, stream_id: i64) -> &mut Self {
        self.stream_id = Some(stream_id);
        self
    }
}

#[derive(Serialize, Debug)]
pub struct AddEmojiReactionRequest {
    #[serde(skip_serializing)]
    pub(crate) message_id: i64,
    emoji_name: String,
    emoji_code: Option<String>,
    reaction_type: Option<ReactionType>,
}

impl AddEmojiReactionRequest {
    pub fn new(message_id: i64, emoji_name: &str) -> Self {
        Self {
            message_id,
            emoji_name: emoji_name.to_string(),
            emoji_code: None,
            reaction_type: None,
        }
    }
    pub fn emoji_code(&mut self, emoji_code: &str) -> &mut Self {
        self.emoji_code = Some(emoji_code.to_string());
        self
    }
    pub fn reaction_type(&mut self, reaction_type: ReactionType) -> &mut Self {
        self.reaction_type = Some(reaction_type);
        self
    }
}

#[derive(Serialize, Debug)]
pub struct RemoveEmojiReactionRequest {
    pub(crate) message_id: i64,
    emoji_name: Option<String>,
    emoji_code: Option<String>,
    reaction_type: Option<ReactionType>,
}

impl RemoveEmojiReactionRequest {
    pub fn new(message_id: i64) -> Self {
        Self {
            message_id,
            emoji_name: None,
            emoji_code: None,
            reaction_type: None,
        }
    }
    pub fn emoji_name(&mut self, emoji_name: &str) -> &mut Self {
        self.emoji_name = Some(emoji_name.to_string());
        self
    }
    pub fn emoji_code(&mut self, emoji_code: &str) -> &mut Self {
        self.emoji_code = Some(emoji_code.to_string());
        self
    }
    pub fn reaction_type(&mut self, reaction_type: ReactionType) -> &mut Self {
        self.reaction_type = Some(reaction_type);
        self
    }
}

#[derive(Serialize, Debug)]
pub enum ReactionType {
    UnicodeEmoji,
    RealmEmoji,
    ZulipExtraEmoji,
}

#[derive(Serialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum PropagateMode {
    ChangeOne,
    ChangeAll,
    ChangeLater,
}