zulip-api 0.0.8

Client library for interacting with the Zulip API
Documentation
use std::borrow::Cow;

use serde::{Deserialize, Serialize};

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

/// Represents the metadata for recipients who were displayed a message.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum DisplayRecipient {
    /// Represents the channel for a message.
    Channel(String),
    /// Represents the list of user recipients of a message.
    User(Vec<UserRecipient>),
}

impl DisplayRecipient {
    /// Creates a new [DisplayRecipient].
    pub const fn new() -> Self {
        Self::Channel(String::new())
    }

    /// Gets the variant name.
    pub const fn variant_name(&self) -> &'static str {
        match self {
            Self::Channel(_) => "DisplayRecipient::Channel",
            Self::User(_) => "DisplayRecipient::User",
        }
    }

    /// Converta a `String`-like argument into a [Self].
    pub fn channel<'c, C: Into<Cow<'c, str>>>(val: C) -> Self {
        Self::Channel(C::into(val).into())
    }

    /// Attempts to get the inner channel recipient.
    pub fn as_channel(&self) -> Result<&str> {
        match self {
            Self::Channel(ch) => Ok(ch.as_str()),
            _ => Err(Error::invalid_field(
                "display_recipient",
                self.variant_name(),
                Self::Channel(Default::default()).variant_name(),
            )),
        }
    }

    /// Converta a `Vec<UserRecipient>`-like argument into a [Self].
    pub fn user<'c, C: Into<Cow<'c, [UserRecipient]>>>(val: C) -> Self {
        Self::User(C::into(val).into())
    }

    /// Attempts to get the inner user recipient.
    pub fn as_user(&self) -> Result<&[UserRecipient]> {
        match self {
            Self::User(ch) => Ok(ch.as_slice()),
            _ => Err(Error::invalid_field(
                "display_recipient",
                self.variant_name(),
                Self::User(Default::default()).variant_name(),
            )),
        }
    }
}

impl_cow!(DisplayRecipient);
impl_default!(DisplayRecipient);
impl_display!(DisplayRecipient);

/// Represents metadata for a user who was displayed a message.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct UserRecipient {
    id: u64,
    email: String,
    full_name: String,
    is_mirror_dummy: bool,
}

impl UserRecipient {
    /// Creates a new [UserRecipient].
    pub const fn new() -> Self {
        Self {
            id: 0,
            email: String::new(),
            full_name: String::new(),
            is_mirror_dummy: false,
        }
    }
}

field_access! {
    UserRecipient {
        id: u64,
        is_mirror_dummy: bool,
    }
}

field_access! {
    UserRecipient {
        email: cow { str },
        full_name: cow { str },
    }
}

impl_default!(UserRecipient);
impl_display!(UserRecipient);

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

    #[test]
    fn test_display_recipient() {
        let id = 1;
        let email = "user@example.com";
        let full_name = "test user";
        let is_mirror_dummy = true;

        let user_recipient = UserRecipient::new()
            .with_id(id)
            .with_email(email)
            .with_full_name(full_name)
            .with_is_mirror_dummy(is_mirror_dummy);

        let user_recipient_json = user_recipient.to_string();

        assert_eq!(user_recipient.id(), id);
        assert_eq!(user_recipient.email(), email);
        assert_eq!(user_recipient.full_name(), full_name);
        assert_eq!(user_recipient.is_mirror_dummy(), is_mirror_dummy);

        assert_eq!(
            serde_json::to_string(&user_recipient).unwrap(),
            user_recipient_json
        );
        assert_eq!(
            serde_json::from_str::<UserRecipient>(&user_recipient_json).unwrap(),
            user_recipient
        );

        let channel = "test_channel";

        let display_channel = DisplayRecipient::channel(channel);
        assert_eq!(display_channel.as_channel(), Ok(channel));
        assert!(display_channel.as_user().is_err());

        let user_recipient_list = vec![user_recipient.clone()];
        let display_user = DisplayRecipient::user(&user_recipient_list);
        assert_eq!(display_user.as_user(), Ok(user_recipient_list.as_ref()));
        assert!(display_user.as_channel().is_err());

        [display_channel, display_user]
            .into_iter()
            .for_each(|display| {
                let display_json = display.to_string();

                assert_eq!(serde_json::to_string(&display).unwrap(), display_json);
                assert_eq!(
                    serde_json::from_str::<DisplayRecipient>(&display_json).unwrap(),
                    display
                );
            });
    }

    #[test]
    fn test_user_recipient() {
        let id = 1;
        let email = "user@example.com";
        let full_name = "test user";
        let is_mirror_dummy = true;

        let user_recipient = UserRecipient::new()
            .with_id(id)
            .with_email(email)
            .with_full_name(full_name)
            .with_is_mirror_dummy(is_mirror_dummy);

        let user_recipient_json = user_recipient.to_string();

        assert_eq!(user_recipient.id(), id);
        assert_eq!(user_recipient.email(), email);
        assert_eq!(user_recipient.full_name(), full_name);
        assert_eq!(user_recipient.is_mirror_dummy(), is_mirror_dummy);

        assert_eq!(
            serde_json::to_string(&user_recipient).unwrap(),
            user_recipient_json
        );
        assert_eq!(
            serde_json::from_str::<UserRecipient>(&user_recipient_json).unwrap(),
            user_recipient
        );
    }
}