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}
55
56/// The endpoint for all issue priorities
57#[derive(Debug, Clone, Builder)]
58#[builder(setter(strip_option))]
59pub struct ListIssuePriorities {}
60
61impl ReturnsJsonResponse for ListIssuePriorities {}
62impl NoPagination for ListIssuePriorities {}
63
64impl ListIssuePriorities {
65    /// Create a builder for the endpoint.
66    #[must_use]
67    pub fn builder() -> ListIssuePrioritiesBuilder {
68        ListIssuePrioritiesBuilder::default()
69    }
70}
71
72impl Endpoint for ListIssuePriorities {
73    fn method(&self) -> Method {
74        Method::GET
75    }
76
77    fn endpoint(&self) -> Cow<'static, str> {
78        "enumerations/issue_priorities.json".into()
79    }
80}
81
82/// helper struct for outer layers with a issue_priorities field holding the inner data
83#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
84pub struct IssuePrioritiesWrapper<T> {
85    /// to parse JSON with issue_priorities key
86    pub issue_priorities: Vec<T>,
87}
88
89/// a minimal type for Redmine time entry activities included in
90/// other Redmine objects
91#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
92pub struct TimeEntryActivityEssentials {
93    /// numeric id
94    pub id: u64,
95    /// display name
96    pub name: String,
97}
98
99impl From<TimeEntryActivity> for TimeEntryActivityEssentials {
100    fn from(v: TimeEntryActivity) -> Self {
101        TimeEntryActivityEssentials {
102            id: v.id,
103            name: v.name,
104        }
105    }
106}
107
108impl From<&TimeEntryActivity> for TimeEntryActivityEssentials {
109    fn from(v: &TimeEntryActivity) -> Self {
110        TimeEntryActivityEssentials {
111            id: v.id,
112            name: v.name.to_owned(),
113        }
114    }
115}
116
117/// a type for time entry activity to use as an API return type
118///
119/// alternatively you can use your own type limited to the fields you need
120#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
121pub struct TimeEntryActivity {
122    /// numeric id
123    pub id: u64,
124    /// display name
125    pub name: String,
126    /// whether this value is the default value
127    pub is_default: bool,
128}
129
130/// The endpoint for all time entry activities
131#[derive(Debug, Clone, Builder)]
132#[builder(setter(strip_option))]
133pub struct ListTimeEntryActivities {}
134
135impl ReturnsJsonResponse for ListTimeEntryActivities {}
136impl NoPagination for ListTimeEntryActivities {}
137
138impl ListTimeEntryActivities {
139    /// Create a builder for the endpoint.
140    #[must_use]
141    pub fn builder() -> ListTimeEntryActivitiesBuilder {
142        ListTimeEntryActivitiesBuilder::default()
143    }
144}
145
146impl Endpoint for ListTimeEntryActivities {
147    fn method(&self) -> Method {
148        Method::GET
149    }
150
151    fn endpoint(&self) -> Cow<'static, str> {
152        "enumerations/time_entry_activities.json".into()
153    }
154}
155
156/// helper struct for outer layers with a time_entry_activities field holding the inner data
157#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
158pub struct TimeEntryActivitiesWrapper<T> {
159    /// to parse JSON with time_entry_activities key
160    pub time_entry_activities: Vec<T>,
161}
162
163/// a minimal type for Redmine document categories included in
164/// other Redmine objects
165#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
166pub struct DocumentCategoryEssentials {
167    /// numeric id
168    pub id: u64,
169    /// display name
170    pub name: String,
171}
172
173impl From<DocumentCategory> for DocumentCategoryEssentials {
174    fn from(v: DocumentCategory) -> Self {
175        DocumentCategoryEssentials {
176            id: v.id,
177            name: v.name,
178        }
179    }
180}
181
182impl From<&DocumentCategory> for DocumentCategoryEssentials {
183    fn from(v: &DocumentCategory) -> Self {
184        DocumentCategoryEssentials {
185            id: v.id,
186            name: v.name.to_owned(),
187        }
188    }
189}
190
191/// a type for document category to use as an API return type
192///
193/// alternatively you can use your own type limited to the fields you need
194#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
195pub struct DocumentCategory {
196    /// numeric id
197    pub id: u64,
198    /// display name
199    pub name: String,
200    /// whether this value is the default value
201    pub is_default: bool,
202}
203
204/// The endpoint for all document categories
205#[derive(Debug, Clone, Builder)]
206#[builder(setter(strip_option))]
207pub struct ListDocumentCategories {}
208
209impl ReturnsJsonResponse for ListDocumentCategories {}
210impl NoPagination for ListDocumentCategories {}
211
212impl ListDocumentCategories {
213    /// Create a builder for the endpoint.
214    #[must_use]
215    pub fn builder() -> ListDocumentCategoriesBuilder {
216        ListDocumentCategoriesBuilder::default()
217    }
218}
219
220impl Endpoint for ListDocumentCategories {
221    fn method(&self) -> Method {
222        Method::GET
223    }
224
225    fn endpoint(&self) -> Cow<'static, str> {
226        "enumerations/document_categories.json".into()
227    }
228}
229
230/// helper struct for outer layers with a document_categories field holding the inner data
231#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
232pub struct DocumentCategoriesWrapper<T> {
233    /// to parse JSON with document_categories key
234    pub document_categories: Vec<T>,
235}
236
237#[cfg(test)]
238mod test {
239    use super::*;
240    use std::error::Error;
241    use tracing_test::traced_test;
242
243    #[traced_test]
244    #[test]
245    fn test_list_issue_priorities_no_pagination() -> Result<(), Box<dyn Error>> {
246        dotenvy::dotenv()?;
247        let redmine = crate::api::Redmine::from_env()?;
248        let endpoint = ListIssuePriorities::builder().build()?;
249        redmine.json_response_body::<_, IssuePrioritiesWrapper<IssuePriority>>(&endpoint)?;
250        Ok(())
251    }
252
253    #[traced_test]
254    #[test]
255    fn test_list_time_entry_activities_no_pagination() -> Result<(), Box<dyn Error>> {
256        dotenvy::dotenv()?;
257        let redmine = crate::api::Redmine::from_env()?;
258        let endpoint = ListTimeEntryActivities::builder().build()?;
259        redmine
260            .json_response_body::<_, TimeEntryActivitiesWrapper<TimeEntryActivity>>(&endpoint)?;
261        Ok(())
262    }
263
264    #[traced_test]
265    #[test]
266    fn test_list_document_categories_no_pagination() -> Result<(), Box<dyn Error>> {
267        dotenvy::dotenv()?;
268        let redmine = crate::api::Redmine::from_env()?;
269        let endpoint = ListDocumentCategories::builder().build()?;
270        redmine.json_response_body::<_, DocumentCategoriesWrapper<DocumentCategory>>(&endpoint)?;
271        Ok(())
272    }
273}