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, NoPagination, 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 {}
53impl NoPagination for GetAttachment {}
54
55impl GetAttachment {
56 #[must_use]
58 pub fn builder() -> GetAttachmentBuilder {
59 GetAttachmentBuilder::default()
60 }
61}
62
63impl Endpoint for GetAttachment {
64 fn method(&self) -> Method {
65 Method::GET
66 }
67
68 fn endpoint(&self) -> Cow<'static, str> {
69 format!("attachments/{}.json", &self.id).into()
70 }
71}
72
73#[derive(Debug, Clone, Builder)]
75#[builder(setter(strip_option))]
76pub struct DeleteAttachment {
77 id: u64,
79}
80
81impl DeleteAttachment {
82 #[must_use]
84 pub fn builder() -> DeleteAttachmentBuilder {
85 DeleteAttachmentBuilder::default()
86 }
87}
88
89impl Endpoint for DeleteAttachment {
90 fn method(&self) -> Method {
91 Method::DELETE
92 }
93
94 fn endpoint(&self) -> Cow<'static, str> {
95 format!("attachments/{}.json", &self.id).into()
96 }
97}
98
99#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
101pub struct AttachmentWrapper<T> {
102 pub attachment: T,
104}
105
106#[cfg(test)]
107mod test {
108 use super::*;
109 use pretty_assertions::assert_eq;
110 use std::error::Error;
111 use tracing_test::traced_test;
112
113 #[traced_test]
114 #[test]
115 fn test_get_attachment() -> Result<(), Box<dyn Error>> {
116 dotenvy::dotenv()?;
117 let redmine = crate::api::Redmine::from_env()?;
118 let endpoint = GetAttachment::builder().id(38468).build()?;
119 redmine.json_response_body::<_, AttachmentWrapper<Attachment>>(&endpoint)?;
120 Ok(())
121 }
122
123 #[traced_test]
128 #[test]
129 fn test_completeness_attachment_type() -> Result<(), Box<dyn Error>> {
130 dotenvy::dotenv()?;
131 let redmine = crate::api::Redmine::from_env()?;
132 let endpoint = GetAttachment::builder().id(38468).build()?;
133 let AttachmentWrapper { attachment: value } =
134 redmine.json_response_body::<_, AttachmentWrapper<serde_json::Value>>(&endpoint)?;
135 let o: Attachment = serde_json::from_value(value.clone())?;
136 let reserialized = serde_json::to_value(o)?;
137 assert_eq!(value, reserialized);
138 Ok(())
139 }
140}