pcloud/file/
movefile.rs

1use crate::folder::{FolderIdentifier, ToFolderIdentifier};
2
3use super::{File, FileIdentifier, FileResponse};
4
5/// Parameters required to move a file to a new folder.
6///
7/// This structure is serialized and sent to the `renamefile` endpoint.
8/// It flattens both the source file identifier and the target folder identifier
9/// into the request payload.
10#[derive(serde::Serialize)]
11struct FileMoveParams<'a> {
12    /// The file to move (by path or file ID).
13    #[serde(flatten)]
14    from: FileIdentifier<'a>,
15
16    /// The target folder to move the file into.
17    #[serde(flatten)]
18    to: ToFolderIdentifier<'a>,
19}
20
21impl crate::Client {
22    /// Moves a file to a different folder on pCloud.
23    ///
24    /// This function calls the `renamefile` API endpoint to move the specified file
25    /// to a new folder. The file is identified either by its file ID or by path.
26    ///
27    /// # Arguments
28    ///
29    /// * `file` - A value that can be converted into a [`FileIdentifier`] (e.g., file ID or path).
30    /// * `to_folder` - A value that can be converted into a [`FolderIdentifier`] representing the destination folder.
31    ///
32    /// # Returns
33    ///
34    /// On success, returns a [`File`] struct containing metadata about the moved file.
35    ///
36    /// # Errors
37    ///
38    /// Returns a [`crate::Error`] if the file or folder is not found, or if the API request fails.
39    ///
40    /// # Examples
41    ///
42    /// ```rust,no_run
43    /// # async fn example(client: &pcloud::Client) -> Result<(), pcloud::Error> {
44    /// let file = client.move_file(12345678u64, "/new/folder").await?;
45    /// println!("Moved file name: {}", file.base.name);
46    /// # Ok(())
47    /// # }
48    /// ```
49    pub async fn move_file(
50        &self,
51        file: impl Into<FileIdentifier<'_>>,
52        to_folder: impl Into<FolderIdentifier<'_>>,
53    ) -> crate::Result<File> {
54        self.get_request::<FileResponse, _>(
55            "renamefile",
56            FileMoveParams {
57                from: file.into(),
58                to: ToFolderIdentifier(to_folder.into()),
59            },
60        )
61        .await
62        .map(|res| res.metadata)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use crate::{Client, Credentials};
69    use mockito::Matcher;
70
71    #[tokio::test]
72    async fn success() {
73        let mut server = mockito::Server::new_async().await;
74        let m = server
75            .mock("GET", "/renamefile")
76            .match_query(Matcher::AllOf(vec![
77                Matcher::UrlEncoded("access_token".into(), "access-token".into()),
78                Matcher::UrlEncoded("fileid".into(), "42".into()),
79                Matcher::UrlEncoded("topath".into(), "/this/dir/".into()),
80            ]))
81            .with_status(200)
82            .with_body(
83                r#"{
84    "result": 0,
85    "metadata": {
86        "name": "yolo.bin",
87        "created": "Sat, 24 Jul 2021 07:38:41 +0000",
88        "thumb": false,
89        "modified": "Sat, 24 Jul 2021 07:38:41 +0000",
90        "isfolder": false,
91        "isdeleted": true,
92        "fileid": 42,
93        "hash": 9403476549337371523,
94        "comments": 0,
95        "category": 0,
96        "id": "f5257731387",
97        "isshared": false,
98        "ismine": true,
99        "size": 10485760,
100        "parentfolderid": 1075398908,
101        "contenttype": "application\/octet-stream",
102        "icon": "file"
103    }
104}"#,
105            )
106            .create();
107        let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
108        let result = client.move_file(42, "/this/dir/").await.unwrap();
109        assert_eq!(result.file_id, 42);
110        m.assert();
111    }
112}