zulip-api 0.0.8

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

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

/// Represents the response to a `Edit Message` API request.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Response {
    #[serde(flatten)]
    base: BaseResponse,
    #[serde(skip_serializing_if = "Option::is_none")]
    detached_uploads: Option<Vec<Attachment>>,
}

impl_response!(Response, base);

impl Response {
    /// Creates a new [Response].
    pub const fn new() -> Self {
        Self {
            base: BaseResponse::new(),
            detached_uploads: None,
        }
    }
}

field_access! {
    Response {
        /// Details on all files uploaded by the acting user whose only references
        /// were removed when editing this message. Clients should ask the acting user
        /// if they wish to delete the uploaded files returned in this response,
        /// which might otherwise remain visible only in message edit history.
        ///
        /// Note that [access to message edit history](https://zulip.com/help/restrict-message-edit-history-access)
        /// is configurable; this detail may be important in presenting the
        /// question clearly to users.
        ///
        /// New in Zulip 10.0 (feature level 285).
        detached_uploads: option_cow_deref { [Attachment], Vec<Attachment> },
    }
}

impl_default!(Response);
impl_display!(Response);

#[cfg(test)]
mod tests {
    use super::*;
    use crate::response::{ApiResult, ErrorCode, Response as _};

    #[test]
    fn test_success_response() {
        let msg = "test response";
        let msg_json = serde_json::to_string(&msg).unwrap();

        let result = ApiResult::Success;
        let result_json = serde_json::to_string(&result).unwrap();

        let id = 1;
        let name = "name";
        let path_id = "path_id";
        let size = 2;
        let create_time = 3;

        let detached = Attachment::new()
            .with_id(id)
            .with_name(name)
            .with_path_id(path_id)
            .with_size(size)
            .with_create_time(create_time);

        let detached_uploads = vec![detached];
        let detached_uploads_json = serde_json::to_string(&detached_uploads).unwrap();

        let response = Response::new()
            .with_msg(msg)
            .with_result(result)
            .with_detached_uploads(detached_uploads.clone());

        let response_json = format!(
            r#"{{"msg":{msg_json},"result":{result_json},"detached_uploads":{detached_uploads_json}}}"#
        );

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

        assert_eq!(response.msg(), msg);
        assert_eq!(response.result(), result);
        assert_eq!(response.code(), None);
        assert_eq!(
            response.detached_uploads(),
            Some(detached_uploads.as_slice())
        );
    }

    #[test]
    fn test_error_response() {
        let msg = "test response";
        let msg_json = serde_json::to_string(&msg).unwrap();

        let result = ApiResult::Error;
        let result_json = serde_json::to_string(&result).unwrap();

        let code = ErrorCode::BadRequest;
        let code_json = serde_json::to_string(&code).unwrap();

        let response = Response::new()
            .with_msg(msg)
            .with_result(result)
            .with_code(code);

        let response_json =
            format!(r#"{{"msg":{msg_json},"result":{result_json},"code":{code_json}}}"#);

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

        assert_eq!(response.msg(), msg);
        assert_eq!(response.result(), result);
        assert_eq!(response.code(), Some(code));
    }
}