redmine_api/api/
enumerations.rs

1//! Enumerations Rest API Endpoint definitions
2//!
3//! [Redmine Documentation](https://www.redmine.org/projects/redmine/wiki/Rest_Enumerations)
4//!
5//! - [x] all issue priorities endpoint
6//! - [x] all time entry activities endpoint
7//! - [x] all document categories endpoint
8
9use derive_builder::Builder;
10use reqwest::Method;
11use std::borrow::Cow;
12
13use crate::api::{Endpoint, NoPagination, ReturnsJsonResponse};
14
15/// a minimal type for Redmine issue priorities included in
16/// other Redmine objects
17#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
18pub struct IssuePriorityEssentials {
19    /// numeric id
20    pub id: u64,
21    /// display name
22    pub name: String,
23}
24
25impl From<IssuePriority> for IssuePriorityEssentials {
26    fn from(v: IssuePriority) -> Self {
27        IssuePriorityEssentials {
28            id: v.id,
29            name: v.name,
30        }
31    }
32}
33
34impl From<&IssuePriority> for IssuePriorityEssentials {
35    fn from(v: &IssuePriority) -> Self {
36        IssuePriorityEssentials {
37            id: v.id,
38            name: v.name.to_owned(),
39        }
40    }
41}
42
43/// a type for issue priority to use as an API return type
44///
45/// alternatively you can use your own type limited to the fields you need
46#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
47pub struct IssuePriority {
48    /// numeric id
49    pub id: u64,
50    /// display name
51    pub name: String,
52    /// whether this value is the default value
53    pub is_default: bool,
54    /// whether this value is active
55    pub active: bool,
56}
57
58/// The endpoint for all issue priorities
59#[derive(Debug, Clone, Builder)]
60#[builder(setter(strip_option))]
61pub struct ListIssuePriorities {}
62
63impl ReturnsJsonResponse for ListIssuePriorities {}
64impl NoPagination for ListIssuePriorities {}
65
66impl ListIssuePriorities {
67    /// Create a builder for the endpoint.
68    #[must_use]
69    pub fn builder() -> ListIssuePrioritiesBuilder {
70        ListIssuePrioritiesBuilder::default()
71    }
72}
73
74impl Endpoint for ListIssuePriorities {
75    fn method(&self) -> Method {
76        Method::GET
77    }
78
79    fn endpoint(&self) -> Cow<'static, str> {
80        "enumerations/issue_priorities.json".into()
81    }
82}
83
84/// helper struct for outer layers with a issue_priorities field holding the inner data
85#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
86pub struct IssuePrioritiesWrapper<T> {
87    /// to parse JSON with issue_priorities key
88    pub issue_priorities: Vec<T>,
89}
90
91/// a minimal type for Redmine time entry activities included in
92/// other Redmine objects
93#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
94pub struct TimeEntryActivityEssentials {
95    /// numeric id
96    pub id: u64,
97    /// display name
98    pub name: String,
99}
100
101impl From<TimeEntryActivity> for TimeEntryActivityEssentials {
102    fn from(v: TimeEntryActivity) -> Self {
103        TimeEntryActivityEssentials {
104            id: v.id,
105            name: v.name,
106        }
107    }
108}
109
110impl From<&TimeEntryActivity> for TimeEntryActivityEssentials {
111    fn from(v: &TimeEntryActivity) -> Self {
112        TimeEntryActivityEssentials {
113            id: v.id,
114            name: v.name.to_owned(),
115        }
116    }
117}
118
119/// a type for time entry activity to use as an API return type
120///
121/// alternatively you can use your own type limited to the fields you need
122#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
123pub struct TimeEntryActivity {
124    /// numeric id
125    pub id: u64,
126    /// display name
127    pub name: String,
128    /// whether this value is the default value
129    pub is_default: bool,
130    /// whether this value is active
131    pub active: bool,
132}
133
134/// The endpoint for all time entry activities
135#[derive(Debug, Clone, Builder)]
136#[builder(setter(strip_option))]
137pub struct ListTimeEntryActivities {}
138
139impl ReturnsJsonResponse for ListTimeEntryActivities {}
140impl NoPagination for ListTimeEntryActivities {}
141
142impl ListTimeEntryActivities {
143    /// Create a builder for the endpoint.
144    #[must_use]
145    pub fn builder() -> ListTimeEntryActivitiesBuilder {
146        ListTimeEntryActivitiesBuilder::default()
147    }
148}
149
150impl Endpoint for ListTimeEntryActivities {
151    fn method(&self) -> Method {
152        Method::GET
153    }
154
155    fn endpoint(&self) -> Cow<'static, str> {
156        "enumerations/time_entry_activities.json".into()
157    }
158}
159
160/// helper struct for outer layers with a time_entry_activities field holding the inner data
161#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
162pub struct TimeEntryActivitiesWrapper<T> {
163    /// to parse JSON with time_entry_activities key
164    pub time_entry_activities: Vec<T>,
165}
166
167/// a minimal type for Redmine document categories included in
168/// other Redmine objects
169#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
170pub struct DocumentCategoryEssentials {
171    /// numeric id
172    pub id: u64,
173    /// display name
174    pub name: String,
175}
176
177impl From<DocumentCategory> for DocumentCategoryEssentials {
178    fn from(v: DocumentCategory) -> Self {
179        DocumentCategoryEssentials {
180            id: v.id,
181            name: v.name,
182        }
183    }
184}
185
186impl From<&DocumentCategory> for DocumentCategoryEssentials {
187    fn from(v: &DocumentCategory) -> Self {
188        DocumentCategoryEssentials {
189            id: v.id,
190            name: v.name.to_owned(),
191        }
192    }
193}
194
195/// a type for document category to use as an API return type
196///
197/// alternatively you can use your own type limited to the fields you need
198#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
199pub struct DocumentCategory {
200    /// numeric id
201    pub id: u64,
202    /// display name
203    pub name: String,
204    /// whether this value is the default value
205    pub is_default: bool,
206    /// whether this value is active
207    pub active: bool,
208}
209
210/// The endpoint for all document categories
211#[derive(Debug, Clone, Builder)]
212#[builder(setter(strip_option))]
213pub struct ListDocumentCategories {}
214
215impl ReturnsJsonResponse for ListDocumentCategories {}
216impl NoPagination for ListDocumentCategories {}
217
218impl ListDocumentCategories {
219    /// Create a builder for the endpoint.
220    #[must_use]
221    pub fn builder() -> ListDocumentCategoriesBuilder {
222        ListDocumentCategoriesBuilder::default()
223    }
224}
225
226impl Endpoint for ListDocumentCategories {
227    fn method(&self) -> Method {
228        Method::GET
229    }
230
231    fn endpoint(&self) -> Cow<'static, str> {
232        "enumerations/document_categories.json".into()
233    }
234}
235
236/// helper struct for outer layers with a document_categories field holding the inner data
237#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
238pub struct DocumentCategoriesWrapper<T> {
239    /// to parse JSON with document_categories key
240    pub document_categories: Vec<T>,
241}
242
243#[cfg(test)]
244mod test {
245    use super::*;
246    use std::error::Error;
247    use tracing_test::traced_test;
248
249    #[traced_test]
250    #[test]
251    fn test_list_issue_priorities_no_pagination() -> Result<(), Box<dyn Error>> {
252        dotenvy::dotenv()?;
253        let redmine = crate::api::Redmine::from_env(
254            reqwest::blocking::Client::builder()
255                .use_rustls_tls()
256                .build()?,
257        )?;
258        let endpoint = ListIssuePriorities::builder().build()?;
259        redmine.json_response_body::<_, IssuePrioritiesWrapper<IssuePriority>>(&endpoint)?;
260        Ok(())
261    }
262
263    #[traced_test]
264    #[test]
265    fn test_list_time_entry_activities_no_pagination() -> Result<(), Box<dyn Error>> {
266        dotenvy::dotenv()?;
267        let redmine = crate::api::Redmine::from_env(
268            reqwest::blocking::Client::builder()
269                .use_rustls_tls()
270                .build()?,
271        )?;
272        let endpoint = ListTimeEntryActivities::builder().build()?;
273        redmine
274            .json_response_body::<_, TimeEntryActivitiesWrapper<TimeEntryActivity>>(&endpoint)?;
275        Ok(())
276    }
277
278    #[traced_test]
279    #[test]
280    fn test_list_document_categories_no_pagination() -> Result<(), Box<dyn Error>> {
281        dotenvy::dotenv()?;
282        let redmine = crate::api::Redmine::from_env(
283            reqwest::blocking::Client::builder()
284                .use_rustls_tls()
285                .build()?,
286        )?;
287        let endpoint = ListDocumentCategories::builder().build()?;
288        redmine.json_response_body::<_, DocumentCategoriesWrapper<DocumentCategory>>(&endpoint)?;
289        Ok(())
290    }
291}