pcloud/file/
checksum.rs

1use super::{File, FileIdentifier};
2
3/// Represents the checksum information for a file stored on pCloud.
4///
5/// This struct includes various checksum types (MD5, SHA-1, SHA-256) as well
6/// as metadata about the file itself.
7#[derive(Debug, serde::Deserialize)]
8pub struct FileChecksum {
9    pub md5: Option<String>,
10    pub sha256: Option<String>,
11    pub sha1: String,
12    pub metadata: File,
13}
14
15impl crate::Client {
16    /// Retrieves the checksums and metadata for a file on pCloud.
17    ///
18    /// This function calls the `checksumfile` endpoint and returns a
19    /// [`FileChecksum`] struct containing the MD5, SHA-1, and SHA-256 hashes,
20    /// as well as basic metadata for the specified file.
21    ///
22    /// # Arguments
23    ///
24    /// * `identifier` - A type that can be converted into a [`FileIdentifier`] used to identify the file (e.g., by file ID or path).
25    ///
26    /// # Errors
27    ///
28    /// Returns a [`crate::Error`] if the request fails or if the file cannot be found.
29    ///
30    /// # Examples
31    ///
32    /// ```rust,no_run
33    /// # async fn example(client: &pcloud::Client) -> Result<(), pcloud::Error> {
34    /// let checksum = client.get_file_checksum("myfolder/myfile.txt").await?;
35    /// println!("SHA-1: {}", checksum.sha1);
36    /// # Ok(())
37    /// # }
38    /// ```
39    pub async fn get_file_checksum(
40        &self,
41        identifier: impl Into<FileIdentifier<'_>>,
42    ) -> crate::Result<FileChecksum> {
43        self.get_request("checksumfile", identifier.into()).await
44    }
45}
46
47#[cfg(test)]
48mod http_tests {
49    use crate::{Client, Credentials};
50    use mockito::Matcher;
51
52    #[tokio::test]
53    async fn success() {
54        let mut server = mockito::Server::new_async().await;
55        let m = server
56            .mock("GET", "/checksumfile")
57            .match_query(Matcher::AllOf(vec![
58                Matcher::UrlEncoded("access_token".into(), "access-token".into()),
59                Matcher::UrlEncoded("fileid".into(), "42".into()),
60            ]))
61            .with_status(200)
62            .with_body(
63                r#"{
64    "result": 0,
65    "sha256": "d535d3354f9d36741e311ac0855c5cde1e8e90eae947f320469f17514d182e19",
66    "sha1": "5b03ef4fa47ed13f2156ec5395866dadbde4e9dc",
67    "metadata": {
68        "name": "C61EWBrr2sU16GM4.bin",
69        "created": "Sat, 24 Jul 2021 07:38:41 +0000",
70        "thumb": false,
71        "modified": "Sat, 24 Jul 2021 07:38:41 +0000",
72        "isfolder": false,
73        "fileid": 5257731387,
74        "hash": 9403476549337371523,
75        "comments": 0,
76        "category": 0,
77        "id": "f5257731387",
78        "isshared": false,
79        "ismine": true,
80        "size": 10485760,
81        "parentfolderid": 1075398908,
82        "contenttype": "application\/octet-stream",
83        "icon": "file"
84    }
85}"#,
86            )
87            .create();
88        let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
89        let result = client.get_file_checksum(42).await.unwrap();
90        assert_eq!(
91            result.sha256.unwrap(),
92            "d535d3354f9d36741e311ac0855c5cde1e8e90eae947f320469f17514d182e19"
93        );
94        m.assert();
95    }
96}