1use super::{Folder, FolderIdentifier, FolderResponse};
2
3#[derive(Default, serde::Serialize)]
8pub struct ListFolderOptions {
9 #[serde(
11 skip_serializing_if = "crate::request::is_false",
12 serialize_with = "crate::request::serialize_bool"
13 )]
14 recursive: bool,
15
16 #[serde(
18 rename = "showdeleted",
19 skip_serializing_if = "crate::request::is_false",
20 serialize_with = "crate::request::serialize_bool"
21 )]
22 show_deleted: bool,
23
24 #[serde(
26 skip_serializing_if = "crate::request::is_false",
27 serialize_with = "crate::request::serialize_bool"
28 )]
29 no_files: bool,
30
31 #[serde(
33 skip_serializing_if = "crate::request::is_false",
34 serialize_with = "crate::request::serialize_bool"
35 )]
36 no_shares: bool,
37}
38
39impl ListFolderOptions {
40 pub fn with_recursive(mut self) -> Self {
42 self.recursive = true;
43 self
44 }
45
46 pub fn with_show_deleted(mut self) -> Self {
48 self.show_deleted = true;
49 self
50 }
51
52 pub fn with_no_files(mut self) -> Self {
54 self.no_files = true;
55 self
56 }
57
58 pub fn with_no_shares(mut self) -> Self {
60 self.no_shares = true;
61 self
62 }
63}
64
65#[derive(serde::Serialize)]
67struct Params<'a> {
68 #[serde(flatten)]
69 identifier: FolderIdentifier<'a>,
70 #[serde(flatten)]
71 options: ListFolderOptions,
72}
73
74impl crate::Client {
75 pub async fn list_folder(
102 &self,
103 identifier: impl Into<FolderIdentifier<'_>>,
104 ) -> crate::Result<Folder> {
105 self.list_folder_with_options(identifier, Default::default())
106 .await
107 }
108
109 pub async fn list_folder_with_options(
142 &self,
143 identifier: impl Into<FolderIdentifier<'_>>,
144 options: ListFolderOptions,
145 ) -> crate::Result<Folder> {
146 let params = Params {
147 identifier: identifier.into(),
148 options,
149 };
150 self.get_request::<FolderResponse, _>("listfolder", params)
151 .await
152 .map(|res| res.metadata)
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use crate::{Client, Credentials};
159 use mockito::Matcher;
160
161 #[tokio::test]
162 async fn success_with_options() {
163 let mut server = mockito::Server::new_async().await;
164 let m = server
165 .mock("GET", "/listfolder")
166 .match_query(Matcher::AllOf(vec![
167 Matcher::UrlEncoded("access_token".into(), "access-token".into()),
168 Matcher::UrlEncoded("folderid".into(), "0".into()),
169 Matcher::UrlEncoded("recursive".into(), "1".into()),
170 Matcher::UrlEncoded("showdeleted".into(), "1".into()),
171 ]))
172 .with_status(200)
173 .with_body(
174 r#"{
175 "result": 0,
176 "metadata": {
177 "path": "\/testing",
178 "name": "testing",
179 "created": "Fri, 23 Jul 2021 19:39:09 +0000",
180 "ismine": true,
181 "thumb": false,
182 "modified": "Fri, 23 Jul 2021 19:39:09 +0000",
183 "id": "d10",
184 "isshared": false,
185 "icon": "folder",
186 "isfolder": true,
187 "parentfolderid": 0,
188 "folderid": 10
189 }
190}"#,
191 )
192 .create();
193 let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
194 let payload = client
195 .list_folder_with_options(
196 0,
197 super::ListFolderOptions::default()
198 .with_recursive()
199 .with_show_deleted(),
200 )
201 .await
202 .unwrap();
203 assert_eq!(payload.base.parent_folder_id, Some(0));
204 m.assert();
205 }
206
207 #[tokio::test]
208 async fn success() {
209 let mut server = mockito::Server::new_async().await;
210 let m = server
211 .mock("GET", "/listfolder")
212 .match_query(Matcher::AllOf(vec![
213 Matcher::UrlEncoded("access_token".into(), "access-token".into()),
214 Matcher::UrlEncoded("folderid".into(), "0".into()),
215 ]))
216 .with_status(200)
217 .with_body(
218 r#"{
219 "result": 0,
220 "metadata": {
221 "path": "\/testing",
222 "name": "testing",
223 "created": "Fri, 23 Jul 2021 19:39:09 +0000",
224 "ismine": true,
225 "thumb": false,
226 "modified": "Fri, 23 Jul 2021 19:39:09 +0000",
227 "id": "d10",
228 "isshared": false,
229 "icon": "folder",
230 "isfolder": true,
231 "parentfolderid": 0,
232 "folderid": 10
233 }
234}"#,
235 )
236 .create();
237 let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
238 let payload = client.list_folder(0).await.unwrap();
239 assert_eq!(payload.base.parent_folder_id, Some(0));
240 m.assert();
241 }
242
243 #[tokio::test]
244 async fn error() {
245 let mut server = mockito::Server::new_async().await;
246 let m = server
247 .mock("GET", "/listfolder")
248 .match_query(Matcher::AllOf(vec![
249 Matcher::UrlEncoded("access_token".into(), "access-token".into()),
250 Matcher::UrlEncoded("folderid".into(), "0".into()),
251 ]))
252 .with_status(200)
253 .with_body(r#"{ "result": 1020, "error": "something went wrong" }"#)
254 .create();
255 let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
256 let error = client.list_folder(0).await.unwrap_err();
257 assert!(matches!(error, crate::Error::Protocol(_, _)));
258 m.assert();
259 }
260}