zulip-api 0.0.8

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

use crate::{impl_default, impl_display, Error, Result};

/// Represents an available Zulip message flag.
///
/// Flags are annotations to messages indicating additional state.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Flag {
    Read,
    Starred,
    Collapsed,
    Mentioned,
    StreamWildcardMentioned,
    TopicWildcardMentioned,
    HasAlertWord,
    Historical,
}

impl Flag {
    /// Represents the string value for the read [Flag].
    pub const READ: &str = "read";
    /// Represents the string value for the starred [Flag].
    pub const STARRED: &str = "starred";
    /// Represents the string value for the collapsed [Flag].
    pub const COLLAPSED: &str = "collapsed";
    /// Represents the string value for the mentioned [Flag].
    pub const MENTIONED: &str = "mentioned";
    /// Represents the string value for the stream wildcard mentioned [Flag].
    pub const STREAM_WILDCARD_MENTIONED: &str = "stream_wildcard_mentioned";
    /// Represents the string value for the topic wildcard mentioned [Flag].
    pub const TOPIC_WILDCARD_MENTIONED: &str = "topic_wildcard_mentioned";
    /// Represents the string value for the has alert word [Flag].
    pub const HAS_ALERT_WORD: &str = "has_alert_word";
    /// Represents the string value for the historical [Flag].
    pub const HISTORICAL: &str = "historical";

    /// Creates a new [Flag].
    pub const fn new() -> Self {
        Self::Read
    }

    /// Gets the [Flag] string representation.
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::Read => Self::READ,
            Self::Starred => Self::STARRED,
            Self::Collapsed => Self::COLLAPSED,
            Self::Mentioned => Self::MENTIONED,
            Self::StreamWildcardMentioned => Self::STREAM_WILDCARD_MENTIONED,
            Self::TopicWildcardMentioned => Self::TOPIC_WILDCARD_MENTIONED,
            Self::HasAlertWord => Self::HAS_ALERT_WORD,
            Self::Historical => Self::HISTORICAL,
        }
    }

    /// Attempts to convert a string into a [Flag].
    pub fn try_from_str(val: &str) -> Result<Self> {
        match val.to_lowercase().as_str() {
            Self::READ => Ok(Self::Read),
            Self::STARRED => Ok(Self::Starred),
            Self::COLLAPSED => Ok(Self::Collapsed),
            Self::MENTIONED => Ok(Self::Mentioned),
            Self::STREAM_WILDCARD_MENTIONED => Ok(Self::StreamWildcardMentioned),
            Self::TOPIC_WILDCARD_MENTIONED => Ok(Self::TopicWildcardMentioned),
            Self::HAS_ALERT_WORD => Ok(Self::HasAlertWord),
            Self::HISTORICAL => Ok(Self::Historical),
            s => Err(Error::invalid_field(
                "flag",
                s,
                format!(
                    "{} | {} | {} | {} | {} | {} | {} | {}",
                    Self::READ,
                    Self::STARRED,
                    Self::COLLAPSED,
                    Self::MENTIONED,
                    Self::STREAM_WILDCARD_MENTIONED,
                    Self::TOPIC_WILDCARD_MENTIONED,
                    Self::HAS_ALERT_WORD,
                    Self::HISTORICAL
                ),
            )),
        }
    }
}

impl From<Flag> for &'static str {
    fn from(val: Flag) -> Self {
        val.as_str()
    }
}

impl From<Flag> for String {
    fn from(val: Flag) -> Self {
        val.as_str().to_string()
    }
}

impl TryFrom<&str> for Flag {
    type Error = Error;

    fn try_from(val: &str) -> Result<Self> {
        Self::try_from_str(val)
    }
}

impl TryFrom<&String> for Flag {
    type Error = Error;

    fn try_from(val: &String) -> Result<Self> {
        Self::try_from_str(val.as_str())
    }
}

impl TryFrom<String> for Flag {
    type Error = Error;

    fn try_from(val: String) -> Result<Self> {
        Self::try_from_str(val.as_str())
    }
}

impl_default!(Flag);
impl_display!(Flag);

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

    #[test]
    fn test_flag() {
        [
            (Flag::Read, Flag::READ),
            (Flag::Starred, Flag::STARRED),
            (Flag::Collapsed, Flag::COLLAPSED),
            (Flag::Mentioned, Flag::MENTIONED),
            (
                Flag::StreamWildcardMentioned,
                Flag::STREAM_WILDCARD_MENTIONED,
            ),
            (Flag::TopicWildcardMentioned, Flag::TOPIC_WILDCARD_MENTIONED),
            (Flag::HasAlertWord, Flag::HAS_ALERT_WORD),
            (Flag::Historical, Flag::HISTORICAL),
        ]
        .into_iter()
        .for_each(|(flag, flag_str)| {
            let flag_json = flag.to_string();

            assert_eq!(flag.as_str(), flag_str);

            assert_eq!(serde_json::to_string(&flag).unwrap(), flag_json);
            assert_eq!(serde_json::from_str::<Flag>(&flag_json).unwrap(), flag);
        });
    }
}