1use crate::client::ConcurClient;
4use crate::error::Result;
5use crate::models::PagedResponse;
6use reqwest::Method;
7use serde::{Deserialize, Serialize};
8
9pub struct ListsApi<'a> {
11 client: &'a ConcurClient,
12}
13
14impl<'a> ListsApi<'a> {
15 pub fn new(client: &'a ConcurClient) -> Self {
16 Self { client }
17 }
18
19 pub async fn list(
21 &self,
22 page: Option<u32>,
23 sort_by: Option<&str>,
24 sort_direction: Option<&str>,
25 filters: Option<Vec<(&str, &str)>>,
26 ) -> Result<PagedResponse<List>> {
27 let mut path = "/list/v4/lists".to_string();
28 let mut params: Vec<(String, String)> = Vec::new();
29 if let Some(p) = page {
30 params.push(("page".to_string(), p.to_string()));
31 }
32 if let Some(s) = sort_by {
33 params.push(("sortBy".to_string(), s.to_string()));
34 }
35 if let Some(s) = sort_direction {
36 params.push(("sortDirection".to_string(), s.to_string()));
37 }
38 if let Some(f) = filters {
39 for (k, v) in f {
40 params.push((k.to_string(), v.to_string()));
41 }
42 }
43 if !params.is_empty() {
44 path.push('?');
45 path.push_str(
46 ¶ms
47 .iter()
48 .map(|(k, v)| format!("{}={}", k, urlencoding::encode(v)))
49 .collect::<Vec<_>>()
50 .join("&"),
51 );
52 }
53 self.client
54 .request(Method::GET, &path)
55 .await?
56 .send()
57 .await?
58 .json()
59 .await
60 .map_err(Into::into)
61 }
62
63 pub async fn create(&self, request: &CreateListRequest) -> Result<List> {
65 let req = self.client.request(Method::POST, "/list/v4/lists").await?;
66 let req = ConcurClient::with_json(req, request)?;
67 self.client.execute(req).await
68 }
69
70 pub async fn update(&self, list_id: &str, request: &CreateListRequest) -> Result<List> {
72 let req = self
73 .client
74 .request(Method::PUT, &format!("/list/v4/lists/{}", list_id))
75 .await?;
76 let req = ConcurClient::with_json(req, request)?;
77 self.client.execute(req).await
78 }
79
80 pub async fn delete(&self, list_id: &str) -> Result<()> {
82 self.client
83 .execute_unit(
84 self.client
85 .request(Method::DELETE, &format!("/list/v4/lists/{}", list_id))
86 .await?,
87 )
88 .await
89 }
90}
91
92pub struct ListItemsApi<'a> {
94 client: &'a ConcurClient,
95}
96
97impl<'a> ListItemsApi<'a> {
98 pub fn new(client: &'a ConcurClient) -> Self {
99 Self { client }
100 }
101
102 pub async fn get(&self, item_id: &str) -> Result<ListItem> {
104 self.client
105 .request(Method::GET, &format!("/list/v4/items/{}", item_id))
106 .await?
107 .send()
108 .await?
109 .json()
110 .await
111 .map_err(Into::into)
112 }
113
114 pub async fn create(&self, request: &CreateListItemRequest) -> Result<ListItem> {
116 let req = self.client.request(Method::POST, "/list/v4/items").await?;
117 let req = ConcurClient::with_json(req, request)?;
118 self.client.execute(req).await
119 }
120
121 pub async fn update(&self, item_id: &str, request: &CreateListItemRequest) -> Result<ListItem> {
123 let req = self
124 .client
125 .request(Method::PUT, &format!("/list/v4/items/{}", item_id))
126 .await?;
127 let req = ConcurClient::with_json(req, request)?;
128 self.client.execute(req).await
129 }
130
131 pub async fn delete(&self, item_id: &str) -> Result<()> {
133 self.client
134 .execute_unit(
135 self.client
136 .request(Method::DELETE, &format!("/list/v4/items/{}", item_id))
137 .await?,
138 )
139 .await
140 }
141
142 pub async fn delete_from_list(&self, list_id: &str, item_id: &str) -> Result<()> {
144 self.client
145 .execute_unit(
146 self.client
147 .request(
148 Method::DELETE,
149 &format!("/list/v4/lists/{}/items/{}", list_id, item_id),
150 )
151 .await?,
152 )
153 .await
154 }
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct List {
159 pub id: String,
160 pub value: String,
161 #[serde(rename = "levelCount")]
162 pub level_count: i32,
163 #[serde(rename = "searchCriteria")]
164 pub search_criteria: String,
165 #[serde(rename = "displayFormat")]
166 pub display_format: String,
167 pub category: ListCategory,
168 #[serde(rename = "isReadOnly")]
169 pub is_read_only: bool,
170 #[serde(rename = "isDeleted")]
171 pub is_deleted: bool,
172 #[serde(rename = "managedBy")]
173 pub managed_by: Option<String>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct ListCategory {
178 pub id: String,
179 #[serde(rename = "type")]
180 pub type_: String,
181}
182
183#[derive(Debug, Clone, Default, Serialize, Deserialize)]
184pub struct CreateListRequest {
185 pub value: String,
186 #[serde(rename = "searchCriteria")]
187 pub search_criteria: String,
188 #[serde(rename = "displayFormat")]
189 pub display_format: String,
190 #[serde(rename = "categoryId", skip_serializing_if = "Option::is_none")]
191 pub category_id: Option<String>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct ListItem {
196 pub id: String,
197 pub code: String,
198 #[serde(rename = "shortCode")]
199 pub short_code: String,
200 pub value: String,
201 #[serde(rename = "parentId")]
202 pub parent_id: Option<String>,
203 pub level: i32,
204 #[serde(rename = "isDeleted")]
205 pub is_deleted: bool,
206 pub lists: Vec<ListItemListRef>,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct ListItemListRef {
211 pub id: String,
212 #[serde(rename = "hasChildren")]
213 pub has_children: bool,
214}
215
216#[derive(Debug, Clone, Default, Serialize, Deserialize)]
217pub struct CreateListItemRequest {
218 #[serde(rename = "listId")]
219 pub list_id: String,
220 #[serde(rename = "shortCode")]
221 pub short_code: String,
222 pub value: String,
223 #[serde(rename = "parentId", skip_serializing_if = "Option::is_none")]
224 pub parent_id: Option<String>,
225 #[serde(rename = "parentCode", skip_serializing_if = "Option::is_none")]
226 pub parent_code: Option<String>,
227}