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}