zulip-api 0.0.8

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

use crate::response::BaseResponse;
use crate::{field_access, impl_default, impl_display, impl_response};

/// Represents the request for the `Update Message Flags for Narrow` Zulip API endpoint.
///
/// See [update-message-flags-for-narrow](https://zulip.com/api/update-message-flags-for-narrow) for details.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Response {
    #[serde(flatten)]
    base: BaseResponse,
    processed_count: Option<u64>,
    updated_count: Option<u64>,
    first_processed_id: Option<u64>,
    last_processed_id: Option<u64>,
    found_oldest: Option<bool>,
    found_newest: Option<bool>,
    ignored_because_not_subscribed_channels: Option<Vec<u64>>,
}

impl Response {
    /// Creates a new [Response].
    pub const fn new() -> Self {
        Self {
            base: BaseResponse::new(),
            processed_count: None,
            updated_count: None,
            first_processed_id: None,
            last_processed_id: None,
            found_oldest: None,
            found_newest: None,
            ignored_because_not_subscribed_channels: None,
        }
    }
}

field_access! {
    Response {
        /// The number of messages that were within the
        /// update range (at most `num_before + 1 + num_after`).
        processed_count: option { u64 },
        /// The number of messages where the flag's
        /// value was changed (at most `processed_count`).
        updated_count: option { u64 },
        /// The ID of the oldest message within the
        /// update range, or `null` if the range was empty.
        first_processed_id: option { u64 },
        /// The ID of the newest message within the
        /// update range, or `null` if the range was empty.
        last_processed_id: option { u64 },
        /// Whether the update range reached backward
        /// far enough to include very oldest message
        /// matching the narrow (used by clients doing a
        /// bulk update to decide whether to issue
        /// another request anchored at
        /// `first_processed_id`).
        found_oldest: option { bool },
        /// Whether the update range reached forward far
        /// enough to include very oldest message
        /// matching the narrow (used by clients doing a
        /// bulk update to decide whether to issue
        /// another request anchored at
        /// `last_processed_id`).
        found_newest: option { bool },
    }
}

field_access! {
    Response {
        /// Zulip has an invariant that all unread messages must be in channels
        /// the user is subscribed to. This field will contain a list of the
        /// channels whose messages were skipped to mark as unread because the
        /// user is not subscribed to them.
        ///
        /// Only present if the flag is `read` and the operation is `remove`.
        ///
        /// **Changes**: New in Zulip 10.0 (feature level 355).
        ignored_because_not_subscribed_channels: option_cow_deref { [u64], Vec<u64> },
    }
}

impl_default!(Response);
impl_display!(Response);
impl_response!(Response, base);

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

    #[test]
    fn test_response() {
        let processed_count = 1;
        let updated_count = 2;
        let first_processed_id = 3;
        let last_processed_id = 4;
        let found_oldest = true;
        let found_newest = false;
        let ignored_because_not_subscribed_channels = [5];

        let response = Response::new()
            .with_processed_count(processed_count)
            .with_updated_count(updated_count)
            .with_first_processed_id(first_processed_id)
            .with_last_processed_id(last_processed_id)
            .with_found_oldest(found_oldest)
            .with_found_newest(found_newest)
            .with_ignored_because_not_subscribed_channels(
                ignored_because_not_subscribed_channels.as_ref(),
            );
        let response_json = response.to_string();

        assert_eq!(serde_json::to_string(&response).unwrap(), response_json);
        assert_eq!(
            serde_json::from_str::<Response>(&response_json).unwrap(),
            response
        );

        assert_eq!(response.processed_count(), Some(processed_count));
        assert_eq!(response.updated_count(), Some(updated_count));
        assert_eq!(response.first_processed_id(), Some(first_processed_id));
        assert_eq!(response.last_processed_id(), Some(last_processed_id));
        assert_eq!(response.found_oldest(), Some(found_oldest));
        assert_eq!(response.found_newest(), Some(found_newest));
        assert_eq!(
            response.ignored_because_not_subscribed_channels(),
            Some(ignored_because_not_subscribed_channels.as_ref())
        );
    }
}