pcloud/folder/movefolder.rs
1use super::{Folder, FolderIdentifier, FolderResponse, ToFolderIdentifier};
2
3/// Internal parameter structure for moving a folder.
4#[derive(serde::Serialize)]
5struct FolderMoveParams<'a> {
6 /// The source folder identifier (either folder ID or path).
7 #[serde(flatten)]
8 from: FolderIdentifier<'a>,
9
10 /// The destination folder identifier (either folder ID or path).
11 #[serde(flatten)]
12 to: ToFolderIdentifier<'a>,
13}
14
15impl crate::Client {
16 /// Moves a folder to a new location in pCloud.
17 ///
18 /// This function calls the `renamefolder` API endpoint and moves the specified folder
19 /// from its current location to the target folder. Both the source and destination can
20 /// be specified either by folder ID or path.
21 ///
22 /// # Arguments
23 ///
24 /// * `folder` - A value that can be converted into a [`FolderIdentifier`] (e.g., folder ID or path).
25 /// * `to_folder` - The target folder identifier (e.g., folder ID or path) to move the folder into.
26 ///
27 /// # Returns
28 ///
29 /// A [`Folder`] struct containing the metadata of the moved folder.
30 ///
31 /// # Errors
32 ///
33 /// Returns a [`crate::Error`] if the move operation fails, such as if either folder is not accessible
34 /// or the API call encounters an issue.
35 ///
36 /// # Examples
37 ///
38 /// ```rust,no_run
39 /// # async fn example(client: &pcloud::Client) -> Result<(), pcloud::Error> {
40 /// let moved_folder = client.move_folder("/OldFolder", "/NewFolder").await?;
41 /// println!("Moved folder: {:?}", moved_folder.base.name);
42 /// # Ok(())
43 /// # }
44 /// ```
45 pub async fn move_folder(
46 &self,
47 folder: impl Into<FolderIdentifier<'_>>,
48 to_folder: impl Into<FolderIdentifier<'_>>,
49 ) -> crate::Result<Folder> {
50 self.get_request::<FolderResponse, _>(
51 "renamefolder",
52 FolderMoveParams {
53 from: folder.into(),
54 to: ToFolderIdentifier(to_folder.into()),
55 },
56 )
57 .await
58 .map(|res| res.metadata)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use crate::{Client, Credentials};
65 use mockito::Matcher;
66
67 #[tokio::test]
68 async fn success() {
69 let mut server = mockito::Server::new_async().await;
70 let m = server
71 .mock("GET", "/renamefolder")
72 .match_query(Matcher::AllOf(vec![
73 Matcher::UrlEncoded("access_token".into(), "access-token".into()),
74 Matcher::UrlEncoded("folderid".into(), "42".into()),
75 Matcher::UrlEncoded("topath".into(), "/this/dir/".into()),
76 ]))
77 .with_status(200)
78 .with_body(
79 r#"{
80 "result": 0,
81 "metadata": {
82 "path": "\/testing",
83 "name": "testing",
84 "created": "Fri, 23 Jul 2021 19:39:09 +0000",
85 "ismine": true,
86 "thumb": false,
87 "modified": "Fri, 23 Jul 2021 19:39:09 +0000",
88 "id": "d10",
89 "isshared": false,
90 "icon": "folder",
91 "isfolder": true,
92 "parentfolderid": 0,
93 "folderid": 42
94 }
95}"#,
96 )
97 .create();
98 let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
99 let result = client.move_folder(42, "/this/dir/").await.unwrap();
100 assert_eq!(result.folder_id, 42);
101 m.assert();
102 }
103}