redmine_api/api/
attachments.rs1use derive_builder::Builder;
10use reqwest::Method;
11use std::borrow::Cow;
12
13use crate::api::users::UserEssentials;
14use crate::api::{Endpoint, ReturnsJsonResponse};
15
16#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
20pub struct Attachment {
21 pub id: u64,
23 pub filename: String,
25 pub filesize: u64,
27 pub content_type: Option<String>,
29 #[serde(default)]
31 pub description: Option<String>,
32 pub content_url: String,
34 pub author: UserEssentials,
36 #[serde(
38 serialize_with = "crate::api::serialize_rfc3339",
39 deserialize_with = "crate::api::deserialize_rfc3339"
40 )]
41 pub created_on: time::OffsetDateTime,
42}
43
44#[derive(Debug, Clone, Builder)]
46#[builder(setter(strip_option))]
47pub struct GetAttachment {
48 id: u64,
50}
51
52impl ReturnsJsonResponse for GetAttachment {}
53
54impl GetAttachment {
55 #[must_use]
57 pub fn builder() -> GetAttachmentBuilder {
58 GetAttachmentBuilder::default()
59 }
60}
61
62impl Endpoint for GetAttachment {
63 fn method(&self) -> Method {
64 Method::GET
65 }
66
67 fn endpoint(&self) -> Cow<'static, str> {
68 format!("attachments/{}.json", &self.id).into()
69 }
70}
71
72#[derive(Debug, Clone, Builder)]
74#[builder(setter(strip_option))]
75pub struct DeleteAttachment {
76 id: u64,
78}
79
80impl DeleteAttachment {
81 #[must_use]
83 pub fn builder() -> DeleteAttachmentBuilder {
84 DeleteAttachmentBuilder::default()
85 }
86}
87
88impl Endpoint for DeleteAttachment {
89 fn method(&self) -> Method {
90 Method::DELETE
91 }
92
93 fn endpoint(&self) -> Cow<'static, str> {
94 format!("attachments/{}.json", &self.id).into()
95 }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
100pub struct AttachmentWrapper<T> {
101 pub attachment: T,
103}
104
105#[cfg(test)]
106mod test {
107 use super::*;
108 use pretty_assertions::assert_eq;
109 use std::error::Error;
110 use tracing_test::traced_test;
111
112 #[traced_test]
113 #[test]
114 fn test_get_attachment() -> Result<(), Box<dyn Error>> {
115 dotenvy::dotenv()?;
116 let redmine = crate::api::Redmine::from_env()?;
117 let endpoint = GetAttachment::builder().id(3).build()?;
118 redmine.json_response_body::<_, AttachmentWrapper<Attachment>>(&endpoint)?;
119 Ok(())
120 }
121
122 #[traced_test]
127 #[test]
128 fn test_completeness_attachment_type() -> Result<(), Box<dyn Error>> {
129 dotenvy::dotenv()?;
130 let redmine = crate::api::Redmine::from_env()?;
131 let endpoint = GetAttachment::builder().id(3).build()?;
132 let AttachmentWrapper { attachment: value } =
133 redmine.json_response_body::<_, AttachmentWrapper<serde_json::Value>>(&endpoint)?;
134 let o: Attachment = serde_json::from_value(value.clone())?;
135 let reserialized = serde_json::to_value(o)?;
136 assert_eq!(value, reserialized);
137 Ok(())
138 }
139}